Merge master

This commit is contained in:
Michael Ball 2020-02-06 01:20:11 -08:00
commit 7586112f72
217 changed files with 2853 additions and 3035 deletions

1
.gitignore vendored
View file

@ -33,6 +33,7 @@ pickle-email-*.html
.env.development .env.development
.env.test .env.test
.env.local .env.local
.envrc
docker-compose.override.yml docker-compose.override.yml
.DS_Store .DS_Store
.byebug_history .byebug_history

View file

@ -83,7 +83,6 @@ linters:
- "app/views/admin/questions/index.html.haml" - "app/views/admin/questions/index.html.haml"
- "app/views/admin/questions/show.html.haml" - "app/views/admin/questions/show.html.haml"
- "app/views/admin/registration_periods/_form.html.haml" - "app/views/admin/registration_periods/_form.html.haml"
- "app/views/admin/registration_periods/show.html.haml"
- "app/views/admin/registrations/_questions.html.haml" - "app/views/admin/registrations/_questions.html.haml"
- "app/views/admin/registrations/edit.html.haml" - "app/views/admin/registrations/edit.html.haml"
- "app/views/admin/registrations/index.csv.haml" - "app/views/admin/registrations/index.csv.haml"
@ -209,7 +208,7 @@ linters:
- "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/_user_menu.html.haml"
- "app/views/layouts/application.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"
- "app/views/payments/new.html.haml" - "app/views/payments/new.html.haml"
@ -229,6 +228,7 @@ linters:
- "app/views/schedules/_schedule.html.haml" - "app/views/schedules/_schedule.html.haml"
- "app/views/schedules/_schedule_item.html.haml" - "app/views/schedules/_schedule_item.html.haml"
- "app/views/schedules/_schedule_tabs.html.haml" - "app/views/schedules/_schedule_tabs.html.haml"
- "app/views/schedules/app.html.haml"
- "app/views/schedules/events.html.haml" - "app/views/schedules/events.html.haml"
- "app/views/schedules/show.html.haml" - "app/views/schedules/show.html.haml"
- "app/views/schedules/show.xml.haml" - "app/views/schedules/show.xml.haml"
@ -242,8 +242,6 @@ linters:
- "app/views/surveys/index.html.haml" - "app/views/surveys/index.html.haml"
- "app/views/surveys/show.html.haml" - "app/views/surveys/show.html.haml"
- "app/views/ticket_purchases/index.html.haml" - "app/views/ticket_purchases/index.html.haml"
- "app/views/tickets/_ticket.html.haml"
- "app/views/tickets/index.html.haml"
- "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"
@ -313,6 +311,7 @@ linters:
# Offense count: 1074 # Offense count: 1074
LineLength: LineLength:
max: 150
exclude: exclude:
- "app/views/admin/booths/_change_state_dropdown.html.haml" - "app/views/admin/booths/_change_state_dropdown.html.haml"
- "app/views/admin/booths/index.html.haml" - "app/views/admin/booths/index.html.haml"
@ -359,7 +358,6 @@ linters:
- "app/views/admin/questions/index.html.haml" - "app/views/admin/questions/index.html.haml"
- "app/views/admin/questions/show.html.haml" - "app/views/admin/questions/show.html.haml"
- "app/views/admin/registration_periods/_form.html.haml" - "app/views/admin/registration_periods/_form.html.haml"
- "app/views/admin/registration_periods/show.html.haml"
- "app/views/admin/registrations/edit.html.haml" - "app/views/admin/registrations/edit.html.haml"
- "app/views/admin/registrations/index.html.haml" - "app/views/admin/registrations/index.html.haml"
- "app/views/admin/reports/_all_events.html.haml" - "app/views/admin/reports/_all_events.html.haml"
@ -441,7 +439,7 @@ linters:
- "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/_user_menu.html.haml"
- "app/views/layouts/application.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"
- "app/views/proposals/_form.html.haml" - "app/views/proposals/_form.html.haml"
@ -467,8 +465,6 @@ linters:
- "app/views/surveys/_list.html.haml" - "app/views/surveys/_list.html.haml"
- "app/views/surveys/index.html.haml" - "app/views/surveys/index.html.haml"
- "app/views/surveys/show.html.haml" - "app/views/surveys/show.html.haml"
- "app/views/tickets/_ticket.html.haml"
- "app/views/tickets/index.html.haml"
- "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"
@ -546,7 +542,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/application.haml" - "app/views/layouts/application.html.haml"
- "app/views/payments/_payment.html.haml" - "app/views/payments/_payment.html.haml"
- "app/views/proposals/_form.html.haml" - "app/views/proposals/_form.html.haml"
- "app/views/proposals/_tooltip.html.haml" - "app/views/proposals/_tooltip.html.haml"
@ -560,7 +556,6 @@ linters:
- "app/views/shared/_media_item.html.haml" - "app/views/shared/_media_item.html.haml"
- "app/views/shared/_media_items.html.haml" - "app/views/shared/_media_items.html.haml"
- "app/views/tickets/_ticket.html.haml" - "app/views/tickets/_ticket.html.haml"
- "app/views/tickets/index.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"
@ -596,14 +591,13 @@ linters:
- "app/views/layouts/_admin.html.haml" - "app/views/layouts/_admin.html.haml"
- "app/views/layouts/_navigation.html.haml" - "app/views/layouts/_navigation.html.haml"
- "app/views/layouts/_user_menu.html.haml" - "app/views/layouts/_user_menu.html.haml"
- "app/views/layouts/application.haml" - "app/views/layouts/application.html.haml"
- "app/views/proposals/_encouragement_text.html.haml" - "app/views/proposals/_encouragement_text.html.haml"
- "app/views/proposals/new.html.haml" - "app/views/proposals/new.html.haml"
- "app/views/proposals/registrations.html.haml" - "app/views/proposals/registrations.html.haml"
- "app/views/proposals/show.html.haml" - "app/views/proposals/show.html.haml"
- "app/views/schedules/events.html.haml" - "app/views/schedules/events.html.haml"
- "app/views/schedules/show.xml.haml" - "app/views/schedules/show.xml.haml"
- "app/views/tickets/index.html.haml"
# Offense count: 2 # Offense count: 2
FinalNewline: FinalNewline:
@ -642,7 +636,6 @@ linters:
- "app/views/conference_registrations/_volunteer.html.haml" - "app/views/conference_registrations/_volunteer.html.haml"
- "app/views/devise/passwords/new.html.haml" - "app/views/devise/passwords/new.html.haml"
- "app/views/payments/new.html.haml" - "app/views/payments/new.html.haml"
- "app/views/tickets/index.html.haml"
# Offense count: 13 # Offense count: 13

View file

@ -1,12 +1,13 @@
# This configuration was generated by # This configuration was generated by
# `rubocop --auto-gen-config` # `rubocop --auto-gen-config`
# on 2018-09-08 03:47:39 +0200 using RuboCop version 0.58.2. # on 2019-10-16 20:30:53 -0700 using RuboCop version 0.75.1.
# The point is for the user to remove these configuration records # The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base. # one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new # Note that changes in the inspected code, or installation of new
# versions of RuboCop, may require this file to be generated again. # versions of RuboCop, may require this file to be generated again.
# Offense count: 381 # Offense count: 351
# Cop supports --auto-correct.
Capybara/CurrentPathExpectation: Capybara/CurrentPathExpectation:
Exclude: Exclude:
- 'spec/features/base_controller_spec.rb' - 'spec/features/base_controller_spec.rb'
@ -23,25 +24,12 @@ Capybara/CurrentPathExpectation:
- 'spec/features/track_organizer_ability_spec.rb' - 'spec/features/track_organizer_ability_spec.rb'
- 'spec/features/user_ability_spec.rb' - 'spec/features/user_ability_spec.rb'
# Offense count: 170 # Offense count: 161
# Cop supports --auto-correct. # Cop supports --auto-correct.
# Configuration parameters: EnabledMethods. # Configuration parameters: EnabledMethods.
Capybara/FeatureMethods: Capybara/FeatureMethods:
Enabled: false Enabled: false
# Offense count: 140
# Cop supports --auto-correct.
FactoryBot/AttributeDefinedStatically:
Enabled: false
# Offense count: 1
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, IndentationWidth.
# SupportedStyles: with_first_parameter, with_fixed_indentation
Layout/AlignParameters:
Exclude:
- 'Vagrantfile'
# Offense count: 4 # Offense count: 4
# Cop supports --auto-correct. # Cop supports --auto-correct.
Layout/ClosingParenthesisIndentation: Layout/ClosingParenthesisIndentation:
@ -75,7 +63,7 @@ Layout/EmptyLineAfterMagicComment:
Exclude: Exclude:
- 'spec/models/conference_spec.rb' - 'spec/models/conference_spec.rb'
# Offense count: 121 # Offense count: 118
# Cop supports --auto-correct. # Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle. # Configuration parameters: EnforcedStyle.
# SupportedStyles: empty_lines, no_empty_lines # SupportedStyles: empty_lines, no_empty_lines
@ -88,9 +76,9 @@ Layout/EmptyLinesAroundExceptionHandlingKeywords:
Exclude: Exclude:
- 'app/models/payment.rb' - 'app/models/payment.rb'
# Offense count: 51 # Offense count: 14
# Cop supports --auto-correct. # Cop supports --auto-correct.
# Configuration parameters: AllowForAlignment, ForceEqualSignAlignment. # Configuration parameters: AllowForAlignment, AllowBeforeTrailingComments, ForceEqualSignAlignment.
Layout/ExtraSpacing: Layout/ExtraSpacing:
Exclude: Exclude:
- 'Guardfile' - 'Guardfile'
@ -103,52 +91,49 @@ Layout/ExtraSpacing:
- 'db/migrate/20140623101032_create_ahoy_events.rb' - 'db/migrate/20140623101032_create_ahoy_events.rb'
- 'db/migrate/20140701123203_add_events_per_week_to_conference.rb' - 'db/migrate/20140701123203_add_events_per_week_to_conference.rb'
- 'db/migrate/20140719160903_create_delayed_jobs.rb' - 'db/migrate/20140719160903_create_delayed_jobs.rb'
- 'db/schema.rb'
- 'spec/models/conference_spec.rb' - 'spec/models/conference_spec.rb'
# Offense count: 47 # Offense count: 5
# Cop supports --auto-correct.
# Configuration parameters: IndentationWidth.
Layout/IndentAssignment:
Exclude:
- 'app/helpers/format_helper.rb'
- 'config/environments/development.rb'
# Offense count: 43
# Cop supports --auto-correct. # Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, IndentationWidth. # Configuration parameters: EnforcedStyle, IndentationWidth.
# SupportedStyles: consistent, consistent_relative_to_receiver, special_for_inner_method_call, special_for_inner_method_call_in_parentheses # SupportedStyles: consistent, consistent_relative_to_receiver, special_for_inner_method_call, special_for_inner_method_call_in_parentheses
Layout/FirstParameterIndentation: Layout/IndentFirstArgument:
Enabled: false Enabled: false
# Offense count: 2 # Offense count: 2
# Cop supports --auto-correct. # Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, IndentationWidth. # Configuration parameters: EnforcedStyle, IndentationWidth.
# SupportedStyles: special_inside_parentheses, consistent, align_brackets # SupportedStyles: special_inside_parentheses, consistent, align_brackets
Layout/IndentArray: Layout/IndentFirstArrayElement:
Exclude: Exclude:
- 'app/models/conference.rb' - 'app/models/conference.rb'
# Offense count: 6
# Cop supports --auto-correct.
# Configuration parameters: IndentationWidth.
Layout/IndentAssignment:
Exclude:
- 'app/helpers/format_helper.rb'
- 'app/models/conference.rb'
- 'config/environments/development.rb'
# Offense count: 4 # Offense count: 4
# Cop supports --auto-correct. # Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, IndentationWidth. # Configuration parameters: EnforcedStyle, IndentationWidth.
# SupportedStyles: special_inside_parentheses, consistent, align_braces # SupportedStyles: special_inside_parentheses, consistent, align_braces
Layout/IndentHash: Layout/IndentFirstHashElement:
Exclude: Exclude:
- 'app/models/user.rb' - 'app/models/user.rb'
- 'config/routes.rb' - 'config/routes.rb'
- 'db/migrate/20140701123203_add_events_per_week_to_conference.rb' - 'db/migrate/20140701123203_add_events_per_week_to_conference.rb'
# Offense count: 3 # Offense count: 2
# Cop supports --auto-correct. # Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle. # Configuration parameters: EnforcedStyle.
# SupportedStyles: normal, rails # SupportedStyles: normal, indented_internal_methods
Layout/IndentationConsistency: Layout/IndentationConsistency:
Exclude: Exclude:
- 'app/controllers/users_controller.rb' - 'app/controllers/users_controller.rb'
- 'app/models/event.rb' - 'app/models/event.rb'
- 'spec/controllers/subscriptions_controller_spec.rb'
# Offense count: 1 # Offense count: 1
# Cop supports --auto-correct. # Cop supports --auto-correct.
@ -157,13 +142,13 @@ Layout/IndentationWidth:
Exclude: Exclude:
- 'app/controllers/users_controller.rb' - 'app/controllers/users_controller.rb'
# Offense count: 5 # Offense count: 4
# Cop supports --auto-correct. # Cop supports --auto-correct.
# Configuration parameters: AllowDoxygenCommentStyle.
Layout/LeadingCommentSpace: Layout/LeadingCommentSpace:
Exclude: Exclude:
- 'Guardfile' - 'Guardfile'
- 'app/models/comment.rb' - 'app/models/comment.rb'
- 'config/deploy.rb'
# Offense count: 1 # Offense count: 1
# Cop supports --auto-correct. # Cop supports --auto-correct.
@ -189,7 +174,7 @@ Layout/MultilineHashBraceLayout:
- 'config/routes.rb' - 'config/routes.rb'
- 'spec/models/event_spec.rb' - 'spec/models/event_spec.rb'
# Offense count: 40 # Offense count: 36
# Cop supports --auto-correct. # Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle. # Configuration parameters: EnforcedStyle.
# SupportedStyles: symmetrical, new_line, same_line # SupportedStyles: symmetrical, new_line, same_line
@ -252,7 +237,7 @@ Layout/SpaceAroundOperators:
- 'config/initializers/airbrake.rb' - 'config/initializers/airbrake.rb'
- 'lib/tasks/data.rake' - 'lib/tasks/data.rake'
# Offense count: 487 # Offense count: 138
# Cop supports --auto-correct. # Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces. # Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces.
# SupportedStyles: space, no_space # SupportedStyles: space, no_space
@ -302,20 +287,19 @@ Layout/SpaceInsideBlockBraces:
- 'app/models/ticket.rb' - 'app/models/ticket.rb'
- 'app/models/user.rb' - 'app/models/user.rb'
- 'lib/tasks/events_registrations.rake' - 'lib/tasks/events_registrations.rake'
- 'spec/ability/ability_spec.rb'
- 'spec/controllers/admin/event_schedules_controller_spec.rb' - 'spec/controllers/admin/event_schedules_controller_spec.rb'
- 'spec/controllers/admin/schedules_controller_spec.rb' - 'spec/controllers/admin/schedules_controller_spec.rb'
- 'spec/features/splashpage_spec.rb' - 'spec/features/splashpage_spec.rb'
- 'spec/ability/ability_spec.rb'
- 'spec/models/user_spec.rb' - 'spec/models/user_spec.rb'
# Offense count: 39 # Offense count: 37
# Cop supports --auto-correct. # Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces. # Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces.
# SupportedStyles: space, no_space, compact # SupportedStyles: space, no_space, compact
# SupportedStylesForEmptyBraces: space, no_space # SupportedStylesForEmptyBraces: space, no_space
Layout/SpaceInsideHashLiteralBraces: Layout/SpaceInsideHashLiteralBraces:
Exclude: Exclude:
- 'app/controllers/admin/conferences_controller.rb'
- 'app/controllers/api/v1/speakers_controller.rb' - 'app/controllers/api/v1/speakers_controller.rb'
- 'app/models/conference.rb' - 'app/models/conference.rb'
- 'app/models/event_type.rb' - 'app/models/event_type.rb'
@ -339,15 +323,13 @@ Layout/SpaceInsideParens:
Exclude: Exclude:
- 'app/views/admin/registrations/index.xlsx.axlsx' - 'app/views/admin/registrations/index.xlsx.axlsx'
# Offense count: 5 # Offense count: 2
# Cop supports --auto-correct. # Cop supports --auto-correct.
Layout/SpaceInsidePercentLiteralDelimiters: Layout/SpaceInsidePercentLiteralDelimiters:
Exclude: Exclude:
- 'Gemfile' - 'Gemfile'
- 'config/deploy.rb'
- 'config/initializers/assets.rb'
# Offense count: 2 # Offense count: 4
# Cop supports --auto-correct. # Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle. # Configuration parameters: EnforcedStyle.
# SupportedStyles: space, no_space # SupportedStyles: space, no_space
@ -355,6 +337,13 @@ Layout/SpaceInsideStringInterpolation:
Exclude: Exclude:
- 'config/initializers/active_record_log_subscriber.rb' - 'config/initializers/active_record_log_subscriber.rb'
# Offense count: 1
# Cop supports --auto-correct.
# Configuration parameters: IndentationWidth.
Layout/Tab:
Exclude:
- 'app/controllers/admin/resources_controller.rb'
# Offense count: 3 # Offense count: 3
# Cop supports --auto-correct. # Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle. # Configuration parameters: EnforcedStyle.
@ -389,6 +378,7 @@ Lint/DuplicatedKey:
- 'db/migrate/20140801170430_move_event_media_to_commercial.rb' - 'db/migrate/20140801170430_move_event_media_to_commercial.rb'
# Offense count: 1 # Offense count: 1
# Configuration parameters: AllowComments.
Lint/HandleExceptions: Lint/HandleExceptions:
Exclude: Exclude:
- 'bin/rspec' - 'bin/rspec'
@ -406,6 +396,12 @@ Lint/ScriptPermission:
- 'Guardfile' - 'Guardfile'
- 'Rakefile' - 'Rakefile'
# Offense count: 1
# Cop supports --auto-correct.
Lint/SendWithMixinArgument:
Exclude:
- 'config/initializers/active_record_log_subscriber.rb'
# Offense count: 1 # Offense count: 1
# Cop supports --auto-correct. # Cop supports --auto-correct.
# Configuration parameters: IgnoreEmptyBlocks, AllowUnusedKeywordArguments. # Configuration parameters: IgnoreEmptyBlocks, AllowUnusedKeywordArguments.
@ -420,15 +416,15 @@ Lint/UnusedMethodArgument:
Exclude: Exclude:
- 'config/initializers/fuckups.rb' - 'config/initializers/fuckups.rb'
# Offense count: 142 # Offense count: 139
Metrics/AbcSize: Metrics/AbcSize:
Max: 94 Max: 70
# Offense count: 331 # Offense count: 314
# Configuration parameters: CountComments, ExcludedMethods. # Configuration parameters: CountComments, ExcludedMethods.
# ExcludedMethods: refine # ExcludedMethods: refine
Metrics/BlockLength: Metrics/BlockLength:
Max: 1419 Max: 1344
# Offense count: 1 # Offense count: 1
# Configuration parameters: CountBlocks. # Configuration parameters: CountBlocks.
@ -438,16 +434,16 @@ Metrics/BlockNesting:
# Offense count: 13 # Offense count: 13
# Configuration parameters: CountComments. # Configuration parameters: CountComments.
Metrics/ClassLength: Metrics/ClassLength:
Max: 684 Max: 650
# Offense count: 32 # Offense count: 33
Metrics/CyclomaticComplexity: Metrics/CyclomaticComplexity:
Max: 14 Max: 14
# Offense count: 146 # Offense count: 147
# Configuration parameters: CountComments. # Configuration parameters: CountComments, ExcludedMethods.
Metrics/MethodLength: Metrics/MethodLength:
Max: 60 Max: 56
# Offense count: 5 # Offense count: 5
# Configuration parameters: CountComments. # Configuration parameters: CountComments.
@ -458,7 +454,7 @@ Metrics/ModuleLength:
Metrics/PerceivedComplexity: Metrics/PerceivedComplexity:
Max: 16 Max: 16
# Offense count: 17 # Offense count: 13
Naming/AccessorMethodName: Naming/AccessorMethodName:
Exclude: Exclude:
- 'app/models/conference.rb' - 'app/models/conference.rb'
@ -484,9 +480,17 @@ Naming/PredicateName:
- 'app/models/comment.rb' - 'app/models/comment.rb'
- 'app/models/contact.rb' - 'app/models/contact.rb'
# Offense count: 2
# Cop supports --auto-correct.
# Configuration parameters: PreferredName.
Naming/RescuedExceptionsVariableName:
Exclude:
- 'app/models/commercial.rb'
- 'app/models/payment.rb'
# Offense count: 2 # Offense count: 2
# Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames. # Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames.
# AllowedNames: io, id, to, by, on, in, at, ip # AllowedNames: io, id, to, by, on, in, at, ip, db
Naming/UncommunicativeMethodParamName: Naming/UncommunicativeMethodParamName:
Exclude: Exclude:
- 'app/models/conference.rb' - 'app/models/conference.rb'
@ -498,14 +502,7 @@ Naming/VariableNumber:
Exclude: Exclude:
- 'spec/models/ticket_purchase_spec.rb' - 'spec/models/ticket_purchase_spec.rb'
# Offense count: 4 # Offense count: 28
# Cop supports --auto-correct.
Performance/InefficientHashSearch:
Exclude:
- 'app/controllers/admin/versions_controller.rb'
- 'app/helpers/versions_helper.rb'
# Offense count: 31
RSpec/AnyInstance: RSpec/AnyInstance:
Exclude: Exclude:
- 'spec/controllers/admin/rooms_controller_spec.rb' - 'spec/controllers/admin/rooms_controller_spec.rb'
@ -517,7 +514,7 @@ RSpec/AnyInstance:
- 'spec/controllers/proposals_controller_spec.rb' - 'spec/controllers/proposals_controller_spec.rb'
- 'spec/controllers/tracks_controller_spec.rb' - 'spec/controllers/tracks_controller_spec.rb'
# Offense count: 327 # Offense count: 317
# Configuration parameters: Prefixes. # Configuration parameters: Prefixes.
# Prefixes: when, with, without # Prefixes: when, with, without
RSpec/ContextWording: RSpec/ContextWording:
@ -538,6 +535,24 @@ RSpec/DescribedClass:
- 'spec/models/ticket_purchase_spec.rb' - 'spec/models/ticket_purchase_spec.rb'
- 'spec/models/ticket_spec.rb' - 'spec/models/ticket_spec.rb'
- 'spec/models/user_spec.rb' - 'spec/models/user_spec.rb'
- 'spec/serializers/conference_serializer_spec.rb'
- 'spec/serializers/event_serializer_spec.rb'
- 'spec/serializers/room_serializer_spec.rb'
- 'spec/serializers/speaker_serializer_spec.rb'
- 'spec/serializers/track_serializer_spec.rb'
# Offense count: 13
# Cop supports --auto-correct.
# Configuration parameters: AllowConsecutiveOneLiners.
RSpec/EmptyLineAfterExample:
Exclude:
- 'spec/ability/ability_spec.rb'
- 'spec/controllers/admin/comments_controller_spec.rb'
- 'spec/controllers/admin/registration_periods_controller_spec.rb'
- 'spec/controllers/admin/users_controller_spec.rb'
- 'spec/helpers/events_helper_spec.rb'
- 'spec/models/event_spec.rb'
- 'spec/models/survey_spec.rb'
# Offense count: 3 # Offense count: 3
# Cop supports --auto-correct. # Cop supports --auto-correct.
@ -545,7 +560,7 @@ RSpec/EmptyLineAfterExampleGroup:
Exclude: Exclude:
- 'spec/controllers/admin/users_controller_spec.rb' - 'spec/controllers/admin/users_controller_spec.rb'
# Offense count: 12 # Offense count: 11
# Cop supports --auto-correct. # Cop supports --auto-correct.
RSpec/EmptyLineAfterFinalLet: RSpec/EmptyLineAfterFinalLet:
Exclude: Exclude:
@ -553,7 +568,6 @@ RSpec/EmptyLineAfterFinalLet:
- 'spec/controllers/admin/users_controller_spec.rb' - 'spec/controllers/admin/users_controller_spec.rb'
- 'spec/controllers/application_controller_spec.rb' - 'spec/controllers/application_controller_spec.rb'
- 'spec/features/conference_spec.rb' - 'spec/features/conference_spec.rb'
- 'spec/models/admin_ability_spec.rb'
- 'spec/models/conference_spec.rb' - 'spec/models/conference_spec.rb'
- 'spec/models/payment_spec.rb' - 'spec/models/payment_spec.rb'
- 'spec/models/ticket_spec.rb' - 'spec/models/ticket_spec.rb'
@ -573,12 +587,11 @@ RSpec/EmptyLineAfterHook:
- 'spec/models/payment_spec.rb' - 'spec/models/payment_spec.rb'
- 'spec/models/program_spec.rb' - 'spec/models/program_spec.rb'
# Offense count: 9 # Offense count: 8
# Cop supports --auto-correct. # Cop supports --auto-correct.
RSpec/EmptyLineAfterSubject: RSpec/EmptyLineAfterSubject:
Exclude: Exclude:
- 'spec/ability/ability_spec.rb' - 'spec/ability/ability_spec.rb'
- 'spec/models/admin_ability_spec.rb'
- 'spec/models/booth_spec.rb' - 'spec/models/booth_spec.rb'
- 'spec/models/cfp_spec.rb' - 'spec/models/cfp_spec.rb'
- 'spec/models/event_spec.rb' - 'spec/models/event_spec.rb'
@ -587,7 +600,7 @@ RSpec/EmptyLineAfterSubject:
- 'spec/models/survey_spec.rb' - 'spec/models/survey_spec.rb'
- 'spec/models/track_spec.rb' - 'spec/models/track_spec.rb'
# Offense count: 230 # Offense count: 220
# Configuration parameters: Max. # Configuration parameters: Max.
RSpec/ExampleLength: RSpec/ExampleLength:
Enabled: false Enabled: false
@ -608,7 +621,7 @@ RSpec/ExampleWording:
- 'spec/models/ticket_purchase_spec.rb' - 'spec/models/ticket_purchase_spec.rb'
- 'spec/models/ticket_spec.rb' - 'spec/models/ticket_spec.rb'
# Offense count: 38 # Offense count: 37
# Cop supports --auto-correct. # Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle. # Configuration parameters: EnforcedStyle.
# SupportedStyles: method_call, block # SupportedStyles: method_call, block
@ -638,28 +651,41 @@ RSpec/FilePath:
- 'spec/models/comment_spec.rb' - 'spec/models/comment_spec.rb'
- 'spec/models/openid.rb' - 'spec/models/openid.rb'
# Offense count: 174 # Offense count: 171
# Cop supports --auto-correct. # Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle. # Configuration parameters: EnforcedStyle.
# SupportedStyles: implicit, each, example # SupportedStyles: implicit, each, example
RSpec/HookArgument: RSpec/HookArgument:
Enabled: false Enabled: false
# Offense count: 499 # Offense count: 140
# Cop supports --auto-correct. # Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle. # Configuration parameters: EnforcedStyle.
# SupportedStyles: is_expected, should # SupportedStyles: is_expected, should
RSpec/ImplicitExpect: RSpec/ImplicitExpect:
Enabled: false Exclude:
- 'spec/ability/ability_spec.rb'
- 'spec/models/commercial_spec.rb'
- 'spec/models/conference_spec.rb'
- 'spec/models/event_schedule_spec.rb'
- 'spec/models/event_type_spec.rb'
- 'spec/models/organization_spec.rb'
- 'spec/models/registration_period_spec.rb'
- 'spec/models/room_spec.rb'
- 'spec/models/schedule_spec.rb'
- 'spec/models/sponsor_spec.rb'
- 'spec/models/sponsorship_level_spec.rb'
- 'spec/models/ticket_purchase_spec.rb'
- 'spec/models/ticket_spec.rb'
- 'spec/models/user_spec.rb'
# Offense count: 48 # Offense count: 39
# Cop supports --auto-correct. # Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle. # Configuration parameters: EnforcedStyle.
# SupportedStyles: single_line_only, disallow # SupportedStyles: single_line_only, single_statement_only, disallow
RSpec/ImplicitSubject: RSpec/ImplicitSubject:
Exclude: Exclude:
- 'spec/ability/ability_spec.rb' - 'spec/ability/ability_spec.rb'
- 'spec/models/admin_ability_spec.rb'
- 'spec/models/booth_spec.rb' - 'spec/models/booth_spec.rb'
- 'spec/models/conference_spec.rb' - 'spec/models/conference_spec.rb'
- 'spec/models/event_type_spec.rb' - 'spec/models/event_type_spec.rb'
@ -670,21 +696,35 @@ RSpec/ImplicitSubject:
- 'spec/models/ticket_purchase_spec.rb' - 'spec/models/ticket_purchase_spec.rb'
- 'spec/models/ticket_spec.rb' - 'spec/models/ticket_spec.rb'
# Offense count: 347 # Offense count: 321
# Configuration parameters: AssignmentOnly. # Configuration parameters: AssignmentOnly.
RSpec/InstanceVariable: RSpec/InstanceVariable:
Enabled: false Exclude:
- 'spec/controllers/admin/sponsorship_levels_controller_spec.rb'
- 'spec/controllers/admin/versions_controller_spec.rb'
- 'spec/controllers/api/v1/conferences_controller_spec.rb'
- 'spec/controllers/application_controller_spec.rb'
- 'spec/controllers/conference_registration_controller_spec.rb'
- 'spec/controllers/conferences_controller_spec.rb'
- 'spec/controllers/confirmations_controller_spec.rb'
- 'spec/controllers/proposals_controller_spec.rb'
- 'spec/features/proposals_spec.rb'
- 'spec/helpers/application_helper_spec.rb'
- 'spec/models/conference_spec.rb'
- 'spec/models/event_schedule_spec.rb'
- 'spec/models/sponsorship_level_spec.rb'
- 'spec/models/track_spec.rb'
- 'spec/models/user_spec.rb'
# Offense count: 5 # Offense count: 4
# Cop supports --auto-correct. # Cop supports --auto-correct.
RSpec/LeadingSubject: RSpec/LeadingSubject:
Exclude: Exclude:
- 'spec/ability/ability_spec.rb' - 'spec/ability/ability_spec.rb'
- 'spec/models/admin_ability_spec.rb'
- 'spec/models/conference_spec.rb' - 'spec/models/conference_spec.rb'
- 'spec/models/ticket_spec.rb' - 'spec/models/ticket_spec.rb'
# Offense count: 51 # Offense count: 55
RSpec/LetSetup: RSpec/LetSetup:
Enabled: false Enabled: false
@ -699,12 +739,13 @@ RSpec/MultipleDescribes:
Exclude: Exclude:
- 'spec/controllers/application_controller_spec.rb' - 'spec/controllers/application_controller_spec.rb'
# Offense count: 283 # Offense count: 278
# Configuration parameters: AggregateFailuresByDefault. # Configuration parameters: AggregateFailuresByDefault.
RSpec/MultipleExpectations: RSpec/MultipleExpectations:
Max: 106 Max: 97
# Offense count: 403 # Offense count: 387
# Configuration parameters: IgnoreSharedExamples.
RSpec/NamedSubject: RSpec/NamedSubject:
Exclude: Exclude:
- 'spec/models/conference_spec.rb' - 'spec/models/conference_spec.rb'
@ -712,11 +753,11 @@ RSpec/NamedSubject:
- 'spec/models/room_spec.rb' - 'spec/models/room_spec.rb'
- 'spec/models/track_spec.rb' - 'spec/models/track_spec.rb'
# Offense count: 213 # Offense count: 206
RSpec/NestedGroups: RSpec/NestedGroups:
Max: 7 Max: 7
# Offense count: 93 # Offense count: 85
# Cop supports --auto-correct. # Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle. # Configuration parameters: EnforcedStyle.
# SupportedStyles: not_to, to_not # SupportedStyles: not_to, to_not
@ -746,7 +787,7 @@ RSpec/RepeatedExample:
Exclude: Exclude:
- 'spec/models/conference_spec.rb' - 'spec/models/conference_spec.rb'
# Offense count: 13 # Offense count: 10
# Cop supports --auto-correct. # Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle. # Configuration parameters: EnforcedStyle.
# SupportedStyles: and_return, block # SupportedStyles: and_return, block
@ -754,11 +795,10 @@ RSpec/ReturnFromStub:
Exclude: Exclude:
- 'spec/helpers/events_helper_spec.rb' - 'spec/helpers/events_helper_spec.rb'
# Offense count: 49 # Offense count: 19
RSpec/ScatteredLet: RSpec/ScatteredLet:
Exclude: Exclude:
- 'spec/ability/ability_spec.rb' - 'spec/ability/ability_spec.rb'
- 'spec/models/admin_ability_spec.rb'
- 'spec/models/payment_spec.rb' - 'spec/models/payment_spec.rb'
# Offense count: 2 # Offense count: 2
@ -773,8 +813,8 @@ RSpec/SubjectStub:
- 'spec/models/room_spec.rb' - 'spec/models/room_spec.rb'
- 'spec/models/track_spec.rb' - 'spec/models/track_spec.rb'
# Offense count: 1 # Offense count: 3
# Configuration parameters: IgnoreSymbolicNames. # Configuration parameters: IgnoreNameless, IgnoreSymbolicNames.
RSpec/VerifiedDoubles: RSpec/VerifiedDoubles:
Exclude: Exclude:
- 'spec/datatables/user_datatable_spec.rb' - 'spec/datatables/user_datatable_spec.rb'
@ -785,247 +825,11 @@ RSpec/VoidExpect:
Exclude: Exclude:
- 'spec/models/conference_spec.rb' - 'spec/models/conference_spec.rb'
# Offense count: 1
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, Include.
# SupportedStyles: action, filter
# Include: app/controllers/**/*.rb
Rails/ActionFilter:
Exclude:
- 'app/controllers/users/omniauth_callbacks_controller.rb'
# Offense count: 107
# Cop supports --auto-correct.
Rails/ActiveRecordAliases:
Enabled: false
# Offense count: 128
# Cop supports --auto-correct.
Rails/ApplicationRecord:
Enabled: false
# Offense count: 10
# Cop supports --auto-correct.
# Configuration parameters: NilOrEmpty, NotPresent, UnlessPresent.
Rails/Blank:
Exclude:
- 'app/controllers/conferences_controller.rb'
- 'app/controllers/users/omniauth_callbacks_controller.rb'
- 'app/models/program.rb'
- 'app/models/user.rb'
- 'spec/factories/event_schedule.rb'
# Offense count: 20
# Configuration parameters: Include.
# Include: db/migrate/*.rb
Rails/CreateTableWithTimestamps:
Enabled: false
# Offense count: 126
# Configuration parameters: EnforcedStyle.
# SupportedStyles: strict, flexible
Rails/Date:
Enabled: false
# Offense count: 3 # Offense count: 3
# Cop supports --auto-correct.
# Configuration parameters: EnforceForPrefixed.
Rails/Delegate:
Exclude:
- 'app/models/event.rb'
- 'app/models/room.rb'
- 'app/models/track.rb'
# Offense count: 3
# Cop supports --auto-correct.
# Configuration parameters: Whitelist.
# Whitelist: find_by_sql
Rails/DynamicFindBy:
Exclude:
- 'app/controllers/admin/events_controller.rb'
- 'db/migrate/20140701123203_add_events_per_week_to_conference.rb'
# Offense count: 8
# Configuration parameters: EnforcedStyle.
# SupportedStyles: slashes, arguments
Rails/FilePath:
Exclude:
- 'app/pdfs/ticket_pdf.rb'
- 'config/initializers/active_record_log_subscriber.rb'
- 'config/initializers/carrierwave.rb'
- 'spec/features/lodgings_spec.rb'
- 'spec/features/sponsor_spec.rb'
- 'spec/spec_helper.rb'
# Offense count: 7
# Cop supports --auto-correct.
# Configuration parameters: Include.
# Include: app/models/**/*.rb
Rails/FindBy:
Exclude:
- 'app/models/event.rb'
- 'app/models/openid.rb'
- 'app/models/ticket_purchase.rb'
- 'app/models/user.rb'
# Offense count: 6
# Configuration parameters: Include.
# Include: app/models/**/*.rb
Rails/HasAndBelongsToMany:
Exclude:
- 'app/models/conference.rb'
- 'app/models/qanswer.rb'
- 'app/models/question.rb'
- 'app/models/registration.rb'
- 'app/models/vchoice.rb'
# Offense count: 20
# Configuration parameters: Include.
# Include: app/models/**/*.rb
Rails/HasManyOrHasOneDependent:
Exclude:
- 'app/models/answer.rb'
- 'app/models/event.rb'
- 'app/models/payment.rb'
- 'app/models/physical_ticket.rb'
- 'app/models/question_type.rb'
- 'app/models/registration.rb'
- 'app/models/role.rb'
- 'app/models/room.rb'
- 'app/models/sponsorship_level.rb'
- 'app/models/ticket_purchase.rb'
- 'app/models/track.rb'
- 'app/models/user.rb'
- 'app/models/vday.rb'
- 'app/models/vposition.rb'
# Offense count: 256
# Cop supports --auto-correct.
# Configuration parameters: Include.
# Include: spec/**/*, test/**/*
Rails/HttpPositionalArguments:
Enabled: false
# Offense count: 12
# Configuration parameters: Include.
# Include: app/models/**/*.rb
Rails/InverseOf:
Exclude:
- 'app/models/booth.rb'
- 'app/models/conference.rb'
- 'app/models/event.rb'
- 'app/models/user.rb'
- 'app/models/venue.rb'
# Offense count: 1
# Configuration parameters: Include.
# Include: app/controllers/**/*.rb
Rails/LexicallyScopedActionFilter:
Exclude:
- 'app/controllers/registrations_controller.rb'
# Offense count: 1
# Configuration parameters: Include.
# Include: app/**/*.rb, config/**/*.rb, db/**/*.rb, lib/**/*.rb
Rails/Output:
Exclude:
- 'config/environment.rb'
# Offense count: 4
Rails/OutputSafety:
Exclude:
- 'app/helpers/events_helper.rb'
- 'app/helpers/format_helper.rb'
- 'app/models/commercial.rb'
# Offense count: 15
# Cop supports --auto-correct.
Rails/PluralizationGrammar:
Exclude:
- 'spec/models/conference_spec.rb'
# Offense count: 3
# Cop supports --auto-correct.
Rails/Presence:
Exclude:
- 'app/controllers/schedules_controller.rb'
- 'app/helpers/application_helper.rb'
- 'app/models/user.rb'
# Offense count: 23
# Cop supports --auto-correct.
# Configuration parameters: NotNilAndNotEmpty, NotBlank, UnlessBlank.
Rails/Present:
Exclude:
- 'app/helpers/users_helper.rb'
- 'app/models/cfp.rb'
- 'app/models/email_settings.rb'
- 'app/models/event.rb'
- 'app/models/program.rb'
- 'app/models/venue.rb'
- 'config/routes.rb'
# Offense count: 52
# Configuration parameters: Include.
# Include: db/migrate/*.rb
Rails/ReversibleMigration:
Exclude:
- 'db/migrate/20140530082708_remove_color_defaults.rb'
- 'db/migrate/20140605125153_update_event_states.rb'
- 'db/migrate/20140610173021_change_person_id_to_user_id_in_registrations.rb'
- 'db/migrate/20140611123926_change_person_id_to_user_id_in_votes.rb'
- 'db/migrate/20140623150541_drop_person_and_event_person_tables.rb'
- 'db/migrate/20140731165107_move_conference_contact_details_to_contact.rb'
- 'db/migrate/20140801164901_move_conference_media_to_commercial.rb'
- 'db/migrate/20140801170430_move_event_media_to_commercial.rb'
- 'db/migrate/20140820093735_migrating_supporter_registrations_to_ticket_users.rb'
- 'db/migrate/20140821103643_split_ticket_price_in_price_and_currency.rb'
- 'db/migrate/20140825093132_move_splashpage_attributes_from_conference_to_splashpage.rb'
- 'db/migrate/20140930092923_move_sponsor_email_to_contact.rb'
- 'db/migrate/20141117222919_drop_splash_descriptions_and_photo.rb'
- 'db/migrate/20141130182139_drop_table_event_attachments.rb'
# Offense count: 8
# Configuration parameters: Blacklist.
# Blacklist: decrement!, decrement_counter, increment!, increment_counter, toggle!, touch, update_all, update_attribute, update_column, update_columns, update_counters
Rails/SkipsModelValidations:
Exclude:
- 'app/models/concerns/revision_count.rb'
- 'db/migrate/20140730104658_migrate_roles_for_cancancan.rb'
- 'db/migrate/20161229080315_add_comments_count_to_events.rb'
- 'db/migrate/20180226032958_add_created_at_and_updated_at_to_event_types.rb'
- 'db/migrate/20180313012253_add_timestamps_to_tickets.rb'
- 'lib/tasks/user.rake'
- 'spec/controllers/conferences_controller_spec.rb'
# Offense count: 51
# Configuration parameters: EnforcedStyle.
# SupportedStyles: strict, flexible
Rails/TimeZone:
Exclude:
- 'app/models/comment.rb'
- 'app/models/conference.rb'
- 'config/environments/test.rb'
- 'db/migrate/20180226032958_add_created_at_and_updated_at_to_event_types.rb'
- 'db/migrate/20180313012253_add_timestamps_to_tickets.rb'
- 'lib/tasks/dump_db.rake'
- 'spec/controllers/admin/comments_controller_spec.rb'
- 'spec/controllers/admin/programs_controller_spec.rb'
- 'spec/factories/users.rb'
- 'spec/models/conference_spec.rb'
# Offense count: 2
Security/Open: Security/Open:
Exclude: Exclude:
- 'app/pdfs/ticket_pdf.rb' - 'app/pdfs/ticket_pdf.rb'
# Offense count: 2
# Configuration parameters: EnforcedStyle.
# SupportedStyles: inline, group
Style/AccessModifierDeclarations:
Exclude:
- 'spec/factories/splashpages.rb'
# Offense count: 1 # Offense count: 1
# Cop supports --auto-correct. # Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle. # Configuration parameters: EnforcedStyle.
@ -1046,27 +850,18 @@ Style/ColonMethodCall:
- 'app/models/commercial.rb' - 'app/models/commercial.rb'
- 'app/models/contact.rb' - 'app/models/contact.rb'
# Offense count: 5 # Offense count: 4
# Cop supports --auto-correct. # Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, SingleLineConditionsOnly, IncludeTernaryExpressions. # Configuration parameters: EnforcedStyle, SingleLineConditionsOnly, IncludeTernaryExpressions.
# SupportedStyles: assign_to_condition, assign_inside_condition # SupportedStyles: assign_to_condition, assign_inside_condition
Style/ConditionalAssignment: Style/ConditionalAssignment:
Exclude: Exclude:
- 'app/helpers/format_helper.rb' - 'app/helpers/format_helper.rb'
- 'config/environments/production.rb'
- 'config/initializers/airbrake.rb' - 'config/initializers/airbrake.rb'
- 'db/migrate/20140610165551_migrate_data_person_to_user.rb' - 'db/migrate/20140610165551_migrate_data_person_to_user.rb'
- 'db/migrate/20140820124117_undo_wrong_migration20140801080705_add_users_to_events.rb' - 'db/migrate/20140820124117_undo_wrong_migration20140801080705_add_users_to_events.rb'
# Offense count: 11 # Offense count: 516
Style/DateTime:
Exclude:
- 'app/models/conference.rb'
- 'app/models/program.rb'
- 'spec/models/conference_spec.rb'
- 'spec/models/program_spec.rb'
# Offense count: 514
Style/Documentation: Style/Documentation:
Enabled: false Enabled: false
@ -1088,14 +883,13 @@ Style/EmptyLiteral:
Exclude: Exclude:
- 'spec/models/conference_spec.rb' - 'spec/models/conference_spec.rb'
# Offense count: 9 # Offense count: 7
# Cop supports --auto-correct. # Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle. # Configuration parameters: EnforcedStyle.
# SupportedStyles: compact, expanded # SupportedStyles: compact, expanded
Style/EmptyMethod: Style/EmptyMethod:
Exclude: Exclude:
- 'app/controllers/admin/lodgings_controller.rb' - 'app/controllers/admin/lodgings_controller.rb'
- 'app/controllers/admin/registration_periods_controller.rb'
- 'app/controllers/users_controller.rb' - 'app/controllers/users_controller.rb'
- 'db/migrate/20121223115125_create_tracks_table.rb' - 'db/migrate/20121223115125_create_tracks_table.rb'
- 'db/migrate/20121223115135_create_events_table.rb' - 'db/migrate/20121223115135_create_events_table.rb'
@ -1126,19 +920,26 @@ Style/ExpandPathArguments:
- 'config/environment.rb' - 'config/environment.rb'
- 'spec/spec_helper.rb' - 'spec/spec_helper.rb'
# Offense count: 44 # Offense count: 1
# Configuration parameters: EnforcedStyle.
# SupportedStyles: annotated, template, unannotated
Style/FormatStringToken:
Exclude:
- 'app/uploaders/picture_uploader.rb'
# Offense count: 49
# Cop supports --auto-correct. # Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle. # Configuration parameters: EnforcedStyle.
# SupportedStyles: when_needed, always, never # SupportedStyles: always, never
Style/FrozenStringLiteralComment: Style/FrozenStringLiteralComment:
Enabled: false Enabled: false
# Offense count: 30 # Offense count: 29
# Configuration parameters: MinBodyLength. # Configuration parameters: MinBodyLength.
Style/GuardClause: Style/GuardClause:
Enabled: false Enabled: false
# Offense count: 8 # Offense count: 7
# Cop supports --auto-correct. # Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, UseHashRocketsWithSymbolValues, PreferHashRocketsForNonAlnumEndingSymbols. # Configuration parameters: EnforcedStyle, UseHashRocketsWithSymbolValues, PreferHashRocketsForNonAlnumEndingSymbols.
# SupportedStyles: ruby19, hash_rockets, no_mixed_keys, ruby19_no_mixed_keys # SupportedStyles: ruby19, hash_rockets, no_mixed_keys, ruby19_no_mixed_keys
@ -1149,16 +950,15 @@ Style/HashSyntax:
- 'app/views/admin/registrations/index.xlsx.axlsx' - 'app/views/admin/registrations/index.xlsx.axlsx'
- 'lib/tasks/user.rake' - 'lib/tasks/user.rake'
# Offense count: 61 # Offense count: 58
# Cop supports --auto-correct. # Cop supports --auto-correct.
Style/IfUnlessModifier: Style/IfUnlessModifier:
Enabled: false Enabled: false
# Offense count: 8 # Offense count: 10
# Cop supports --auto-correct. # Cop supports --auto-correct.
Style/LineEndConcatenation: Style/LineEndConcatenation:
Exclude: Exclude:
- 'spec/features/cfp_spec.rb'
- 'spec/features/conference_spec.rb' - 'spec/features/conference_spec.rb'
- 'spec/features/registration_periods_spec.rb' - 'spec/features/registration_periods_spec.rb'
@ -1192,6 +992,8 @@ Style/MultilineIfModifier:
# Offense count: 2 # Offense count: 2
# Cop supports --auto-correct. # Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: literals, strict
Style/MutableConstant: Style/MutableConstant:
Exclude: Exclude:
- 'app/models/event_user.rb' - 'app/models/event_user.rb'
@ -1213,7 +1015,7 @@ Style/NestedParenthesizedCalls:
Style/Next: Style/Next:
Enabled: false Enabled: false
# Offense count: 121 # Offense count: 120
# Cop supports --auto-correct. # Cop supports --auto-correct.
# Configuration parameters: EnforcedOctalStyle. # Configuration parameters: EnforcedOctalStyle.
# SupportedOctalStyles: zero_with_o, zero_only # SupportedOctalStyles: zero_with_o, zero_only
@ -1234,9 +1036,9 @@ Style/NumericLiteralPrefix:
Style/NumericLiterals: Style/NumericLiterals:
MinDigits: 15 MinDigits: 15
# Offense count: 41 # Offense count: 36
# Cop supports --auto-correct. # Cop supports --auto-correct.
# Configuration parameters: AutoCorrect, EnforcedStyle. # Configuration parameters: AutoCorrect, EnforcedStyle, IgnoredMethods.
# SupportedStyles: predicate, comparison # SupportedStyles: predicate, comparison
Style/NumericPredicate: Style/NumericPredicate:
Exclude: Exclude:
@ -1274,7 +1076,7 @@ Style/ParenthesesAroundCondition:
- 'app/controllers/application_controller.rb' - 'app/controllers/application_controller.rb'
- 'app/helpers/format_helper.rb' - 'app/helpers/format_helper.rb'
# Offense count: 28 # Offense count: 22
# Cop supports --auto-correct. # Cop supports --auto-correct.
# Configuration parameters: PreferredDelimiters. # Configuration parameters: PreferredDelimiters.
Style/PercentLiteralDelimiters: Style/PercentLiteralDelimiters:
@ -1307,15 +1109,15 @@ Style/RedundantParentheses:
Exclude: Exclude:
- 'app/controllers/admin/base_controller.rb' - 'app/controllers/admin/base_controller.rb'
# Offense count: 3 # Offense count: 4
# Cop supports --auto-correct. # Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, AllowInnerSlashes. # Configuration parameters: EnforcedStyle, AllowInnerSlashes.
# SupportedStyles: slashes, percent_r, mixed # SupportedStyles: slashes, percent_r, mixed
Style/RegexpLiteral: Style/RegexpLiteral:
Exclude: Exclude:
- 'Guardfile' - 'Guardfile'
- 'config/initializers/airbrake.rb'
- 'app/uploaders/picture_uploader.rb' - 'app/uploaders/picture_uploader.rb'
- 'config/initializers/airbrake.rb'
# Offense count: 2 # Offense count: 2
# Cop supports --auto-correct. # Cop supports --auto-correct.
@ -1342,21 +1144,18 @@ Style/SingleLineMethods:
Exclude: Exclude:
- 'Guardfile' - 'Guardfile'
# Offense count: 672 # Offense count: 611
# Cop supports --auto-correct. # Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, ConsistentQuotesInMultiline. # Configuration parameters: EnforcedStyle, ConsistentQuotesInMultiline.
# SupportedStyles: single_quotes, double_quotes # SupportedStyles: single_quotes, double_quotes
Style/StringLiterals: Style/StringLiterals:
Exclude: Exclude:
- 'Gemfile' - 'Gemfile'
- 'Vagrantfile'
- 'bin/rspec' - 'bin/rspec'
- 'bin/spring' - 'bin/spring'
- 'config/deploy.rb' - 'config/deploy.rb'
- 'config/environments/production.rb' - 'config/environments/production.rb'
- 'config/initializers/devise.rb'
- 'config/puma.rb' - 'config/puma.rb'
- 'config/routes.rb'
- 'db/schema.rb' - 'db/schema.rb'
- 'lib/tasks/dump_db.rake' - 'lib/tasks/dump_db.rake'
- 'lib/tasks/events_registrations.rake' - 'lib/tasks/events_registrations.rake'
@ -1374,19 +1173,13 @@ Style/StringLiteralsInInterpolation:
- 'app/views/admin/events/_confirmed_events.xlsx.axlsx' - 'app/views/admin/events/_confirmed_events.xlsx.axlsx'
- 'lib/tasks/dump_db.rake' - 'lib/tasks/dump_db.rake'
# Offense count: 109 # Offense count: 110
# Cop supports --auto-correct. # Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, MinSize. # Configuration parameters: EnforcedStyle, MinSize.
# SupportedStyles: percent, brackets # SupportedStyles: percent, brackets
Style/SymbolArray: Style/SymbolArray:
Enabled: false Enabled: false
# Offense count: 1
# Cop supports --auto-correct.
Style/SymbolLiteral:
Exclude:
- 'config/deploy.rb'
# Offense count: 10 # Offense count: 10
# Cop supports --auto-correct. # Cop supports --auto-correct.
# Configuration parameters: IgnoredMethods. # Configuration parameters: IgnoredMethods.
@ -1439,7 +1232,7 @@ Style/UnneededCondition:
- 'app/helpers/versions_helper.rb' - 'app/helpers/versions_helper.rb'
- 'app/models/ticket.rb' - 'app/models/ticket.rb'
# Offense count: 8 # Offense count: 9
# Cop supports --auto-correct. # Cop supports --auto-correct.
# Configuration parameters: WordRegex. # Configuration parameters: WordRegex.
# SupportedStyles: percent, brackets # SupportedStyles: percent, brackets
@ -1447,8 +1240,9 @@ Style/WordArray:
EnforcedStyle: percent EnforcedStyle: percent
MinSize: 8 MinSize: 8
# Offense count: 3041 # Offense count: 2915
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns. # Cop supports --auto-correct.
# Configuration parameters: AutoCorrect, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
# URISchemes: http, https # URISchemes: http, https
Metrics/LineLength: Metrics/LineLength:
Max: 619 Max: 619

View file

@ -1,17 +1,19 @@
sudo: required sudo: required
dist: trusty dist: xenial
addons:
apt:
packages:
- chromium-browser
language: ruby language: ruby
cache: bundler cache: bundler
rvm: rvm:
- 2.5.0@osem --ignore-gemsets
branches: branches:
only: except:
- master - /^depfu/.*$/
before_install: before_install:
- "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc" - "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc"
- "echo `phantomjs -v`" - gem uninstall -v '>= 2' -i $(rvm gemdir)@global -ax bundler || true
addons: - gem install bundler -v $(tail -n 1 Gemfile.lock)
chrome: stable
notifications: notifications:
email: email:
on_success: change on_success: change
@ -23,6 +25,7 @@ notifications:
on_failure: change on_failure: change
before_script: before_script:
- RAILS_ENV=test bundle exec rake db:bootstrap --trace - RAILS_ENV=test bundle exec rake db:bootstrap --trace
- RAILS_ENV=test bundle exec bin/rails webdrivers:chromedriver:update
script: script:
- "./travis_script.sh $TEST_SUITE" - "./travis_script.sh $TEST_SUITE"
env: env:

70
CHANGES.md Normal file
View file

@ -0,0 +1,70 @@
# Changes in OSEM 2.0
Not release yet...
## Update from 1.0
### Multiple Schedules
A conference can have multiple schedules now so it's easier for organizers to
test schedules and collaborate on different versions.
For this some of the existing data needs to be changed. If you update
from 1.0 please run this rake task to move your old schedules to the
new system.
```
bundle exec rake data:move_events_attributes RAILS_ENV=production
```
### Dropped visit/campaign tracking
We have dropped the feature to track visits and campaigns (utm parameters)
inside OSEM. We recommend you use [matomo](https://matomo.org/) for things
like that. Before you update to OSEM 1.1 you should drop all the data we
have collected.
```
bundle exec rake data:drop_all_ahoy_events RAILS_ENV=production
```
### Conference wide revision history
There is now a conference wide revision history that will show organizers
everything that is happening. To be able to do this we need to change old
data.
```
bundle exec rake data:set_conference_in_versions RAILS_ENV=production
```
### Organization admins
We have a new role `organization admins` which allow a user to manage his the
organization and create and manage conference within the organization. This
needs the role to exist in the database, otherwise the application crashes
as it is assumed to exist. For that, run the following rake task:
```
bundle exec rake roles:add RAILS_ENV=production
```
# Changes in OSEM 1.0
[Released May 24, 2016](https://osem.io/1.0)
Our first release after developing and using this app in production for
many years. Too many changes to list, see the release announcement to
learn what OSEM is about.
https://osem.io/1.0
## Update from master
### Configuration through the environment
If you have deployed OSEM from master before there is one thing you need to do
manually. OSEM is now configured through environment variables and not through
the config/options.yml anymore. There is a rake task to migrate your existing
data to a .env file that OSEM will use:
```
bundle exec rake data:migrate:config2dotenv RAILS_ENV=production
```

View file

@ -1,4 +1,5 @@
# Contributing to OSEM # Contributing to OSEM
We here at OSEM are open for all types of contributions from anyone. Tell us about our [issues/ideas](https://github.com/openSUSE/osem/issues/new), propose code changes via [pull requests](https://help.github.com/articles/using-pull-requests) or contribute artwork and documentation. We here at OSEM are open for all types of contributions from anyone. Tell us about our [issues/ideas](https://github.com/openSUSE/osem/issues/new), propose code changes via [pull requests](https://help.github.com/articles/using-pull-requests) or contribute artwork and documentation.
We welcome all new developers and are also prepared to mentor you through your first contributions! All OSEM maintainers are seasoned developers and have participated in mentoring programs, such as [GSoC](https://summerofcode.withgoogle.com/) and [RGSoC](https://railsgirlssummerofcode.org/). We welcome all new developers and are also prepared to mentor you through your first contributions! All OSEM maintainers are seasoned developers and have participated in mentoring programs, such as [GSoC](https://summerofcode.withgoogle.com/) and [RGSoC](https://railsgirlssummerofcode.org/).
@ -8,10 +9,12 @@ We need your input and contributions to OSEM. In particular we seek the followin
* **code**: contribute your expertise in an area by helping us expand OSEM with features/bugfixes/UX * **code**: contribute your expertise in an area by helping us expand OSEM with features/bugfixes/UX
* **code editing**: fix typos, clarify language, and generally improve the quality of the content of OSEM * **code editing**: fix typos, clarify language, and generally improve the quality of the content of OSEM
* **ideas**: participate in an issues thread or start your own to have your voice heard * **ideas**: participate in an issues thread or start your own to have your voice heard
* **translations**: translate OSEM into other languages than English
Read this guide on how to do that. Read this guide on how to do that.
## How to contribute code ## How to contribute code
1. Fork the repository and make a pull-request with your changes 1. Fork the repository and make a pull-request with your changes
1. Make sure that the test suite passes and that you comply to our code style 1. Make sure that the test suite passes and that you comply to our code style
1. Please increase code coverage with your pull request 1. Please increase code coverage with your pull request
@ -19,10 +22,59 @@ Read this guide on how to do that.
1. If you are already a contributor and you get a positive review, you can merge your pull-request yourself 1. If you are already a contributor and you get a positive review, you can merge your pull-request yourself
1. If you are not already a contributor, one of the existing contributors will merge your pull-request 1. If you are not already a contributor, one of the existing contributors will merge your pull-request
**However, please bear in mind the following things:**
### Discuss Large Changes in Advance
If you see a glaring flaw within OSEM, resist the urge to jump into the
code and make sweeping changes right away. We know it can be tempting, but
especially for large, structural changes it's a wiser choice to first discuss
them in the [issue list](https://github.com/openSUSE/osem/issues).
A good rule of thumb, of what a *structural change* is, is to estimate how much
time would be wasted if the pull request was rejected. If it's a couple of minutes
then you can probably dive head first and eat the loss in the worst case. Otherwise,
making a quick check with the other developers could save you lots of time down the line.
Why? It may turn out that someone is already working on this or that someone already
has tried to solve this and hit a roadblock, maybe there even is a good reason
why this particular flaw exists? If nothing else, a discussion of the change will
usually familiarize the reviewer with your proposed changes and streamline the
review process when you finally create a pull request.
### Small Commits & Pull Request Scope
A commit should contain a single logical change, the scope should be as small
as possible. And a pull request should only consist of the commits that you
need for your change. If it's possible for you to split larger changes into
smaller blocks please do so.
Why? Limiting the scope of commits/pull requests makes reviewing much easier.
Because it will usually mean each commit can be evaluated independently and a
smaller amount of commits per pull request usually also means a smaller amount
of code to be reviewed.
### Proper Commit Messages
We are keen on proper commit messages because they will help us to maintain
this code in the future. We define proper commit messages like this:
* The title of your commit message summarizes **what** has been done
* The body of your commit message explains **why** you have done this
If the title is to small to explain **what** you have done, then you can of course
elaborate about it in the body. Please avoid explaining *how* you have done this,
we are developers too and we see the diff, if we do not understand something we will
ask you in the review.
Additional to **what** and **why** you should explain potential **side-effects** of
this change, if you are aware of any.
The content is most important, but please also use a [proper style](https://github.com/openSUSE/osem/wiki/Commit-message-guidelines).
## Development Environment ## Development Environment
### with docker-compose To isolate your host system from OSEM development we have prepared a container
To isolate you host system from OSEM development we have prepared a container
based development environment, based on [docker](https://www.docker.com/) and based development environment, based on [docker](https://www.docker.com/) and
[docker-compose](https://docs.docker.com/compose/). Here's a step by step guide [docker-compose](https://docs.docker.com/compose/). Here's a step by step guide
how to set it up. how to set it up.
@ -50,7 +102,7 @@ sed "s/13042/`id -u`/" docker-compose.override.yml.example > docker-compose.over
1. Check out your OSEM rails app. You can access the app at http://localhost:3000. Whatever you change in your cloned repository will have effect in the development environment. Sign up, the first user will be automatically assigned the admin role. 1. Check out your OSEM rails app. You can access the app at http://localhost:3000. Whatever you change in your cloned repository will have effect in the development environment. Sign up, the first user will be automatically assigned the admin role.
1. Changed something? Test your changes! 1. Changed something? Run the tests to verify your changes!
```bash ```bash
docker-compose run --rm osem bundle exec rspec spec docker-compose run --rm osem bundle exec rspec spec
``` ```
@ -62,65 +114,28 @@ sed "s/13042/`id -u`/" docker-compose.override.yml.example > docker-compose.over
1. Or explore the development environment: 1. Or explore the development environment:
```bash ```bash
docker-compose exec osem_1 /bin/bash -l docker-compose exec osem /bin/bash -l
``` ```
### with Vagrant 1. Want to know more?
Another option is using [Vagrant](https://www.vagrantup.com/) and [VirtualBox 5.0.10](https://www.virtualbox.org/wiki/Download_Old_Builds_5_0) to create your development environment. In our wiki you can find more information about what is possible in our development environment,
how we work with each other on github or other topics of interest for OSEM developers.
1. Install [vagrant-exec](https://github.com/p0deje/vagrant-exec): https://github.com/openSUSE/osem/wiki
```bash ## How to contribute translations
vagrant plugin install vagrant-exec
```
1. Start the development environment Please refer to our [translation guide](https://github.com/openSUSE/osem/wiki/Translation) in the wiki.
```
vagrant up
```
1. Start OSEM inside the development environment
```
vagrant exec /vagrant/bin/rails server -b 0.0.0.0
```
6. Check out your OSEM rails app:
You can access the app [localhost:3000](http://localhost:3000). Whatever you change in your cloned repository will have effect in the development environment. Sign up, the first user will be automatically assigned the admin role.
7. Changed something? Test your changes!:
```
vagrant exec bundle exec rspec spec
```
9. Issue any standard `rails`/`rake`/`bundler` command
```
vagrant exec bundle exec rake db:migrate
```
8. Or explore the development environment:
```
vagrant ssh
```
## Want to know more?
In our wiki you can find more information about what is possible in our development environment,
how we work with each other on github or other topics of interest for developers. Visit us at
>>>>>>> Introduces docker-compose to the contribution guide
https://github.com/openSUSE/osem/wiki
## Code of Conduct ## Code of Conduct
OSEM is part of the openSUSE project. We follow all the OSEM is part of the openSUSE project. We follow all the
[openSUSE Guiding Principles!](http://en.opensuse.org/openSUSE:Guiding_principles) [openSUSE Guiding Principles!](http://en.opensuse.org/openSUSE:Guiding_principles)
If you think someone doesn't do that, please let us know at maintainers@osem.io or If you think someone doesn't do that, please let us know at maintainers@osem.io or
address your concerns to the [openSUSE Board](https://en.opensuse.org/openSUSE:Board). address your concerns to the [openSUSE Board](https://en.opensuse.org/openSUSE:Board).
## Contact ## Contact
GitHub issues and pull requests are the primary way for communicating about specific proposed GitHub issues and pull requests are the primary way for communicating about specific proposed
changes to this project. If you have other questions feel free to subscribe to changes to this project. If you have other questions feel free to subscribe to
the [opensuse-web@opensuse.org](http://lists.opensuse.org/opensuse-web/) the [opensuse-web@opensuse.org](http://lists.opensuse.org/opensuse-web/)

View file

@ -1,10 +1,5 @@
FROM opensuse/leap:15 FROM opensuse/leap:15
# Enable/Disable the repositories we need/don't need
RUN zypper rr openSUSE-Leap-15.0-Non-Oss openSUSE-Leap-15.0-Update-Non-Oss \
zypper ar -f https://download.opensuse.org/repositories/devel:/tools/openSUSE_Leap_15.0/devel:tools.repo \
zypper --gpg-auto-import-keys refresh
# Install our requirements # Install our requirements
RUN zypper -n install --no-recommends \ RUN zypper -n install --no-recommends \
# for compiling assets/gems # for compiling assets/gems
@ -18,11 +13,11 @@ RUN zypper -n install --no-recommends \
# for nokogiri # for nokogiri
libxml2-devel libxslt-devel \ libxml2-devel libxslt-devel \
# for the interactive shell # for the interactive shell
ack curl wget w3m \ ack curl wget w3m vim which \
# for running our tests
phantomjs which \
# as ruby # as ruby
ruby2.5-devel ruby2.5-devel \
# as browser for feature tests
chromium
# Setup sudo # Setup sudo
RUN echo 'osem ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers RUN echo 'osem ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers
@ -31,7 +26,7 @@ RUN echo 'osem ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers
RUN echo 'install: --no-format-executable' >> /etc/gemrc RUN echo 'install: --no-format-executable' >> /etc/gemrc
# Install bundler & foreman # Install bundler & foreman
RUN gem install bundler foreman RUN gem install bundler:1.17.3 foreman
# Create our user # Create our user
RUN useradd -m --user-group osem RUN useradd -m --user-group osem

View file

@ -1,23 +1,16 @@
FROM osem/base FROM osem/base
# We copy the Gemfiles into this intermediate build stage so it's checksum
# changes and all the subsequent stages (a.k.a. the bundle install call below)
# have to be rebuild. Otherwise, after the first build of this image,
# docker would use it's cache for this and the following stages.
COPY Gemfile /osem/
COPY Gemfile.lock /osem/
RUN chown -R osem /osem
# Add our files # Add our files
COPY --chown=1000:1000 . /osem/
USER osem USER osem
WORKDIR /osem/ WORKDIR /osem/
COPY --chown=osem:osem . /osem/
# Install our bundle # Install our bundle
RUN export NOKOGIRI_USE_SYSTEM_LIBRARIES=1; bundle install --jobs=3 --retry=3 --without test development RUN export NOKOGIRI_USE_SYSTEM_LIBRARIES=1; bundle install --jobs=3 --retry=3 --without test development
# Configure OSEM # Generate assets
RUN mv config/database.yml.example config/database.yml RUN export RAILS_ENV=production; bundle exec rake assets:clobber assets:precompile
ENV RAILS_ENV=production ENV RAILS_ENV=production

41
Gemfile
View file

@ -10,16 +10,11 @@ if Gem::Version.new(Bundler::VERSION) < Gem::Version.new('1.8.4')
end end
# as web framework # as web framework
gem 'rails', '~> 5.0.7' gem 'rails', '~> 5.2.3'
# Use Puma as the app server # Use Puma as the app server
gem 'puma', '~> 3.0' gem 'puma', '~> 3.0'
# enables serving assets in production and setting your logger to standard out
# both of which are required to run an application on a twelve-factor provider
# like heroku.com
gem 'rails_12factor', group: :production
# respond_to methods have been extracted to the responders gem # respond_to methods have been extracted to the responders gem
# http://edgeguides.rubyonrails.org/upgrading_ruby_on_rails.html#responders # http://edgeguides.rubyonrails.org/upgrading_ruby_on_rails.html#responders
gem 'responders', '~> 2.0' gem 'responders', '~> 2.0'
@ -37,7 +32,7 @@ gem 'carrierwave-bombshelter'
gem 'mini_magick' gem 'mini_magick'
# for internationalizing # for internationalizing
gem 'rails-i18n', '~> 5.0.0' gem 'rails-i18n'
# as authentification framework # as authentification framework
gem 'devise' gem 'devise'
@ -54,7 +49,7 @@ gem 'omniauth-openid'
gem 'recaptcha', require: 'recaptcha/rails' gem 'recaptcha', require: 'recaptcha/rails'
# as authorization framework # as authorization framework
gem 'cancancan', '~> 2.0' gem 'cancancan'
# for roles # for roles
gem 'rolify' gem 'rolify'
@ -67,7 +62,7 @@ gem 'transitions', :require => %w( transitions active_record/transitions )
# for comments # for comments
gem 'acts_as_commentable_with_threading' gem 'acts_as_commentable_with_threading'
gem 'awesome_nested_set', '~> 3.1.3' gem 'awesome_nested_set'
# as templating language # as templating language
gem 'haml-rails' gem 'haml-rails'
@ -80,7 +75,7 @@ gem 'uglifier', '>= 1.3.0'
# as the front-end framework # as the front-end framework
gem 'autoprefixer-rails' gem 'autoprefixer-rails'
gem 'bootstrap-sass', '~> 3.3.4.1' gem 'bootstrap-sass', '~> 3.4.0'
gem 'cocoon' gem 'cocoon'
gem 'formtastic', '~> 3.1.5' gem 'formtastic', '~> 3.1.5'
gem 'formtastic-bootstrap' gem 'formtastic-bootstrap'
@ -92,8 +87,6 @@ gem 'jquery-ui-rails', '~> 4.2.1'
# for languages validation # for languages validation
gem 'iso-639' gem 'iso-639'
gem 'thor', '~> 0.19'
# frontend javascripts # frontend javascripts
source 'https://rails-assets.org' do source 'https://rails-assets.org' do
# for placeholder images # for placeholder images
@ -117,18 +110,17 @@ source 'https://rails-assets.org' do
# for select with icon # for select with icon
gem 'rails-assets-bootstrap-select' gem 'rails-assets-bootstrap-select'
gem 'rails-assets-markdown' gem 'rails-assets-markdown'
gem 'rails-assets-to-markdown' gem 'rails-assets-to-markdown', '~> 3'
end end
# as date picker # as date picker
gem 'bootstrap3-datetimepicker-rails', '~> 3.0.2' gem 'bootstrap3-datetimepicker-rails', '~> 4.17.47'
# data tables # data tables
gem 'ajax-datatables-rails' gem 'ajax-datatables-rails'
gem 'jquery-datatables-rails' gem 'jquery-datatables-rails'
# for charts # for charts
gem 'chart-js-rails'
gem 'chartkick' gem 'chartkick'
# for displaying maps # for displaying maps
@ -141,8 +133,10 @@ gem 'gravtastic'
gem 'country_select' gem 'country_select'
# as PDF generator # as PDF generator
gem 'prawn-qrcode', '~> 0.2.2.1' gem 'prawn-qrcode'
gem 'prawn_rails' gem 'prawn-rails'
# for QR code generation
gem 'rqrcode' gem 'rqrcode'
# to render XLS spreadsheets # to render XLS spreadsheets
@ -150,7 +144,7 @@ gem 'axlsx', git: 'https://github.com/randym/axlsx.git'
gem 'axlsx_rails' gem 'axlsx_rails'
# as error catcher # as error catcher
gem 'airbrake', '~> 7.1' gem 'airbrake'
# to make links faster # to make links faster
gem 'turbolinks' gem 'turbolinks'
@ -187,7 +181,7 @@ gem 'acts_as_list'
gem 'bootstrap-switch-rails', '~> 3.0.0' gem 'bootstrap-switch-rails', '~> 3.0.0'
# for parsing OEmbed data # for parsing OEmbed data
gem 'ruby-oembed', '~>0.12.0' gem 'ruby-oembed'
# for uploading images to the cloud # for uploading images to the cloud
gem 'cloudinary' gem 'cloudinary'
@ -200,7 +194,7 @@ gem 'dotenv-rails'
gem 'feature' gem 'feature'
# For countable.js # For countable.js
gem "countable-rails", "~> 0.0.1" gem "countable-rails"
# Both are not in a group as we use it also for rake data:demo # Both are not in a group as we use it also for rake data:demo
# for fake data # for fake data
@ -239,12 +233,10 @@ group :development do
gem 'rubocop-rspec' gem 'rubocop-rspec'
# to open mails # to open mails
gem 'letter_opener' gem 'letter_opener'
# to open mails in browser
gem 'letter_opener_web'
# as deployment system # as deployment system
gem 'mina' gem 'mina'
# as debugger on error pages # as debugger on error pages
gem 'web-console', '~> 2.0' gem 'web-console'
# as development database # as development database
gem 'sqlite3' gem 'sqlite3'
end end
@ -252,12 +244,11 @@ end
group :test do group :test do
# as test framework # as test framework
gem 'capybara' gem 'capybara'
gem 'chromedriver-helper'
gem 'database_cleaner' gem 'database_cleaner'
gem 'geckodriver-helper' gem 'geckodriver-helper'
gem 'rspec-rails' gem 'rspec-rails'
gem 'selenium-webdriver'
gem 'transactional_capybara' gem 'transactional_capybara'
gem 'webdrivers'
# for measuring test coverage # for measuring test coverage
gem 'codecov', require: false gem 'codecov', require: false
# for describing models # for describing models

View file

@ -13,44 +13,48 @@ GEM
remote: https://rails-assets.org/ remote: https://rails-assets.org/
specs: specs:
Ascii85 (1.0.3) Ascii85 (1.0.3)
actioncable (5.0.7.1) actioncable (5.2.3)
actionpack (= 5.0.7.1) actionpack (= 5.2.3)
nio4r (>= 1.2, < 3.0) nio4r (~> 2.0)
websocket-driver (~> 0.6.1) websocket-driver (>= 0.6.1)
actionmailer (5.0.7.1) actionmailer (5.2.3)
actionpack (= 5.0.7.1) actionpack (= 5.2.3)
actionview (= 5.0.7.1) actionview (= 5.2.3)
activejob (= 5.0.7.1) activejob (= 5.2.3)
mail (~> 2.5, >= 2.5.4) mail (~> 2.5, >= 2.5.4)
rails-dom-testing (~> 2.0) rails-dom-testing (~> 2.0)
actionpack (5.0.7.1) actionpack (5.2.3)
actionview (= 5.0.7.1) actionview (= 5.2.3)
activesupport (= 5.0.7.1) activesupport (= 5.2.3)
rack (~> 2.0) rack (~> 2.0)
rack-test (~> 0.6.3) rack-test (>= 0.6.3)
rails-dom-testing (~> 2.0) rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.0.2) rails-html-sanitizer (~> 1.0, >= 1.0.2)
actionview (5.0.7.1) actionview (5.2.3)
activesupport (= 5.0.7.1) activesupport (= 5.2.3)
builder (~> 3.1) builder (~> 3.1)
erubis (~> 2.7.0) erubi (~> 1.4)
rails-dom-testing (~> 2.0) rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.0.3) rails-html-sanitizer (~> 1.0, >= 1.0.3)
active_model_serializers (0.10.8) active_model_serializers (0.10.10)
actionpack (>= 4.1, < 6) actionpack (>= 4.1, < 6.1)
activemodel (>= 4.1, < 6) activemodel (>= 4.1, < 6.1)
case_transform (>= 0.2) case_transform (>= 0.2)
jsonapi-renderer (>= 0.1.1.beta1, < 0.3) jsonapi-renderer (>= 0.1.1.beta1, < 0.3)
activejob (5.0.7.1) activejob (5.2.3)
activesupport (= 5.0.7.1) activesupport (= 5.2.3)
globalid (>= 0.3.6) globalid (>= 0.3.6)
activemodel (5.0.7.1) activemodel (5.2.3)
activesupport (= 5.0.7.1) activesupport (= 5.2.3)
activerecord (5.0.7.1) activerecord (5.2.3)
activemodel (= 5.0.7.1) activemodel (= 5.2.3)
activesupport (= 5.0.7.1) activesupport (= 5.2.3)
arel (~> 7.0) arel (>= 9.0)
activesupport (5.0.7.1) activestorage (5.2.3)
actionpack (= 5.2.3)
activerecord (= 5.2.3)
marcel (~> 0.3.1)
activesupport (5.2.3)
concurrent-ruby (~> 1.0, >= 1.0.2) concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2) i18n (>= 0.7, < 2)
minitest (~> 5.1) minitest (~> 5.1)
@ -59,21 +63,22 @@ GEM
activerecord (>= 4.0) activerecord (>= 4.0)
activesupport (>= 4.0) activesupport (>= 4.0)
awesome_nested_set (>= 3.0) awesome_nested_set (>= 3.0)
acts_as_list (0.9.17) acts_as_list (0.9.19)
activerecord (>= 3.0) activerecord (>= 3.0)
addressable (2.5.2) addressable (2.6.0)
public_suffix (>= 2.0.2, < 4.0) public_suffix (>= 2.0.2, < 4.0)
afm (0.2.2) afm (0.2.2)
airbrake (7.4.0) airbrake (9.2.2)
airbrake-ruby (~> 2.12) airbrake-ruby (~> 4.4)
airbrake-ruby (2.12.0) airbrake-ruby (4.4.0)
rbtree3 (~> 0.5)
ajax-datatables-rails (0.4.3) ajax-datatables-rails (0.4.3)
railties (>= 4.0) railties (>= 4.0)
archive-zip (0.11.0) archive-zip (0.12.0)
io-like (~> 0.3.0) io-like (~> 0.3.0)
arel (7.1.4) arel (9.0.0)
ast (2.4.0) ast (2.4.0)
autoprefixer-rails (9.4.3) autoprefixer-rails (9.6.4)
execjs execjs
awesome_nested_set (3.1.4) awesome_nested_set (3.1.4)
activerecord (>= 4.0.0, < 5.3) activerecord (>= 4.0.0, < 5.3)
@ -81,27 +86,26 @@ GEM
axlsx_rails (0.5.2) axlsx_rails (0.5.2)
actionpack (>= 3.1) actionpack (>= 3.1)
axlsx (>= 2.0.1) axlsx (>= 2.0.1)
bcrypt (3.1.12) bcrypt (3.1.13)
binding_of_caller (0.7.2) bindex (0.6.0)
debug_inspector (>= 0.0.1) bootstrap-sass (3.4.1)
bootstrap-sass (3.3.4.1) autoprefixer-rails (>= 5.2.1)
autoprefixer-rails (>= 5.0.0.1) sassc (>= 2.0.0)
sass (>= 3.2.19)
bootstrap-switch-rails (3.0.2) bootstrap-switch-rails (3.0.2)
bootstrap3-datetimepicker-rails (3.0.3) bootstrap3-datetimepicker-rails (4.17.47)
momentjs-rails (>= 2.8.1) momentjs-rails (>= 2.8.1)
builder (3.2.3) builder (3.2.3)
byebug (10.0.2) byebug (11.0.1)
cancancan (2.3.0) cancancan (2.3.0)
capybara (3.12.0) capybara (3.26.0)
addressable addressable
mini_mime (>= 0.1.3) mini_mime (>= 0.1.3)
nokogiri (~> 1.8) nokogiri (~> 1.8)
rack (>= 1.6.0) rack (>= 1.6.0)
rack-test (>= 0.6.3) rack-test (>= 0.6.3)
regexp_parser (~> 1.2) regexp_parser (~> 1.5)
xpath (~> 3.2) xpath (~> 3.2)
carrierwave (1.3.0) carrierwave (1.3.1)
activemodel (>= 4.0.0) activemodel (>= 4.0.0)
activesupport (>= 4.0.0) activesupport (>= 4.0.0)
mime-types (>= 1.16) mime-types (>= 1.16)
@ -111,67 +115,60 @@ GEM
fastimage fastimage
case_transform (0.2) case_transform (0.2)
activesupport activesupport
chart-js-rails (0.1.6) chartkick (3.3.0)
railties (> 3.1) childprocess (3.0.0)
chartkick (3.0.1)
childprocess (0.9.0)
ffi (~> 1.0, >= 1.0.11)
chromedriver-helper (2.1.0)
archive-zip (~> 0.10)
nokogiri (~> 1.8)
chronic (0.10.2) chronic (0.10.2)
chunky_png (1.3.8) chunky_png (1.3.11)
climate_control (0.2.0) climate_control (0.2.0)
cloudinary (1.11.1) cloudinary (1.11.1)
aws_cf_signer aws_cf_signer
rest-client rest-client
cocoon (1.2.12) cocoon (1.2.14)
codecov (0.1.14) codecov (0.1.14)
json json
simplecov simplecov
url url
coderay (1.1.1) coderay (1.1.1)
concurrent-ruby (1.1.4) concurrent-ruby (1.1.5)
connection_pool (2.2.2) connection_pool (2.2.2)
countable-rails (0.0.1) countable-rails (0.0.1)
railties (>= 3.1) railties (>= 3.1)
countries (2.1.4) countries (3.0.0)
i18n_data (~> 0.8.0) i18n_data (~> 0.8.0)
money (~> 6.9)
sixarm_ruby_unaccent (~> 1.1) sixarm_ruby_unaccent (~> 1.1)
unicode_utils (~> 1.4) unicode_utils (~> 1.4)
country_select (3.1.1) country_select (4.0.0)
countries (~> 2.0) countries (~> 3.0)
sort_alphabetical (~> 1.0) sort_alphabetical (~> 1.0)
crack (0.4.3) crack (0.4.3)
safe_yaml (~> 1.0.0) safe_yaml (~> 1.0.0)
crass (1.0.4) crass (1.0.5)
daemons (1.3.1) daemons (1.3.1)
dalli (2.7.9) dalli (2.7.10)
dante (0.2.0) dante (0.2.0)
database_cleaner (1.7.0) database_cleaner (1.7.0)
debug_inspector (0.0.3) delayed_job (4.1.8)
delayed_job (4.1.5) activesupport (>= 3.0, < 6.1)
activesupport (>= 3.0, < 5.3) delayed_job_active_record (4.1.4)
delayed_job_active_record (4.1.3) activerecord (>= 3.0, < 6.1)
activerecord (>= 3.0, < 5.3)
delayed_job (>= 3.0, < 5) delayed_job (>= 3.0, < 5)
devise (4.5.0) devise (4.7.1)
bcrypt (~> 3.0) bcrypt (~> 3.0)
orm_adapter (~> 0.1) orm_adapter (~> 0.1)
railties (>= 4.1.0, < 6.0) railties (>= 4.1.0)
responders responders
warden (~> 1.2.3) warden (~> 1.2.3)
devise_ichain_authenticatable (0.3.1) devise_ichain_authenticatable (0.3.2)
devise (>= 2.2) devise (>= 2.2)
diff-lcs (1.3) diff-lcs (1.3)
docile (1.3.1) docile (1.3.1)
domain_name (0.5.20180417) domain_name (0.5.20180417)
unf (>= 0.0.5, < 1.0.0) unf (>= 0.0.5, < 1.0.0)
dotenv (2.5.0) dotenv (2.7.5)
dotenv-rails (2.5.0) dotenv-rails (2.7.5)
dotenv (= 2.5.0) dotenv (= 2.7.5)
railties (>= 3.2, < 6.0) railties (>= 3.2, < 6.1)
erubi (1.9.0)
erubis (2.7.0) erubis (2.7.0)
execjs (2.7.0) execjs (2.7.0)
factory_bot (4.11.1) factory_bot (4.11.1)
@ -179,15 +176,15 @@ GEM
factory_bot_rails (4.11.1) factory_bot_rails (4.11.1)
factory_bot (~> 4.11.1) factory_bot (~> 4.11.1)
railties (>= 3.0.0) railties (>= 3.0.0)
faker (1.9.1) faker (1.9.3)
i18n (>= 0.7) i18n (>= 0.7)
faraday (0.15.4) faraday (0.15.4)
multipart-post (>= 1.2, < 3) multipart-post (>= 1.2, < 3)
fastimage (2.1.4) fastimage (2.1.4)
feature (1.4.0) feature (1.4.0)
ffi (1.9.25) ffi (1.10.0)
font-awesome-rails (4.7.0.4) font-awesome-rails (4.7.0.5)
railties (>= 3.2, < 6.0) railties (>= 3.2, < 6.1)
formatador (0.2.5) formatador (0.2.5)
formtastic (3.1.5) formtastic (3.1.5)
actionpack (>= 3.2.13) actionpack (>= 3.2.13)
@ -195,7 +192,7 @@ GEM
formtastic (>= 3.0) formtastic (>= 3.0)
geckodriver-helper (0.23.0) geckodriver-helper (0.23.0)
archive-zip (~> 0.7) archive-zip (~> 0.7)
globalid (0.4.1) globalid (0.4.2)
activesupport (>= 4.2.0) activesupport (>= 4.2.0)
gravtastic (3.2.6) gravtastic (3.2.6)
guard (2.14.1) guard (2.14.1)
@ -238,84 +235,82 @@ GEM
htmlentities (4.3.4) htmlentities (4.3.4)
http-cookie (1.0.3) http-cookie (1.0.3)
domain_name (~> 0.5) domain_name (~> 0.5)
i18n (0.9.5) i18n (1.7.0)
concurrent-ruby (~> 1.0) concurrent-ruby (~> 1.0)
i18n_data (0.8.0) i18n_data (0.8.0)
inversion (1.1.1) inversion (1.1.1)
loggability (~> 0.12) loggability (~> 0.12)
io-like (0.3.0) io-like (0.3.0)
iso-639 (0.2.8) iso-639 (0.2.8)
jaro_winkler (1.5.1) jaro_winkler (1.5.3)
jquery-datatables-rails (3.4.0) jquery-datatables-rails (3.4.0)
actionpack (>= 3.1) actionpack (>= 3.1)
jquery-rails jquery-rails
railties (>= 3.1) railties (>= 3.1)
sass-rails sass-rails
jquery-rails (4.3.3) jquery-rails (4.3.5)
rails-dom-testing (>= 1, < 3) rails-dom-testing (>= 1, < 3)
railties (>= 4.2.0) 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)
json (2.1.0) json (2.2.0)
json-schema (2.8.1) json-schema (2.8.1)
addressable (>= 2.4) addressable (>= 2.4)
jsonapi-renderer (0.2.0) jsonapi-renderer (0.2.2)
jwt (2.1.0) jwt (2.1.0)
launchy (2.4.3) launchy (2.4.3)
addressable (~> 2.3) addressable (~> 2.3)
leaflet-rails (1.3.1) leaflet-rails (1.5.1)
rails (>= 4.2.0) rails (>= 4.2.0)
letter_opener (1.7.0) letter_opener (1.7.0)
launchy (~> 2.2) launchy (~> 2.2)
letter_opener_web (1.3.0)
actionmailer (>= 3.2)
letter_opener (~> 1.0)
railties (>= 3.2)
listen (3.1.5) listen (3.1.5)
rb-fsevent (~> 0.9, >= 0.9.4) rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7) rb-inotify (~> 0.9, >= 0.9.7)
ruby_dep (~> 1.2) ruby_dep (~> 1.2)
loggability (0.14.0) loggability (0.14.0)
loofah (2.2.3) loofah (2.4.0)
crass (~> 1.0.2) crass (~> 1.0.2)
nokogiri (>= 1.5.9) nokogiri (>= 1.5.9)
lumberjack (1.0.12) lumberjack (1.0.12)
mail (2.7.1) mail (2.7.1)
mini_mime (>= 0.1.1) mini_mime (>= 0.1.1)
marcel (0.3.3)
mimemagic (~> 0.3.2)
method_source (0.8.2) method_source (0.8.2)
mime-types (3.2.2) mime-types (3.2.2)
mime-types-data (~> 3.2015) mime-types-data (~> 3.2015)
mime-types-data (3.2018.0812) mime-types-data (3.2018.0812)
mimemagic (0.3.2) mimemagic (0.3.3)
mina (0.3.8) mina (1.2.3)
open4 (~> 1.3.4) open4 (~> 1.3.4)
rake rake
mini_magick (4.9.2) mini_magick (4.9.5)
mini_mime (1.0.1) mini_mime (1.0.2)
mini_portile2 (2.4.0) mini_portile2 (2.4.0)
minitest (5.11.3) minitest (5.13.0)
momentjs-rails (2.8.1) momentjs-rails (2.20.1)
railties (>= 3.1) railties (>= 3.1)
monetize (1.9.0) monetize (1.9.2)
money (~> 6.12) money (~> 6.12)
money (6.13.1) money (6.13.4)
i18n (>= 0.6.4, <= 2) i18n (>= 0.6.4, <= 2)
money-rails (1.13.0) money-rails (1.13.3)
activesupport (>= 3.0) activesupport (>= 3.0)
monetize (~> 1.9.0) monetize (~> 1.9.0)
money (~> 6.13.0) money (~> 6.13.2)
railties (>= 3.0) railties (>= 3.0)
multi_json (1.13.1) multi_json (1.13.1)
multi_xml (0.6.0) multi_xml (0.6.0)
multipart-post (2.0.0) multipart-post (2.1.1)
mysql2 (0.5.2) mysql2 (0.5.2)
nenv (0.3.0) nenv (0.3.0)
net-http-persistent (3.0.0) net-http-persistent (3.0.1)
connection_pool (~> 2.2) connection_pool (~> 2.2)
netrc (0.11.0) netrc (0.11.0)
nio4r (2.3.1) nio4r (2.5.2)
nokogiri (1.9.1) nokogiri (1.10.5)
mini_portile2 (~> 2.4.0) mini_portile2 (~> 2.4.0)
notiffany (0.1.1) notiffany (0.1.1)
nenv (~> 0.1) nenv (~> 0.1)
@ -334,8 +329,8 @@ GEM
omniauth-github (1.3.0) omniauth-github (1.3.0)
omniauth (~> 1.5) omniauth (~> 1.5)
omniauth-oauth2 (>= 1.4.0, < 2.0) omniauth-oauth2 (>= 1.4.0, < 2.0)
omniauth-google-oauth2 (0.5.4) omniauth-google-oauth2 (0.6.1)
jwt (>= 1.5) jwt (>= 2.0)
omniauth (>= 1.1.1) omniauth (>= 1.1.1)
omniauth-oauth2 (>= 1.5) omniauth-oauth2 (>= 1.5)
omniauth-oauth2 (1.6.0) omniauth-oauth2 (1.6.0)
@ -346,13 +341,13 @@ GEM
rack-openid (~> 1.3.1) rack-openid (~> 1.3.1)
open4 (1.3.4) open4 (1.3.4)
orm_adapter (0.5.0) orm_adapter (0.5.0)
paper_trail (10.1.0) paper_trail (10.3.1)
activerecord (>= 4.2, < 6.0) activerecord (>= 4.2)
request_store (~> 1.1) request_store (~> 1.1)
parallel (1.12.1) parallel (1.18.0)
parser (2.5.3.0) parser (2.6.5.0)
ast (~> 2.4.0) ast (~> 2.4.0)
pdf-core (0.2.5) pdf-core (0.7.0)
pdf-inspector (1.3.0) pdf-inspector (1.3.0)
pdf-reader (>= 1.0, < 3.0.a) pdf-reader (>= 1.0, < 3.0.a)
pdf-reader (2.2.0) pdf-reader (2.2.0)
@ -361,44 +356,47 @@ GEM
hashery (~> 2.0) hashery (~> 2.0)
ruby-rc4 ruby-rc4
ttfunk ttfunk
pg (1.1.3) pg (1.1.4)
piwik_analytics (1.0.2) piwik_analytics (1.0.2)
actionpack actionpack
activesupport activesupport
rails (>= 3.0.0) rails (>= 3.0.0)
powerpack (0.1.2) prawn (2.2.2)
prawn (1.0.0) pdf-core (~> 0.7.0)
pdf-core (~> 0.2.2) ttfunk (~> 1.5)
ttfunk (~> 1.1.1) prawn-qrcode (0.3.1)
prawn-qrcode (0.2.2.1) prawn (>= 1)
prawn (>= 0.11.1)
rqrcode (>= 0.4.1) rqrcode (>= 0.4.1)
prawn_rails (0.0.11) prawn-rails (1.2.0)
prawn (>= 0.11.1) prawn
railties (>= 3.0.0) prawn-table
rails (>= 3.1.0)
prawn-table (0.2.2)
prawn (>= 1.3.0, < 3.0.0)
pry (0.10.4) pry (0.10.4)
coderay (~> 1.1.0) coderay (~> 1.1.0)
method_source (~> 0.8.1) method_source (~> 0.8.1)
slop (~> 3.4) slop (~> 3.4)
public_suffix (3.0.3) public_suffix (3.1.1)
puma (3.12.0) puma (3.12.2)
rack (2.0.6) rack (2.0.8)
rack-openid (1.3.1) rack-openid (1.3.1)
rack (>= 1.1.0) rack (>= 1.1.0)
ruby-openid (>= 2.1.8) ruby-openid (>= 2.1.8)
rack-test (0.6.3) rack-test (1.1.0)
rack (>= 1.0) rack (>= 1.0, < 3)
rails (5.0.7.1) rails (5.2.3)
actioncable (= 5.0.7.1) actioncable (= 5.2.3)
actionmailer (= 5.0.7.1) actionmailer (= 5.2.3)
actionpack (= 5.0.7.1) actionpack (= 5.2.3)
actionview (= 5.0.7.1) actionview (= 5.2.3)
activejob (= 5.0.7.1) activejob (= 5.2.3)
activemodel (= 5.0.7.1) activemodel (= 5.2.3)
activerecord (= 5.0.7.1) activerecord (= 5.2.3)
activesupport (= 5.0.7.1) activestorage (= 5.2.3)
activesupport (= 5.2.3)
bundler (>= 1.3.0) bundler (>= 1.3.0)
railties (= 5.0.7.1) railties (= 5.2.3)
sprockets-rails (>= 2.0.0) sprockets-rails (>= 2.0.0)
rails-assets-bootstrap (3.3.6) rails-assets-bootstrap (3.3.6)
rails-assets-jquery (>= 1.9.1, < 3) rails-assets-jquery (>= 1.9.1, < 3)
@ -417,7 +415,7 @@ GEM
rails-assets-spectrum (1.8.0) rails-assets-spectrum (1.8.0)
rails-assets-jquery (>= 1.7.2) rails-assets-jquery (>= 1.7.2)
rails-assets-tinycolor (1.4.1) rails-assets-tinycolor (1.4.1)
rails-assets-to-markdown (3.0.0) rails-assets-to-markdown (3.1.1)
rails-assets-trianglify (1.2.0) rails-assets-trianglify (1.2.0)
rails-assets-waypoints (4.0.0) rails-assets-waypoints (4.0.0)
rails-controller-testing (1.0.4) rails-controller-testing (1.0.4)
@ -427,42 +425,38 @@ GEM
rails-dom-testing (2.0.3) rails-dom-testing (2.0.3)
activesupport (>= 4.2.0) activesupport (>= 4.2.0)
nokogiri (>= 1.6) nokogiri (>= 1.6)
rails-html-sanitizer (1.0.4) rails-html-sanitizer (1.3.0)
loofah (~> 2.2, >= 2.2.2) loofah (~> 2.3)
rails-i18n (5.0.4) rails-i18n (5.1.3)
i18n (~> 0.7) i18n (>= 0.7, < 2)
railties (~> 5.0) railties (>= 5.0, < 6)
rails_12factor (0.0.3) railties (5.2.3)
rails_serve_static_assets actionpack (= 5.2.3)
rails_stdout_logging activesupport (= 5.2.3)
rails_serve_static_assets (0.0.4)
rails_stdout_logging (0.0.3)
railties (5.0.7.1)
actionpack (= 5.0.7.1)
activesupport (= 5.0.7.1)
method_source method_source
rake (>= 0.8.7) rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0) thor (>= 0.19.0, < 2.0)
rainbow (3.0.0) rainbow (3.0.0)
rake (12.3.1) rake (12.3.3)
rb-fsevent (0.10.2) rb-fsevent (0.10.3)
rb-inotify (0.9.10) rb-inotify (0.10.0)
ffi (>= 0.5.0, < 2) ffi (~> 1.0)
rbtree3 (0.5.0)
rdoc (6.0.4) rdoc (6.0.4)
rdoc-generator-fivefish (0.4.0) rdoc-generator-fivefish (0.4.0)
inversion (~> 1.1) inversion (~> 1.1)
loggability (~> 0.12) loggability (~> 0.12)
rdoc (~> 6.0) rdoc (~> 6.0)
yajl-ruby (~> 1.3) yajl-ruby (~> 1.3)
recaptcha (4.13.1) recaptcha (4.14.0)
json json
redcarpet (3.4.0) redcarpet (3.5.0)
regexp_parser (1.3.0) regexp_parser (1.6.0)
request_store (1.4.1) request_store (1.4.1)
rack (>= 1.4) rack (>= 1.4)
responders (2.4.0) responders (2.4.1)
actionpack (>= 4.2.0, < 5.3) actionpack (>= 4.2.0, < 6.0)
railties (>= 4.2.0, < 5.3) railties (>= 4.2.0, < 6.0)
rest-client (2.0.2) rest-client (2.0.2)
http-cookie (>= 1.0.2, < 2.0) http-cookie (>= 1.0.2, < 2.0)
mime-types (>= 1.16, < 4.0) mime-types (>= 1.16, < 4.0)
@ -495,26 +489,25 @@ GEM
rspec-mocks (~> 3.6.0) rspec-mocks (~> 3.6.0)
rspec-support (~> 3.6.0) rspec-support (~> 3.6.0)
rspec-support (3.6.0) rspec-support (3.6.0)
rubocop (0.61.1) rubocop (0.75.1)
jaro_winkler (~> 1.5.1) jaro_winkler (~> 1.5.1)
parallel (~> 1.10) parallel (~> 1.10)
parser (>= 2.5, != 2.5.1.1) parser (>= 2.6)
powerpack (~> 0.1)
rainbow (>= 2.2.2, < 4.0) rainbow (>= 2.2.2, < 4.0)
ruby-progressbar (~> 1.7) ruby-progressbar (~> 1.7)
unicode-display_width (~> 1.4.0) unicode-display_width (>= 1.4.0, < 1.7)
rubocop-rspec (1.30.1) rubocop-rspec (1.36.0)
rubocop (>= 0.60.0) rubocop (>= 0.68.1)
ruby-oembed (0.12.0) ruby-oembed (0.12.0)
ruby-openid (2.5.0) ruby-openid (2.9.2)
ruby-progressbar (1.10.0) ruby-progressbar (1.10.1)
ruby-rc4 (0.1.5) ruby-rc4 (0.1.5)
ruby_dep (1.5.0) ruby_dep (1.5.0)
ruby_parser (3.11.0) ruby_parser (3.11.0)
sexp_processor (~> 4.9) sexp_processor (~> 4.9)
rubyzip (1.2.2) rubyzip (1.3.0)
safe_yaml (1.0.4) safe_yaml (1.0.4)
sass (3.5.7) sass (3.7.2)
sass-listen (~> 4.0.0) sass-listen (~> 4.0.0)
sass-listen (4.0.0) sass-listen (4.0.0)
rb-fsevent (~> 0.9, >= 0.9.4) rb-fsevent (~> 0.9, >= 0.9.4)
@ -525,23 +518,26 @@ GEM
sprockets (>= 2.8, < 4.0) sprockets (>= 2.8, < 4.0)
sprockets-rails (>= 2.0, < 4.0) sprockets-rails (>= 2.0, < 4.0)
tilt (>= 1.1, < 3) tilt (>= 1.1, < 3)
sassc (2.0.1)
ffi (~> 1.9)
rake
selectize-rails (0.12.6) selectize-rails (0.12.6)
selenium-webdriver (3.141.0) selenium-webdriver (3.142.6)
childprocess (~> 0.5) childprocess (>= 0.5, < 4.0)
rubyzip (~> 1.2, >= 1.2.2) rubyzip (>= 1.2.2)
sexp_processor (4.11.0) sexp_processor (4.11.0)
shellany (0.0.1) shellany (0.0.1)
shoulda-matchers (2.8.0) shoulda-matchers (4.1.2)
activesupport (>= 3.0.0) activesupport (>= 4.2.0)
simplecov (0.16.1) simplecov (0.16.1)
docile (~> 1.1) docile (~> 1.1)
json (>= 1.8, < 3) json (>= 1.8, < 3)
simplecov-html (~> 0.10.0) simplecov-html (~> 0.10.0)
simplecov-html (0.10.2) simplecov-html (0.10.2)
sixarm_ruby_unaccent (1.2.0) sixarm_ruby_unaccent (1.2.0)
skylight (3.1.2) skylight (3.1.5)
skylight-core (= 3.1.2) skylight-core (= 3.1.5)
skylight-core (3.1.2) skylight-core (3.1.5)
activesupport (>= 4.2.0) activesupport (>= 4.2.0)
slop (3.6.0) slop (3.6.0)
sort_alphabetical (1.1.0) sort_alphabetical (1.1.0)
@ -556,11 +552,11 @@ GEM
actionpack (>= 4.0) actionpack (>= 4.0)
activesupport (>= 4.0) activesupport (>= 4.0)
sprockets (>= 3.0.0) sprockets (>= 3.0.0)
sqlite3 (1.3.13) sqlite3 (1.4.1)
stripe (4.4.0) stripe (4.21.3)
faraday (~> 0.13) faraday (~> 0.13)
net-http-persistent (~> 3.0) net-http-persistent (~> 3.0)
stripe-ruby-mock (2.5.6) stripe-ruby-mock (2.5.8)
dante (>= 0.2.0) dante (>= 0.2.0)
multi_json (~> 1.0) multi_json (~> 1.0)
stripe (>= 2.0.3) stripe (>= 2.0.3)
@ -572,9 +568,9 @@ GEM
timecop (0.9.1) timecop (0.9.1)
transactional_capybara (0.2.0) transactional_capybara (0.2.0)
capybara capybara
transitions (0.1.12) transitions (1.2.1)
ttfunk (1.1.1) ttfunk (1.5.1)
turbolinks (5.2.0) turbolinks (5.2.1)
turbolinks-source (~> 5.2) turbolinks-source (~> 5.2)
turbolinks-source (5.2.0) turbolinks-source (5.2.0)
tzinfo (1.2.5) tzinfo (1.2.5)
@ -584,25 +580,29 @@ GEM
unf (0.1.4) unf (0.1.4)
unf_ext unf_ext
unf_ext (0.0.7.5) unf_ext (0.0.7.5)
unicode-display_width (1.4.0) unicode-display_width (1.6.0)
unicode_utils (1.4.0) unicode_utils (1.4.0)
unobtrusive_flash (3.3.1) unobtrusive_flash (3.3.1)
railties railties
url (0.3.2) url (0.3.2)
warden (1.2.7) warden (1.2.8)
rack (>= 1.0) rack (>= 2.0.6)
web-console (2.3.0) web-console (3.7.0)
activemodel (>= 4.0) actionview (>= 5.0)
binding_of_caller (>= 0.7.2) activemodel (>= 5.0)
railties (>= 4.0) bindex (>= 0.4.0)
sprockets-rails (>= 2.0, < 4.0) railties (>= 5.0)
webmock (3.4.2) webdrivers (4.1.3)
nokogiri (~> 1.6)
rubyzip (>= 1.3.0)
selenium-webdriver (>= 3.0, < 4.0)
webmock (3.5.1)
addressable (>= 2.3.6) addressable (>= 2.3.6)
crack (>= 0.3.2) crack (>= 0.3.2)
hashdiff hashdiff
websocket-driver (0.6.5) websocket-driver (0.7.1)
websocket-extensions (>= 0.1.0) websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.3) websocket-extensions (0.1.4)
whenever (0.10.0) whenever (0.10.0)
chronic (>= 0.6.3) chronic (>= 0.6.3)
xpath (3.2.0) xpath (3.2.0)
@ -616,28 +616,26 @@ DEPENDENCIES
active_model_serializers active_model_serializers
acts_as_commentable_with_threading acts_as_commentable_with_threading
acts_as_list acts_as_list
airbrake (~> 7.1) airbrake
ajax-datatables-rails ajax-datatables-rails
autoprefixer-rails autoprefixer-rails
awesome_nested_set (~> 3.1.3) awesome_nested_set
axlsx! axlsx!
axlsx_rails axlsx_rails
bootstrap-sass (~> 3.3.4.1) bootstrap-sass (~> 3.4.0)
bootstrap-switch-rails (~> 3.0.0) bootstrap-switch-rails (~> 3.0.0)
bootstrap3-datetimepicker-rails (~> 3.0.2) bootstrap3-datetimepicker-rails (~> 4.17.47)
byebug byebug
cancancan (~> 2.0) cancancan
capybara capybara
carrierwave carrierwave
carrierwave-bombshelter carrierwave-bombshelter
chart-js-rails
chartkick chartkick
chromedriver-helper
climate_control climate_control
cloudinary cloudinary
cocoon cocoon
codecov codecov
countable-rails (~> 0.0.1) countable-rails
country_select country_select
daemons daemons
dalli dalli
@ -664,7 +662,6 @@ DEPENDENCIES
json-schema json-schema
leaflet-rails leaflet-rails
letter_opener letter_opener
letter_opener_web
mina mina
mini_magick mini_magick
money-rails money-rails
@ -679,10 +676,10 @@ DEPENDENCIES
pdf-inspector pdf-inspector
pg pg
piwik_analytics (~> 1.0.1) piwik_analytics (~> 1.0.1)
prawn-qrcode (~> 0.2.2.1) prawn-qrcode
prawn_rails prawn-rails
puma (~> 3.0) puma (~> 3.0)
rails (~> 5.0.7) rails (~> 5.2.3)
rails-assets-bootstrap-markdown! rails-assets-bootstrap-markdown!
rails-assets-bootstrap-select! rails-assets-bootstrap-select!
rails-assets-date.format! rails-assets-date.format!
@ -692,12 +689,11 @@ DEPENDENCIES
rails-assets-momentjs! rails-assets-momentjs!
rails-assets-spectrum! rails-assets-spectrum!
rails-assets-tinycolor! rails-assets-tinycolor!
rails-assets-to-markdown! rails-assets-to-markdown (~> 3)!
rails-assets-trianglify! rails-assets-trianglify!
rails-assets-waypoints! rails-assets-waypoints!
rails-controller-testing rails-controller-testing
rails-i18n (~> 5.0.0) rails-i18n
rails_12factor
rdoc-generator-fivefish rdoc-generator-fivefish
recaptcha recaptcha
redcarpet redcarpet
@ -708,10 +704,9 @@ DEPENDENCIES
rspec-rails rspec-rails
rubocop rubocop
rubocop-rspec rubocop-rspec
ruby-oembed (~> 0.12.0) ruby-oembed
sass-rails (>= 4.0.2) sass-rails (>= 4.0.2)
selectize-rails selectize-rails
selenium-webdriver
shoulda-matchers shoulda-matchers
skylight skylight
spring-commands-rspec spring-commands-rspec
@ -719,14 +714,14 @@ DEPENDENCIES
sqlite3 sqlite3
stripe stripe
stripe-ruby-mock stripe-ruby-mock
thor (~> 0.19)
timecop timecop
transactional_capybara transactional_capybara
transitions transitions
turbolinks turbolinks
uglifier (>= 1.3.0) uglifier (>= 1.3.0)
unobtrusive_flash (>= 3) unobtrusive_flash (>= 3)
web-console (~> 2.0) web-console
webdrivers
webmock webmock
whenever whenever
@ -734,4 +729,4 @@ RUBY VERSION
ruby 2.5.0p0 ruby 2.5.0p0
BUNDLED WITH BUNDLED WITH
1.16.5 1.17.3

View file

@ -1,5 +1,14 @@
# Install Open Source Event Manager # Install Open Source Event Manager
All the information that you need to install OSEM. If you have any problems with installing don't hesitate to [contact us](https://github.com/openSUSE/osem#contact) Here is what you need to install OSEM.
# 💥💥💥 WARNING 💥💥💥
![explosions](https://media.giphy.com/media/Yl5aO3gdVfsQ0/giphy.gif)
OSEM is a Ruby on Rails server application for professional use, not some desktop app you run for yourself. If you deploy it, **YOU** are responsible for the data that users enter into it, this data includes personal information like email addresses and/or passwords that most likely can be used to harm them in some form (cracking, doxing, social engineering).
If you never deployed a Ruby on Rails app before we **strongly** suggest you seek help from someone who has. That someone is **NOT** the OSEM team so please do **NOT** open an issue expecting us to explain how to do this.
*You should know what you do and you have been warned*.
## Versions ## Versions
OSEM is an [semantic versioned](http://semver.org/) app. That means given a version number MAJOR.MINOR.PATCH we increment the: OSEM is an [semantic versioned](http://semver.org/) app. That means given a version number MAJOR.MINOR.PATCH we increment the:
@ -9,102 +18,65 @@ OSEM is an [semantic versioned](http://semver.org/) app. That means given a vers
3. PATCH version when we make backwards-compatible bug fixes 3. PATCH version when we make backwards-compatible bug fixes
## Download ## Download
You can find the latest OSEM releases on our [release page](https://github.com/openSUSE/osem/releases/latest) ([older release here](https://github.com/openSUSE/osem/releases)) You can find the latest OSEM releases on our [release page](https://github.com/openSUSE/osem/releases)
## Deploy to the cloud
## Deploy The easiest way to deploy OSEM is to use one of the many platform as a service providers that support ruby on rails. We have prepared OSEM to be used with [heroku](https://heroku.com). So if you have an account there, you can deploy OSEM by pressing this button:
OSEM is a *Ruby on Rails* application. We recommend to run OSEM in production with [mod_passenger](https://www.phusionpassenger.com/download/#open_source)
and the [apache web-server](https://www.apache.org/). There are tons of guides on how to deploy rails apps on various
base operating systems. [Check Google](https://encrypted.google.com/search?hl=en&q=ruby%20on%20rails%20apache%20passenger) ;-)
For more information about rails and what it can do, see the [rails guides.](http://guides.rubyonrails.org/getting_started.html)
If you have an heroku account you can also
<a href="https://heroku.com/deploy?template=https://github.com/openSUSE/osem/tree/v1.0"> <a href="https://heroku.com/deploy?template=https://github.com/openSUSE/osem/tree/v1.0">
<img src="https://www.herokucdn.com/deploy/button.svg" alt="Deploy"> <img src="https://www.herokucdn.com/deploy/button.svg" alt="Deploy">
</a> </a>
### Deploy with Docker ## Deploy to your own server
We recommend to run OSEM in production with [mod_passenger](https://www.phusionpassenger.com/download/#open_source)
and the [apache web-server](https://www.apache.org/). There are tons of guides on how to deploy rails apps on various
base operating systems. [Check Google](https://encrypted.google.com/search?hl=en&q=ruby%20on%20rails%20apache%20passenger). Of course there are also other options for the application server and reverse proxy, pick your poison.
You can deploy OSEM using [Docker](https://docker.com/) and [Docker-Compose](https://docs.docker.com/compose/overview/). ## Deploy via docker/docker-compose
There is a rudimentary docker-compose configuration for production usage (`docker-compose.yml.production-example`). It brings [OSEM up](http://0.0.0.0:8080) on port 8080. It uses persistent storage volumes for all the data users might create. You can start it with
*This is just a short guide and does not explain how to use Docker and/or Docker-Compose. You need some experience with these tools to be able to deploy OSEM with Docker properly.*
First of all, copy `docker-compose.yml.example` to `docker-compose.yml` and `docker-compose.env.example` to `docker-compose.env`. You should immediately change
`docker-compose.env`'s permissions to `0600` to make sure all the passphrases in it are kept secret.
(Tip: the easiest and most secure way to do it is to do it with a single command, for example `install -m 0600 docker-compose.env.example docker-compose.env`).
There are two configurations to deploy OSEM with Docker: *evaluation mode* and *production mode*.
#### Evaluation mode
If you want to evaluate OSEM to see if it fits your needs, the default configuration in `docker-compose.env` will work perfectly fine for you.
For convenience reasons, `docker-compose.yml` already contains a [MailHog](https://github.com/mailhog/MailHog) service configuration. MailHog
is going to catch every email sent by OSEM and displays them on a special web service. Thus, it eliminates the need to set up an SMTP server just to try out OSEM.
Just point your browser to http://localhost:8025 to get access to registration confirmation links etc.
Run `docker-compose up --build` to start the services. On first run, it will take a few minutes to initialize the database. Thus, wait a few minutes before you open up
http://localhost:9292 in your browser.
#### Production mode
To deploy OSEM for production, you have to make a few changes to `docker-compose.yml`. First, remove (or comment) the `mailhog` service, as it is only useful for evaluation and
cannot be used for production.
You can change the forwarded port from port `9292` to any other value if this port is already in use or you just want to use another one.
Next, you have to modify `docker-compose.env`. This file works as a Docker-like replacement for the regular Rails `.env` files described below.
You can configure any of the configuration values shown in the **Configure** section below in it. The most essential variables are already configured to standard
values in `docker-compose.env` which you most likely want to change.
First, you need to modify the email related settings. You need a working SMTP server for OSEM to send out registration confirmation mails etc.
For security reasons, the following variables have to be changed, too:
- `MYSQL_PASSWORD`
- `MYSQL_ROOT_PASSWORD`
- `SECRET_KEY_BASE`
These variables need to be set to the correct values at first, as they are used to initialize everything. Modification of these variables after installation and initialization is more
complicated and out of this document's scope.
As with any other Docker-Compose configuration, run `docker-compose up --build` (or `docker-compose up --build -d` to run in background) to start the services. During the first
start, the database has to be initialized which can take several minutes. The web service is by default exposed on localhost only as it is intended to be served by a reverse proxy (for SSL
termination, caching etc.).
You should not directly expose the web server port unless you have a good reason to do so.
## Configure 1. Configure OSEM
There are a couple of environment variables you can set to configure OSEM. Check out the *dotenv.example* file. You have at least to set `SECRET_KEY_BASE`
```
cp dotenv.example .env.production
vim .env.production
```
1. Build the docker image (only once)
```
docker-compose -f docker-compose.yml.production-example build
```
1. Start the services
```
docker-compose -f docker-compose.yml.production-example up
```
### Online Ticket Payments ## Configuration
We use [Stripe](https://stripe.com) for accepting your ticket payments securely over the web. OSEM is configured through environment variables and falls back to sensible defaults. See the [dotenv.example](https://github.com/openSUSE/osem/blob/master/dotenv.example) for all possible configuration options. However here is a list of things you most likey want to configure because otherwise things will not work as expected.
Our application uses iFrame for accepting your user's payment details without storing them, making the application PCI SAQ-A Compliant.
Please refer to [PAYMENTS](PAYMENTS.md) documentation file for setting up your stripe account and start accepting payments from your users.
## Dependencies ### `SECRET_KEY_BASE`
A [random string](https://www.randomlists.com/string?base=16&length=64&qty=1) to encrypt sessions/cookies.
### ImageMagick ### `OSEM_NAME`
We use [ImageMagick](http://imagemagick.org/) for image manipulation so it needs to be available in your installation. The name of your OSEM installation
If you would like to resize exisiting logos in your OSEM installation you can do so by running the following rake task:
```shell ### How to send emails
$ bundle exec rake logo:reprocess By default OSEM tries to send emails over localhost.
```
### Ruby
OSEM is using Ruby version 2.5
## openID #### `OSEM_HOSTNAME`
In order to use [openID](http://openid.net/) logins for your OSEM installation you need to register your application with the providers ([Google](https://code.google.com/apis/console#:access), [GitHub](https://github.com/settings/applications/new) or [Facebook](https://developers.facebook.com/)) and enter their API keys in the environment variables found in your *.env* file(s). The host this OSEM instance runs on. This is used for generating urls in emails sent.
## Recurring Jobs #### `OSEM_EMAIL_ADDRESS`
Open a separate terminal and go into the directory where the rails app is present, and type the following to start the delayed_jobs worker for sending email notifications. The address OSEM uses to sending mails from.
```
bundle exec rake jobs:work
```
## Performance #### `OSEM_SMTP_ADDRESS`
If you are experiencing performance issues (or just curious), you may be able to [apply a free Skylight account](https://www.skylight.io/oss). The mail server we send mail over. (*default*: localhost)
Once you have your account setup, simply set `SKYLIGHT_AUTHENTICATION` and `SKYLIGHT_PUBLIC_DASHBOARD_URL` in your `.env` file.
If you are reporting a performance issue or submiting a performance patch, it would be helpful (but not required) to link to the relevant Skylight data. #### `OSEM_SMTP_AUTHENTICATION`
If your mail server requires authentication, you need to specify the authentication type here. This is a symbol and one of :plain (will send the password in the clear), :login (will send password Base64 encoded) or :cram_md5 (combines a Challenge/Response mechanism to exchange information and a cryptographic Message Digest 5 algorithm to hash important information)
#### `OSEM_SMTP_USERNAME`
If your mail server requires authentication, set the username in this setting.
#### `OSEM_SMTP_PASSWORD`
If your mail server requires authentication, set the password in this setting.

View file

@ -1,46 +0,0 @@
# Payments through Stripe
Here you will find all the information that you need to setup your Stripe account and integrate it into OSEM.
If you experience any problems, don't hesitate to [contact us](https://github.com/openSUSE/osem#contact)
**To enable payments, you need to add the API keys, provided by Stripe, in OSEM.**
## Add Stripe credentials
To integrate Stripe into OSEM, all you need to do is add the *publishable* and *secret* keys into the Rails environment.
1. Register with Stripe [here](https://dashboard.stripe.com/register) and get your API keys for free
2. Add your Stripe API keys in the following variables of your `.env` file:
* For **development**
* `STRIPE_PUBLISHABLE_KEY = 'pk_**test**_random123example456'`
* `STRIPE_SECRET_KEY = 'sk_**test**_random123example456'`
In development mode, the Stripe integration is useful for feature testing purposes. However, if you wish to enable payments for users, you need to use the live API keys.
* For **production**
* `STRIPE_PUBLISHABLE_KEY = 'pk_**live**_random123example456'`
* `STRIPE_SECRET_KEY = 'sk_**live**_random123example456'`
3. You are ready to start accepting payments from users
## Feature tests in development mode
You can test the payment feature in development mode using test credit cards; check out the list [here](https://stripe.com/docs/testing#cards).
### PCI Self Assessment Questionnaire(SAQ)
> As long as you serve your payment pages over TLS, and use either Checkout or Stripe.js
> as the only way of handling card information, Stripe automatically creates a prefilled SAQ A questionnaire for you,
> and you wont need to undergo a PCI audit. If card data is stored or transferred through your servers,
> you are responsible for following PCI DSS guidelines for handling card data, and periodic audits by a PCI-certified auditor.
As we are using Stripe Checkout for accepting payments, Stripe will help you for filling SAQ for your application.
You can read the full security documentation [here](https://stripe.com/docs/security).
## Configure Stripe to send emails for successful transactions
Stripe can send email reciepts for every successful payment done through its gateway.
Please refer [here](https://dashboard.stripe.com/account/emails) to enable invoice emails for your users.
## Customize Stripe invoice emails for your application
You can customise your payment reciepts by adding your personalisation like organisation name, logo etc.
Please see the options for invoice personalisation [here](https://dashboard.stripe.com/account/public).

View file

@ -1,2 +1,2 @@
web: bundle exec puma -C config/puma.rb web: bundle exec rails server -b 0.0.0.0
worker: bundle exec rails jobs:work worker: bundle exec rails jobs:work

View file

@ -6,21 +6,16 @@
<a href="https://heroku.com/deploy?template=https://github.com/openSUSE/osem/tree/v1.0"> <a href="https://heroku.com/deploy?template=https://github.com/openSUSE/osem/tree/v1.0">
<img src="https://www.herokucdn.com/deploy/button.svg" height="20px" alt="Deploy"> <img src="https://www.herokucdn.com/deploy/button.svg" height="20px" alt="Deploy">
</a> </a>
# Open Source Event Manager # Open Source Event Manager - [osem.io](https://osem.io)
![OSEM Logo](doc/osem-logo.png) ![OSEM Logo](doc/osem-logo.png)
An event management tool tailored to Free and Open Source Software conferences. An event management tool tailored to Free and Open Source Software conferences.
OSEM actively participates in [GSoC](https://summerofcode.withgoogle.com/) and [RGSoC](https://railsgirlssummerofcode.org/).
## Installation ## Installation
Please refer to [INSTALL](INSTALL.md) documentation file Please refer to our [installation guide](INSTALL.md).
## How to contribute to OSEM ## How to contribute to OSEM
Please refer to our [CONTRIBUTING guide](CONTRIBUTING.md) Please refer to our [contributing guide](CONTRIBUTING.md).
## How to translate OSEM into your language
Please refer to our [TRANSLATION guide](TRANSLATION.md)
## Contact ## Contact
GitHub issues are the primary way for communicating about specific proposed changes to this project. If you have other questions feel free to subscribe to the [opensuse-web@opensuse.org](http://lists.opensuse.org/opensuse-web/) mailinglist, all OSEM contributors are on that list! Additionally you can use #osem channel on freenode IRC. GitHub issues are the primary way for communicating about specific proposed changes to this project. If you have other questions feel free to subscribe to the [opensuse-web@opensuse.org](http://lists.opensuse.org/opensuse-web/) mailinglist, all OSEM contributors are on that list! Additionally you can use #osem channel on freenode IRC.

View file

@ -1,52 +0,0 @@
# Translation
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.
>Automated collection only works if you use the API key (See at the end of this file)
## 1. Translate
* Start translating:
1. Navigate to the [project's page](https://www.transifex.com/opensuse-community/osem)
2. Click **translation** button
3. Select **language**
4. Select **resource** (events.opensuse.org)
Eg. Assuming you have signed up yourself as a translator for OSEM, to translate in German, for example, you go to: https://www.transifex.com/projects/p/osem/translate/#de_DE/eventsopensuseorg/31056760
* Request a new language
If you want to translate OSEM into a language that does not already exist, you can request a new language from the Transifex interface. Your request will have to be approved by an admin of the OSEM project in Transifex.
## 2. Publish translations
* How to make translations visible (if you have the proper access):
1. Visit https://www.transifex.com/projects/p/osem/live/#en/events.opensuse.org
2. Click **Publish** (from right sidebar menu)
3. Select the language(s)
4. Click **Publish**
* 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:
Title: [Transifex] Publish translation for EN
Content: Publish new reviewed strings for language EN
(You substitute EN with the initials of the language you want to publish)
> Note: We only publish **reviewed** translated strings
## 3. Use translations
You can view OSEM in other languages by selecting the language you want from the language selector icon (bottom right corner).
## 4. API key
When you run your own instance of OSEM, if you want to have the translations available you need to add the api key in the `.env.development` file:
`OSEM_TRANSIFEX_APIKEY="cf866a61277842b39c897c5a0b5ec075"`
## 5. Strings with dynamic contents
Strings containing dynamic content should be tagged in the haml file with "notranslate" classes as described in:
http://docs.transifex.com/live/webmasters/#how-to-handle-inline-block-variables

85
Vagrantfile vendored
View file

@ -1,85 +0,0 @@
# frozen_string_literal: true
# -*- mode: ruby -*-
# vi: set ft=ruby :
# All Vagrant configuration is done below. The "2" in Vagrant.configure
# configures the configuration version (we support older styles for
# backwards compatibility). Please don't change it unless you know what
# you're doing.
Vagrant.configure(2) do |config|
# The most common configuration options are documented and commented below.
# For a complete reference, please see the online documentation at
# https://docs.vagrantup.com.
# Every Vagrant development environment requires a box. You can search for
# boxes at https://atlas.hashicorp.com/search.
config.vm.box = "opensuse/openSUSE-42.2-x86_64"
# Disable automatic box update checking. If you disable this, then
# boxes will only be checked for updates when the user runs
# `vagrant box outdated`. This is not recommended.
# config.vm.box_check_update = false
# Create a forwarded port mapping which allows access to a specific port
# within the machine from a port on the host machine. In the example below,
# accessing "localhost:8080" will access port 80 on the guest machine.
config.vm.network "forwarded_port", guest: 3000, host: 3000
# Create a private network, which allows host-only access to the machine
# using a specific IP.
# config.vm.network "private_network", ip: "192.168.33.10"
# Create a public network, which generally matched to bridged network.
# Bridged networks make the machine appear as another physical device on
# your network.
# config.vm.network "public_network"
# Share an additional folder to the guest VM. The first argument is
# the path on the host to the actual folder. The second argument is
# the path on the guest to mount the folder. And the optional third
# argument is a set of non-required options.
# config.vm.synced_folder "../data", "/vagrant_data"
# When using the default settings, we will attempt to mount this share
# as the vagrant user and the vagrant group. Alas, box opensuse/openSUSE-42.1-x86_64
# does not have the vagrant group created, so this share fails and
# requires manual mounting for the vagrant setup to continue. Setting
# to the hardcoded numbers will allow the mount to successfully
# mount without working about the group mismatch
VAGRANT_UID = 1000 # User vagrant
VAGRANT_GID = 100 # Group users
config.vm.synced_folder ".", "/vagrant",
owner: VAGRANT_UID, group: VAGRANT_GID
# Provider-specific configuration so you can fine-tune various
# backing providers for Vagrant. These expose provider-specific options.
# Example for VirtualBox:
#
# config.vm.provider "virtualbox" do |vb|
# # Display the VirtualBox GUI when booting the machine
# vb.gui = true
#
# # Customize the amount of memory on the VM:
# vb.memory = "1024"
# end
#
# View the documentation for the provider you are using for more
# information on available options.
# Define a Vagrant Push strategy for pushing to Atlas. Other push strategies
# such as FTP and Heroku are also available. See the documentation at
# https://docs.vagrantup.com/v2/push/atlas.html for more information.
# config.push.define "atlas" do |push|
# push.app = "YOUR_ATLAS_USERNAME/YOUR_APPLICATION_NAME"
# end
# Enable provisioning with a shell script. Additional provisioners such as
# Puppet, Chef, Ansible, Salt, and Docker are also available. Please see the
# documentation for more information about their specific syntax and use.
config.vm.provision :shell, path: "bootstrap.sh"
# config.vm.provision "shell", inline: <<-SHELL
# sudo apt-get update
# sudo apt-get install -y apache2
# SHELL
end

View file

@ -1,67 +1,21 @@
{ {
"name": "osem", "name": "osem",
"description": "Open Source Event Manager", "description": "Open Source Event Manager",
"repository": "https://github.com/openSUSE/osem",
"env": { "env": {
"CLOUDINARY_URL": { "CLOUDINARY_URL": {
"description": "Configure your cloudinary.com cloud name and api key/secret", "description": "Create a https://cloudinary.com account and set the cloud url here. It starts with cloudinary://"
"required": true
},
"DATABASE_URL": {
"description": "Configure your database connection",
"required": false
}, },
"SECRET_KEY_BASE": { "SECRET_KEY_BASE": {
"description": "a key which allows sessions to be verified against a known secure key to prevent tampering", "description": "A key to verify sessions. At least 40 characters. For instance: https://www.randomlists.com/string?base=16&length=64&qty=1",
"required": true "generator": "secret"
}, },
"LANG": { "NOKOGIRI_USE_SYSTEM_LIBRARIES": "1",
"required": false "RAILS_ENV": "production",
}, "RACK_ENV": "production"
"OSEM_EMAIL_ADDRESS": {
"description": "The address OSEM uses for sending mails",
"required": false
},
"OSEM_HOSTNAME": {
"description": "The host this OSEM instance runs on",
"required": false
},
"OSEM_NAME": {
"description": "The name of your page",
"required": false
},
"OSEM_SMTP_ADDRESS": {
"description": "The smtp server to use",
"required": false
},
"OSEM_SMTP_AUTHENTICATION": {
"description": "The auth method for the smtp server",
"required": false
},
"OSEM_SMTP_DOMAIN": {
"description": "The HELO domain for the smtp server",
"required": false
},
"OSEM_SMTP_PASSWORD": {
"description": "The password for the smtp server",
"required": false
},
"OSEM_SMTP_PORT": {
"description": "The port on the smtp server",
"required": false
},
"OSEM_SMTP_USERNAME": {
"description": "The user for the smtp server",
"required": false
},
"RACK_ENV": {
"required": false
},
"RAILS_ENV": {
"required": false
}
}, },
"scripts": { "scripts": {
"postdeploy": "bundle exec rake db:reset data:demo" "postdeploy": "bundle exec rake db:schema:load db:seed"
}, },
"formation": { "formation": {
"web": { "web": {
@ -72,12 +26,11 @@
} }
}, },
"addons": [ "addons": [
"heroku-postgresql",
"sendgrid"
],
"buildpacks": [
{ {
"url": "heroku/ruby" "plan": "heroku-postgresql"
},
{
"plan": "sendgrid"
} }
] ]
} }

View file

@ -20,8 +20,9 @@
//= require dataTables/bootstrap/3/jquery.dataTables.bootstrap //= require dataTables/bootstrap/3/jquery.dataTables.bootstrap
//= require cocoon //= require cocoon
//= require bootstrap //= require bootstrap
//= require Chart.bundle
//= require chartkick
//= require osem //= require osem
//= require osem-dashboard
//= require jquery-smooth-scroll //= require jquery-smooth-scroll
//= require trianglify //= require trianglify
//= require tinycolor //= require tinycolor

View file

@ -1,146 +0,0 @@
$(function() {
var t;
function size(animate){
if (animate == undefined){
animate = false;
}
clearTimeout(t);
t = setTimeout(function(){
$("canvas").each(function(i,el){
$(el).attr({
"width":$(el).parent().width()
});
});
$(".line_chart").each(function(){
draw_line_chart(animate, $(this));
});
$(".doughnut_chart").each(function(){
if($(this).is(":visible")){
draw_doughnut_chart(animate, $(this));
}
});
}, 30);
}
function draw_doughnut_chart(animation, $this){
var options = get_animation({}, animation);
var tmp = $this.data('chart');
if(jQuery.isEmptyObject(tmp)){
// Append error message if there is no data
$this.parent().append("<h4 class=\"text-warning\">No data!</h4>");
// Remove canvas
$this.remove();
}else{
var data = [];
for (var key in tmp) {
data.push(tmp[key]);
}
var ctx = $this.get(0).getContext("2d");
new Chart(ctx).Doughnut(data, options);
}
}
function get_animation(options, animation){
if (!animation){
options.animation = false;
} else {
options.animation = true;
}
return options;
}
function draw_line_chart(animation, $canvas){
var chart_data = create_dataset($canvas);
var weeks = $canvas.parent().data('weeks');
var data = {
labels : weeks,
datasets : chart_data
}
var options = get_animation(wholeNumberAxisFix(data), animation);
var ctx = $canvas.get(0).getContext("2d");
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){
var selected = getSelectedConferences($canvas);
var chart_data = $canvas.parent().data('chart');
var conferences = $canvas.parent().data('conferences');
var result = [];
for(var i in conferences){
if(selected.indexOf(conferences[i].short_title) >= 0){
var options = {};
options.fillColor = "rgba(255,255,255,0.0)";
options.strokeColor = conferences[i].color;
options.data = chart_data[conferences[i].short_title];
if(options.data == null || options.data.length == 0){
options.data = [0];
}
result.push(options)
}
}
return result
}
function getSelectedConferences($canvas){
var name = $canvas.data('name');
var id = '#' + name + 'Checkboxes'
var selected = [];
var $checkboxes = $(id + ' input');
// If there are checkboxes -> get selected
// Else -> use the active conference
if($checkboxes.length){
$(id + ' input').each(function(){
if($(this).is(":checked")) {
selected.push($(this).attr('name'));
}
});
}else{
var active = $canvas.parent().data('active');
for(i in active){
selected.push(active[i].short_title)
}
}
return selected;
}
$('.conferenceCheckboxes input').change(function(){
var chart_name = $(this).parent().data('chart');
var $canvas = $('#line_chart_' + chart_name);
draw_line_chart(false, $canvas);
});
$(window).on('resize', function(){
size(false);
});
$('#doughnut_tabs a').click(function (e) {
e.preventDefault();
$(this).tab('show');
size(false);
});
size(true);
});

View file

@ -2,114 +2,104 @@
var today = new Date().toISOString().slice(0, 10); var today = new Date().toISOString().slice(0, 10);
$(function () { $(function () {
$("input[id^='datetimepicker']").datetimepicker({ $("input[id^='datetimepicker']").datetimepicker({
pickTime: true,
useCurrent: false, useCurrent: false,
sideBySide: true, sideBySide: true,
autoclose: true,
format: 'YYYY-MM-DD HH:mm' format: 'YYYY-MM-DD HH:mm'
}); });
$('.datetimepicker').datetimepicker({ $('.datetimepicker').datetimepicker({
pickTime: true,
useCurrent: false, useCurrent: false,
sideBySide: true, sideBySide: true,
format: 'YYYY-MM-DD HH:mm' format: 'YYYY-MM-DD HH:mm'
}); });
$("#registration-arrival-datepicker").datetimepicker({ $("#registration-arrival-datepicker").datetimepicker({
pickTime: true,
useCurrent: false, useCurrent: false,
minuteStepping: 15, stepping: 15,
sideBySide: true, sideBySide: true,
format: "YYYY-MM-DD HH:mm", format: "YYYY-MM-DD HH:mm",
// current_date <= arrival_date <= end_date // current_date <= arrival_date <= end_date
maxDate : $("#registration-arrival-datepicker").attr('end_date'), maxDate : $("#registration-arrival-datepicker").attr('end_date'),
minDate : today, minDate : today
}); });
$("#registration-departure-datepicker").datetimepicker({ $("#registration-departure-datepicker").datetimepicker({
pickTime: true,
useCurrent: false, useCurrent: false,
minuteStepping: 15, stepping: 15,
sideBySide: true, sideBySide: true,
format: "YYYY-MM-DD HH:mm", format: "YYYY-MM-DD HH:mm",
// departure_date > start_date // departure_date > start_date
minDate : $("#registration-arrival-datepicker").attr('start_date'), minDate : $("#registration-arrival-datepicker").attr('start_date')
}); });
$("#registration-arrival-datepicker").on("dp.change",function (e) { $("#registration-arrival-datepicker").on("dp.change",function (e) {
// departure_date > start_date,arrival_date // departure_date > start_date,arrival_date
if ((new Date(e.date).getTime()) > (new Date($("#registration-arrival-datepicker").attr('start_date')).getTime())){ if ((new Date(e.date).getTime()) > (new Date($("#registration-arrival-datepicker").attr('start_date')).getTime())){
$('#registration-departure-datepicker').data("DateTimePicker").setMinDate(e.date); $('#registration-departure-datepicker').data("DateTimePicker").minDate(e.date);
} }
else{ else{
$('#registration-departure-datepicker').data("DateTimePicker").setMinDate($("#registration-arrival-datepicker").attr('start_date')); $('#registration-departure-datepicker').data("DateTimePicker").minDate($("#registration-arrival-datepicker").attr('start_date'));
} }
}); });
// departure_date >= arrival_date // departure_date >= arrival_date
$("#registration-departure-datepicker").on("dp.change",function (e) { $("#registration-departure-datepicker").on("dp.change",function (e) {
$('#registration-arrival-datepicker').data("DateTimePicker").setMaxDate(e.date); $('#registration-arrival-datepicker').data("DateTimePicker").maxDate(e.date);
}); });
$("#conference-start-datepicker").datetimepicker({ $("#conference-start-datepicker").datetimepicker({
pickTime: false,
useCurrent: false, useCurrent: false,
format: "YYYY-MM-DD", format: "YYYY-MM-DD",
// conference-start-day >= Current_date // conference-start-day >= Current_date
minDate : today , minDate : today
}); });
$("#conference-end-datepicker").datetimepicker({ $("#conference-end-datepicker").datetimepicker({
pickTime: false,
useCurrent: false, useCurrent: false,
format: "YYYY-MM-DD", format: "YYYY-MM-DD"
}); });
// end_date_conference >= registration-period-Start_date >= Current_date // today <= start_registration <= end_registration <= end_conference
// registration-period-Start_date <= registration-period-End_date <= End_date (of conference) var end_conference = $('form').data('end-conference');
$("#registration-period-start-datepicker").datetimepicker({
pickTime: false, $('#registration-period-start-datepicker').datetimepicker({
useCurrent: false, format: 'YYYY-MM-DD',
format: "YYYY-MM-DD",
minDate : today, minDate : today,
maxDate : $("#registration-period-start-datepicker").attr('end_date'), maxDate : end_conference
}); });
$("#registration-period-end-datepicker").datetimepicker({ $('#registration-period-end-datepicker').datetimepicker({
pickTime: false, format: 'YYYY-MM-DD',
useCurrent: false, minDate : today,
format: "YYYY-MM-DD", maxDate : end_conference
minDate: today,
maxDate : $("#registration-period-start-datepicker").attr('end_date'),
}); });
$("#conference-start-datepicker").on("dp.change",function (e) { $("#conference-start-datepicker").on("dp.change",function (e) {
$('#conference-end-datepicker').data("DateTimePicker").setMinDate(e.date); $('#conference-end-datepicker').data("DateTimePicker").minDate(e.date);
if (!$('#conference-end-datepicker').val()) { if (!$('#conference-end-datepicker').val()) {
$('#conference-end-datepicker').data("DateTimePicker").setDate(e.date); $('#conference-end-datepicker').data("DateTimePicker").date(e.date);
} }
}); });
$("#conference-start-datepicker").change(function (e) { $("#conference-start-datepicker").change(function (e) {
$('#conference-start-datepicker').val()?$('#conference-end-datepicker').data("DateTimePicker").setMinDate(e.date):$('#conference-end-datepicker').data("DateTimePicker").setMinDate(null); $('#conference-start-datepicker').val()?$('#conference-end-datepicker').data("DateTimePicker").minDate(e.date):$('#conference-end-datepicker').data("DateTimePicker").minDate(null);
}); });
$("#conference-end-datepicker").on("dp.change",function (e) { $("#conference-end-datepicker").on("dp.change",function (e) {
$('#conference-start-datepicker').data("DateTimePicker").setMaxDate(e.date); $('#conference-start-datepicker').data("DateTimePicker").maxDate(e.date);
}); });
$("#conference-end-datepicker").change(function (e) { $("#conference-end-datepicker").change(function (e) {
$('#conference-end-datepicker').val()?$('#conference-start-datepicker').data("DateTimePicker").setMaxDate(e.date):$('#conference-start-datepicker').data("DateTimePicker").setMaxDate(null); $('#conference-end-datepicker').val()?$('#conference-start-datepicker').data("DateTimePicker").maxDate(e.date):$('#conference-start-datepicker').data("DateTimePicker").maxDate(null);
}); });
$("#registration-period-start-datepicker").on("dp.change",function (e) { $("#registration-period-start-datepicker").on("dp.change",function (e) {
$('#registration-period-end-datepicker').data("DateTimePicker").setMinDate(e.date); $('#registration-period-end-datepicker').data("DateTimePicker").minDate(e.date);
if (!$('#registration-period-end-datepicker').val()) { if (!$('#registration-period-end-datepicker').val()) {
$('#registration-period-end-datepicker').data("DateTimePicker").setDate(e.date); $('#registration-period-end-datepicker').data("DateTimePicker").date(e.date);
} }
}); });
$("#registration-period-end-datepicker").on("dp.change",function (e) { $("#registration-period-end-datepicker").on("dp.change",function (e) {
$('#registration-period-start-datepicker').data("DateTimePicker").setMaxDate(e.date); $('#registration-period-start-datepicker').data("DateTimePicker").maxDate(e.date);
}); });
} ); } );

View file

@ -18,13 +18,11 @@ var Schedule = {
if(event_schedule_id != null){ if(event_schedule_id != null){
var my_url = url + '/' + event_schedule_id; var my_url = url + '/' + event_schedule_id;
var success_callback = function(data) { var success_callback = function(data) {
console.log(data);
e.attr("event_schedule_id", null); e.attr("event_schedule_id", null);
e.appendTo($(".unscheduled-events")); e.appendTo($(".unscheduled-events"));
e.find(".schedule-event-delete-button").hide(); e.find(".schedule-event-delete-button").hide();
} }
var error_callback = function(data) { var error_callback = function(data) {
console.log(data);
showError($.parseJSON(data.responseText).errors); showError($.parseJSON(data.responseText).errors);
} }
$.ajax({ $.ajax({
@ -57,12 +55,10 @@ var Schedule = {
params['event_schedule']['schedule_id'] = schedule_id; params['event_schedule']['schedule_id'] = schedule_id;
} }
var success_callback = function(data) { var success_callback = function(data) {
console.log(data);
event.attr("event_schedule_id", data.event_schedule_id); event.attr("event_schedule_id", data.event_schedule_id);
event.find(".schedule-event-delete-button").show(); event.find(".schedule-event-delete-button").show();
} }
var error_callback = function(data) { var error_callback = function(data) {
console.log(data);
showError($.parseJSON(data.responseText).errors); showError($.parseJSON(data.responseText).errors);
event.appendTo(previous_parent); event.appendTo(previous_parent);
} }
@ -87,7 +83,6 @@ $(document).ready( function() {
snap: '.schedule-room-slot', snap: '.schedule-room-slot',
revertDuration: 200, revertDuration: 200,
revert: function (event, ui) { revert: function (event, ui) {
console.log(event.attr);
return !event; return !event;
}, },
stop: function(event, ui) { stop: function(event, ui) {
@ -96,7 +91,8 @@ $(document).ready( function() {
}, },
opacity: 0.7, opacity: 0.7,
snapMode: "inner", snapMode: "inner",
zIndex: 2 zIndex: 2,
scroll: true
}); });
// set room cells as droppable // set room cells as droppable

View file

@ -1,3 +1,12 @@
#schedule-content .carousel-control{
width: 12%;
}
@media (min-width: 768px){
#schedule-content .carousel-control{
width: 5%;
}
}
.room-name{ .room-name{
font-weight: bold; font-weight: bold;

View file

@ -6,7 +6,7 @@ module Admin
load_and_authorize_resource through: :conference load_and_authorize_resource through: :conference
def index def index
@file_name = "booths_for_#{@conference.short_title}" @file_name = "#{(t 'booth').pluralize}_for_#{@conference.short_title}"
@booth_export_option = params[:booth_export_option] @booth_export_option = params[:booth_export_option]
respond_to do |format| respond_to do |format|
format.html format.html
@ -14,12 +14,12 @@ module Admin
format.json { render json: Booth.where(state: :confirmed, program: @program).to_json } format.json { render json: Booth.where(state: :confirmed, program: @program).to_json }
format.xlsx do format.xlsx do
response.headers['Content-Disposition'] = "attachment; filename=\"#{@file_name}.xlsx\"" response.headers['Content-Disposition'] = "attachment; filename=\"#{@file_name}.xlsx\""
render 'booths' render 'booths', layout: false
end end
format.pdf { render 'booths' } format.pdf { render 'booths', layout: false }
format.csv do format.csv do
response.headers['Content-Disposition'] = "attachment; filename=\"#{@file_name}.csv\"" response.headers['Content-Disposition'] = "attachment; filename=\"#{@file_name}.csv\""
render 'booths' render 'booths', layout: false
end end
end end
end end
@ -39,9 +39,9 @@ module Admin
if @booth.save if @booth.save
redirect_to admin_conference_booths_path, redirect_to admin_conference_booths_path,
notice: 'Booth successfully created.' notice: "#{(t 'booth').capitalize} successfully created."
else else
flash.now[:error] = "Creating booth failed. #{@booth.errors.full_messages.to_sentence}." flash.now[:error] = "Creating #{t 'booth'} failed. #{@booth.errors.full_messages.to_sentence}."
render :new render :new
end end
end end
@ -57,9 +57,9 @@ module Admin
if @booth.save if @booth.save
redirect_to admin_conference_booths_path, redirect_to admin_conference_booths_path,
notice: "Successfully updated booth for #{@booth.title}." notice: "Successfully updated #{t 'booth'} for #{@booth.title}."
else else
flash.now[:error] = "An error prohibited the Booth for #{@booth.title} "\ flash.now[:error] = "An error prohibited the #{t'booth'} for #{@booth.title} "\
"#{@booth.errors.full_messages.join('. ')}." "#{@booth.errors.full_messages.join('. ')}."
render :edit render :edit
end end
@ -70,47 +70,49 @@ module Admin
if @booth.save if @booth.save
if @conference.email_settings.send_on_booths_acceptance if @conference.email_settings.send_on_booths_acceptance
Mailbot.conference_booths_acceptance_mail(@booth).deliver Mailbot.conference_booths_acceptance_mail(@booth).deliver_later
end end
redirect_to admin_conference_booths_path(conference_id: @conference.short_title), redirect_to admin_conference_booths_path(conference_id: @conference.short_title),
notice: 'Booth successfully accepted!' notice: "#{(t'booth').capitalize} successfully accepted!"
else else
redirect_to admin_conference_booths_path(conference_id: @conference.short_title) redirect_to admin_conference_booths_path(conference_id: @conference.short_title)
flash[:error] = "Booth could not be accepted. #{@booth.errors.full_messages.to_sentence}." flash[:error] = "#{(t 'booth').capitalize} could not be accepted. #{@booth.errors.full_messages.to_sentence}."
end end
end end
def to_accept def to_accept
update_state(:to_accept, 'Booth to accept') update_state(:to_accept, "#{(t'booth').capitalize} to accept")
end end
def to_reject def to_reject
update_state(:to_reject, 'Booth to reject') update_state(:to_reject, "#{(t'booth').capitalize} to reject")
end end
def reject def reject
@booth.reject! @booth.reject!
if @booth.save if @booth.save
Mailbot.conference_booths_rejection_mail(@booth).deliver if @conference.email_settings.send_on_booths_rejection
Mailbot.conference_booths_rejection_mail(@booth).deliver_later
end
redirect_to admin_conference_booths_path(conference_id: @conference.short_title), redirect_to admin_conference_booths_path(conference_id: @conference.short_title),
notice: 'Booth successfully rejected.' notice: "#{(t'booth').capitalize} successfully rejected."
else else
redirect_to admin_conference_booths_path(conference_id: @conference.short_title) redirect_to admin_conference_booths_path(conference_id: @conference.short_title)
flash[:error] = "Booth could not be rejected. #{@booth.errors.full_messages.to_sentence}." flash[:error] = "#{(t 'booth').capitalize} could not be rejected. #{@booth.errors.full_messages.to_sentence}."
end end
end end
def restart def restart
update_state(:restart, 'Booth is submitted') update_state(:restart, "#{(t 'booth').capitalize} is submitted")
end end
def cancel def cancel
update_state(:cancel, 'Booth is canceled') update_state(:cancel, "#{(t 'booth').capitalize} is canceled")
end end
def confirm def confirm
update_state(:confirm, 'Booth successfully confirmed') update_state(:confirm, "#{(t 'booth').capitalize} successfully confirmed")
end end
private private

View file

@ -45,9 +45,9 @@ module Admin
def render_commercial def render_commercial
result = Commercial.render_from_url(params[:url]) result = Commercial.render_from_url(params[:url])
if result[:error] if result[:error]
render text: result[:error], status: 400 render plain: result[:error], status: 400
else else
render text: result[:html] render plain: result[:html]
end end
end end
@ -70,7 +70,7 @@ module Admin
flash[:error] = errors_text flash[:error] = errors_text
end end
redirect_to :back redirect_back(fallback_location: root_path)
end end
private private

View file

@ -37,43 +37,33 @@ module Admin
@top_submitter = Conference.get_top_submitter @top_submitter = Conference.get_top_submitter
@submissions = {} @registrations = []
@cfp_weeks = [0] @submissions = []
@tickets = []
@registrations = {}
@registration_weeks = [0]
@tickets = {}
@ticket_weeks = [0]
@conferences.each do |c| @conferences.each do |c|
# Event submissions over time chart
@submissions[c.short_title] = c.get_submissions_per_week
@cfp_weeks.push(@submissions[c.short_title].length)
# Conference registrations over time chart # Conference registrations over time chart
@registrations[c.short_title] = c.get_registrations_per_week @registrations << {
@registration_weeks.push(@registrations[c.short_title].length) name: c.short_title,
data: c.get_registrations_per_week
}
# Event submissions over time chart
@submissions << {
name: c.short_title,
data: c.get_submissions_per_week
}
# Tickets sold over time chart # Tickets sold over time chart
@tickets[c.short_title] = c.get_tickets_sold_per_week @tickets << {
@ticket_weeks.push(@tickets[c.short_title].length) name: c.short_title,
data: c.get_tickets_sold_per_week
}
end end
@cfp_weeks = @cfp_weeks.max
@submissions = normalize_array_length(@submissions, @cfp_weeks)
@cfp_weeks = @cfp_weeks > 0 ? (1..@cfp_weeks).to_a : 1
@registration_weeks = @registration_weeks.max
@registrations = normalize_array_length(@registrations, @registration_weeks)
@registration_weeks = @registration_weeks > 0 ? (1..@registration_weeks).to_a : 1
@ticket_weeks = @ticket_weeks.max
@tickets = normalize_array_length(@tickets, @ticket_weeks)
@ticket_weeks = @ticket_weeks > 0 ? (1..@ticket_weeks).to_a : 1
@event_distribution = Conference.event_distribution @event_distribution = Conference.event_distribution
@user_distribution = Conference.user_distribution @event_distribution_colors = Event::COLORS.values
@user_distribution = User.distribution
@user_distribution_colors = User::DISTRIBUTION_COLORS.values
end end
def new def new
@ -138,35 +128,9 @@ module Admin
@conference_progress = @conference.get_status @conference_progress = @conference.get_status
# Line charts # Line charts
@registrations = {@conference.short_title => @conference.get_registrations_per_week} @registrations = @conference.get_registrations_per_week
@registration_weeks = [0] @submissions = @conference.get_submissions_data
@registration_weeks.push(@registrations[@conference.short_title].length) @tickets = @conference.get_tickets_data
@registration_weeks = @registration_weeks.max
@registrations = normalize_array_length(@registrations, @registration_weeks)
@registration_weeks = @registration_weeks > 0 ? (1..@registration_weeks).to_a : 1
@submissions = Conference.get_event_state_line_colors
@submissions_data = @conference.get_submissions_data
@cfp_weeks = 0
if @submissions_data['Weeks']
@cfp_weeks = @submissions_data['Weeks']
@submissions_data = @submissions_data.except('Weeks')
end
@tickets_data = @conference.get_tickets_data
@ticket_weeks = 0
if @tickets_data['Weeks']
@ticket_weeks = @tickets_data['Weeks']
@tickets_data = @tickets_data.except('Weeks')
end
# Set line color using a hash function
@tickets = []
@tickets_data.each_key do |title|
@tickets.append(short_title: title, color: "\##{Digest::MD5.hexdigest(title)[0..5]}")
end
# Doughnut charts # Doughnut charts
@event_type_distribution = @conference.event_type_distribution @event_type_distribution = @conference.event_type_distribution

View file

@ -3,6 +3,7 @@
module Admin module Admin
class EventSchedulesController < Admin::BaseController class EventSchedulesController < Admin::BaseController
load_and_authorize_resource :event_schedule load_and_authorize_resource :event_schedule
skip_before_action :verify_authenticity_token
def create def create
if @event_schedule.save if @event_schedule.save

View file

@ -16,6 +16,7 @@ module Admin
@event_types = @program.event_types @event_types = @program.event_types
@tracks_distribution_confirmed = @conference.tracks_distribution(:confirmed) @tracks_distribution_confirmed = @conference.tracks_distribution(:confirmed)
@event_distribution = @conference.event_distribution @event_distribution = @conference.event_distribution
@event_distribution_colors = Event::COLORS.values
@scheduled_event_distribution = @conference.scheduled_event_distribution @scheduled_event_distribution = @conference.scheduled_event_distribution
@file_name = "events_for_#{@conference.short_title}" @file_name = "events_for_#{@conference.short_title}"
@event_export_option = params[:event_export_option] @event_export_option = params[:event_export_option]
@ -27,12 +28,12 @@ module Admin
format.json { render json: Event.where(state: :confirmed, program: @program).to_json } format.json { render json: Event.where(state: :confirmed, program: @program).to_json }
format.xlsx do format.xlsx do
response.headers['Content-Disposition'] = "attachment; filename=\"#{@file_name}.xlsx\"" response.headers['Content-Disposition'] = "attachment; filename=\"#{@file_name}.xlsx\""
render 'events' render 'events', layout: false
end end
format.pdf { render 'events' } format.pdf { render 'events', layout: false }
format.csv do format.csv do
response.headers['Content-Disposition'] = "attachment; filename=\"#{@file_name}.csv\"" response.headers['Content-Disposition'] = "attachment; filename=\"#{@file_name}.csv\""
render 'events' render 'events', layout: false
end end
end end
end end

View file

@ -23,12 +23,6 @@ module Admin
end end
end end
def edit
end
def show
end
def update def update
@registration_period.assign_attributes(registration_period_params) @registration_period.assign_attributes(registration_period_params)
send_mail_on_reg_update = @conference.notify_on_registration_dates_changed? send_mail_on_reg_update = @conference.notify_on_registration_dates_changed?

View file

@ -15,12 +15,22 @@ module Admin
@registration_distribution = @conference.registration_distribution @registration_distribution = @conference.registration_distribution
@affiliation_distribution = @conference.affiliation_distribution @affiliation_distribution = @conference.affiliation_distribution
@code_of_conduct = @conference.code_of_conduct.present? @code_of_conduct = @conference.code_of_conduct.present?
@file_name = "registrations_for_#{@conference.short_title}"
respond_to do |format| respond_to do |format|
format.html format.html
format.json do format.json do
render json: RegistrationDatatable.new(view_context, conference: @conference) render json: RegistrationDatatable.new(view_context, conference: @conference)
end end
format.pdf { render 'index', layout: false }
format.xlsx do
response.headers['Content-Disposition'] = "attachment; filename=\"#{@file_name}.xlsx\""
render 'index', layout: false
end
format.csv do
response.headers['Content-Disposition'] = "attachment; filename=\"#{@file_name}.csv\""
render 'index', layout: false
end
end end
end end

View file

@ -15,8 +15,9 @@ module Admin
attended_registrants_ids = @conference.registrations.where(attended: true).pluck(:user_id) attended_registrants_ids = @conference.registrations.where(attended: true).pluck(:user_id)
@missing_event_speakers = EventUser.joins(:event) @missing_event_speakers = EventUser.joins(:event)
.where('event_role = ? and program_id = ?', 'submitter', @program.id) .where('event_role = ? and program_id = ?', 'speaker', @program.id)
.where.not(user_id: attended_registrants_ids) .where.not(user_id: attended_registrants_ids)
.where(event_id: @events.pluck(:id))
.includes(:user, :event) .includes(:user, :event)
end end
end end

View file

@ -19,7 +19,7 @@ module Admin
if @survey.save if @survey.save
redirect_to new_admin_conference_survey_survey_question_path(@conference.short_title, @survey), notice: 'Successfully created survey' redirect_to new_admin_conference_survey_survey_question_path(@conference.short_title, @survey), notice: 'Successfully created survey'
else else
redirect_to new_admin_conference_survey_survey_question_path(@conference.short_title, @survey), error: 'Could not create survey.' + @survey.errors.full_messages.to_sentence redirect_to new_admin_conference_survey_path(@conference.short_title, survey: { surveyable_type: survey_params['surveyable_type'], surveyable_id: survey_params['surveyable_id'] }), error: 'Could not create survey.' + @survey.errors.full_messages.to_sentence
end end
end end

View file

@ -19,12 +19,12 @@ module Admin
format.json { render json: Track.where(state: :confirmed, program: @program).to_json } format.json { render json: Track.where(state: :confirmed, program: @program).to_json }
format.xlsx do format.xlsx do
response.headers['Content-Disposition'] = "attachment; filename=\"#{@file_name}.xlsx\"" response.headers['Content-Disposition'] = "attachment; filename=\"#{@file_name}.xlsx\""
render 'tracks' render 'tracks', layout: false
end end
format.pdf { render 'tracks' } format.pdf { render 'tracks', layout: false }
format.csv do format.csv do
response.headers['Content-Disposition'] = "attachment; filename=\"#{@file_name}.csv\"" response.headers['Content-Disposition'] = "attachment; filename=\"#{@file_name}.csv\""
render 'tracks' render 'tracks', layout: false
end end
end end
end end

View file

@ -40,9 +40,9 @@ module Admin
def render_commercial def render_commercial
result = Commercial.render_from_url(params[:url]) result = Commercial.render_from_url(params[:url])
if result[:error] if result[:error]
render text: result[:error], status: 400 render plain: result[:error], status: 400
else else
render text: result[:html] render plain: result[:html]
end end
end end

View file

@ -23,9 +23,9 @@ class BoothsController < ApplicationController
if @booth.save if @booth.save
redirect_to conference_booths_path, redirect_to conference_booths_path,
notice: 'Booth successfully created.' notice: "#{(t 'booth').capitalize} successfully created."
else else
flash.now[:error] = "Creating booth failed. #{@booth.errors.full_messages.to_sentence}." flash.now[:error] = "Creating #{t 'booth'} failed. #{@booth.errors.full_messages.to_sentence}."
render :new render :new
end end
end end
@ -43,6 +43,7 @@ class BoothsController < ApplicationController
notice: 'Booth successfully updated!' notice: 'Booth successfully updated!'
else else
flash.now[:error] = "Booth could not be updated. #{@booth.errors.full_messages.to_sentence}." flash.now[:error] = "Booth could not be updated. #{@booth.errors.full_messages.to_sentence}."
render :edit
end end
end end

View file

@ -4,6 +4,7 @@ class CommercialsController < ApplicationController
load_resource :conference, find_by: :short_title load_resource :conference, find_by: :short_title
before_action :set_event before_action :set_event
load_and_authorize_resource through: :event load_and_authorize_resource through: :event
skip_before_action :verify_authenticity_token
def create def create
@commercial = @event.commercials.build(commercial_params) @commercial = @event.commercials.build(commercial_params)
@ -37,9 +38,9 @@ class CommercialsController < ApplicationController
def render_commercial def render_commercial
result = Commercial.render_from_url(params[:url]) result = Commercial.render_from_url(params[:url])
if result[:error] if result[:error]
render text: result[:error], status: 400 render plain: result[:error], status: 400
else else
render text: result[:html] render plain: result[:html]
end end
end end

View file

@ -6,9 +6,8 @@ class ConferencesController < ApplicationController
load_and_authorize_resource find_by: :short_title, except: :show load_and_authorize_resource find_by: :short_title, except: :show
def index def index
@current, @antiquated = Conference.reorder(start_date: :asc).all.partition do |conference| @current = Conference.where('end_date >= ?', Date.current).reorder(start_date: :asc)
conference.end_date >= Date.current @antiquated = Conference.where('end_date < ?', Date.current)
end
end end
def show def show

View file

@ -6,6 +6,6 @@ class OpenidsController < ApplicationController
def destroy def destroy
@openid.destroy @openid.destroy
redirect_to :back redirect_back(fallback_location: root_path)
end end
end end

View file

@ -104,7 +104,7 @@ class ProposalsController < ApplicationController
@event.event_schedules.destroy_all @event.event_schedules.destroy_all
end end
rescue Transitions::InvalidTransition rescue Transitions::InvalidTransition
redirect_to :back, error: "Event can't be withdrawn" redirect_back(fallback_location: root_path, error: "Event can't be withdrawn")
return return
end end
@ -124,7 +124,7 @@ class ProposalsController < ApplicationController
begin begin
@event.confirm @event.confirm
rescue Transitions::InvalidTransition rescue Transitions::InvalidTransition
redirect_to :back, error: "Event can't be confirmed" redirect_back(fallback_location: root_path, error: "Event can't be confirmed")
return return
end end

View file

@ -2,7 +2,6 @@
class SchedulesController < ApplicationController class SchedulesController < ApplicationController
load_and_authorize_resource load_and_authorize_resource
protect_from_forgery with: :null_session
before_action :respond_to_options before_action :respond_to_options
load_resource :conference, find_by: :short_title load_resource :conference, find_by: :short_title
load_resource :program, through: :conference, singleton: true, except: :index load_resource :program, through: :conference, singleton: true, except: :index
@ -61,6 +60,10 @@ class SchedulesController < ApplicationController
@tag = day.strftime('%Y-%m-%d') if day @tag = day.strftime('%Y-%m-%d') if day
end end
def app
@qr_code = RQRCode::QRCode.new(conference_schedule_url).as_svg(offset: 20, color: '000', shape_rendering: 'crispEdges', module_size: 11)
end
private private
def respond_to_options def respond_to_options

View file

@ -40,6 +40,6 @@ class SurveysController < ApplicationController
end end
end end
redirect_to :back redirect_back(fallback_location: root_path)
end end
end end

View file

@ -16,9 +16,11 @@ class TicketPurchasesController < ApplicationController
elsif current_user.ticket_purchases.by_conference(@conference).paid.any? elsif current_user.ticket_purchases.by_conference(@conference).paid.any?
redirect_to conference_physical_tickets_path, redirect_to conference_physical_tickets_path,
notice: 'You have free tickets for the conference.' notice: 'You have free tickets for the conference.'
else elsif @conference.tickets.for_registration.any?
redirect_to conference_tickets_path(@conference.short_title), redirect_to conference_tickets_path(@conference.short_title),
error: 'Please get at least one ticket to continue.' error: 'Please get at least one ticket to continue.'
else
redirect_to conference_conference_registration_path(@conference.short_title)
end end
else else
redirect_to conference_tickets_path(@conference.short_title), redirect_to conference_tickets_path(@conference.short_title),

View file

@ -2,7 +2,7 @@
module Users module Users
class OmniauthCallbacksController < Devise::OmniauthCallbacksController class OmniauthCallbacksController < Devise::OmniauthCallbacksController
skip_before_filter :verify_authenticity_token skip_before_action :verify_authenticity_token
skip_authorization_check skip_authorization_check
User.omniauth_providers.each do |provider| User.omniauth_providers.each do |provider|
@ -35,8 +35,7 @@ module Users
openid.save! openid.save!
sign_in user sign_in user
redirect_to request.env['omniauth.origin'] || root_path, redirect_to root_path, notice: "#{user.email} signed in successfully with #{provider}"
notice: "#{user.email} signed in successfully with #{provider}"
rescue => e rescue => e
flash[:error] = e.message flash[:error] = e.message
redirect_back_or_to new_user_registration_path redirect_back_or_to new_user_registration_path

View file

@ -88,10 +88,9 @@ module ApplicationHelper
end end
end end
# Same as redirect_to(:back) if there is a valid HTTP referer, otherwise redirect_to()
def redirect_back_or_to(options = {}, response_status = {}) def redirect_back_or_to(options = {}, response_status = {})
if request.env['HTTP_REFERER'] if request.env['HTTP_REFERER']
redirect_to :back redirect_back(fallback_location: root_path)
else else
redirect_to options, response_status redirect_to options, response_status
end end
@ -121,19 +120,19 @@ module ApplicationHelper
end end
def speaker_selector_input(form) def speaker_selector_input(form)
user_selector_input(:speakers, form, '', false) user_selector_input(:speakers, form, '', true)
end end
def responsibles_selector_input(form) def responsibles_selector_input(form)
user_selector_input( user_selector_input(
:responsibles, :responsibles,
form, form,
'The people responsible for the booth. You can only select existing users.' "The people responsible for the #{t 'booth'}. You can only select existing users."
) )
end end
def user_selector_input(field, form, hint = '', multiple = true) def user_selector_input(field, form, hint = '', multiple = true)
users = User.active.pluck(:id, :name, :username, :email).map { |user| [user[0], user[1].blank? ? user[2] : user[1], user[2], user[3]] }.sort_by { |user| user[1].downcase } users = User.where(is_disabled: false).pluck(:id, :name, :username, :email).map { |user| [user[0], user[1].blank? ? user[2] : user[1], user[2], user[3]] }.sort_by { |user| user[1].downcase }
form.input( form.input(
field, field,
as: :select, as: :select,

View file

@ -0,0 +1,17 @@
# frozen_string_literal: true
module ChartHelper
def chart_values(distribution_hash)
Hash[
distribution_hash.collect do |key, data|
[key, data['value']]
end
]
end
def chart_colors(distribution_hash)
distribution_hash.collect do |_key, data|
data['color']
end
end
end

BIN
app/models/.lodging.rb.swp Normal file

Binary file not shown.

View file

@ -31,10 +31,23 @@ class Ability
event.state == 'confirmed' event.state == 'confirmed'
end end
can [:show, :events, :app], Schedule do |schedule|
schedule.program.schedule_public
end
# can view Commercials of confirmed Events # can view Commercials of confirmed Events
can :show, Commercial, commercialable_type: 'Event', commercialable_id: Event.where(state: 'confirmed').pluck(:id) can :show, Commercial, commercialable: Event.where(state: 'confirmed')
can [:show, :create], User can [:show, :create], User
unless ENV['OSEM_ICHAIN_ENABLED'] == 'true'
can [:index, :show], Survey, surveyable_type: 'Conference'
# Things that are possible without ichain enabled that are **not*+ possible with ichain mode enabled.
if ENV['OSEM_ICHAIN_ENABLED'] != 'true'
# There is no reliable way for this workflow (enable not logged in users to fill out a form, then telling
# them to sign up once they submit) in ichain. So enable it only without ichain.
# FIXME: The following abilities need to be checked. Are they about the type of workflow mentioned above? Or are
# they just here because they worked in development mode (without ichain). We are suspicious that it's the latter!
can :show, Registration do |registration| can :show, Registration do |registration|
registration.new_record? registration.new_record?
end end
@ -51,12 +64,6 @@ class Ability
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 [:show, :events], Schedule do |schedule|
schedule.program.schedule_public
end
can [:index, :show], Survey, surveyable_type: 'Conference'
end end
end end

View file

@ -117,10 +117,7 @@ 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 do |registration_period| can :manage, RegistrationPeriod, conference_id: conf_ids
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|

View file

@ -18,7 +18,7 @@ class Cfp < ApplicationRecord
in: TYPES in: TYPES
}, },
uniqueness: { uniqueness: {
scope: :program, scope: :program_id,
case_sensitive: false case_sensitive: false
} }

View file

@ -29,11 +29,7 @@ class Conference < ApplicationRecord
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 do has_many :tickets, dependent: :destroy
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
has_many :confirmed_booths, -> { where(state: 'confirmed') }, class_name: 'Booth' has_many :confirmed_booths, -> { where(state: 'confirmed') }, class_name: 'Booth'
@ -84,7 +80,8 @@ class Conference < ApplicationRecord
:start_hour, :start_hour,
:end_hour, :end_hour,
:ticket_layout, :ticket_layout,
:organization, presence: true :organization,
:timezone, presence: true
validates :short_title, uniqueness: true validates :short_title, uniqueness: true
validates :short_title, format: { with: /\A[a-zA-Z0-9_-]*\z/ } validates :short_title, format: { with: /\A[a-zA-Z0-9_-]*\z/ }
@ -118,7 +115,7 @@ class Conference < ApplicationRecord
# Delete all EventSchedules that are not in the hours range # Delete all EventSchedules that are not in the hours range
# After the conference has been successfully updated # After the conference has been successfully updated
def delete_event_schedules def delete_event_schedules
if start_hour_changed? || end_hour_changed? if saved_change_to_start_hour? || saved_change_to_end_hour?
event_schedules = program.event_schedules.select do |event_schedule| event_schedules = program.event_schedules.select do |event_schedule|
event_schedule.start_time.hour < start_hour || event_schedule.start_time.hour < start_hour ||
event_schedule.end_time.hour > end_hour || event_schedule.end_time.hour > end_hour ||
@ -176,24 +173,22 @@ class Conference < ApplicationRecord
# ====Returns # ====Returns
# * +Array+ -> e.g. 'Submitted' => [0, 3, 3, 5] -> first week 0 events, second week 3 events. # * +Array+ -> e.g. 'Submitted' => [0, 3, 3, 5] -> first week 0 events, second week 3 events.
def get_submissions_data def get_submissions_data
result = {} return [] unless program&.cfp && program&.events
if program&.cfp && program&.events
result = get_events_per_week_by_state
start_week = program.cfp.start_week start_week = program.cfp.start_week
end_week = end_date.strftime('%W').to_i get_events_per_week_by_state.collect do |state, values|
weeks = weeks(start_week, end_week) if state == 'Submitted'
{
result.each do |state, values| name: 'Submitted',
if state == 'Submitted' data: add_week_indices(pad_array_left_kumulative(start_week, values))
result['Submitted'] = pad_array_left_kumulative(start_week, values) }
else else
result[state] = pad_array_left_not_kumulative(start_week, values) {
end name: state,
data: add_week_indices(pad_array_left_not_kumulative(start_week, values))
}
end end
result['Weeks'] = weeks > 0 ? (1..weeks).to_a : 0
end end
result
end end
## ##
@ -202,19 +197,15 @@ class Conference < ApplicationRecord
# ====Returns # ====Returns
# * +Array+ -> e.g. [0, 3, 3, 5] -> first week 0, second week 3 registrations # * +Array+ -> e.g. [0, 3, 3, 5] -> first week 0, second week 3 registrations
def get_registrations_per_week def get_registrations_per_week
result = [] return [] unless registrations &&
registration_period &&
registration_period.start_date &&
registration_period.end_date
if registrations && reg = registrations.group(:week).order(:week).count
registration_period && start_week = get_registration_start_week
registration_period.start_date && weeks = registration_weeks
registration_period.end_date calculate_items_per_week(start_week, weeks, reg)
reg = registrations.group(:week).order(:week).count
start_week = get_registration_start_week
weeks = registration_weeks
result = calculate_items_per_week(start_week, weeks, reg)
end
result
end end
## ##
@ -223,15 +214,12 @@ class Conference < ApplicationRecord
# ====Returns # ====Returns
# * +Array+ -> e.g. [0, 3, 3, 5] -> first week 0, second week 3 tickets sold # * +Array+ -> e.g. [0, 3, 3, 5] -> first week 0, second week 3 tickets sold
def get_tickets_sold_per_week def get_tickets_sold_per_week
result = [] return [] unless tickets && ticket_purchases && registration_period
if tickets && ticket_purchases && registration_period tickets_sold = ticket_purchases.paid.group(:week).sum(:quantity)
tickets_sold = ticket_purchases.paid.group(:week).sum(:quantity) start_week = get_registration_start_week
start_week = get_registration_start_week weeks = registration_weeks
weeks = registration_weeks calculate_items_per_week(start_week, weeks, tickets_sold)
result = calculate_items_per_week(start_week, weeks, tickets_sold)
end
result
end end
## ##
@ -241,33 +229,32 @@ class Conference < ApplicationRecord
# ====Returns # ====Returns
# * +Array+ -> e.g. 'Free Access' => [0, 3, 3, 5] -> first week 0 tickets sold, second week 3 tickets sold. # * +Array+ -> e.g. 'Free Access' => [0, 3, 3, 5] -> first week 0 tickets sold, second week 3 tickets sold.
def get_tickets_data def get_tickets_data
result = {} return [] unless tickets && ticket_purchases && registration_period
if tickets && ticket_purchases && registration_period
tickets_per_ticket_id_and_week = ticket_purchases.paid.group(:ticket_id, :week).sum(:quantity)
start_week = get_registration_start_week tickets_per_ticket_id_and_week = ticket_purchases.paid.group(:ticket_id, :week).sum(:quantity)
weeks = registration_weeks
tickets_by_id_per_week = {} start_week = get_registration_start_week
weeks = registration_weeks
tickets.each do |ticket| tickets_by_id_per_week = {}
tickets_by_id_per_week[ticket.id] = {}
(start_week...(start_week + weeks)).each do |week| tickets.each do |ticket|
tickets_by_id_per_week[ticket.id][week] = 0 tickets_by_id_per_week[ticket.id] = {}
end (start_week...(start_week + weeks)).each do |week|
tickets_by_id_per_week[ticket.id][week] = 0
end end
tickets_per_ticket_id_and_week.each do |ticket_week, value|
tickets_by_id_per_week[ticket_week[0]][ticket_week[1]] = value
end
tickets_by_id_per_week.each do |ticket, values|
result[Ticket.find(ticket).title] = pad_array_left_not_kumulative(start_week, values)
end
result['Weeks'] = weeks > 0 ? (1..weeks).to_a : 0
end end
result
tickets_per_ticket_id_and_week.each do |ticket_week, value|
tickets_by_id_per_week[ticket_week[0]][ticket_week[1]] = value
end
tickets_by_id_per_week.collect do |ticket, values|
{
name: Ticket.find(ticket).title,
data: add_week_indices(pad_array_left_not_kumulative(start_week, values))
}
end
end end
## ##
@ -400,7 +387,9 @@ class Conference < ApplicationRecord
# ====Returns # ====Returns
# * +hash+ -> hash # * +hash+ -> hash
def event_distribution def event_distribution
Conference.calculate_event_distribution_hash(program.events.select(:state).group(:state).count) Conference.calculate_event_distribution_hash(
program.events.select(:state).group(:state).count
)
end end
## ##
@ -465,22 +454,6 @@ class Conference < ApplicationRecord
result result
end end
##
# Returns a hash with user distribution => {value: count of user state, color: color}
# active: signed in during the last 3 months
# unconfirmed: registered but not confirmed
# dead: not signed in during the last year
#
# ====Returns
# * +hash+ -> hash
def self.user_distribution
active_user = User.where('last_sign_in_at > ?', Date.today - 3.months).count
unconfirmed_user = User.where('confirmed_at IS NULL').count
dead_user = User.where('last_sign_in_at < ?', Date.today - 1.year).count
calculate_user_distribution_hash(active_user, unconfirmed_user, dead_user)
end
## ##
# Returns a hash with per ticket sales => { "Title" => { value: number of tickets sold, # Returns a hash with per ticket sales => { "Title" => { value: number of tickets sold,
# color: generated from the title using a hash function }, ...} # color: generated from the title using a hash function }, ...}
@ -669,7 +642,7 @@ class Conference < ApplicationRecord
def notify_on_dates_changed? def notify_on_dates_changed?
return false unless email_settings.send_on_conference_dates_updated return false unless email_settings.send_on_conference_dates_updated
# do not notify unless one of the dates changed # do not notify unless one of the dates changed
return false unless start_date_changed? || end_date_changed? return false unless saved_change_to_start_date? || saved_change_to_end_date?
# do not notify unless the mail content is set up # do not notify unless the mail content is set up
(email_settings.conference_dates_updated_subject.present? && email_settings.conference_dates_updated_body.present?) (email_settings.conference_dates_updated_subject.present? && email_settings.conference_dates_updated_body.present?)
@ -686,7 +659,7 @@ class Conference < ApplicationRecord
# do not notify unless we allow a registration # do not notify unless we allow a registration
return false unless registration_period return false unless registration_period
# do not notify unless one of the dates changed # do not notify unless one of the dates changed
return false unless registration_period.start_date_changed? || registration_period.end_date_changed? return false unless registration_period.saved_change_to_start_date? || registration_period.saved_change_to_end_date?
# do not notify unless the mail content is set up # do not notify unless the mail content is set up
(email_settings.conference_registration_dates_updated_subject.present? && email_settings.conference_registration_dates_updated_body.present?) (email_settings.conference_registration_dates_updated_subject.present? && email_settings.conference_registration_dates_updated_body.present?)
@ -1110,20 +1083,19 @@ class Conference < ApplicationRecord
end end
## ##
# Helper method. Calculates hash with corresponding colors of event state distribution. # Helper method. Calculates hash of all event states in a consistent order.
# #
# ====Returns # ====Returns
# * +hash+ -> hash # * +hash+ -> hash
def self.calculate_event_distribution_hash(states) def self.calculate_event_distribution_hash(counts)
result = {} return {} if counts.values.sum == 0
states.each do |key, value|
result[key.capitalize] = Hash[
{ Event.state_machine.states.collect do |state|
'value' => value, state_name = state.name.to_s
'color' => Event.get_state_color(key) [state_name.capitalize, counts[state_name] || 0]
} end
end ]
result
end end
## ##
@ -1148,7 +1120,6 @@ class Conference < ApplicationRecord
# #
def create_email_settings def create_email_settings
build_email_settings build_email_settings
true
end end
## ##
@ -1211,6 +1182,12 @@ class Conference < ApplicationRecord
result += Array.new(weeks - result.length, sum) result += Array.new(weeks - result.length, sum)
end end
result add_week_indices(result)
end
def add_week_indices(values)
Hash[
values.collect.with_index { |value, index| ["Wk #{index + 1}", value] }
]
end end
end end

View file

@ -44,7 +44,6 @@ class Event < ApplicationRecord
validates :abstract, presence: true validates :abstract, presence: true
validates :event_type, presence: true validates :event_type, presence: true
validates :program, presence: true validates :program, presence: true
validates :speakers, presence: true
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
@ -83,6 +82,15 @@ class Event < ApplicationRecord
end end
end end
COLORS = {
new: '#0000FF', # blue
withdrawn: '#FF8000', # orange
unconfirmed: '#FFFF00', # yellow
confirmed: '#00FF00', # green
canceled: '#848484', # grey
rejected: '#FF0000' # red
}.freeze
## ##
# Checkes if the event has a start_time and a room for the selected schedule if there is any # Checkes if the event has a start_time and a room for the selected schedule if there is any
# ====Returns # ====Returns
@ -176,16 +184,7 @@ class Event < ApplicationRecord
end end
def self.get_state_color(state) def self.get_state_color(state)
color = { COLORS[state.to_sym] || '#00FFFF' # azure
new: '#0000FF', # blue
withdrawn: '#FF8000', # orange
confirmed: '#00FF00', # green
unconfirmed: '#FFFF00', # yellow
rejected: '#FF0000', # red
canceled: '#848484' # grey
}[state.to_sym]
color || '#00FFFF' # azure
end end
def update_state(transition, mail = false, subject = false, send_mail = false, send_mail_param) def update_state(transition, mail = false, subject = false, send_mail = false, send_mail_param)

View file

@ -72,8 +72,8 @@ class Program < ApplicationRecord
after_create :create_event_types after_create :create_event_types
after_create :create_difficulty_levels after_create :create_difficulty_levels
after_save :unschedule_unfit_events, if: :schedule_interval_changed? after_save :unschedule_unfit_events, if: :saved_change_to_schedule_interval?
after_save :normalize_event_types_length, if: :schedule_interval_changed? after_save :normalize_event_types_length, if: :saved_change_to_schedule_interval?
validate :check_languages_format validate :check_languages_format
# Returns all event_schedules for the selected schedule ordered by start_time # Returns all event_schedules for the selected schedule ordered by start_time
@ -211,7 +211,6 @@ class Program < ApplicationRecord
EventType.create(title: 'Workshop', length: 60, color: '#0000FF', description: 'Interactive hands-on practice', EventType.create(title: 'Workshop', length: 60, color: '#0000FF', description: 'Interactive hands-on practice',
minimum_abstract_length: 0, minimum_abstract_length: 0,
maximum_abstract_length: 500, program_id: id) maximum_abstract_length: 500, program_id: id)
true
end end
## ##
@ -227,7 +226,6 @@ class Program < ApplicationRecord
DifficultyLevel.create(title: 'Hard', DifficultyLevel.create(title: 'Hard',
description: 'Events require expert knowledge of the topic.', description: 'Events require expert knowledge of the topic.',
color: '#EF6E69', program_id: id) color: '#EF6E69', program_id: id)
true
end end
## ##

View file

@ -31,7 +31,7 @@ class Registration < ApplicationRecord
validate :registration_to_events_only_if_present validate :registration_to_events_only_if_present
validates :accepted_code_of_conduct, acceptance: { validates :accepted_code_of_conduct, acceptance: {
if: -> { conference.code_of_conduct.present? } if: -> { conference.try(:code_of_conduct).present? }
} }
after_create :set_week, :subscribe_to_conference, :send_registration_mail after_create :set_week, :subscribe_to_conference, :send_registration_mail
@ -76,7 +76,7 @@ class Registration < ApplicationRecord
end end
def registration_limit_not_exceed def registration_limit_not_exceed
if conference.registration_limit > 0 && conference.registrations(:reload).count >= conference.registration_limit if conference.registration_limit > 0 && conference.registrations.count >= conference.registration_limit
errors.add(:base, 'Registration limit exceeded') errors.add(:base, 'Registration limit exceeded')
end end
end end

View file

@ -18,6 +18,6 @@ class Role < ApplicationRecord
# Needed to ensure that removing all user from role doesn't remove role. # Needed to ensure that removing all user from role doesn't remove role.
def cancel def cancel
false throw(:abort)
end end
end end

View file

@ -10,7 +10,7 @@ class SurveyQuestion < ActiveRecord::Base
ICONS = { boolean: 'dot-circle-o', choice: 'check-square-o', string: 'edit', text: 'align-left', datetime: 'clock-o', numeric: 'slack' }.freeze ICONS = { boolean: 'dot-circle-o', choice: 'check-square-o', string: 'edit', text: 'align-left', datetime: 'clock-o', numeric: 'slack' }.freeze
validates :title, presence: true validates :title, presence: true
validates :possible_answers, :max_choices, :min_choices, presence: true, if: 'choice?' validates :possible_answers, :max_choices, :min_choices, presence: true, if: :choice?
validates :min_choices, numericality: { greater_than_or_equal_to: 1 }, allow_blank: true validates :min_choices, numericality: { greater_than_or_equal_to: 1 }, allow_blank: true
validates :max_choices, numericality: { greater_than_or_equal_to: 1 }, allow_blank: true validates :max_choices, numericality: { greater_than_or_equal_to: 1 }, allow_blank: true

View file

@ -10,6 +10,8 @@ class Ticket < ApplicationRecord
monetize :price_cents, with_model_currency: :price_currency monetize :price_cents, with_model_currency: :price_currency
scope :for_registration, -> { where(registration_ticket: true) }
# This validation is for the sake of simplicity. # This validation is for the sake of simplicity.
# If we would allow different currencies per conference we also have to handle convertions between currencies! # If we would allow different currencies per conference we also have to handle convertions between currencies!
validate :tickets_of_conference_have_same_currency validate :tickets_of_conference_have_same_currency

View file

@ -45,7 +45,7 @@ class Track < ApplicationRecord
scope :cfp_active, -> { where(cfp_active: true) } scope :cfp_active, -> { where(cfp_active: true) }
scope :self_organized, -> { where.not(submitter: nil) } scope :self_organized, -> { where.not(submitter: nil) }
state_machine initial: :pending do state_machine initial: :new do
state :new state :new
state :to_accept state :to_accept
state :accepted state :accepted

View file

@ -11,6 +11,7 @@ class User < ApplicationRecord
# prevent N+1 queries with has_cached_role? by preloading roles *always* # prevent N+1 queries with has_cached_role? by preloading roles *always*
default_scope { preload(:roles) } default_scope { preload(:roles) }
has_many :ticket_purchases, dependent: :destroy
has_many :physical_tickets, through: :ticket_purchases do has_many :physical_tickets, through: :ticket_purchases do
def by_conference(conference) def by_conference(conference)
where('ticket_purchases.conference_id = ?', conference) where('ticket_purchases.conference_id = ?', conference)
@ -32,6 +33,13 @@ class User < ApplicationRecord
# add scope # add scope
scope :comment_notifiable, ->(conference) {joins(:roles).where('roles.name IN (?)', [:organizer, :cfp]).where('roles.resource_type = ? AND roles.resource_id = ?', 'Conference', conference.id)} scope :comment_notifiable, ->(conference) {joins(:roles).where('roles.name IN (?)', [:organizer, :cfp]).where('roles.resource_type = ? AND roles.resource_id = ?', 'Conference', conference.id)}
# scopes for user distributions
scope :recent, lambda {
where('last_sign_in_at > ?', Date.today - 3.months).where(is_disabled: false)
}
scope :unconfirmed, -> { where('confirmed_at IS NULL') }
scope :dead, -> { where('last_sign_in_at < ?', Date.today - 1.year) }
# Include default devise modules. Others available are: # Include default devise modules. Others available are:
# :token_authenticatable, :confirmable, # :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable # :lockable, :timeoutable and :omniauthable
@ -60,7 +68,6 @@ class User < ApplicationRecord
end end
end end
has_many :events_registrations, through: :registrations has_many :events_registrations, through: :registrations
has_many :ticket_purchases, dependent: :destroy
has_many :payments, dependent: :destroy has_many :payments, dependent: :destroy
has_many :tickets, through: :ticket_purchases, source: :ticket do has_many :tickets, through: :ticket_purchases, source: :ticket do
def for_registration conference def for_registration conference
@ -79,7 +86,9 @@ class User < ApplicationRecord
accepts_nested_attributes_for :roles accepts_nested_attributes_for :roles
scope :admin, -> { where(is_admin: true) } scope :admin, -> { where(is_admin: true) }
scope :active, -> { where(is_disabled: false) } scope :active, lambda {
where(is_disabled: false)
}
validates :email, presence: true validates :email, presence: true
@ -91,6 +100,12 @@ class User < ApplicationRecord
validate :biography_limit validate :biography_limit
DISTRIBUTION_COLORS = {
'Active' => 'green',
'Unconfirmed' => 'red',
'Dead' => 'black'
}.freeze
## ##
# Checkes if the user attended the event # Checkes if the user attended the event
# This is used for events that require registration # This is used for events that require registration
@ -152,6 +167,22 @@ class User < ApplicationRecord
user user
end end
##
# Returns a hash with user distribution => {value: count of user state, color: color}
# active: signed in during the last 3 months
# unconfirmed: registered but not confirmed
# dead: not signed in during the last year
#
# ====Returns
# * +hash+ -> hash
def self.distribution
{
'Active' => User.recent.count,
'Unconfirmed' => User.unconfirmed.count,
'Dead' => User.dead.count
}
end
def self.find_for_database_authentication(warden_conditions) def self.find_for_database_authentication(warden_conditions)
conditions = warden_conditions.dup conditions = warden_conditions.dup
login = conditions.delete(:login) login = conditions.delete(:login)
@ -237,12 +268,14 @@ class User < ApplicationRecord
proposals(conference).count proposals(conference).count
end end
def self.empty?
User.count == 1 && User.first.email == 'deleted@localhost.osem'
end
private private
def setup_role def setup_role
if User.count == 1 && User.first.email == 'deleted@localhost.osem' self.is_admin = true if User.empty?
self.is_admin = true
end
end end
def touch_events def touch_events
@ -257,4 +290,8 @@ class User < ApplicationRecord
errors.add(:biography, 'is limited to 150 words.') if biography.split.length > 150 errors.add(:biography, 'is limited to 150 words.') if biography.split.length > 150
end end
end end
def send_devise_notification(notification, *args)
devise_mailer.send(notification, self, *args).deliver_later
end
end end

View file

@ -37,7 +37,7 @@ class Venue < ApplicationRecord
def notify_on_venue_changed? def notify_on_venue_changed?
return false unless conference.try(:email_settings).try(:send_on_venue_updated) return false unless conference.try(:email_settings).try(:send_on_venue_updated)
# do not notify unless the address changed # do not notify unless the address changed
return false unless name_changed? || street_changed? || city_changed? || country_changed? return false unless saved_change_to_name? || saved_change_to_street? || saved_change_to_city? || saved_change_to_country?
# do not notify unless the mail content is set up # do not notify unless the mail content is set up
(!conference.email_settings.venue_updated_subject.blank? && !conference.email_settings.venue_updated_body.blank?) (!conference.email_settings.venue_updated_subject.blank? && !conference.email_settings.venue_updated_body.blank?)

View file

@ -1,4 +1,4 @@
- headers = ['Booth ID', - headers = ["#{(t'booth').capitalize } ID",
'Title', 'Title',
'Description', 'Description',
'Reasoning', 'Reasoning',
@ -6,7 +6,7 @@
'Submitter Relationship', 'Submitter Relationship',
'Website Url', 'Website Url',
'State'] 'State']
= CSV.generate_line ['All booths'] = CSV.generate_line ["All #{(t'booth').pluralize}"]
= CSV.generate_line headers = CSV.generate_line headers
- @booths.each do |booth| - @booths.each do |booth|
= CSV.generate_line([booth.id, = CSV.generate_line([booth.id,

View file

@ -1,6 +1,6 @@
prawn_document(force_download: true, filename: "#{@file_name}.pdf", page_layout: :landscape) do |pdf| prawn_document(force_download: true, filename: "#{@file_name}.pdf", page_layout: :landscape) do |pdf|
booths_array = [] booths_array = []
header_array = ['Booth ID', header_array = ["#{(t'booth').capitalize } ID",
'Title', 'Title',
'Description', 'Description',
'Reasoning', 'Reasoning',
@ -21,6 +21,6 @@ prawn_document(force_download: true, filename: "#{@file_name}.pdf", page_layout:
row << booth.state row << booth.state
booths_array << row booths_array << row
end end
pdf.text "#{@conference.short_title} booths", font_size: 25, align: :center pdf.text "#{@conference.short_title} #{(t'booth').pluralize}", font_size: 25, align: :center
pdf.table booths_array, header: true, cell_style: {size: 8, border_width: 1},column_widths: [45,70,153,152,70,80,105,45] pdf.table booths_array, header: true, cell_style: {size: 8, border_width: 1},column_widths: [45,70,153,152,70,80,105,45]
end end

View file

@ -1,9 +1,9 @@
# frozen_string_literal: true # frozen_string_literal: true
wb.add_worksheet(name: 'all booths') do |sheet| wb.add_worksheet(name: "all #{(t 'booth').pluralize}") do |sheet|
bold_style = wb.styles.add_style(b: true) bold_style = wb.styles.add_style(b: true)
wrap_text = wb.styles.add_style alignment: {wrap_text: true} wrap_text = wb.styles.add_style alignment: {wrap_text: true}
row = ['Booth ID', row = ["#{(t 'booth').capitalize} ID",
'Title', 'Title',
'Description', 'Description',
'Reasoning', 'Reasoning',

View file

@ -2,12 +2,12 @@
- if booth.transition_possible? :accept - if booth.transition_possible? :accept
- if can? :accept, booth - if can? :accept, booth
- if @conference.booth_limit > 0 - if @conference.booth_limit > 0
- 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?" - confirm_message = ' You are able to accept '+ pluralize(@conference.booth_limit - (@conference.booths.accepted.count + @conference.booths.confirmed.count), "more #{t'booth'}") + " (#{t'booth'} limit set to #{@conference.booth_limit}). Are you sure you want to accept this one?"
- if @conference.email_settings.send_on_booths_acceptance - if @conference.email_settings.send_on_booths_acceptance
- link = 'Accept with email' - 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 - confirm_message = "By accepting this #{t'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 - else
- link = 'Accept booth' - link = "Accept #{t'booth'}"
%li= link_to link, %li= link_to link,
accept_admin_conference_booth_path(@conference.short_title, booth), accept_admin_conference_booth_path(@conference.short_title, booth),
method: :patch ,id: "accept_booth_#{booth.id}", method: :patch ,id: "accept_booth_#{booth.id}",
@ -24,7 +24,7 @@
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) 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 #{t'booth'}",
to_reject_admin_conference_booth_path(@conference.short_title, booth), to_reject_admin_conference_booth_path(@conference.short_title, booth),
method: :patch, id: "to_reject_booth_#{booth.id}" method: :patch, id: "to_reject_booth_#{booth.id}"
@ -34,16 +34,16 @@
method: :patch, id: "restart_booth_#{booth.id}" method: :patch, id: "restart_booth_#{booth.id}"
- if booth.transition_possible? :to_accept - if booth.transition_possible? :to_accept
%li= link_to 'To accept booth', %li= link_to "To accept #{t'booth'}",
to_accept_admin_conference_booth_path(@conference.short_title, booth), to_accept_admin_conference_booth_path(@conference.short_title, booth),
method: :patch, id: "to_accept_booth_#{booth.id}" method: :patch, id: "to_accept_booth_#{booth.id}"
- if booth.transition_possible? :cancel - if booth.transition_possible? :cancel
%li= link_to 'Cancel booth', %li= link_to "Cancel #{t'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 - if booth.transition_possible? :confirm
%li= link_to 'Confirm booth', %li= link_to "Confirm #{t'booth'}",
confirm_admin_conference_booth_path(@conference.short_title, booth), confirm_admin_conference_booth_path(@conference.short_title, booth),
method: :patch, id: "confirm_booth_#{booth.id}" method: :patch, id: "confirm_booth_#{booth.id}"

View file

@ -1,4 +1,4 @@
- headers = ['Booth ID', - headers = ["#{(t'booth').capitalize } ID",
'Title', 'Title',
'Description', 'Description',
'Reasoning', 'Reasoning',
@ -6,7 +6,7 @@
'Submitter Relationship', 'Submitter Relationship',
'Website Url', 'Website Url',
'State'] 'State']
= CSV.generate_line ['All booths'] = CSV.generate_line ["All #{(t'booth').pluralize}"]
= CSV.generate_line headers = CSV.generate_line headers
- @booths.confirmed.each do |booth| - @booths.confirmed.each do |booth|
= CSV.generate_line([booth.id, = CSV.generate_line([booth.id,

View file

@ -1,6 +1,6 @@
prawn_document(force_download: true, filename: "#{@file_name}.pdf", page_layout: :landscape) do |pdf| prawn_document(force_download: true, filename: "#{@file_name}.pdf", page_layout: :landscape) do |pdf|
booths_array = [] booths_array = []
header_array = ['Booth ID', header_array = ["#{(t'booth').capitalize } ID",
'Title', 'Title',
'Description', 'Description',
'Reasoning', 'Reasoning',

View file

@ -1,9 +1,9 @@
# frozen_string_literal: true # frozen_string_literal: true
wb.add_worksheet(name: 'all booths') do |sheet| wb.add_worksheet(name: "all #{(t 'booth').pluralize}") do |sheet|
bold_style = wb.styles.add_style(b: true) bold_style = wb.styles.add_style(b: true)
wrap_text = wb.styles.add_style alignment: {wrap_text: true} wrap_text = wb.styles.add_style alignment: {wrap_text: true}
row = ['Booth ID', row = ["#{(t 'booth').capitalize} ID",
'Title', 'Title',
'Description', 'Description',
'Reasoning', 'Reasoning',

View file

@ -2,7 +2,7 @@
.col-md-12 .col-md-12
.page-header .page-header
%h1 %h1
Booths #{(t'booth').pluralize.capitalize }
.pull-right .pull-right
- if can? :read, Booth - if can? :read, Booth
.btn-group .btn-group
@ -11,8 +11,8 @@
Export PDF Export PDF
%span.caret %span.caret
%ul.dropdown-menu{ role: 'menu' } %ul.dropdown-menu{ role: 'menu' }
%li= link_to 'All Booths', admin_conference_booths_path(@conference.short_title, format: :pdf, booth_export_option: 'all') %li= link_to "All #{(t'booth').pluralize.capitalize }", admin_conference_booths_path(@conference.short_title, format: :pdf, booth_export_option: 'all')
%li= link_to 'Confirmed Booths', admin_conference_booths_path(@conference.short_title, format: :pdf, booth_export_option: 'confirmed') %li= link_to "Confirmed #{(t'booth').pluralize.capitalize }", admin_conference_booths_path(@conference.short_title, format: :pdf, booth_export_option: 'confirmed')
.btn-group .btn-group
%button.btn.btn-default.dropdown-toggle{ 'data-toggle' => 'dropdown', type: 'button', class: 'btn btn-success' } %button.btn.btn-default.dropdown-toggle{ 'data-toggle' => 'dropdown', type: 'button', class: 'btn btn-success' }
Export CSV Export CSV
@ -29,7 +29,7 @@
%li= link_to 'Confirmed', admin_conference_booths_path(@conference.short_title, format: :xlsx, booth_export_option: 'confirmed') %li= link_to 'Confirmed', admin_conference_booths_path(@conference.short_title, format: :xlsx, booth_export_option: 'confirmed')
= "(#{@booths.length})" if @booths.any? = "(#{@booths.length})" if @booths.any?
%p.text-muted %p.text-muted
All the booth requests All the #{t'booth'} requests
.row .row
.col-md-12 .col-md-12
@ -37,21 +37,21 @@
- if @conference.booth_limit == 0 - if @conference.booth_limit == 0
%p %p
Set the Set the
= link_to 'Booth limit', edit_admin_conference_path(@conference.short_title) = link_to "#{(t'booth').capitalize } limit", edit_admin_conference_path(@conference.short_title)
to make sure you are not accepting more booths than you can accommodate. to make sure you are not accepting more #{(t'booth').pluralize} than you can accommodate.
- elsif !@conference.maximum_accepted_booths? - elsif !@conference.maximum_accepted_booths?
%p %p
You cannot accept more than You cannot accept more than
%b %b
= pluralize(@conference.booth_limit, 'booth') = pluralize(@conference.booth_limit, "#{t'booth'}")
( (
= pluralize(@conference.booths.accepted.count + @conference.booths.confirmed.count, 'accepted booth') = pluralize(@conference.booths.accepted.count + @conference.booths.confirmed.count, "accepted #{t'booth'}")
so far) so far)
- else - else
%p %p
You have reached the maximum number of accepted booths. You have reached the maximum number of accepted #{(t'booth').pluralize}.
( (
= link_to "#{@conference.booth_limit} booths", edit_admin_conference_path(@conference.short_title) = link_to "#{@conference.booth_limit} #{(t'booth').pluralize}", edit_admin_conference_path(@conference.short_title)
) )
- if @booths.any? - if @booths.any?
%table.datatable %table.datatable

View file

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

View file

@ -7,15 +7,15 @@
.row .row
.col-md-8 .col-md-8
= semantic_form_for(cfp, url: cfp_form_url(cfp, conference), = semantic_form_for(cfp, url: cfp_form_url(cfp, conference),
html: { multipart: true }) do |f| html: { multipart: true,
data: { end_conference: conference.end_date.to_s } }) do |f|
= f.input :cfp_type, as: :hidden = f.input :cfp_type, as: :hidden
= f.input :start_date, as: :string, = f.input :start_date, as: :string,
input_html: { id: 'registration-period-start-datepicker', input_html: { class: 'form-control',
start_date: conference.start_date, id: 'registration-period-start-datepicker' }
end_date: conference.end_date, readonly: 'readonly' }
= f.input :end_date, as: :string, = f.input :end_date, as: :string,
input_html: { id: 'registration-period-end-datepicker', input_html: { class: 'form-control',
readonly: 'readonly' } id: 'registration-period-end-datepicker' }
= f.input :description, hint: markdown_hint, = f.input :description, hint: markdown_hint,
input_html: { rows: 2, data: { provide: 'markdown-editable' } } input_html: { rows: 2, data: { provide: 'markdown-editable' } }
- if cfp.cfp_type == 'events' - if cfp.cfp_type == 'events'

View file

@ -1,23 +0,0 @@
.text-center
%h4 #{title}
%canvas.doughnut_chart{ id: "dough_#{title.parameterize.underscore}", 'data-chart' => data.to_json }
- if data
- data.each do |key, value|
%span{ 'style' => "border-bottom: 3px solid #{value['color']}" } #{key}: #{value['value']}
:javascript
$(document).ready( function(){
var d = $("#dough_#{title.parameterize.underscore}");
var dt = d.get(0).getContext('2d');
$(window).resize( respondCanvas );
function respondCanvas(){
dt.canvas.width = 150;
dt.canvas.height = 150;
}
respondCanvas();
});

View file

@ -1,47 +0,0 @@
.row
.col-md-12
.text-center
%h4
= title
.row
.col-md-12
.chart_data{ 'data-chart' => "#{y.to_json}", 'data-conferences' => "#{conferences.to_json}",
'data-deactive' => "#{deactive_conferences.to_json}", 'data-weeks' => "#{x.to_json}",
'data-active' => "#{active_conferences.to_json}" }
%canvas.line_chart{ id: "line_chart_#{name}", 'data-name' => "#{name}" }
.row
.col-md-12
.text-center
= unit
.row
.col-md-12
.conferenceCheckboxes{ id: "#{name}Checkboxes", 'data-name' => "#{name}" }
- if active_conferences && deactive_conferences && conferences && conferences.length > 1
- active_conferences.each do |conference|
%div
%span{ 'style' => "border-bottom: 3px solid #{conference[:color]};", 'data-chart' => "#{name}" }
%input{ 'type' => 'checkbox', 'name' => "#{conference[:short_title]}", 'checked' => 'checked' }
#{conference[:short_title]}
- deactive_conferences.each do |conference|
%div
%span{ 'style' => "border-bottom: 3px solid #{conference[:color]};", 'data-chart' => "#{name}" }
%input{ 'type' => 'checkbox', 'name' => "#{conference[:short_title]}" }
#{conference[:short_title]}
:javascript
$(document).ready( function(){
var c = $("#line_chart_#{name}");
var ct = c.get(0).getContext('2d');
var container = $(c).parent();
$(window).resize( respondCanvas );
function respondCanvas(){
c.attr('width', $(container).width() );
c.attr('height', $(container).height() );
}
respondCanvas();
});

View file

@ -14,10 +14,7 @@
%td= link_to user.email, admin_user_path(user.id) %td= link_to user.email, admin_user_path(user.id)
%td= user.created_at.strftime('%m/%d/%Y') %td= user.created_at.strftime('%m/%d/%Y')
%td %td
= check_box_tag user.id, user.id, user.confirmed?, = user.confirmed? ? 'Yes' : 'No'
url: "/admin/users/#{user.id}/toggle_confirmation?user[to_confirm]=",
class: 'switch-checkbox',
readonly: true
- else - else
%h5.text-warning.text-center %h5.text-warning.text-center
No sign ups! No sign ups!

View file

@ -28,5 +28,5 @@
= 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.inputs name: 'Booths' do
= f.input :booth_limit, as: :number, in: 0..9999, = 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') +'.' hint: "#{(t'booth').capitalize } limit is the maximum number of #{(t'booth').pluralize} 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 #{(t'booth').pluralize} than the conference can accommodate. You currently have " + pluralize(@conference.booths.accepted.count, "accepted #{t'booth'}") +'.'
= f.action :submit, as: :button, button_html: { class: 'btn btn-primary', data: { confirm: 'Are you sure you want to proceed?' } } = f.action :submit, as: :button, button_html: { class: 'btn btn-primary', data: { confirm: 'Are you sure you want to proceed?' } }

View file

@ -1,52 +1,32 @@
= javascript_include_tag 'Chart.min'
.row .row
.col-sm-3.col-xs-3 .col-sm-3.col-xs-3
= render "shared/big_statistic", = render "big_statistic",
icon: "user", subtitle: "User", value: @total_user, delta: @new_user icon: "user", subtitle: "User", value: @total_user, delta: @new_user
.col-sm-3.col-xs-3 .col-sm-3.col-xs-3
= render "shared/big_statistic", = render "big_statistic",
icon: "check-square", subtitle: "Registration", value: @total_reg, delta: @new_reg icon: "check-square", subtitle: "Registration", value: @total_reg, delta: @new_reg
.col-sm-3.col-xs-3 .col-sm-3.col-xs-3
= render "shared/big_statistic", = render "big_statistic",
icon: "file-text", subtitle: "Submission", value: @total_submissions, delta: @new_submissions icon: "file-text", subtitle: "Submission", value: @total_submissions, delta: @new_submissions
.col-sm-3.col-xs-3 .col-sm-3.col-xs-3
= render "shared/big_statistic", = render "big_statistic",
icon: "archive", subtitle: "Withdrawn", value: @total_withdrawn, delta: @new_withdrawn, reverse: true icon: "archive", subtitle: "Withdrawn", value: @total_withdrawn, delta: @new_withdrawn, reverse: true
.row#registrations .row#registrations
.col-md-8 .col-md-8
= render partial: 'line_chart', locals: { title: 'Registrations over time', = render 'line_chart', title: 'Registrations per week', data: @registrations
name: 'registrations',
conferences: @conferences,
active_conferences: @active_conferences,
deactive_conferences: @deactive_conferences,
y: @registrations,
x: @registration_weeks,
unit: 'weeks' }
.col-md-4 .col-md-4
= render partial: 'doughnut_chart', locals: { title: 'Events', data: @event_distribution } = render 'donut_chart', title: 'Events',
data: @event_distribution, colors: @event_distribution_colors
.row#submissions .row#submissions
.col-md-8 .col-md-8
= render partial: 'line_chart', locals: { title: 'Submissions over time', = render 'line_chart', title: 'Submissions per week', data: @submissions
name: 'submissions',
conferences: @conferences,
active_conferences: @active_conferences,
deactive_conferences: @deactive_conferences,
y: @submissions,
x: @cfp_weeks,
unit: 'weeks' }
.col-md-4 .col-md-4
= render partial: 'doughnut_chart', locals: { title: 'User', data: @user_distribution } = render 'donut_chart', title: 'Users',
data: @user_distribution, colors: @user_distribution_colors
.row#tickets .row#tickets
.col-md-8 .col-md-8
= render partial: 'line_chart', locals: { title: 'Tickets sold over time', = render 'line_chart', title: 'Tickets sold per week', data: @tickets
name: 'tickets',
conferences: @conferences,
active_conferences: @active_conferences,
deactive_conferences: @deactive_conferences,
y: @tickets,
x: @ticket_weeks,
unit: 'weeks' }
%br %br
.row .row
.col-md-8 .col-md-8

View file

@ -1,21 +1,19 @@
= javascript_include_tag 'Chart.min'
%h1 %h1
%span.fa.fa-tachometer %span.fa.fa-tachometer
Dashboard for #{@conference.title} Dashboard for #{@conference.title}
%hr %hr
.row .row
.col-sm-3.col-xs-3 .col-sm-3.col-xs-3
= render "shared/big_statistic", = render "big_statistic",
icon: "user", subtitle: "Registration", value: @total_reg, delta: @new_reg icon: "user", subtitle: "Registration", value: @total_reg, delta: @new_reg
.col-sm-3.col-xs-3 .col-sm-3.col-xs-3
= render "shared/big_statistic", = render "big_statistic",
icon: "check-square", subtitle: "Submission", value: @total_submissions, delta: @new_submissions icon: "check-square", subtitle: "Submission", value: @total_submissions, delta: @new_submissions
.col-sm-3.col-xs-3 .col-sm-3.col-xs-3
= render "shared/big_statistic", = render "big_statistic",
icon: "file-text", subtitle: "Hour", value: @program_length, delta: @new_program_length icon: "file-text", subtitle: "Hour", value: @program_length, delta: @new_program_length
.col-sm-3.col-xs-3 .col-sm-3.col-xs-3
= render "shared/big_statistic", = render "big_statistic",
icon: "archive", subtitle: "Withdrawn", value: @total_withdrawn, delta: @new_withdrawn icon: "archive", subtitle: "Withdrawn", value: @total_withdrawn, delta: @new_withdrawn
.row .row
@ -24,37 +22,19 @@
.col-md-8 .col-md-8
.row#registrations .row#registrations
.col-md-12 .col-md-12
= render partial: 'line_chart', locals: { title: 'Registrations over time', = render 'line_chart',
name: 'registrations', title: 'Registrations per week', data: @registrations
conferences: [@conference],
active_conferences: [@conference],
deactive_conferences: [],
y: @registrations,
x: @registration_weeks,
unit: 'weeks' }
.row#submissions .row#submissions
.col-md-12 .col-md-12
= render partial: 'line_chart', locals: { title: 'Submissions over time', = render 'line_chart',
name: 'submissions', title: 'Submissions per week', data: @submissions
conferences: @submissions,
active_conferences: @submissions,
deactive_conferences: [],
y: @submissions_data,
x: @cfp_weeks,
unit: 'weeks' }
.col-md-4 .col-md-4
= render partial: 'todo_list', locals: { conference_progress: @conference_progress, = render 'todo_list',
conference: @conference } conference_progress: @conference_progress, conference: @conference
.row#tickets .row#tickets
.col-md-8 .col-md-8
= render partial: 'line_chart', locals: { title: 'Tickets sold over time', = render 'line_chart',
name: 'tickets', title: 'Tickets sold per week', data: @tickets
conferences: @tickets,
active_conferences: @tickets,
deactive_conferences: [],
y: @tickets_data,
x: @ticket_weeks,
unit: 'weeks' }
%br %br
.row .row
.col-md-12#doughnut .col-md-12#doughnut
@ -75,27 +55,36 @@
.tab-pane.active#distribution_all .tab-pane.active#distribution_all
.row .row
.col-md-4 .col-md-4
= render partial: 'doughnut_chart', locals: {title: 'Event types', data: @event_type_distribution} = render 'donut_chart', title: 'Event types',
combined_data: @event_type_distribution
.col-md-4 .col-md-4
= render partial: 'doughnut_chart', locals: {title: 'Difficulty levels', data: @difficulty_levels_distribution} = render 'donut_chart', title: 'Difficulty levels',
combined_data: @difficulty_levels_distribution
.col-md-4 .col-md-4
= render partial: 'doughnut_chart', locals: {title: 'Tracks', data: @tracks_distribution} = render 'donut_chart', title: 'Tracks',
combined_data: @tracks_distribution
.tab-pane#distribution_confirmed .tab-pane#distribution_confirmed
.row .row
.col-md-4 .col-md-4
= render partial: 'doughnut_chart', locals: {title: 'Event types', data: @event_type_distribution_confirmed} = render 'donut_chart', title: 'Event types',
combined_data: @event_type_distribution_confirmed
.col-md-4 .col-md-4
= render partial: 'doughnut_chart', locals: {title: 'Difficulty levels', data: @difficulty_levels_distribution_confirmed} = render 'donut_chart', title: 'Difficulty levels',
combined_data: @difficulty_levels_distribution_confirmed
.col-md-4 .col-md-4
= render partial: 'doughnut_chart', locals: {title: 'Tracks', data: @tracks_distribution_confirmed} = render 'donut_chart', title: 'Tracks',
combined_data: @tracks_distribution_confirmed
.tab-pane#distribution_withdrawn .tab-pane#distribution_withdrawn
.row .row
.col-md-4 .col-md-4
= render partial: 'doughnut_chart', locals: {title: 'Event types', data: @event_type_distribution_withdrawn} = render 'donut_chart', title: 'Event types',
combined_data: @event_type_distribution_withdrawn
.col-md-4 .col-md-4
= render partial: 'doughnut_chart', locals: {title: 'Difficulty levels', data: @difficulty_levels_distribution_withdrawn} = render 'donut_chart', title: 'Difficulty levels',
combined_data: @difficulty_levels_distribution_withdrawn
.col-md-4 .col-md-4
= render partial: 'doughnut_chart', locals: {title: 'Tracks', data: @tracks_distribution_withdrawn} = render 'donut_chart', title: 'Tracks',
combined_data: @tracks_distribution_withdrawn
.row .row
.col-md-8 .col-md-8

View file

@ -114,18 +114,18 @@
= f.input :booths_acceptance_subject = f.input :booths_acceptance_subject
= f.input :booths_acceptance_body, input_html: { rows:10, cols: 20 } = 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', %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-subject-text' => "Your #{t'booth'} has been accepted!",
'data-body-input-id' => 'email_settings_booths_acceptance_body', '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 'data-body-text' => "Dear {name},\n\nWe are pleased to inform you that your #{t'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 %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} = render partial: 'help', locals: {id: 'booth_acceptance_help', show_event_variables: false}
= f.input :send_on_booths_rejection = f.input :send_on_booths_rejection
= f.input :booths_rejection_subject = f.input :booths_rejection_subject
= f.input :booths_rejection_body, input_html: { rows:10, cols:20 } = 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', %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-subject-text' => "Your #{t'booth'} request has been rejected",
'data-body-input-id' => 'email_settings_booths_rejection_body', '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 'data-body-text' => "Dear {name},\n\nThank you for your #{t'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 %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} = render partial: 'help', locals: {id: 'booth_rejection_help', show_event_variables: false}

View file

@ -24,11 +24,15 @@
Unknown submitter Unknown submitter
%td %td
- event.speakers_ordered.each do |speaker| - if event.speakers.any?
.speaker - event.speakers_ordered.each do |speaker|
= link_to speaker.name, admin_user_path(speaker) .speaker
- unless speaker.registrations.for_conference(event.conference) = link_to speaker.name, admin_user_path(speaker)
%span.label.label-danger Unregistered - unless speaker.registrations.for_conference(event.conference)
%span.label.label-danger Unregistered
- else
.small
No Speaker
- if @program.languages.present? - if @program.languages.present?
%td %td

View file

@ -1,5 +1,3 @@
= javascript_include_tag 'Chart.min'
.row .row
.col-md-12 .col-md-12
.page-header .page-header
@ -47,17 +45,14 @@
= f.submit 'Add', class: 'btn btn-primary' = f.submit 'Add', class: 'btn btn-primary'
.row .row
.col-md-4 .col-md-4
= render 'admin/conferences/doughnut_chart', = render 'donut_chart', title: 'Events state',
title: 'Events state', data: @event_distribution, colors: @event_distribution_colors
data: @event_distribution
.col-md-4 .col-md-4
= render 'admin/conferences/doughnut_chart', = render 'donut_chart', title: 'Confirmed events scheduled',
title: 'Confirmed events scheduled', combined_data: @scheduled_event_distribution
data: @scheduled_event_distribution
.col-md-4 .col-md-4
= render 'admin/conferences/doughnut_chart', = render 'donut_chart', title: 'Tracks of confirmed events',
title: 'Tracks of confirmed events', combined_data: @tracks_distribution_confirmed
data: @tracks_distribution_confirmed
.row .row
.col-md-12 .col-md-12
.margin-event-table .margin-event-table

View file

@ -11,7 +11,7 @@
for for
= @event.title = @event.title
- if @event.room && (@event_registrations.length > @event.room.size) - if @event.room.try(:size) && (@event_registrations.length > @event.room.size)
%b Attention: %b Attention:
You have more registrations than the capacity of the room! You have more registrations than the capacity of the room!
@ -32,7 +32,7 @@
%td= event_registration.email %td= event_registration.email
%td= event_registration.created_at %td= event_registration.created_at
%td %td
= check_box_tag @conference.short_title, @event.id, event_registration.attended, class: 'switch-checkbox', url: "/admin/conferences/#{@conference.short_title}/program/events/#{@event.id}/toggle_attendance?events_registration_id=#{event_registration.id}&&event_registration[attended]=" = check_box_tag @conference.short_title, @event.id, event_registration.attended, class: 'switch-checkbox', url: "#{toggle_attendance_admin_conference_program_event_path(@conference, @event, events_registration_id: event_registration)}&&event_registration[attended]="
%td %td
- if event_registration.registration.attended - if event_registration.registration.attended
%i.fa.fa-check.text-success %i.fa.fa-check.text-success

View file

@ -69,9 +69,10 @@
%span{ 'class' => [icon_for_todo(progress_status['registered']), 'fa-lg'] } %span{ 'class' => [icon_for_todo(progress_status['registered']), 'fa-lg'] }
%tr %tr
%td %td
- if @event.speakers.count == 1 - speakers_count = @event.speakers.count
- if speakers_count == 1
= link_to 'Fill out speaker\'s biography', edit_admin_user_path(@event.speakers.first) = link_to 'Fill out speaker\'s biography', edit_admin_user_path(@event.speakers.first)
- else - elsif speakers_count > 1
Fill out speaker's biography: Fill out speaker's biography:
= speaker_links(@event) = speaker_links(@event)
%td{ 'class' => class_for_todo(progress_status['biographies']) } %td{ 'class' => class_for_todo(progress_status['biographies']) }

View file

@ -16,9 +16,9 @@
- else - else
- 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.thumb, class: 'img-responsive img-lodging' = image_tag lodging.picture.thumb.url, class: 'img-responsive img-lodging'
- else - else
= image_tag lodging.picture.thumb, class: 'img-responsive img-lodging' = image_tag lodging.picture.thumb.url, class: 'img-responsive img-lodging'
.caption .caption
%h3.text-center %h3.text-center
= lodging.name = lodging.name

View file

@ -1,5 +1,3 @@
= javascript_include_tag 'Chart.min'
.container .container
.row .row
.col-md-12.page-header .col-md-12.page-header
@ -9,11 +7,11 @@
Tickets sold for the conference Tickets sold for the conference
.row .row
.col-md-4 .col-md-4
= render partial: 'admin/conferences/doughnut_chart', = render 'donut_chart', title: 'Tickets sold',
locals: { title: 'Tickets sold', data: @tickets_sold_distribution } combined_data: @tickets_sold_distribution
.col-md-4 .col-md-4
= render partial: 'admin/conferences/doughnut_chart', = render 'donut_chart', title: 'Tickets turnover',
locals: {title: 'Tickets turnover', data: @tickets_turnover_distribution} combined_data: @tickets_turnover_distribution
%br %br
- if @physical_tickets.any? - if @physical_tickets.any?
.row .row

View file

@ -11,7 +11,7 @@
= f.input :languages, hint: "Enter the languages allowed for events as values of #{link_to('ISO 639-1', 'http://www.loc.gov/standards/iso639-2/php/code_list.php', target: "_blank")} language codes separated with commas. The first language would be the default language. Leave it blank if you do not want to specify languages.".html_safe = f.input :languages, hint: "Enter the languages allowed for events as values of #{link_to('ISO 639-1', 'http://www.loc.gov/standards/iso639-2/php/code_list.php', target: "_blank")} language codes separated with commas. The first language would be the default language. Leave it blank if you do not want to specify languages.".html_safe
= f.input :schedule_interval, input_html: { autofocus: true }, hint: "It is the minimal time interval of your schedule. The value should be 5, 6, 10, 12, 15, 20, 30 or 60. Warning! Some events could be unscheduled when changing this value." = f.input :schedule_interval, input_html: { autofocus: true }, hint: "It is the minimal time interval of your schedule. The value should be 5, 6, 10, 12, 15, 20, 30 or 60. Warning! Some events could be unscheduled when changing this value."
= f.input :blind_voting, hint: 'Enable this feature if you do not want to show voting results and voters prior to user submitting a vote. For the feature to work you need to set the voting dates below as well' = f.input :blind_voting, hint: 'Enable this feature if you do not want to show voting results and voters prior to user submitting a vote. For the feature to work you need to set the voting dates below as well'
= f.input :voting_start_date, as: :string, input_html: { id: 'datetimepicker-voting_start_date', readonly: true, value: (f.object.voting_start_date.to_formatted_s(:db_without_seconds) unless f.object.voting_start_date.nil?) } = f.input :voting_start_date, as: :string, input_html: { id: 'datetimepicker-voting_start_date', value: (f.object.voting_start_date.to_formatted_s(:db_without_seconds) unless f.object.voting_start_date.nil?) }
= f.input :voting_end_date, as: :string, input_html: { id: 'datetimepicker-voting_start_date', readonly: true, value: (f.object.voting_end_date.to_formatted_s(:db_without_seconds) unless f.object.voting_end_date.nil?) } = f.input :voting_end_date, as: :string, input_html: { id: 'datetimepicker-voting_end_date', value: (f.object.voting_end_date.to_formatted_s(:db_without_seconds) unless f.object.voting_end_date.nil?) }
%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

@ -5,7 +5,7 @@
.row .row
.col-md-8 .col-md-8
= semantic_form_for(@registration_period, url: admin_conference_registration_period_path(@conference.short_title)) do |f| = semantic_form_for(@registration_period, url: admin_conference_registration_period_path(@conference.short_title)) do |f|
= 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' } = f.input :start_date, as: :string, input_html: { id: 'registration-period-start-datepicker', start_date: @conference.start_date, end_date: @conference.end_date }
= f.input :end_date, as: :string, input_html: { id: 'registration-period-end-datepicker', readonly: 'readonly' } = f.input :end_date, as: :string, input_html: { id: 'registration-period-end-datepicker' }
%p.text-right %p.text-right
= f.submit 'Save Registration Period', class: 'btn btn-primary' = f.submit 'Save Registration Period', class: 'btn btn-primary'

View file

@ -8,29 +8,38 @@
.row .row
.col-md-8 .col-md-8
%dl.dl-horizontal %dl.dl-horizontal
%dt %dt Start Date
Start Date %dd= @registration_period.start_date
%dd %dt End Date
= @registration_period.start_date %dd= @registration_period.end_date
%dt %dt Ticket required?
End Date %dd= @conference.tickets.for_registration.any? ? 'Yes' : 'No'
%dd
= @registration_period.end_date .row
.col-md-12
%p
If you would like to require a ticket purchase for registration, at least
one
= link_to 'ticket', admin_conference_tickets_path(@conference)
must be set as a registration ticket, and the registration process
will not proceed without the purchase (or selection of a free) single
registration ticket.
%p
To make ticketing optional, do not mark any
= link_to 'tickets', admin_conference_tickets_path(@conference)
as registration tickets, and registration can proceed without them.
.row .row
.col-md-12.text-right .col-md-12.text-right
- if @registration_period .btn-group{ role: 'group' }
- if can? :update, @registration_period - if @registration_period
= link_to 'Edit', edit_admin_conference_registration_period_path, class: 'btn btn-primary' - if can? :update, @registration_period
- if can? :destroy, @registration_period = link_to 'Edit', edit_admin_conference_registration_period_path,
= link_to 'Delete', admin_conference_registration_period_path, class: 'btn btn-primary'
method: :delete, data: { confirm: 'Are you sure?' }, class: 'btn btn-danger' - if can? :destroy, @registration_period
- else = link_to 'Delete', admin_conference_registration_period_path,
- if @conference.tickets.for_registration.empty? method: :delete, data: { confirm: 'Are you sure?' },
.h3.text-left class: 'btn btn-danger'
No Registration Tickets! - elsif can? :create, @conference.build_registration_period
%small = link_to 'New Registration Period',
= link_to 'Create registration tickets', new_admin_conference_ticket_path new_admin_conference_registration_period_path,
before creating the registration period. class: 'btn btn-primary'
- else
- if can? :create, @conference.build_registration_period
= link_to 'New Registration Period', new_admin_conference_registration_period_path, class: 'btn btn-primary'

View file

@ -1,4 +1,16 @@
- headers = ['Name', 'Email'] - headers = ['Attended',
'Name',
'Nickname',
'Affilιation',
'Email',
'Arrival',
'Departure']
= CSV.generate_line headers = CSV.generate_line headers
- @registrations.each do |registration| - @registrations.each do |registration|
= CSV.generate_line([registration.name, registration.email]) = CSV.generate_line([registration.attended ? 'X' : '',
registration.name,
registration.nickname,
registration.affiliation,
registration.email,
registration.arrival.to_s,
registration.departure.to_s])

View file

@ -1,5 +1,3 @@
= javascript_include_tag 'Chart.min'
.row .row
.col-md-12 .col-md-12
.page-header .page-header
@ -14,10 +12,12 @@
%p.text-muted %p.text-muted
All the people who registered to your event All the people who registered to your event
.col-md-4 .col-md-4
= render partial: 'admin/conferences/doughnut_chart', locals: {title: 'Affiliation', data: @affiliation_distribution} = render 'donut_chart', title: 'Affiliation',
combined_data: @affiliation_distribution
- unless @conference.pending? - unless @conference.pending?
.col-md-4 .col-md-4
= render partial: 'admin/conferences/doughnut_chart', locals: {title: 'Attended registrations', data: @registration_distribution} = render 'donut_chart', title: 'Attended registrations',
combined_data: @registration_distribution
.row .row
.col-md-12 .col-md-12
%div.margin-event-table %div.margin-event-table

View file

@ -27,10 +27,14 @@
%td %td
= link_to event.title, edit_admin_conference_program_event_path(@conference.short_title, event) = link_to event.title, edit_admin_conference_program_event_path(@conference.short_title, event)
%br %br
.small - if(event.speakers.any?)
(Presented by .small
= speaker_links(event) (Presented by
) = speaker_links(event)
)
- else
.small
(No speaker)
- %w(registered biographies commercials subtitle difficulty_level).each do |info| - %w(registered biographies commercials subtitle difficulty_level).each do |info|
%td{'data-order' => "#{progress_status[info]}"} %td{'data-order' => "#{progress_status[info]}"}

View file

@ -18,4 +18,8 @@
%td= event.id %td= event.id
%td= link_to event.title, edit_admin_conference_program_event_path(@conference.short_title, event) %td= link_to event.title, edit_admin_conference_program_event_path(@conference.short_title, event)
%td %td
= speaker_links(event) - if(event.speakers.any?)
= speaker_links(event)
- else
.small
(No speaker)

View file

@ -1,30 +1,29 @@
- cache [:admin, @conference, @program, :schedule, event] do - cells_length = event.event_type.length / @program.schedule_interval
- cells_length = event.event_type.length / @program.schedule_interval / this height fits the room cells
/ this height fits the room cells - compact_grid = @program.schedule_interval < 15
- compact_grid = @program.schedule_interval < 15 - single_cell_height = compact_grid ? 32 : 58
- single_cell_height = compact_grid ? 32 : 58 - height = (cells_length * single_cell_height)
- height = (cells_length * single_cell_height) - height -= 23 unless compact_grid
- height -= 23 unless compact_grid / 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)
- 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} #{'non_schedulable' if non_schedulable}" }
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 %b
%b = link_to(event.id, admin_conference_program_event_path(@conference, event))
= link_to(event.id, admin_conference_program_event_path(@conference, event)) = event.speakers.collect(&:name).to_sentence
= event.speakers.collect(&:name).to_sentence = ':'
= ':' = event.title
= event.title - if event.difficulty_level
- if event.difficulty_level %span.label.label-default= event.difficulty_level.title
%span.label.label-default= event.difficulty_level.title - if event.event_type
- if event.event_type %span.label.label-default= event.event_type.title
%span.label.label-default= event.event_type.title - if event.track
- if event.track %span.label.label-default= event.track.short_name
%span.label.label-default= event.track.short_name

View file

@ -8,6 +8,13 @@
.col-md-12 .col-md-12
= f.inputs name: 'Components' do = f.inputs name: 'Components' do
%ul.fa-ul %ul.fa-ul
%li
%th
%button.btn.btn-default#select-all{ type: "button" }
Select All
%th
%button.btn.btn-default#unselect-all{ type: "button" }
Unselect All
%li %li
= f.input :include_cfp, label: 'Display call for papers and call for tracks, while open', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_cfp) } = f.input :include_cfp, label: 'Display call for papers and call for tracks, while open', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_cfp) }
%li %li
@ -17,7 +24,7 @@
%li %li
= f.input :include_tracks, label: 'Include confirmed tracks', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_tracks) } = f.input :include_tracks, label: 'Include confirmed tracks', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_tracks) }
%li %li
= f.input :include_booths, label: 'Include confirmed booths', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_booths) } = f.input :include_booths, label: "Include confirmed #{(t'booth').pluralize}", input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_booths) }
%li %li
= f.input :include_registrations, label: 'Display the registration period', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_registrations) } = f.input :include_registrations, label: 'Display the registration period', input_html: { checked: params[:action] == 'new' || @splashpage.try(:include_registrations) }
@ -45,3 +52,15 @@
.col-md-12 .col-md-12
%p.text-right %p.text-right
= f.submit 'Save Changes', class: 'btn btn-primary' = f.submit 'Save Changes', class: 'btn btn-primary'
:javascript
$(document).ready(function(){
$('#select-all').click(function(event) {
var parent = $(this).parents('.inputs:last');
parent.find('.input.checkbox input[type=checkbox]').prop('checked',true);
});
$('#unselect-all').click(function(event) {
var parent = $(this).parents('.inputs:last');
parent.find('.input.checkbox input[type=checkbox]').prop('checked',false);
});
});

View file

@ -26,7 +26,7 @@
Include confirmed tracks Include confirmed tracks
%li %li
%i{ class: "fa-li #{icon_for_todo @splashpage.include_booths?}" } %i{ class: "fa-li #{icon_for_todo @splashpage.include_booths?}" }
Include confirmed booths Include confirmed #{(t'booth').pluralize}
%li %li
%i{ class: "fa-li #{icon_for_todo @splashpage.include_registrations?}" } %i{ class: "fa-li #{icon_for_todo @splashpage.include_registrations?}" }
Display the registration period Display the registration period

View file

@ -10,7 +10,7 @@
.col-md-8 .col-md-8
= semantic_form_for(@sponsor, url: (@sponsor.new_record? ? admin_conference_sponsors_path : admin_conference_sponsor_path(@conference.short_title, @sponsor))) do |f| = semantic_form_for(@sponsor, url: (@sponsor.new_record? ? admin_conference_sponsors_path : admin_conference_sponsor_path(@conference.short_title, @sponsor))) do |f|
= f.input :name, input_html: { autofocus: true } = f.input :name, input_html: { autofocus: true }
= f.input :description = f.input :description, input_html: { rows: 5, cols: 20, data: { provide: 'markdown-editable' } }, hint: markdown_hint
= image_tag f.object.picture.thumb.url if f.object.picture? = image_tag f.object.picture.thumb.url if f.object.picture?
= f.input :picture = f.input :picture
= f.input :website_url = f.input :website_url

View file

@ -24,7 +24,7 @@
%td %td
= sponsor.name = sponsor.name
%td %td
= truncate(sponsor.description) = truncate(markdown(sponsor.description))
%td %td
= sponsor.website_url = sponsor.website_url
%td %td

View file

@ -1,6 +1,3 @@
= javascript_include_tag "//www.google.com/jsapi", "chartkick"
= javascript_include_tag 'chartkick'
= bar_chart @survey.survey_questions.map{ |q| [q.title, q.survey_replies.count] } = bar_chart @survey.survey_questions.map{ |q| [q.title, q.survey_replies.count] }
- @survey.survey_questions.each.with_index(1) do |survey_question, question_index| - @survey.survey_questions.each.with_index(1) do |survey_question, question_index|

View file

@ -12,8 +12,8 @@
= f.input :name, input_html: { autofocus: true } = f.input :name, input_html: { autofocus: true }
= 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 :start_date, as: :string, input_html: { id: 'registration-period-start-datepicker', start_date: @conference.start_date, end_date: @conference.end_date, 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? } = f.input :end_date, as: :string, input_html: { id: 'registration-period-end-datepicker', required: @track.self_organized_and_accepted_or_confirmed? }
- if @conference.venue.try(:rooms).present? - if @conference.venue.try(:rooms).present?
= 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? } = 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 - else

View file

@ -6,12 +6,12 @@
Confirmed? Confirmed?
- if can? :toggle_confirmation, @user - if can? :toggle_confirmation, @user
= check_box_tag @user.id, @user.id, @user.confirmed?, = check_box_tag @user.id, @user.id, @user.confirmed?,
url: "/admin/users/#{@user.id}/toggle_confirmation?user[to_confirm]=", url: "#{toggle_confirmation_admin_user_path(@user.id)}?user[to_confirm]=",
class: 'switch-checkbox', class: 'switch-checkbox',
readonly: false readonly: false
- else - else
= check_box_tag @user.id, @user.id, @user.confirmed?, = check_box_tag @user.id, @user.id, @user.confirmed?,
url: "/admin/users/#{@user.id}/toggle_confirmation?user[to_confirm]=", url: "#{toggle_confirmation_admin_user_path(@user.id)}?user[to_confirm]=",
class: 'switch-checkbox', class: 'switch-checkbox',
readonly: true readonly: true
= f.input :is_admin, hint: 'An admin can create a new conference, manage users and make other users admins.' = f.input :is_admin, hint: 'An admin can create a new conference, manage users and make other users admins.'

View file

@ -36,12 +36,12 @@
%td %td
- if can? :toggle_confirmation, @user - if can? :toggle_confirmation, @user
= check_box_tag @user.id, @user.id, @user.confirmed?, = check_box_tag @user.id, @user.id, @user.confirmed?,
url: "/admin/users/#{@user.id}/toggle_confirmation?user[to_confirm]=", url: "#{toggle_confirmation_admin_user_path(@user)}?user[to_confirm]=",
class: 'switch-checkbox', class: 'switch-checkbox',
readonly: false readonly: false
- else - else
= check_box_tag @user.id, @user.id, @user.confirmed?, = check_box_tag @user.id, @user.id, @user.confirmed?,
url: "/admin/users/#{@user.id}/toggle_confirmation?user[to_confirm]=", url: "#{toggle_confirmation_admin_user_path(@user)}?user[to_confirm]=",
class: 'switch-checkbox', class: 'switch-checkbox',
readonly: true readonly: true
- else - else

View file

@ -79,8 +79,8 @@
= link_to (current_or_last_object_state('Event', object.event_id).try(:title) || 'deleted'), = link_to (current_or_last_object_state('Event', object.event_id).try(:title) || 'deleted'),
admin_conference_program_event_path(conference_short_title, object.event_id) admin_conference_program_event_path(conference_short_title, object.event_id)
in in
= link_to "Schedule #{event_schedule.schedule_id}", = link_to "Schedule #{version.item.schedule_id}",
admin_conference_schedule_path(conference_short_title, event_schedule.schedule_id) admin_conference_schedule_path(conference_short_title, version.item.schedule_id)
- when 'Schedule' - when 'Schedule'
= link_if_alive version, "Schedule #{version.item_id}", = link_if_alive version, "Schedule #{version.item_id}",
@ -102,7 +102,7 @@
conference conference
- when 'Booth' - when 'Booth'
= 'booth' = t 'booth'
= link_if_alive version, object.title, = link_if_alive version, object.title,
admin_conference_booth_path(conference_id: Conference.find(version.conference_id).short_title, id: version.item_id ), admin_conference_booth_path(conference_id: Conference.find(version.conference_id).short_title, id: version.item_id ),
conference conference

View file

@ -0,0 +1,16 @@
:ruby
combined_data ||= {}
data ||= chart_values(combined_data)
colors ||= chart_colors(combined_data)
options = {
donut: true,
legend: 'bottom',
download: true,
messages: { empty: 'No data' }
}
options[:colors] = colors if colors.present?
.text-center
%h4= title
= pie_chart data, options

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