Compare commits
133 Commits
maintenanc
...
master
Author | SHA1 | Date |
---|---|---|
Petko Bordjukov | deebcbc95a | |
Tocho Tochev | 5660c3ef53 | |
Petko Bordjukov | 71e8ab74da | |
Petko Bordjukov | 89dd1890fd | |
Petko Bordjukov | 1018b93b11 | |
Tocho Tochev | 8cd4a4856d | |
Tocho Tochev | 0cffe052c8 | |
Tocho Tochev | 6af2d09896 | |
Tocho Tochev | ef5935bd85 | |
Tocho Tochev | 10e68f3453 | |
Petko Bordjukov | 5bbe601110 | |
Petko Bordjukov | 89438b474b | |
Petko Bordjukov | 7a64633ac0 | |
Petko Bordjukov | 6171e484cc | |
Petko Bordjukov | 2bacd84654 | |
Petko Bordjukov | fc08089796 | |
Petko Bordjukov | 93611a3bd9 | |
Tocho Tochev | 459be53b5c | |
Tocho Tochev | bcac28d4ff | |
Tocho Tochev | 5ff505d246 | |
Tocho Tochev | 87df897fe9 | |
Tocho Tochev | d44738bf58 | |
Tocho Tochev | 486a763277 | |
Tocho Tochev | cd8c3bbcc7 | |
Tocho Tochev | 2180b0ea9f | |
Petko Bordjukov | 1c42261f2a | |
Petko Bordjukov | d123a8c69d | |
Petko Bordjukov | ce6fac9764 | |
Petko Bordjukov | 78c73d273e | |
Petko Bordjukov | 1834beb13d | |
Petko Bordjukov | e461ec504f | |
Petko Bordjukov | 0e0d73cbbd | |
Petko Bordjukov | f43c125e6d | |
Petko Bordjukov | 977e231e14 | |
Petko Bordjukov | 20c7c20633 | |
Petko Bordjukov | 4c96ba1e9c | |
Petko Bordjukov | 281b69e66d | |
Petko Bordjukov | fdd75603f7 | |
Petko Bordjukov | 2ab307bede | |
Petko Bordjukov | 5628650e5b | |
Petko Bordjukov | 28348696c5 | |
Petko Bordjukov | b80eab40cc | |
Petko Bordjukov | 14dacf02c1 | |
Petko Bordjukov | 2aa5891e32 | |
Petko Bordjukov | 19ea5f5880 | |
Tocho Tochev | e71d9c683c | |
Tocho Tochev | 6326500ffe | |
Tocho Tochev | ddc11f4fcc | |
Petko Bordjukov | 2545a294f7 | |
Petko Bordjukov | 72b7787003 | |
Petko Bordjukov | c04be87f53 | |
Petko Bordjukov | 05617add98 | |
Petko Bordjukov | c818f30737 | |
Petko Bordjukov | 0af5523a88 | |
Petko Bordjukov | 76ce1bf861 | |
Petko Bordjukov | 74bd417da3 | |
Vasil Kolev | e6ce449f99 | |
Vasil Kolev | 32861f640d | |
Vasil Kolev | 85b6331c21 | |
Vasil Kolev | 98982b1823 | |
Petko Bordjukov | c34955e106 | |
Ivaylo Markov | 6755ea4b1e | |
Petko Bordjukov | e4f36af7c0 | |
Ivaylo Markov | 2c1b86b720 | |
Petko Bordjukov | 014c88c4e5 | |
Ivaylo Markov | eacd083237 | |
Petko Bordjukov | a95dcc866f | |
Petko Bordjukov | 9dc216f30b | |
Petko Bordjukov | 4e97ad0eaa | |
Petko Bordjukov | de45091c59 | |
Vasil Kolev | b5c88b1f8e | |
Petko Bordjukov | 49b85190f2 | |
Petko Bordjukov | 3dfdbad313 | |
Petko Bordjukov | 41718b9fca | |
Petko Bordjukov | ec34b39699 | |
Petko Bordjukov | ca91ba4255 | |
Petko Bordjukov | cbd69fab5a | |
Petko Bordjukov | f724e58800 | |
Petko Bordjukov | 8daac96d55 | |
Petko Bordjukov | ab8b7102fb | |
Petko Bordjukov | e67f719998 | |
Petko Bordjukov | 7c57ff699d | |
Petko Bordjukov | 23bd2ab334 | |
Petko Bordjukov | eeb92483f3 | |
Petko Bordjukov | f704bdb82f | |
Petko Bordjukov | 35aa246df4 | |
Petko Bordjukov | ed85b96f4d | |
Petko Bordjukov | 9930665156 | |
Petko Bordjukov | 7bb4ba478c | |
Petko Bordjukov | 2d19046d35 | |
Petko Bordjukov | b774cb9b11 | |
Petko Bordjukov | 48c979549f | |
Petko Bordjukov | e97dd3a09f | |
Petko Bordjukov | 4a8ee144c1 | |
Petko Bordjukov | 57db0a548c | |
Petko Bordjukov | 2c36c8c354 | |
Petko Bordjukov | 752c3123d6 | |
Petko Bordjukov | a8d7cde7a1 | |
Petko Bordjukov | e20861689f | |
Petko Bordjukov | 895bf8a5f3 | |
Petko Bordjukov | 992ede0735 | |
Petko Bordjukov | c40f65fade | |
Petko Bordjukov | 9c46c4cf5d | |
Petko Bordjukov | 6f627d34d6 | |
Petko Bordjukov | c95a0c8d4b | |
Petko Bordjukov | e6b16ed1ae | |
Petko Bordjukov | c073cf56ca | |
Petko Bordjukov | b40c6ae877 | |
Petko Bordjukov | 52dc663119 | |
Petko Bordjukov | 32b1b1c458 | |
Petko Bordjukov | e0abfa5253 | |
Petko Bordjukov | d284eb3e2b | |
Petko Bordjukov | 0d7571d637 | |
Petko Bordjukov | 77e93809f6 | |
Petko Bordjukov | 69f4c4dc26 | |
Petko Bordjukov | a7c9c83e02 | |
Petko Bordjukov | eacc973cf2 | |
Petko Bordjukov | 88de288029 | |
Petko Bordjukov | 6ab333edf7 | |
Petko Bordjukov | fffcd8db2c | |
Petko Bordjukov | e2217d4d6e | |
Petko Bordjukov | f4afa949d5 | |
Petko Bordjukov | d727f0e4d4 | |
Petko Bordjukov | d56c489f16 | |
Petko Bordjukov | 26d6c868b5 | |
Petko Bordjukov | 8444015e90 | |
Petko Bordjukov | 62b4fc4456 | |
Petko Bordjukov | db85a64686 | |
Petko Bordjukov | 9848898695 | |
Petko Bordjukov | 09440ba9c5 | |
Petko Bordjukov | 20787bcfb3 | |
Petko Bordjukov | 34c2532141 | |
Petko Bordjukov | 8adfd721df |
|
@ -0,0 +1,43 @@
|
|||
# See https://docs.docker.com/engine/reference/builder/#dockerignore-file for more about ignoring files.
|
||||
|
||||
# Ignore git directory.
|
||||
/.git/
|
||||
|
||||
# Ignore bundler config.
|
||||
/.bundle
|
||||
|
||||
# Ignore all environment files (except templates).
|
||||
/.env*
|
||||
!/.env*.erb
|
||||
|
||||
# Ignore all default key files.
|
||||
/config/master.key
|
||||
/config/credentials/*.key
|
||||
|
||||
# Ignore all logfiles and tempfiles.
|
||||
/log/*
|
||||
/tmp/*
|
||||
!/log/.keep
|
||||
!/tmp/.keep
|
||||
|
||||
# Ignore pidfiles, but keep the directory.
|
||||
/tmp/pids/*
|
||||
!/tmp/pids/.keep
|
||||
|
||||
# Ignore storage (uploaded files in development and any SQLite databases).
|
||||
/storage/*
|
||||
!/storage/.keep
|
||||
/tmp/storage/*
|
||||
!/tmp/storage/.keep
|
||||
|
||||
# Ignore assets.
|
||||
/node_modules/
|
||||
/app/assets/builds/*
|
||||
!/app/assets/builds/.keep
|
||||
/public/assets
|
||||
|
||||
# Archives
|
||||
*.tar.gz
|
||||
|
||||
# SQL
|
||||
*.sql
|
|
@ -7,18 +7,29 @@
|
|||
# Ignore bundler config.
|
||||
/.bundle
|
||||
|
||||
# Ignore the default SQLite database.
|
||||
/db/*.sqlite3
|
||||
/db/*.sqlite3-journal
|
||||
# Ignore all environment files (except templates).
|
||||
/.env*
|
||||
!/.env*.erb
|
||||
|
||||
# Ignore all logfiles and tempfiles.
|
||||
/log/*.log
|
||||
/tmp
|
||||
/config/database.yml
|
||||
/config/secrets.yml
|
||||
/db/schema.rb
|
||||
/erd.pdf
|
||||
/public/uploads/tmp/*
|
||||
/public/uploads/personal_profile/*
|
||||
.sass-cache/
|
||||
/coverage/
|
||||
/log/*
|
||||
/tmp/*
|
||||
!/log/.keep
|
||||
!/tmp/.keep
|
||||
|
||||
# Ignore pidfiles, but keep the directory.
|
||||
/tmp/pids/*
|
||||
!/tmp/pids/
|
||||
!/tmp/pids/.keep
|
||||
|
||||
# Ignore storage (uploaded files in development and any SQLite databases).
|
||||
/storage/*
|
||||
!/storage/.keep
|
||||
/tmp/storage/*
|
||||
!/tmp/storage/
|
||||
!/tmp/storage/.keep
|
||||
|
||||
/public/assets
|
||||
|
||||
# Ignore master key for decrypting credentials and more.
|
||||
/config/master.key
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
require: standard
|
||||
|
||||
inherit_gem:
|
||||
standard: config/base.yml
|
||||
|
||||
AllCops:
|
||||
DisabledByDefault: true
|
|
@ -0,0 +1 @@
|
|||
3.3.5
|
13
.travis.yml
13
.travis.yml
|
@ -1,7 +1,16 @@
|
|||
language: ruby
|
||||
dist: xenial
|
||||
cache: bundler
|
||||
rvm:
|
||||
- 2.4.5
|
||||
- 3.3
|
||||
script:
|
||||
- RAILS_ENV=test bundle exec rake --trace bootstrap spec
|
||||
sudo: false
|
||||
addons:
|
||||
chrome: stable
|
||||
apt:
|
||||
packages:
|
||||
- chromium-chromedriver
|
||||
services:
|
||||
- postgresql
|
||||
before_script:
|
||||
- ln -s /usr/lib/chromium-browser/chromedriver ~/bin/chromedriver
|
||||
|
|
22
Capfile
22
Capfile
|
@ -1,8 +1,11 @@
|
|||
# Load DSL and set up stages
|
||||
require 'capistrano/setup'
|
||||
require "capistrano/setup"
|
||||
|
||||
# Include default deployment tasks
|
||||
require 'capistrano/deploy'
|
||||
require "capistrano/deploy"
|
||||
|
||||
require "capistrano/scm/git"
|
||||
install_plugin Capistrano::SCM::Git
|
||||
|
||||
# Include tasks from other gems included in your Gemfile
|
||||
#
|
||||
|
@ -15,16 +18,19 @@ require 'capistrano/deploy'
|
|||
# https://github.com/capistrano/rails
|
||||
# https://github.com/capistrano/passenger
|
||||
#
|
||||
# require 'capistrano/rvm'
|
||||
require 'capistrano/rvm'
|
||||
# require 'capistrano/rbenv'
|
||||
# require 'capistrano/chruby'
|
||||
require 'capistrano/bundler'
|
||||
require 'capistrano/rails/assets'
|
||||
require 'capistrano/rails/migrations'
|
||||
require 'capistrano/puma'
|
||||
require "capistrano/bundler"
|
||||
require "capistrano/rails/assets"
|
||||
require "capistrano/rails/migrations"
|
||||
require "capistrano/puma"
|
||||
install_plugin Capistrano::Puma # Default puma tasks
|
||||
install_plugin Capistrano::Puma::Workers # if you want to control the workers (in cluster mode)
|
||||
install_plugin Capistrano::Puma::Nginx # if you want to upload a nginx site template
|
||||
# require 'capistrano/puma/nginx' # if you want to upload a nginx site template
|
||||
# require 'capistrano/passenger'
|
||||
# require 'capistrano/rvm'
|
||||
|
||||
# Load custom tasks from `lib/capistrano/tasks` if you have any defined
|
||||
Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }
|
||||
Dir.glob("lib/capistrano/tasks/*.rake").each { |r| import r }
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
# syntax = docker/dockerfile:1
|
||||
|
||||
# Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile
|
||||
ARG RUBY_VERSION=3.3.5
|
||||
FROM registry.docker.com/library/ruby:$RUBY_VERSION-slim as base
|
||||
|
||||
# Rails app lives here
|
||||
WORKDIR /rails
|
||||
|
||||
# Set production environment
|
||||
ENV RAILS_ENV="production" \
|
||||
BUNDLE_DEPLOYMENT="1" \
|
||||
BUNDLE_PATH="/usr/local/bundle" \
|
||||
BUNDLE_WITHOUT="development"
|
||||
|
||||
|
||||
# Throw-away build stage to reduce size of final image
|
||||
FROM base as build
|
||||
|
||||
# Install packages needed to build gems
|
||||
RUN apt-get update -qq && \
|
||||
apt-get install --no-install-recommends -y build-essential git libvips pkg-config libpq-dev libsqlite3-dev nodejs yarn
|
||||
|
||||
# Install application gems
|
||||
COPY Gemfile Gemfile.lock ./
|
||||
RUN bundle install && \
|
||||
rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git && \
|
||||
bundle exec bootsnap precompile --gemfile
|
||||
|
||||
# Copy application code
|
||||
COPY . .
|
||||
|
||||
# Precompile bootsnap code for faster boot times
|
||||
RUN bundle exec bootsnap precompile app/ lib/
|
||||
|
||||
# Precompiling assets for production without requiring secret RAILS_MASTER_KEY
|
||||
RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile
|
||||
|
||||
|
||||
# Final stage for app image
|
||||
FROM base
|
||||
|
||||
# Install packages needed for deployment
|
||||
RUN apt-get update -qq && \
|
||||
apt-get install --no-install-recommends -y curl libsqlite3-0 nodejs libpq5 libvips && \
|
||||
rm -rf /var/lib/apt/lists /var/cache/apt/archives
|
||||
|
||||
# Copy built artifacts: gems, application
|
||||
COPY --from=build /usr/local/bundle /usr/local/bundle
|
||||
COPY --from=build /rails /rails
|
||||
|
||||
# Run and own only the runtime files as a non-root user for security
|
||||
RUN useradd rails --create-home --shell /bin/bash && \
|
||||
chown -R rails:rails db log storage tmp
|
||||
USER rails:rails
|
||||
|
||||
# Entrypoint prepares the database.
|
||||
ENTRYPOINT ["/rails/bin/docker-entrypoint"]
|
||||
|
||||
# Start the server by default, this can be overwritten at runtime
|
||||
EXPOSE 80
|
||||
CMD ["./bin/thrust", "./bin/rails", "server", "--early-hints"]
|
119
Gemfile
119
Gemfile
|
@ -1,95 +1,92 @@
|
|||
source 'https://rubygems.org'
|
||||
source "https://rubygems.org"
|
||||
|
||||
gem 'rails', '~> 4.2.11'
|
||||
gem "rails", "~> 7.1.0"
|
||||
gem "bootsnap"
|
||||
gem "sprockets"
|
||||
|
||||
gem 'sqlite3'
|
||||
gem 'pg'
|
||||
gem "sqlite3"
|
||||
gem "pg"
|
||||
|
||||
gem 'sass-rails'
|
||||
gem "sass-rails"
|
||||
|
||||
gem 'uglifier'
|
||||
gem 'coffee-rails'
|
||||
gem 'mini_racer', platforms: :ruby
|
||||
gem 'jquery-rails'
|
||||
gem "uglifier"
|
||||
gem "coffee-rails"
|
||||
gem "jquery-rails"
|
||||
|
||||
gem 'slim-rails'
|
||||
gem "slim-rails"
|
||||
|
||||
gem 'rails-i18n'
|
||||
gem "rails-i18n"
|
||||
|
||||
gem 'devise'
|
||||
gem 'devise-i18n'
|
||||
gem "devise"
|
||||
gem "devise-i18n"
|
||||
|
||||
gem 'simple_form'
|
||||
gem "simple_form"
|
||||
|
||||
# Phone validation
|
||||
gem 'phony_rails'
|
||||
gem "phony"
|
||||
gem "phony_rails"
|
||||
|
||||
# Picture uploads
|
||||
gem 'carrierwave'
|
||||
#gem 'rmagick'
|
||||
gem "mini_magick"
|
||||
gem "puma", group: :production
|
||||
|
||||
gem "refile", require: ['refile/rails', 'refile/simple_form']
|
||||
gem "refile-mini_magick"
|
||||
gem "globalize"
|
||||
|
||||
gem 'puma', group: :production
|
||||
gem "yaml_db"
|
||||
|
||||
gem 'globalize'
|
||||
gem "bootstrap-sass"
|
||||
gem "bootstrap-sass-extras"
|
||||
gem "bootswatch-rails"
|
||||
gem "autoprefixer-rails"
|
||||
gem "font-awesome-sass", "~> 4.6.2"
|
||||
|
||||
gem 'yaml_db'
|
||||
gem "nested_form"
|
||||
gem "jquery-datatables-rails"
|
||||
# gem "morrisjs-rails"
|
||||
gem "raphael-rails"
|
||||
|
||||
gem 'bootstrap-sass'
|
||||
gem 'bootstrap-sass-extras'
|
||||
gem 'bootswatch-rails'
|
||||
gem 'autoprefixer-rails'
|
||||
gem 'font-awesome-sass'
|
||||
gem "copy_carrierwave_file"
|
||||
|
||||
gem 'nested_form'
|
||||
gem 'jquery-datatables-rails'
|
||||
gem 'morrisjs-rails'
|
||||
gem 'raphael-rails'
|
||||
gem "jbuilder"
|
||||
|
||||
gem 'copy_carrierwave_file'
|
||||
gem "search_object"
|
||||
|
||||
gem 'jbuilder'
|
||||
gem "faraday"
|
||||
|
||||
gem 'search_object'
|
||||
gem "rqrcode"
|
||||
|
||||
gem 'faraday'
|
||||
gem "draper"
|
||||
|
||||
gem 'rqrcode'
|
||||
gem "icalendar", require: ['icalendar', 'icalendar/tzinfo']
|
||||
|
||||
group :development do
|
||||
gem 'spring'
|
||||
gem 'spring-commands-rspec'
|
||||
gem 'guard-rspec' # Continuous testing with Guard
|
||||
gem 'rails-erd'
|
||||
gem 'pry-rails'
|
||||
gem "spring"
|
||||
gem "spring-commands-rspec"
|
||||
gem "guard-rspec" # Continuous testing with Guard
|
||||
gem "rails-erd"
|
||||
gem "pry-rails"
|
||||
# gem 'hirb'
|
||||
gem 'awesome_print'
|
||||
gem 'quiet_assets'
|
||||
gem 'capistrano'
|
||||
gem 'capistrano-rails'
|
||||
# gem 'capistrano-rvm'
|
||||
gem 'capistrano3-puma'
|
||||
gem 'better_errors'
|
||||
gem 'binding_of_caller'
|
||||
gem "awesome_print"
|
||||
gem "better_errors"
|
||||
gem "binding_of_caller"
|
||||
end
|
||||
|
||||
group :development, :test do
|
||||
gem 'rspec-rails'
|
||||
gem 'factory_girl_rails'
|
||||
gem 'faker'
|
||||
gem 'capybara'
|
||||
gem 'selenium-webdriver'
|
||||
gem "rspec-rails"
|
||||
gem "faker"
|
||||
gem "capybara"
|
||||
gem "selenium-webdriver"
|
||||
|
||||
gem 'byebug'
|
||||
gem 'simplecov'
|
||||
gem 'i18n-tasks'
|
||||
gem "byebug"
|
||||
gem "simplecov"
|
||||
gem "i18n-tasks"
|
||||
|
||||
gem 'delorean'
|
||||
gem "delorean"
|
||||
|
||||
gem "standard"
|
||||
end
|
||||
|
||||
group :test do
|
||||
gem 'database_cleaner'
|
||||
gem "database_cleaner"
|
||||
gem "factory_bot_rails"
|
||||
end
|
||||
|
||||
gem "thruster", "~> 0.1.8"
|
||||
|
|
773
Gemfile.lock
773
Gemfile.lock
|
@ -1,158 +1,208 @@
|
|||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
actionmailer (4.2.11)
|
||||
actionpack (= 4.2.11)
|
||||
actionview (= 4.2.11)
|
||||
activejob (= 4.2.11)
|
||||
actioncable (7.1.3)
|
||||
actionpack (= 7.1.3)
|
||||
activesupport (= 7.1.3)
|
||||
nio4r (~> 2.0)
|
||||
websocket-driver (>= 0.6.1)
|
||||
zeitwerk (~> 2.6)
|
||||
actionmailbox (7.1.3)
|
||||
actionpack (= 7.1.3)
|
||||
activejob (= 7.1.3)
|
||||
activerecord (= 7.1.3)
|
||||
activestorage (= 7.1.3)
|
||||
activesupport (= 7.1.3)
|
||||
mail (>= 2.7.1)
|
||||
net-imap
|
||||
net-pop
|
||||
net-smtp
|
||||
actionmailer (7.1.3)
|
||||
actionpack (= 7.1.3)
|
||||
actionview (= 7.1.3)
|
||||
activejob (= 7.1.3)
|
||||
activesupport (= 7.1.3)
|
||||
mail (~> 2.5, >= 2.5.4)
|
||||
rails-dom-testing (~> 1.0, >= 1.0.5)
|
||||
actionpack (4.2.11)
|
||||
actionview (= 4.2.11)
|
||||
activesupport (= 4.2.11)
|
||||
rack (~> 1.6)
|
||||
rack-test (~> 0.6.2)
|
||||
rails-dom-testing (~> 1.0, >= 1.0.5)
|
||||
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
||||
actionview (4.2.11)
|
||||
activesupport (= 4.2.11)
|
||||
net-imap
|
||||
net-pop
|
||||
net-smtp
|
||||
rails-dom-testing (~> 2.2)
|
||||
actionpack (7.1.3)
|
||||
actionview (= 7.1.3)
|
||||
activesupport (= 7.1.3)
|
||||
nokogiri (>= 1.8.5)
|
||||
racc
|
||||
rack (>= 2.2.4)
|
||||
rack-session (>= 1.0.1)
|
||||
rack-test (>= 0.6.3)
|
||||
rails-dom-testing (~> 2.2)
|
||||
rails-html-sanitizer (~> 1.6)
|
||||
actiontext (7.1.3)
|
||||
actionpack (= 7.1.3)
|
||||
activerecord (= 7.1.3)
|
||||
activestorage (= 7.1.3)
|
||||
activesupport (= 7.1.3)
|
||||
globalid (>= 0.6.0)
|
||||
nokogiri (>= 1.8.5)
|
||||
actionview (7.1.3)
|
||||
activesupport (= 7.1.3)
|
||||
builder (~> 3.1)
|
||||
erubis (~> 2.7.0)
|
||||
rails-dom-testing (~> 1.0, >= 1.0.5)
|
||||
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
||||
activejob (4.2.11)
|
||||
activesupport (= 4.2.11)
|
||||
globalid (>= 0.3.0)
|
||||
activemodel (4.2.11)
|
||||
activesupport (= 4.2.11)
|
||||
erubi (~> 1.11)
|
||||
rails-dom-testing (~> 2.2)
|
||||
rails-html-sanitizer (~> 1.6)
|
||||
activejob (7.1.3)
|
||||
activesupport (= 7.1.3)
|
||||
globalid (>= 0.3.6)
|
||||
activemodel (7.1.3)
|
||||
activesupport (= 7.1.3)
|
||||
activemodel-serializers-xml (1.0.2)
|
||||
activemodel (> 5.x)
|
||||
activesupport (> 5.x)
|
||||
builder (~> 3.1)
|
||||
activerecord (4.2.11)
|
||||
activemodel (= 4.2.11)
|
||||
activesupport (= 4.2.11)
|
||||
arel (~> 6.0)
|
||||
activesupport (4.2.11)
|
||||
i18n (~> 0.7)
|
||||
minitest (~> 5.1)
|
||||
thread_safe (~> 0.3, >= 0.3.4)
|
||||
tzinfo (~> 1.1)
|
||||
addressable (2.5.2)
|
||||
public_suffix (>= 2.0.2, < 4.0)
|
||||
airbrussh (1.1.1)
|
||||
sshkit (>= 1.6.1, != 1.7.0)
|
||||
arel (6.0.4)
|
||||
ast (2.3.0)
|
||||
autoprefixer-rails (6.5.1)
|
||||
execjs
|
||||
awesome_print (1.7.0)
|
||||
bcrypt (3.1.11)
|
||||
better_errors (2.1.1)
|
||||
coderay (>= 1.0.0)
|
||||
erubis (>= 2.6.6)
|
||||
activerecord (7.1.3)
|
||||
activemodel (= 7.1.3)
|
||||
activesupport (= 7.1.3)
|
||||
timeout (>= 0.4.0)
|
||||
activestorage (7.1.3)
|
||||
actionpack (= 7.1.3)
|
||||
activejob (= 7.1.3)
|
||||
activerecord (= 7.1.3)
|
||||
activesupport (= 7.1.3)
|
||||
marcel (~> 1.0)
|
||||
activesupport (7.1.3)
|
||||
base64
|
||||
bigdecimal
|
||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||
connection_pool (>= 2.2.5)
|
||||
drb
|
||||
i18n (>= 1.6, < 2)
|
||||
minitest (>= 5.1)
|
||||
mutex_m
|
||||
tzinfo (~> 2.0)
|
||||
addressable (2.8.6)
|
||||
public_suffix (>= 2.0.2, < 6.0)
|
||||
ast (2.4.2)
|
||||
autoprefixer-rails (10.4.16.0)
|
||||
execjs (~> 2)
|
||||
awesome_print (1.9.2)
|
||||
base64 (0.2.0)
|
||||
bcrypt (3.1.20)
|
||||
better_errors (2.10.1)
|
||||
erubi (>= 1.0.0)
|
||||
rack (>= 0.9.0)
|
||||
binding_of_caller (0.7.2)
|
||||
rouge (>= 1.0.0)
|
||||
better_html (2.0.2)
|
||||
actionview (>= 6.0)
|
||||
activesupport (>= 6.0)
|
||||
ast (~> 2.0)
|
||||
erubi (~> 1.4)
|
||||
parser (>= 2.4)
|
||||
smart_properties
|
||||
bigdecimal (3.1.6)
|
||||
binding_of_caller (1.0.0)
|
||||
debug_inspector (>= 0.0.1)
|
||||
bootstrap-sass (3.3.7)
|
||||
bootsnap (1.18.3)
|
||||
msgpack (~> 1.2)
|
||||
bootstrap-sass (3.4.1)
|
||||
autoprefixer-rails (>= 5.2.1)
|
||||
sass (>= 3.3.4)
|
||||
bootstrap-sass-extras (0.0.7)
|
||||
sassc (>= 2.0.0)
|
||||
bootstrap-sass-extras (0.1.0)
|
||||
rails (>= 3.1.0)
|
||||
bootswatch-rails (3.3.5)
|
||||
railties (>= 3.1)
|
||||
builder (3.2.3)
|
||||
byebug (10.0.2)
|
||||
capistrano (3.6.1)
|
||||
airbrussh (>= 1.0.0)
|
||||
capistrano-harrow
|
||||
i18n
|
||||
rake (>= 10.0.0)
|
||||
sshkit (>= 1.9.0)
|
||||
capistrano-bundler (1.2.0)
|
||||
capistrano (~> 3.1)
|
||||
sshkit (~> 1.2)
|
||||
capistrano-harrow (0.5.3)
|
||||
capistrano-rails (1.1.8)
|
||||
capistrano (~> 3.1)
|
||||
capistrano-bundler (~> 1.1)
|
||||
capistrano3-puma (1.2.1)
|
||||
capistrano (~> 3.0)
|
||||
puma (>= 2.6)
|
||||
capybara (3.10.1)
|
||||
builder (3.2.4)
|
||||
byebug (11.1.3)
|
||||
capybara (3.40.0)
|
||||
addressable
|
||||
matrix
|
||||
mini_mime (>= 0.1.3)
|
||||
nokogiri (~> 1.8)
|
||||
nokogiri (~> 1.11)
|
||||
rack (>= 1.6.0)
|
||||
rack-test (>= 0.6.3)
|
||||
regexp_parser (~> 1.2)
|
||||
regexp_parser (>= 1.5, < 3.0)
|
||||
xpath (~> 3.2)
|
||||
carrierwave (0.11.2)
|
||||
activemodel (>= 3.2.0)
|
||||
activesupport (>= 3.2.0)
|
||||
json (>= 1.7)
|
||||
mime-types (>= 1.16)
|
||||
mimemagic (>= 0.3.0)
|
||||
childprocess (0.9.0)
|
||||
ffi (~> 1.0, >= 1.0.11)
|
||||
carrierwave (3.0.5)
|
||||
activemodel (>= 6.0.0)
|
||||
activesupport (>= 6.0.0)
|
||||
addressable (~> 2.6)
|
||||
image_processing (~> 1.1)
|
||||
marcel (~> 1.0.0)
|
||||
ssrf_filter (~> 1.0)
|
||||
choice (0.2.0)
|
||||
chronic (0.10.2)
|
||||
chunky_png (1.3.8)
|
||||
coderay (1.1.1)
|
||||
coffee-rails (4.2.1)
|
||||
chunky_png (1.4.0)
|
||||
coderay (1.1.3)
|
||||
coffee-rails (5.0.0)
|
||||
coffee-script (>= 2.2.0)
|
||||
railties (>= 4.0.0, < 5.2.x)
|
||||
railties (>= 5.2.0)
|
||||
coffee-script (2.4.1)
|
||||
coffee-script-source
|
||||
execjs
|
||||
coffee-script-source (1.10.0)
|
||||
concurrent-ruby (1.1.4)
|
||||
coffee-script-source (1.12.2)
|
||||
concurrent-ruby (1.2.3)
|
||||
connection_pool (2.4.1)
|
||||
copy_carrierwave_file (1.3.0)
|
||||
carrierwave (>= 0.9)
|
||||
crass (1.0.4)
|
||||
database_cleaner (1.7.0)
|
||||
debug_inspector (0.0.2)
|
||||
crass (1.0.6)
|
||||
database_cleaner (2.0.2)
|
||||
database_cleaner-active_record (>= 2, < 3)
|
||||
database_cleaner-active_record (2.1.0)
|
||||
activerecord (>= 5.a)
|
||||
database_cleaner-core (~> 2.0.0)
|
||||
database_cleaner-core (2.0.1)
|
||||
date (3.3.4)
|
||||
debug_inspector (1.2.0)
|
||||
delorean (2.1.0)
|
||||
chronic
|
||||
devise (4.2.0)
|
||||
devise (4.9.3)
|
||||
bcrypt (~> 3.0)
|
||||
orm_adapter (~> 0.1)
|
||||
railties (>= 4.1.0, < 5.1)
|
||||
railties (>= 4.1.0)
|
||||
responders
|
||||
warden (~> 1.2.3)
|
||||
devise-i18n (1.1.0)
|
||||
diff-lcs (1.3)
|
||||
docile (1.1.5)
|
||||
domain_name (0.5.20160826)
|
||||
unf (>= 0.0.5, < 1.0.0)
|
||||
easy_translate (0.5.0)
|
||||
json
|
||||
thread
|
||||
thread_safe
|
||||
erubis (2.7.0)
|
||||
execjs (2.7.0)
|
||||
factory_girl (4.7.0)
|
||||
activesupport (>= 3.0.0)
|
||||
factory_girl_rails (4.7.0)
|
||||
factory_girl (~> 4.7.0)
|
||||
railties (>= 3.0.0)
|
||||
faker (1.6.6)
|
||||
i18n (~> 0.5)
|
||||
faraday (0.9.2)
|
||||
multipart-post (>= 1.2, < 3)
|
||||
ffi (1.10.0)
|
||||
devise-i18n (1.12.0)
|
||||
devise (>= 4.9.0)
|
||||
diff-lcs (1.5.1)
|
||||
docile (1.4.0)
|
||||
draper (4.0.2)
|
||||
actionpack (>= 5.0)
|
||||
activemodel (>= 5.0)
|
||||
activemodel-serializers-xml (>= 1.0)
|
||||
activesupport (>= 5.0)
|
||||
request_store (>= 1.0)
|
||||
ruby2_keywords
|
||||
drb (2.2.0)
|
||||
ruby2_keywords
|
||||
erubi (1.12.0)
|
||||
execjs (2.9.1)
|
||||
factory_bot (6.4.6)
|
||||
activesupport (>= 5.0.0)
|
||||
factory_bot_rails (6.4.3)
|
||||
factory_bot (~> 6.4)
|
||||
railties (>= 5.0.0)
|
||||
faker (3.2.3)
|
||||
i18n (>= 1.8.11, < 2)
|
||||
faraday (2.9.0)
|
||||
faraday-net_http (>= 2.0, < 3.2)
|
||||
faraday-net_http (3.1.0)
|
||||
net-http
|
||||
ffi (1.16.3)
|
||||
font-awesome-sass (4.6.2)
|
||||
sass (>= 3.2)
|
||||
formatador (0.2.5)
|
||||
globalid (0.4.1)
|
||||
activesupport (>= 4.2.0)
|
||||
globalize (5.0.1)
|
||||
activemodel (>= 4.2.0, < 4.3)
|
||||
activerecord (>= 4.2.0, < 4.3)
|
||||
guard (2.14.0)
|
||||
formatador (1.1.0)
|
||||
globalid (1.2.1)
|
||||
activesupport (>= 6.1)
|
||||
globalize (6.3.0)
|
||||
activemodel (>= 4.2, < 7.2)
|
||||
activerecord (>= 4.2, < 7.2)
|
||||
request_store (~> 1.0)
|
||||
guard (2.18.1)
|
||||
formatador (>= 0.2.4)
|
||||
listen (>= 2.7, < 4.0)
|
||||
lumberjack (~> 1.0)
|
||||
lumberjack (>= 1.0.12, < 2.0)
|
||||
nenv (~> 0.1)
|
||||
notiffany (~> 0.0)
|
||||
pry (>= 0.9.12)
|
||||
pry (>= 0.13.0)
|
||||
shellany (~> 0.0)
|
||||
thor (>= 0.18.1)
|
||||
guard-compat (1.2.1)
|
||||
|
@ -160,241 +210,309 @@ GEM
|
|||
guard (~> 2.1)
|
||||
guard-compat (~> 1.1)
|
||||
rspec (>= 2.99.0, < 4.0)
|
||||
highline (1.7.8)
|
||||
http-cookie (1.0.3)
|
||||
domain_name (~> 0.5)
|
||||
i18n (0.9.5)
|
||||
highline (3.0.1)
|
||||
i18n (1.14.1)
|
||||
concurrent-ruby (~> 1.0)
|
||||
i18n-tasks (0.9.5)
|
||||
i18n-tasks (1.0.13)
|
||||
activesupport (>= 4.0.2)
|
||||
ast (>= 2.1.0)
|
||||
easy_translate (>= 0.5.0)
|
||||
erubis
|
||||
highline (>= 1.7.3)
|
||||
better_html (>= 1.0, < 3.0)
|
||||
erubi
|
||||
highline (>= 2.0.0)
|
||||
i18n
|
||||
parser (>= 2.2.3.0)
|
||||
term-ansicolor (>= 1.3.2)
|
||||
parser (>= 3.2.2.1)
|
||||
rails-i18n
|
||||
rainbow (>= 2.2.2, < 4.0)
|
||||
terminal-table (>= 1.5.1)
|
||||
jbuilder (2.6.0)
|
||||
activesupport (>= 3.0.0, < 5.1)
|
||||
multi_json (~> 1.2)
|
||||
icalendar (2.10.1)
|
||||
ice_cube (~> 0.16)
|
||||
ice_cube (0.16.4)
|
||||
image_processing (1.12.2)
|
||||
mini_magick (>= 4.9.5, < 5)
|
||||
ruby-vips (>= 2.0.17, < 3)
|
||||
io-console (0.7.2)
|
||||
irb (1.11.2)
|
||||
rdoc
|
||||
reline (>= 0.4.2)
|
||||
jbuilder (2.11.5)
|
||||
actionview (>= 5.0.0)
|
||||
activesupport (>= 5.0.0)
|
||||
jquery-datatables-rails (3.4.0)
|
||||
actionpack (>= 3.1)
|
||||
jquery-rails
|
||||
railties (>= 3.1)
|
||||
sass-rails
|
||||
jquery-rails (4.2.1)
|
||||
jquery-rails (4.6.0)
|
||||
rails-dom-testing (>= 1, < 3)
|
||||
railties (>= 4.2.0)
|
||||
thor (>= 0.14, < 2.0)
|
||||
json (2.1.0)
|
||||
libv8 (6.7.288.46.1)
|
||||
listen (3.1.5)
|
||||
rb-fsevent (~> 0.9, >= 0.9.4)
|
||||
rb-inotify (~> 0.9, >= 0.9.7)
|
||||
ruby_dep (~> 1.2)
|
||||
loofah (2.2.3)
|
||||
json (2.7.1)
|
||||
language_server-protocol (3.17.0.3)
|
||||
lint_roller (1.1.0)
|
||||
listen (3.8.0)
|
||||
rb-fsevent (~> 0.10, >= 0.10.3)
|
||||
rb-inotify (~> 0.9, >= 0.9.10)
|
||||
loofah (2.22.0)
|
||||
crass (~> 1.0.2)
|
||||
nokogiri (>= 1.5.9)
|
||||
lumberjack (1.0.10)
|
||||
mail (2.7.1)
|
||||
nokogiri (>= 1.12.0)
|
||||
lumberjack (1.2.10)
|
||||
mail (2.8.1)
|
||||
mini_mime (>= 0.1.1)
|
||||
method_source (0.8.2)
|
||||
mime-types (2.99.3)
|
||||
mimemagic (0.3.2)
|
||||
mini_magick (4.5.1)
|
||||
mini_mime (1.0.1)
|
||||
mini_portile2 (2.4.0)
|
||||
mini_racer (0.2.4)
|
||||
libv8 (>= 6.3)
|
||||
minitest (5.11.3)
|
||||
morrisjs-rails (0.5.1)
|
||||
railties (> 3.1, < 5)
|
||||
multi_json (1.12.1)
|
||||
multipart-post (2.0.0)
|
||||
net-imap
|
||||
net-pop
|
||||
net-smtp
|
||||
marcel (1.0.2)
|
||||
matrix (0.4.2)
|
||||
method_source (1.0.0)
|
||||
mini_magick (4.12.0)
|
||||
mini_mime (1.1.5)
|
||||
mini_portile2 (2.8.5)
|
||||
minitest (5.22.2)
|
||||
msgpack (1.7.2)
|
||||
mutex_m (0.2.0)
|
||||
nenv (0.3.0)
|
||||
nested_form (0.3.2)
|
||||
net-scp (1.2.1)
|
||||
net-ssh (>= 2.6.5)
|
||||
net-ssh (3.2.0)
|
||||
netrc (0.11.0)
|
||||
nokogiri (1.10.0)
|
||||
mini_portile2 (~> 2.4.0)
|
||||
notiffany (0.1.1)
|
||||
net-http (0.4.1)
|
||||
uri
|
||||
net-imap (0.4.10)
|
||||
date
|
||||
net-protocol
|
||||
net-pop (0.1.2)
|
||||
net-protocol
|
||||
net-protocol (0.2.2)
|
||||
timeout
|
||||
net-smtp (0.4.0.1)
|
||||
net-protocol
|
||||
nio4r (2.7.0)
|
||||
nokogiri (1.16.2)
|
||||
mini_portile2 (~> 2.8.2)
|
||||
racc (~> 1.4)
|
||||
notiffany (0.1.3)
|
||||
nenv (~> 0.1)
|
||||
shellany (~> 0.0)
|
||||
orm_adapter (0.5.0)
|
||||
parser (2.3.1.4)
|
||||
ast (~> 2.2)
|
||||
pg (0.19.0)
|
||||
phony (2.15.32)
|
||||
phony_rails (0.14.4)
|
||||
parallel (1.24.0)
|
||||
parser (3.3.0.5)
|
||||
ast (~> 2.4.1)
|
||||
racc
|
||||
pg (1.5.5)
|
||||
phony (2.20.12)
|
||||
phony_rails (0.15.0)
|
||||
activesupport (>= 3.0)
|
||||
phony (~> 2.15)
|
||||
pry (0.10.4)
|
||||
coderay (~> 1.1.0)
|
||||
method_source (~> 0.8.1)
|
||||
slop (~> 3.4)
|
||||
pry-rails (0.3.4)
|
||||
pry (>= 0.9.10)
|
||||
public_suffix (3.0.3)
|
||||
puma (3.10.0)
|
||||
quiet_assets (1.1.0)
|
||||
railties (>= 3.1, < 5.0)
|
||||
rack (1.6.11)
|
||||
rack-protection (1.5.5)
|
||||
rack
|
||||
rack-test (0.6.3)
|
||||
rack (>= 1.0)
|
||||
rails (4.2.11)
|
||||
actionmailer (= 4.2.11)
|
||||
actionpack (= 4.2.11)
|
||||
actionview (= 4.2.11)
|
||||
activejob (= 4.2.11)
|
||||
activemodel (= 4.2.11)
|
||||
activerecord (= 4.2.11)
|
||||
activesupport (= 4.2.11)
|
||||
bundler (>= 1.3.0, < 2.0)
|
||||
railties (= 4.2.11)
|
||||
sprockets-rails
|
||||
rails-deprecated_sanitizer (1.0.3)
|
||||
activesupport (>= 4.2.0.alpha)
|
||||
rails-dom-testing (1.0.9)
|
||||
activesupport (>= 4.2.0, < 5.0)
|
||||
nokogiri (~> 1.6)
|
||||
rails-deprecated_sanitizer (>= 1.0.1)
|
||||
rails-erd (1.5.0)
|
||||
activerecord (>= 3.2)
|
||||
activesupport (>= 3.2)
|
||||
phony (>= 2.18.12)
|
||||
pry (0.14.2)
|
||||
coderay (~> 1.1)
|
||||
method_source (~> 1.0)
|
||||
pry-rails (0.3.9)
|
||||
pry (>= 0.10.4)
|
||||
psych (5.1.2)
|
||||
stringio
|
||||
public_suffix (5.0.4)
|
||||
puma (6.4.2)
|
||||
nio4r (~> 2.0)
|
||||
racc (1.7.3)
|
||||
rack (3.0.9)
|
||||
rack-session (2.0.0)
|
||||
rack (>= 3.0.0)
|
||||
rack-test (2.1.0)
|
||||
rack (>= 1.3)
|
||||
rackup (2.1.0)
|
||||
rack (>= 3)
|
||||
webrick (~> 1.8)
|
||||
rails (7.1.3)
|
||||
actioncable (= 7.1.3)
|
||||
actionmailbox (= 7.1.3)
|
||||
actionmailer (= 7.1.3)
|
||||
actionpack (= 7.1.3)
|
||||
actiontext (= 7.1.3)
|
||||
actionview (= 7.1.3)
|
||||
activejob (= 7.1.3)
|
||||
activemodel (= 7.1.3)
|
||||
activerecord (= 7.1.3)
|
||||
activestorage (= 7.1.3)
|
||||
activesupport (= 7.1.3)
|
||||
bundler (>= 1.15.0)
|
||||
railties (= 7.1.3)
|
||||
rails-dom-testing (2.2.0)
|
||||
activesupport (>= 5.0.0)
|
||||
minitest
|
||||
nokogiri (>= 1.6)
|
||||
rails-erd (1.7.2)
|
||||
activerecord (>= 4.2)
|
||||
activesupport (>= 4.2)
|
||||
choice (~> 0.2.0)
|
||||
ruby-graphviz (~> 1.2)
|
||||
rails-html-sanitizer (1.0.4)
|
||||
loofah (~> 2.2, >= 2.2.2)
|
||||
rails-i18n (4.0.9)
|
||||
i18n (~> 0.7)
|
||||
railties (~> 4.0)
|
||||
railties (4.2.11)
|
||||
actionpack (= 4.2.11)
|
||||
activesupport (= 4.2.11)
|
||||
rake (>= 0.8.7)
|
||||
thor (>= 0.18.1, < 2.0)
|
||||
rake (12.3.2)
|
||||
rails-html-sanitizer (1.6.0)
|
||||
loofah (~> 2.21)
|
||||
nokogiri (~> 1.14)
|
||||
rails-i18n (7.0.8)
|
||||
i18n (>= 0.7, < 2)
|
||||
railties (>= 6.0.0, < 8)
|
||||
railties (7.1.3)
|
||||
actionpack (= 7.1.3)
|
||||
activesupport (= 7.1.3)
|
||||
irb
|
||||
rackup (>= 1.0.0)
|
||||
rake (>= 12.2)
|
||||
thor (~> 1.0, >= 1.2.2)
|
||||
zeitwerk (~> 2.6)
|
||||
rainbow (3.1.1)
|
||||
rake (13.1.0)
|
||||
raphael-rails (2.1.2)
|
||||
rb-fsevent (0.9.7)
|
||||
rb-inotify (0.9.7)
|
||||
ffi (>= 0.5.0)
|
||||
refile (0.6.2)
|
||||
mime-types
|
||||
rest-client (~> 1.8)
|
||||
sinatra (~> 1.4.5)
|
||||
refile-mini_magick (0.2.0)
|
||||
mini_magick (~> 4.0)
|
||||
refile (~> 0.5)
|
||||
regexp_parser (1.2.0)
|
||||
responders (2.3.0)
|
||||
railties (>= 4.2.0, < 5.1)
|
||||
rest-client (1.8.0)
|
||||
http-cookie (>= 1.0.2, < 2.0)
|
||||
mime-types (>= 1.16, < 3.0)
|
||||
netrc (~> 0.7)
|
||||
rqrcode (0.10.1)
|
||||
rb-fsevent (0.11.2)
|
||||
rb-inotify (0.10.1)
|
||||
ffi (~> 1.0)
|
||||
rdoc (6.6.2)
|
||||
psych (>= 4.0.0)
|
||||
regexp_parser (2.9.0)
|
||||
reline (0.4.2)
|
||||
io-console (~> 0.5)
|
||||
request_store (1.6.0)
|
||||
rack (>= 1.4)
|
||||
responders (3.1.1)
|
||||
actionpack (>= 5.2)
|
||||
railties (>= 5.2)
|
||||
rexml (3.2.6)
|
||||
rouge (4.2.0)
|
||||
rqrcode (2.2.0)
|
||||
chunky_png (~> 1.0)
|
||||
rspec (3.5.0)
|
||||
rspec-core (~> 3.5.0)
|
||||
rspec-expectations (~> 3.5.0)
|
||||
rspec-mocks (~> 3.5.0)
|
||||
rspec-core (3.5.4)
|
||||
rspec-support (~> 3.5.0)
|
||||
rspec-expectations (3.5.0)
|
||||
rqrcode_core (~> 1.0)
|
||||
rqrcode_core (1.2.0)
|
||||
rspec (3.13.0)
|
||||
rspec-core (~> 3.13.0)
|
||||
rspec-expectations (~> 3.13.0)
|
||||
rspec-mocks (~> 3.13.0)
|
||||
rspec-core (3.13.0)
|
||||
rspec-support (~> 3.13.0)
|
||||
rspec-expectations (3.13.0)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.5.0)
|
||||
rspec-mocks (3.5.0)
|
||||
rspec-support (~> 3.13.0)
|
||||
rspec-mocks (3.13.0)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.5.0)
|
||||
rspec-rails (3.5.2)
|
||||
actionpack (>= 3.0)
|
||||
activesupport (>= 3.0)
|
||||
railties (>= 3.0)
|
||||
rspec-core (~> 3.5.0)
|
||||
rspec-expectations (~> 3.5.0)
|
||||
rspec-mocks (~> 3.5.0)
|
||||
rspec-support (~> 3.5.0)
|
||||
rspec-support (3.5.0)
|
||||
ruby-graphviz (1.2.2)
|
||||
ruby_dep (1.5.0)
|
||||
rubyzip (1.2.2)
|
||||
sass (3.4.22)
|
||||
sass-rails (5.0.6)
|
||||
railties (>= 4.0.0, < 6)
|
||||
sass (~> 3.1)
|
||||
sprockets (>= 2.8, < 4.0)
|
||||
sprockets-rails (>= 2.0, < 4.0)
|
||||
tilt (>= 1.1, < 3)
|
||||
search_object (1.1.1)
|
||||
selenium-webdriver (3.141.0)
|
||||
childprocess (~> 0.5)
|
||||
rubyzip (~> 1.2, >= 1.2.2)
|
||||
rspec-support (~> 3.13.0)
|
||||
rspec-rails (6.1.1)
|
||||
actionpack (>= 6.1)
|
||||
activesupport (>= 6.1)
|
||||
railties (>= 6.1)
|
||||
rspec-core (~> 3.12)
|
||||
rspec-expectations (~> 3.12)
|
||||
rspec-mocks (~> 3.12)
|
||||
rspec-support (~> 3.12)
|
||||
rspec-support (3.13.0)
|
||||
rubocop (1.60.2)
|
||||
json (~> 2.3)
|
||||
language_server-protocol (>= 3.17.0)
|
||||
parallel (~> 1.10)
|
||||
parser (>= 3.3.0.2)
|
||||
rainbow (>= 2.2.2, < 4.0)
|
||||
regexp_parser (>= 1.8, < 3.0)
|
||||
rexml (>= 3.2.5, < 4.0)
|
||||
rubocop-ast (>= 1.30.0, < 2.0)
|
||||
ruby-progressbar (~> 1.7)
|
||||
unicode-display_width (>= 2.4.0, < 3.0)
|
||||
rubocop-ast (1.30.0)
|
||||
parser (>= 3.2.1.0)
|
||||
rubocop-performance (1.20.2)
|
||||
rubocop (>= 1.48.1, < 2.0)
|
||||
rubocop-ast (>= 1.30.0, < 2.0)
|
||||
ruby-graphviz (1.2.5)
|
||||
rexml
|
||||
ruby-progressbar (1.13.0)
|
||||
ruby-vips (2.2.0)
|
||||
ffi (~> 1.12)
|
||||
ruby2_keywords (0.0.5)
|
||||
rubyzip (2.3.2)
|
||||
sass (3.7.4)
|
||||
sass-listen (~> 4.0.0)
|
||||
sass-listen (4.0.0)
|
||||
rb-fsevent (~> 0.9, >= 0.9.4)
|
||||
rb-inotify (~> 0.9, >= 0.9.7)
|
||||
sass-rails (6.0.0)
|
||||
sassc-rails (~> 2.1, >= 2.1.1)
|
||||
sassc (2.4.0)
|
||||
ffi (~> 1.9)
|
||||
sassc-rails (2.1.2)
|
||||
railties (>= 4.0.0)
|
||||
sassc (>= 2.0)
|
||||
sprockets (> 3.0)
|
||||
sprockets-rails
|
||||
tilt
|
||||
search_object (1.2.5)
|
||||
selenium-webdriver (4.18.1)
|
||||
base64 (~> 0.2)
|
||||
rexml (~> 3.2, >= 3.2.5)
|
||||
rubyzip (>= 1.2.2, < 3.0)
|
||||
websocket (~> 1.0)
|
||||
shellany (0.0.1)
|
||||
simple_form (3.3.1)
|
||||
actionpack (> 4, < 5.1)
|
||||
activemodel (> 4, < 5.1)
|
||||
simplecov (0.12.0)
|
||||
docile (~> 1.1.0)
|
||||
json (>= 1.8, < 3)
|
||||
simplecov-html (~> 0.10.0)
|
||||
simplecov-html (0.10.0)
|
||||
sinatra (1.4.7)
|
||||
rack (~> 1.5)
|
||||
rack-protection (~> 1.4)
|
||||
tilt (>= 1.3, < 3)
|
||||
slim (3.0.7)
|
||||
temple (~> 0.7.6)
|
||||
tilt (>= 1.3.3, < 2.1)
|
||||
slim-rails (3.1.1)
|
||||
simple_form (5.3.0)
|
||||
actionpack (>= 5.2)
|
||||
activemodel (>= 5.2)
|
||||
simplecov (0.22.0)
|
||||
docile (~> 1.1)
|
||||
simplecov-html (~> 0.11)
|
||||
simplecov_json_formatter (~> 0.1)
|
||||
simplecov-html (0.12.3)
|
||||
simplecov_json_formatter (0.1.4)
|
||||
slim (5.2.1)
|
||||
temple (~> 0.10.0)
|
||||
tilt (>= 2.1.0)
|
||||
slim-rails (3.6.3)
|
||||
actionpack (>= 3.1)
|
||||
railties (>= 3.1)
|
||||
slim (~> 3.0)
|
||||
slop (3.6.0)
|
||||
spring (2.0.0)
|
||||
activesupport (>= 4.2)
|
||||
slim (>= 3.0, < 6.0, != 5.0.0)
|
||||
smart_properties (1.17.0)
|
||||
spring (4.1.3)
|
||||
spring-commands-rspec (1.0.4)
|
||||
spring (>= 0.9.1)
|
||||
sprockets (3.7.2)
|
||||
sprockets (4.2.1)
|
||||
concurrent-ruby (~> 1.0)
|
||||
rack (> 1, < 3)
|
||||
sprockets-rails (3.2.1)
|
||||
actionpack (>= 4.0)
|
||||
activesupport (>= 4.0)
|
||||
rack (>= 2.2.4, < 4)
|
||||
sprockets-rails (3.4.2)
|
||||
actionpack (>= 5.2)
|
||||
activesupport (>= 5.2)
|
||||
sprockets (>= 3.0.0)
|
||||
sqlite3 (1.3.12)
|
||||
sshkit (1.11.3)
|
||||
net-scp (>= 1.1.2)
|
||||
net-ssh (>= 2.8.0)
|
||||
temple (0.7.7)
|
||||
term-ansicolor (1.4.0)
|
||||
tins (~> 1.0)
|
||||
terminal-table (1.7.3)
|
||||
unicode-display_width (~> 1.1.1)
|
||||
thor (0.20.3)
|
||||
thread (0.2.2)
|
||||
thread_safe (0.3.6)
|
||||
tilt (2.0.5)
|
||||
tins (1.12.0)
|
||||
tzinfo (1.2.5)
|
||||
thread_safe (~> 0.1)
|
||||
uglifier (3.0.2)
|
||||
sqlite3 (1.7.2)
|
||||
mini_portile2 (~> 2.8.0)
|
||||
ssrf_filter (1.1.2)
|
||||
standard (1.34.0)
|
||||
language_server-protocol (~> 3.17.0.2)
|
||||
lint_roller (~> 1.0)
|
||||
rubocop (~> 1.60)
|
||||
standard-custom (~> 1.0.0)
|
||||
standard-performance (~> 1.3)
|
||||
standard-custom (1.0.2)
|
||||
lint_roller (~> 1.0)
|
||||
rubocop (~> 1.50)
|
||||
standard-performance (1.3.1)
|
||||
lint_roller (~> 1.1)
|
||||
rubocop-performance (~> 1.20.2)
|
||||
stringio (3.1.0)
|
||||
temple (0.10.3)
|
||||
terminal-table (3.0.2)
|
||||
unicode-display_width (>= 1.1.1, < 3)
|
||||
thor (1.3.0)
|
||||
thruster (0.1.8)
|
||||
tilt (2.3.0)
|
||||
timeout (0.4.1)
|
||||
tzinfo (2.0.6)
|
||||
concurrent-ruby (~> 1.0)
|
||||
uglifier (4.2.0)
|
||||
execjs (>= 0.3.0, < 3)
|
||||
unf (0.1.4)
|
||||
unf_ext
|
||||
unf_ext (0.0.7.2)
|
||||
unicode-display_width (1.1.1)
|
||||
warden (1.2.6)
|
||||
rack (>= 1.0)
|
||||
unicode-display_width (2.5.0)
|
||||
uri (0.13.0)
|
||||
warden (1.2.9)
|
||||
rack (>= 2.0.9)
|
||||
webrick (1.8.1)
|
||||
websocket (1.2.10)
|
||||
websocket-driver (0.7.6)
|
||||
websocket-extensions (>= 0.1.0)
|
||||
websocket-extensions (0.1.5)
|
||||
xpath (3.2.0)
|
||||
nokogiri (~> 1.8)
|
||||
yaml_db (0.4.2)
|
||||
rails (>= 3.0, < 5.1)
|
||||
yaml_db (0.7.0)
|
||||
rails (>= 3.0)
|
||||
rake (>= 0.8.7)
|
||||
zeitwerk (2.6.13)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
@ -404,46 +522,40 @@ DEPENDENCIES
|
|||
awesome_print
|
||||
better_errors
|
||||
binding_of_caller
|
||||
bootsnap
|
||||
bootstrap-sass
|
||||
bootstrap-sass-extras
|
||||
bootswatch-rails
|
||||
byebug
|
||||
capistrano
|
||||
capistrano-rails
|
||||
capistrano3-puma
|
||||
capybara
|
||||
carrierwave
|
||||
coffee-rails
|
||||
copy_carrierwave_file
|
||||
database_cleaner
|
||||
delorean
|
||||
devise
|
||||
devise-i18n
|
||||
factory_girl_rails
|
||||
draper
|
||||
factory_bot_rails
|
||||
faker
|
||||
faraday
|
||||
font-awesome-sass
|
||||
font-awesome-sass (~> 4.6.2)
|
||||
globalize
|
||||
guard-rspec
|
||||
i18n-tasks
|
||||
icalendar
|
||||
jbuilder
|
||||
jquery-datatables-rails
|
||||
jquery-rails
|
||||
mini_magick
|
||||
mini_racer
|
||||
morrisjs-rails
|
||||
nested_form
|
||||
pg
|
||||
phony
|
||||
phony_rails
|
||||
pry-rails
|
||||
puma
|
||||
quiet_assets
|
||||
rails (~> 4.2.11)
|
||||
rails (~> 7.1.0)
|
||||
rails-erd
|
||||
rails-i18n
|
||||
raphael-rails
|
||||
refile
|
||||
refile-mini_magick
|
||||
rqrcode
|
||||
rspec-rails
|
||||
sass-rails
|
||||
|
@ -454,9 +566,12 @@ DEPENDENCIES
|
|||
slim-rails
|
||||
spring
|
||||
spring-commands-rspec
|
||||
sprockets
|
||||
sqlite3
|
||||
standard
|
||||
thruster (~> 0.1.8)
|
||||
uglifier
|
||||
yaml_db
|
||||
|
||||
BUNDLED WITH
|
||||
1.17.1
|
||||
2.5.6
|
||||
|
|
14
Guardfile
14
Guardfile
|
@ -1,18 +1,20 @@
|
|||
# More info at https://github.com/guard/guard#readme
|
||||
|
||||
guard :rspec, cmd: 'spring rspec' do
|
||||
guard :rspec, cmd: "spring rspec" do
|
||||
watch(%r{^spec/.+_spec\.rb$})
|
||||
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
||||
watch('spec/spec_helper.rb') { 'spec' }
|
||||
watch('spec/rails_helper.rb') { 'spec' }
|
||||
watch("spec/spec_helper.rb") { "spec" }
|
||||
watch("spec/rails_helper.rb") { "spec" }
|
||||
|
||||
watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
||||
watch(%r{^app/(.*)(\.erb|\.haml|\.slim)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
|
||||
watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
|
||||
watch(%r{^spec/support/(.+)\.rb$}) { 'spec' }
|
||||
watch('config/routes.rb') { 'spec/routing' }
|
||||
watch('app/controllers/application_controller.rb') { 'spec/controllers' }
|
||||
watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
|
||||
watch("config/routes.rb") { "spec/routing" }
|
||||
watch("app/controllers/application_controller.rb") { "spec/controllers" }
|
||||
|
||||
# Capybara features specs
|
||||
watch(%r{^app/views/(.+)/.*\.(erb|haml|slim)$}) { |m| "spec/features/#{m[1]}_spec.rb" }
|
||||
|
||||
notification :off
|
||||
end
|
||||
|
|
34
README.md
34
README.md
|
@ -1,11 +1,31 @@
|
|||
Clarion
|
||||
=======
|
||||
# Clarion
|
||||
|
||||
A CfP automation system for OpenFest.
|
||||
|
||||
Installation
|
||||
------------
|
||||
## Installation
|
||||
|
||||
1. `git clone https://github.com/ignisf/clarion.git`
|
||||
2. Run `bundle install; bin/rake bootstrap`
|
||||
3. You can now run the rails server with `bin/rails s`
|
||||
### For local development
|
||||
|
||||
1. `git clone https://git.openfest.org/Site/clarion/`
|
||||
2. Run `rvm install "ruby-$(cat .ruby-version)"; rvm install "ruby-$(cat .ruby-version)"`
|
||||
3. Start up postgresql
|
||||
4. Run `bundle install; bin/rake bootstrap`
|
||||
5. You can now run the rails server with `bin/rails s`
|
||||
|
||||
### For production
|
||||
|
||||
`docker build -t clarion:latest -f Dockerfile .`
|
||||
|
||||
Note that the docker image contains a default user (for credentials see `db/seeds.rb`).
|
||||
|
||||
### docker-compose
|
||||
|
||||
`docker-compose up` will bring everything up on `http://127.0.0.1:3000` with production configuration.
|
||||
|
||||
## Initial Usage
|
||||
|
||||
1. Go to `http://127.0.0.1:3000/management/`
|
||||
2. Login (for initial creds see `db/seeds.rb`)
|
||||
3. Change the credentials
|
||||
4. Create a conference.
|
||||
- NB: When creating a conference make sure to use the same `domain` as the one you are currently using, otherwise nothing will be shown.
|
||||
|
|
2
Rakefile
2
Rakefile
|
@ -1,6 +1,6 @@
|
|||
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
||||
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
|
||||
|
||||
require File.expand_path('../config/application', __FILE__)
|
||||
require File.expand_path("../config/application", __FILE__)
|
||||
|
||||
Rails.application.load_tasks
|
||||
|
|
15
TODO
15
TODO
|
@ -1,14 +1,14 @@
|
|||
- User-facing:
|
||||
- Event proposal: lecture, workshop, open space (CRUD)
|
||||
- Volunteership
|
||||
- # Event proposal: lecture, workshop, open space (CRUD)
|
||||
- # Volunteership
|
||||
- Sponsorship
|
||||
|
||||
- Admin:
|
||||
- # Create a conference, halls, tracks
|
||||
- # Starting a CFP
|
||||
- # conferences#show -> admin dashboard
|
||||
- volunteers#index -> approved volunteers
|
||||
- sponsorships#index -> generate token, links to send around
|
||||
- # volunteers#index -> approved volunteers
|
||||
- # sponsorships#index -> generate token, links to send around
|
||||
- scheduling -> calendar with events
|
||||
|
||||
- # proposals#index -> undecided events, grouped by user
|
||||
|
@ -17,12 +17,11 @@
|
|||
- users:
|
||||
- # edit profile: image upload and stuff
|
||||
- # show profile
|
||||
- Edit profiles instead
|
||||
- # Edit profiles instead
|
||||
|
||||
- Home-area user CRUD
|
||||
- # Home-area user CRUD
|
||||
- # Controller before_action that checks for current_conference
|
||||
- Devise view styling
|
||||
- # Devise view styling
|
||||
|
||||
Notes:
|
||||
- .row > .col-lg-12 -> put that outside of the "yield"?
|
||||
- human_attribute_name -> create a short alias?
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
//= link_tree ../images
|
||||
//= link_tree ../../../lib/initfest/assets/images
|
||||
//= link_directory ../javascripts .js
|
||||
//= link_directory ../stylesheets .css
|
||||
//= link initfest/application.css
|
||||
//= link initfest/application.js
|
Binary file not shown.
After Width: | Height: | Size: 2.8 KiB |
|
@ -0,0 +1,37 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
height="665"
|
||||
width="1185"
|
||||
id="svg4"
|
||||
version="1.1"
|
||||
viewBox="0 0 1185 665"
|
||||
role="img"
|
||||
class="svg-inline--fa fa-user-secret fa-w-14"
|
||||
data-icon="user-secret"
|
||||
data-prefix="fas"
|
||||
focusable="false"
|
||||
aria-hidden="true">
|
||||
<metadata
|
||||
id="metadata10">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs8" />
|
||||
<path
|
||||
style="fill:currentColor"
|
||||
id="path2"
|
||||
d="m 752.4,384.79271 23.9,-62.6 c 4,-10.5 -3.7,-21.7 -15,-21.7 h -58.5 c 11,-18.9 17.8,-40.6 17.8,-64 v -0.3 c 39.2,-7.8 64,-19.1 64,-31.7 0,-13.3 -27.3,-25.1 -70.1,-33 -9.2,-32.8 -27,-65.8 -40.6,-82.799998 -9.5,-11.9 -25.9,-15.6 -39.5,-8.8 l -27.6,13.8 c -9,4.5 -19.6,4.5 -28.6,0 l -27.6,-13.8 c -13.6,-6.8 -30,-3.1 -39.5,8.8 -13.5,16.999998 -31.4,49.999998 -40.6,82.799998 -42.7,7.9 -70,19.7 -70,33 0,12.6 24.8,23.9 64,31.7 v 0.3 c 0,23.4 6.8,45.1 17.8,64 h -57.5 c -11.5,0 -19.2,11.7 -14.7,22.3 l 25.8,60.2 c -40.1,23.3 -67.4,66.2 -67.4,115.9 v 44.8 c 0,24.7 20.1,44.8 44.8,44.8 h 358.4 c 24.7,0 44.8,-20.1 44.8,-44.8 v -44.8 c 0,-48.4 -25.8,-90.4 -64.1,-114.1 z m -207.9,171.7 -41.6,-192 49.6,32 24,40 z m 96,0 -32,-120 24,-40 49.6,-32 z m 41.7,-298.5 c -3.9,11.9 -7,24.6 -16.5,33.4 -10.1,9.3 -48,22.4 -64,-25 -2.8,-8.4 -15.4,-8.4 -18.3,0 -17,50.2 -56,32.4 -64,25 -9.5,-8.8 -12.7,-21.5 -16.5,-33.4 -0.8,-2.5 -6.3,-5.7 -6.3,-5.8 v -10.8 c 28.3,3.6 61,5.8 96,5.8 35,0 67.7,-2.1 96,-5.8 v 10.8 c -0.1,0.1 -5.6,3.2 -6.4,5.8 z" />
|
||||
</svg>
|
After Width: | Height: | Size: 1.9 KiB |
|
@ -3,6 +3,5 @@
|
|||
//= require jquery_nested_form
|
||||
//= require bootstrap-sprockets
|
||||
//= require raphael
|
||||
//= require morris
|
||||
//= require chroma-js/chroma
|
||||
//= require_directory .
|
||||
|
|
|
@ -22,6 +22,10 @@ th.action, td.action {
|
|||
}
|
||||
}
|
||||
|
||||
th.main {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.conference-title {
|
||||
display: inline-block;
|
||||
@include button-size($padding-base-vertical, $padding-base-horizontal, $font-size-base, $line-height-base, $btn-border-radius-base);
|
||||
|
|
|
@ -1,24 +1,10 @@
|
|||
.speaker-profile {
|
||||
@extend .col-sm-offset-2;
|
||||
@extend .col-sm-8;
|
||||
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.profile-image {
|
||||
@extend .img-thumbnail;
|
||||
max-width: 171px;
|
||||
max-height: 180px;
|
||||
}
|
||||
|
||||
.social {
|
||||
@extend .btn-group;
|
||||
margin-top: 10px;
|
||||
|
||||
a {
|
||||
@extend .btn;
|
||||
@extend .btn-default;
|
||||
}
|
||||
}
|
||||
.panel .panel-image img {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
max-height: 250px;
|
||||
height: auto;
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
width: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
@import "bootstrap";
|
||||
@import "bootswatch/simplex/bootswatch";
|
||||
|
||||
@import "morris";
|
||||
/* @import "morris"; */
|
||||
|
||||
@import "users";
|
||||
@import "colors";
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
class Api::ConferencesController < Api::ApplicationController
|
||||
include ::PublicApiExposing
|
||||
|
||||
def index
|
||||
@conferences = Conference.all
|
||||
fresh_when @conferences
|
||||
end
|
||||
end
|
|
@ -1,9 +1,10 @@
|
|||
class Api::EventTypesController < Api::ApplicationController
|
||||
include ::CurrentConferenceAssigning
|
||||
include ::PublicApiExposing
|
||||
before_filter :require_current_conference!
|
||||
before_action :require_current_conference!
|
||||
|
||||
def index
|
||||
@event_types = current_conference.event_types.includes(:translations)
|
||||
fresh_when @event_types
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
class Api::EventsController < Api::ApplicationController
|
||||
include ::CurrentConferenceAssigning
|
||||
include ::PublicApiExposing
|
||||
before_filter :require_current_conference!
|
||||
before_action :require_current_conference!
|
||||
|
||||
def index
|
||||
@events = current_conference.events.approved.joins(:proposition).includes(:participations)
|
||||
end
|
||||
|
||||
def halfnarp_friendly
|
||||
@events = current_conference.events.includes(:track, :event_type)
|
||||
render json: @events, include: [:track, :event_type]
|
||||
@events = current_conference.events.joins(:proposition).includes(:track, :event_type).where.not(propositions: {status: :rejected})
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
class Api::HallsController < Api::ApplicationController
|
||||
include ::CurrentConferenceAssigning
|
||||
include ::PublicApiExposing
|
||||
before_filter :require_current_conference!
|
||||
before_action :require_current_conference!
|
||||
|
||||
def index
|
||||
@halls = current_conference.halls
|
||||
fresh_when @halls
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
class Api::SchedulesController < Api::ApplicationController
|
||||
include ::CurrentConferenceAssigning
|
||||
include ::PublicApiExposing
|
||||
before_action :require_current_conference!
|
||||
|
||||
def show
|
||||
@halls = Conference.last.halls.includes(:translations, slots: {approved_event: [:participants_with_personal_profiles, :proposition]})
|
||||
end
|
||||
end
|
|
@ -1,9 +1,11 @@
|
|||
class Api::SlotsController < Api::ApplicationController
|
||||
include ::CurrentConferenceAssigning
|
||||
include ::PublicApiExposing
|
||||
before_filter :require_current_conference!
|
||||
before_action :require_current_conference!
|
||||
|
||||
def index
|
||||
@slots = current_conference.slots
|
||||
|
||||
fresh_when @slots
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
class Api::SpeakersController < Api::ApplicationController
|
||||
include ::CurrentConferenceAssigning
|
||||
include ::PublicApiExposing
|
||||
before_filter :require_current_conference!
|
||||
before_action :require_current_conference!
|
||||
|
||||
def index
|
||||
@speakers = PersonalProfile.joins(user: {participations: {event: :proposition}}).where(events: {id: current_conference.approved_events.pluck(:id)}, conference: current_conference).distinct
|
||||
fresh_when @speakers
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
class Api::TracksController < Api::ApplicationController
|
||||
include ::CurrentConferenceAssigning
|
||||
include ::PublicApiExposing
|
||||
before_filter :require_current_conference!
|
||||
before_action :require_current_conference!
|
||||
|
||||
def index
|
||||
@tracks = current_conference.tracks.includes(:translations)
|
||||
fresh_when @tracks
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,15 +4,15 @@ class ApplicationController < ActionController::Base
|
|||
# Prevent CSRF attacks by raising an exception.
|
||||
# For APIs, you may want to use :null_session instead.
|
||||
protect_from_forgery with: :exception
|
||||
before_filter :configure_permitted_parameters, if: :devise_controller?
|
||||
before_action :configure_permitted_parameters, if: :devise_controller?
|
||||
before_action :set_locale
|
||||
before_action :set_view_paths
|
||||
|
||||
# TODO: make this get the domain from the database
|
||||
#layout Proc.new { |controller| controller.request.host }
|
||||
layout 'public/application'
|
||||
# layout Proc.new { |controller| controller.request.host }
|
||||
layout "public/application"
|
||||
|
||||
def self.default_url_options(options={})
|
||||
def self.default_url_options(options = {})
|
||||
if I18n.locale != I18n.default_locale
|
||||
options.merge({locale: I18n.locale})
|
||||
else
|
||||
|
@ -24,17 +24,17 @@ class ApplicationController < ActionController::Base
|
|||
|
||||
def set_locale
|
||||
I18n.locale = params[:locale] || I18n.default_locale
|
||||
if user_signed_in? and current_user.language != I18n.locale
|
||||
if user_signed_in? && (current_user.language != I18n.locale)
|
||||
current_user.update(language: I18n.locale)
|
||||
end
|
||||
end
|
||||
|
||||
def set_view_paths
|
||||
# TODO: make this get the domain from the database
|
||||
prepend_view_path 'lib/initfest/views' if request.host =~ /openfest/
|
||||
prepend_view_path 'lib/initfest/views' if request.host =~ /example/
|
||||
prepend_view_path 'lib/initfest/views' if request.host =~ /127\.0\.0/
|
||||
|
||||
prepend_view_path "lib/initfest/views" if request.host =~ /openfest/
|
||||
prepend_view_path "lib/initfest/views" if request.host =~ /example/
|
||||
prepend_view_path "lib/initfest/views" if request.host =~ /^127\.0\.0/
|
||||
prepend_view_path "lib/initfest/views" if request.host =~ /^localhost$/
|
||||
end
|
||||
|
||||
protected
|
||||
|
|
|
@ -11,8 +11,8 @@ module CurrentConferenceAssigning
|
|||
end
|
||||
|
||||
def current_conference
|
||||
if not @current_conference
|
||||
if @conference and not @conference.new_record?
|
||||
unless @current_conference
|
||||
if @conference && !@conference.new_record?
|
||||
@current_conference = @conference
|
||||
elsif params[:conference_id].present?
|
||||
@current_conference = Conference.find(params[:conference_id])
|
||||
|
@ -23,8 +23,8 @@ module CurrentConferenceAssigning
|
|||
end
|
||||
|
||||
def require_current_conference!
|
||||
if not current_conference?
|
||||
raise ActionController::RoutingError.new('Not Found')
|
||||
unless current_conference?
|
||||
raise ActionController::RoutingError.new("Not Found")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
require 'active_support/concern'
|
||||
require "active_support/concern"
|
||||
|
||||
module PublicApiExposing
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
def set_access_control_headers
|
||||
if request.format.json?
|
||||
response.headers['Access-Control-Allow-Origin'] = '*'
|
||||
response.headers["Access-Control-Allow-Origin"] = "*"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -6,9 +6,9 @@ class ConfirmationsController < Devise::ConfirmationsController
|
|||
if resource.errors.empty?
|
||||
set_flash_message(:notice, :confirmed) if is_flashing_format?
|
||||
sign_in(resource_name, resource)
|
||||
respond_with_navigational(resource){ redirect_to after_confirmation_path_for(resource_name, resource) }
|
||||
respond_with_navigational(resource) { redirect_to after_confirmation_path_for(resource_name, resource) }
|
||||
else
|
||||
respond_with_navigational(resource.errors, status: :unprocessable_entity){ render :new }
|
||||
respond_with_navigational(resource.errors, status: :unprocessable_entity) { render :new }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,12 +2,12 @@ module Management
|
|||
class CallForParticipationsController < ManagementController
|
||||
def create
|
||||
current_conference.call_for_participation.open!
|
||||
redirect_to :back
|
||||
redirect_back fallback_location: [:management, current_conference]
|
||||
end
|
||||
|
||||
def destroy
|
||||
current_conference.call_for_participation.close!
|
||||
redirect_to :back
|
||||
redirect_back fallback_location: [:management, current_conference]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,10 +2,10 @@ module Management
|
|||
class ConferencesController < ManagementController
|
||||
def new
|
||||
@conference = Conference.new
|
||||
@conference.event_types.build(name: 'Event type 1')
|
||||
@conference.tracks.build(name: 'Track 1')
|
||||
@conference.halls.build(name: 'Hall 1')
|
||||
@conference.volunteer_teams.build(name: 'Volunteer Team 1')
|
||||
@conference.event_types.build(name: "Event type 1")
|
||||
@conference.tracks.build(name: "Track 1")
|
||||
@conference.halls.build(name: "Hall 1")
|
||||
@conference.volunteer_teams.build(name: "Volunteer Team 1")
|
||||
end
|
||||
|
||||
def create
|
||||
|
@ -49,13 +49,13 @@ module Management
|
|||
|
||||
begin
|
||||
if @conference.update_vote_data!
|
||||
flash[:notice] = t('.vote_data_successfully_updated')
|
||||
flash[:notice] = t(".vote_data_successfully_updated")
|
||||
else
|
||||
flash[:alert] = t('.error_during_vote_data_save')
|
||||
flash[:alert] = t(".error_during_vote_data_save")
|
||||
end
|
||||
redirect_to :back
|
||||
rescue StandardError => e
|
||||
flash[:alert] = t('.error_during_connection_with_voting_endpoint', error: e.message)
|
||||
redirect_back fallback_location: [:management, @conference]
|
||||
rescue => e
|
||||
flash[:alert] = t(".error_during_connection_with_voting_endpoint", error: e.message)
|
||||
render :vote_results
|
||||
end
|
||||
end
|
||||
|
@ -75,9 +75,9 @@ module Management
|
|||
:title, :email, :start_date, :end_date, :description, :host_name,
|
||||
:planned_cfp_end_date, :vote_data_endpoint,
|
||||
event_types_attributes: [:id, :name, :description, :maximum_length,
|
||||
:minimum_length, :_destroy],
|
||||
:minimum_length, :_destroy,],
|
||||
tracks_attributes: [:id, :name, :color, :css_class, :description,
|
||||
:css_style, :foreground_color, :_destroy],
|
||||
:css_style, :foreground_color, :_destroy,],
|
||||
halls_attributes: [:id, :name, :_destroy],
|
||||
volunteer_teams_attributes: [:id, :name, :description, :color, :_destroy]
|
||||
)
|
||||
|
|
|
@ -2,8 +2,15 @@ module Management
|
|||
class EventsController < ManagementController
|
||||
def index
|
||||
@conference = find_conference
|
||||
@filters = params[:filters] || {}
|
||||
@events = EventSearch.new(scope: Event.where(conference: @conference).eager_load(:participants_with_personal_profiles, :proposition, :proposer, :track, :event_type).preload(:conference), filters: params[:filters]).results
|
||||
@filters = filter_params || {}
|
||||
|
||||
@events = EventSearch
|
||||
.new(scope: Event.where(conference: @conference)
|
||||
.eager_load(:participants_with_personal_profiles,
|
||||
:proposition, :proposer, {track: [:translations]},
|
||||
{event_type: [:translations]}, :feedbacks)
|
||||
.preload(:conference), filters: params[:filters]).results
|
||||
|
||||
# @events = @conference.events.order(:title).includes(:proposition, :proposer, :track, :event_type)
|
||||
end
|
||||
|
||||
|
@ -22,10 +29,10 @@ module Management
|
|||
@event = @conference.events.find(params[:id])
|
||||
|
||||
if @event.update(event_params)
|
||||
flash[:notice] = 'Event was successfully updated.'
|
||||
flash[:notice] = t(".event_successfully_updated")
|
||||
redirect_to [:management, @conference, @event]
|
||||
else
|
||||
render action: 'edit'
|
||||
render action: "edit"
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -46,27 +53,38 @@ module Management
|
|||
private
|
||||
|
||||
def find_conference
|
||||
Conference.find(params[:conference_id])
|
||||
Conference.eager_load({tracks: :translations}, {event_types: :translations}).find(params[:conference_id])
|
||||
end
|
||||
|
||||
def filter_params
|
||||
params.fetch(:filters, {}).permit(
|
||||
:event_type_id,
|
||||
:track_id,
|
||||
:language,
|
||||
:status,
|
||||
:confirmed,
|
||||
:not_confirmed,
|
||||
)
|
||||
end
|
||||
|
||||
def event_params
|
||||
params.require(:event).permit(
|
||||
:title,
|
||||
:subtitle,
|
||||
:length,
|
||||
:language,
|
||||
:abstract,
|
||||
:description,
|
||||
:notes,
|
||||
:track_id,
|
||||
:event_type_id,
|
||||
participations_attributes: [
|
||||
:id,
|
||||
:participant_id,
|
||||
:approved,
|
||||
:_destroy
|
||||
]
|
||||
)
|
||||
:title,
|
||||
:subtitle,
|
||||
:length,
|
||||
:language,
|
||||
:abstract,
|
||||
:description,
|
||||
:notes,
|
||||
:track_id,
|
||||
:event_type_id,
|
||||
participations_attributes: [
|
||||
:id,
|
||||
:participant_id,
|
||||
:approved,
|
||||
:_destroy,
|
||||
]
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
module Management
|
||||
class FeedbackController < ManagementController
|
||||
def index
|
||||
@conference = find_conference
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_conference
|
||||
Conference.find(params[:conference_id])
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,14 +1,18 @@
|
|||
require 'csv'
|
||||
require "csv"
|
||||
module Management
|
||||
class ManagementController < ::ApplicationController
|
||||
before_action :authenticate_user!, :authorize_user!
|
||||
|
||||
layout 'management'
|
||||
layout "management"
|
||||
|
||||
private
|
||||
|
||||
def authorize_user!
|
||||
head :forbidden unless current_user.admin?
|
||||
if params[:conference_id] && params[:conference_id].to_i < Conference.last.id
|
||||
head :forbidden unless current_user.admin? && current_user.owner?
|
||||
else
|
||||
head :forbidden unless current_user.admin?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -10,7 +10,7 @@ module Management
|
|||
@user = find_profile.user
|
||||
|
||||
@user.toggle_admin!
|
||||
redirect_to :back
|
||||
redirect_back fallback_location: {action: :show}
|
||||
end
|
||||
|
||||
def show
|
||||
|
@ -18,7 +18,7 @@ module Management
|
|||
@profile = find_profile
|
||||
@user = @profile.user
|
||||
|
||||
if not @profile
|
||||
unless @profile
|
||||
flash[:error] = "No profile, needs to be created"
|
||||
redirect_to action: :edit
|
||||
end
|
||||
|
@ -36,7 +36,7 @@ module Management
|
|||
@profile = @user.build_personal_profile(@conference, profile_params)
|
||||
|
||||
if @profile.save
|
||||
flash[:notice] = t('.successfully_created')
|
||||
flash[:notice] = t(".successfully_created")
|
||||
redirect_to management_conference_personal_profile_path(@profile, conference_id: @conference.id)
|
||||
else
|
||||
render action: :new
|
||||
|
@ -53,10 +53,10 @@ module Management
|
|||
@conference = find_conference
|
||||
@profile = find_profile
|
||||
|
||||
if @profile.update_attributes(profile_params)
|
||||
if @profile.update(profile_params)
|
||||
redirect_to [:management, @conference, @profile]
|
||||
else
|
||||
render action: 'edit'
|
||||
render action: "edit"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ module Management
|
|||
|
||||
@proposition.update(proposition_params)
|
||||
|
||||
redirect_to :back
|
||||
redirect_back fallback_location: [:management, current_conference, @proposition]
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -3,8 +3,8 @@ module Management
|
|||
include CurrentConferenceAssigning
|
||||
|
||||
def index
|
||||
@filters = params[:filters] || {}
|
||||
@volunteers = VolunteerSearch.new(scope: Volunteer.where(conference: current_conference).eager_load(:volunteer_teams), filters: params[:filters]).results
|
||||
@filters = filter_params || {}
|
||||
@volunteers = VolunteerSearch.new(scope: Volunteer.where(conference: current_conference).eager_load(:volunteer_team), filters: params[:filters]).results
|
||||
end
|
||||
|
||||
def show
|
||||
|
@ -15,6 +15,12 @@ module Management
|
|||
@volunteer = current_conference.volunteers.find(params[:id])
|
||||
end
|
||||
|
||||
def destroy
|
||||
@volunteer = current_conference.volunteers.find(params[:id])
|
||||
@volunteer.destroy!
|
||||
redirect_to management_conference_volunteers_path(conference_id: current_conference.id)
|
||||
end
|
||||
|
||||
def update
|
||||
@volunteer = current_conference.volunteers.find(params[:id])
|
||||
|
||||
|
@ -26,12 +32,18 @@ module Management
|
|||
end
|
||||
|
||||
private
|
||||
|
||||
def filter_params
|
||||
params.fetch(:filters, {}).permit(:volunteer_team_id)
|
||||
end
|
||||
|
||||
def volunteer_params
|
||||
params.require(:volunteer).permit(:name, :picture, :email, :phone,
|
||||
:tshirt_size, :tshirt_cut,
|
||||
:food_preferences, :previous_experience,
|
||||
:notes, :language,
|
||||
volunteer_team_ids: [])
|
||||
:tshirt_size, :tshirt_cut,
|
||||
:food_preferences, :previous_experience,
|
||||
:notes, :language, :terms_accepted,
|
||||
:volunteer_team_id,
|
||||
additional_volunteer_team_ids: [])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
module Public
|
||||
class ApplicationController < ::ApplicationController
|
||||
include ::CurrentConferenceAssigning
|
||||
before_filter :require_current_conference!
|
||||
before_action :require_current_conference!
|
||||
|
||||
def current_conference
|
||||
@current_conference ||= Conference.order(created_at: :desc).find_by(host_name: request.host)
|
||||
|
|
|
@ -2,33 +2,32 @@ class Public::ConferenceFeedbacksController < Public::ApplicationController
|
|||
def index
|
||||
@conference = current_conference
|
||||
@unrated_events = @conference.events
|
||||
.joins(:proposition).approved
|
||||
.joins('LEFT JOIN feedbacks ON feedbacks.feedback_receiving_id = events.id AND feedbacks.feedback_receiving_type = \'Event\'')
|
||||
.where('feedbacks.session_id != ? OR feedbacks.id IS NULL', session.id).distinct
|
||||
.joins(:proposition).approved
|
||||
.joins("LEFT JOIN feedbacks ON feedbacks.feedback_receiving_id = events.id AND feedbacks.feedback_receiving_type = 'Event'")
|
||||
.where("feedbacks.session_id != ? OR feedbacks.id IS NULL", session.id.to_s).distinct
|
||||
|
||||
@rated_events = @conference.events
|
||||
.joins(:proposition).approved
|
||||
.joins(:feedbacks)
|
||||
.where(feedbacks: {session_id: session.id}).distinct
|
||||
|
||||
.joins(:proposition).approved
|
||||
.joins(:feedbacks)
|
||||
.where(feedbacks: {session_id: session.id.to_s}).distinct
|
||||
end
|
||||
|
||||
def new
|
||||
if current_conference.feedbacks.where(session_id: session.id).exists?
|
||||
@feedback = current_conference.feedbacks.where(session_id: session.id).order(updated_at: :asc).last
|
||||
if current_conference.feedbacks.where(session_id: session.id.to_s).exists?
|
||||
@feedback = current_conference.feedbacks.where(session_id: session.id.to_s).order(updated_at: :asc).last
|
||||
else
|
||||
@feedback = current_conference.feedbacks.build
|
||||
@feedback.author_email = Feedback.where(session_id: session.id).order(updated_at: :asc).last.try(:author_email)
|
||||
@feedback.author_email = Feedback.where(session_id: session.id.to_s).order(updated_at: :asc).last.try(:author_email)
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
@feedback = current_conference.feedbacks.build(feedback_params)
|
||||
@feedback.ip_address = request.remote_ip
|
||||
@feedback.session_id = session.id
|
||||
@feedback.session_id = session.id.to_s
|
||||
|
||||
if @feedback.save
|
||||
flash[:notice] = I18n.t('public.conference_feedbacks.new.success')
|
||||
flash[:notice] = I18n.t("public.conference_feedbacks.new.success")
|
||||
redirect_to conference_feedbacks_path
|
||||
else
|
||||
render :new, status: :unprocessable_entity
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
class Public::EventFeedbackQrcodesController < Public::ApplicationController
|
||||
def show
|
||||
event = current_conference.events.joins(:proposition).approved.find(params[:event_id])
|
||||
@qr = RQRCode::QRCode.new(new_event_feedback_url(event_id: event.id), level: :l)
|
||||
event = current_conference.events.joins(:proposition).approved.find(params[:event_id]).decorate
|
||||
|
||||
respond_to do |format|
|
||||
format.svg do
|
||||
render(inline: @qr.as_svg(shape_rendering: 'crispEdges', module_size: 11, fill: 'ffffff', offset: 10),
|
||||
render(inline: event.feedback_qr_code_as_svg,
|
||||
filename: "feedback_qr_code_#{event.id}.svg")
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
class Public::EventFeedbacksController < Public::ApplicationController
|
||||
def new
|
||||
if event.feedbacks.where(session_id: session.id).exists?
|
||||
@feedback = event.feedbacks.where(session_id: session.id).order(updated_at: :asc).last
|
||||
if event.feedbacks.where(session_id: session.id.to_s).exists?
|
||||
@feedback = event.feedbacks.where(session_id: session.id.to_s).order(updated_at: :asc).last
|
||||
else
|
||||
@feedback = event.feedbacks.build
|
||||
@feedback.author_email = Feedback.where(session_id: session.id).order(updated_at: :asc).last.try(:author_email)
|
||||
@feedback.author_email = Feedback.where(session_id: session.id.to_s).order(updated_at: :asc).last.try(:author_email)
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
@feedback = event.feedbacks.build(feedback_params)
|
||||
@feedback.ip_address = request.remote_ip
|
||||
@feedback.session_id = session.id
|
||||
@feedback.session_id = session.id.to_s
|
||||
|
||||
if @feedback.save
|
||||
flash[:notice] = I18n.t('public.event_feedbacks.new.success')
|
||||
flash[:notice] = I18n.t("public.event_feedbacks.new.success")
|
||||
redirect_to conference_feedbacks_path
|
||||
else
|
||||
render :new, status: :unprocessable_entity
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
module Public
|
||||
class EventsController < Public::ApplicationController
|
||||
before_filter :authenticate_user!
|
||||
before_action :authenticate_user!
|
||||
|
||||
def index
|
||||
@events = Event.joins(:conference, :proposition, :participations).where(conference: current_conference).where('propositions.proposer_id = ? OR participations.participant_id = ?', current_user.id, current_user.id)
|
||||
@events = Event.joins(:conference, :proposition, :participations).where(conference: current_conference).where("propositions.proposer_id = ? OR participations.participant_id = ?", current_user.id, current_user.id)
|
||||
end
|
||||
|
||||
def edit
|
||||
|
@ -22,7 +22,7 @@ module Public
|
|||
@event.participations.build participant: current_user, approved: true
|
||||
|
||||
if @event.save
|
||||
flash[:notice] = I18n.t('views.events.event_successfully_created', event_type: @event.event_type.name.mb_chars.downcase)
|
||||
flash[:notice] = I18n.t("views.events.event_successfully_created", event_type: @event.event_type.name.mb_chars.downcase)
|
||||
after_save_redirect
|
||||
else
|
||||
render action: :new
|
||||
|
@ -33,7 +33,7 @@ module Public
|
|||
@event = Event.joins(:participations).find_by(id: params[:id], participations: {participant_id: current_user.id})
|
||||
|
||||
if @event.update(event_params)
|
||||
flash[:notice] = I18n.t('views.events.event_successfully_updated', event_type: @event.event_type.name.mb_chars.downcase)
|
||||
flash[:notice] = I18n.t("views.events.event_successfully_updated", event_type: @event.event_type.name.mb_chars.downcase)
|
||||
after_save_redirect
|
||||
else
|
||||
render action: :edit
|
||||
|
@ -44,9 +44,9 @@ module Public
|
|||
@event = current_user.events.approved.find(params[:id])
|
||||
|
||||
if @event.confirm!
|
||||
flash[:notice] = I18n.t('views.events.successfully_confirmed', event_type: @event.event_type.name.mb_chars.downcase)
|
||||
flash[:notice] = I18n.t("views.events.successfully_confirmed", event_type: @event.event_type.name.mb_chars.downcase)
|
||||
else
|
||||
flash[:alert] = I18n.t('views.events.error_on_confirmation', event_type: @event.event_type.name.mb_chars.downcase)
|
||||
flash[:alert] = I18n.t("views.events.error_on_confirmation", event_type: @event.event_type.name.mb_chars.downcase)
|
||||
end
|
||||
|
||||
after_save_redirect
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
module Public
|
||||
class PersonalProfilesController < Public::ApplicationController
|
||||
before_filter :authenticate_user!
|
||||
before_action :authenticate_user!
|
||||
|
||||
def create
|
||||
@profile = current_user.build_personal_profile(current_conference, profile_params)
|
||||
|
||||
if @profile.save
|
||||
flash[:notice] = t('views.personal_profiles.successfully_created')
|
||||
flash[:notice] = t("views.personal_profiles.successfully_created")
|
||||
redirect_to root_path
|
||||
else
|
||||
render action: :new
|
||||
|
@ -20,11 +20,11 @@ module Public
|
|||
def update
|
||||
@profile = current_user.personal_profile(current_conference)
|
||||
|
||||
if @profile.update_attributes(profile_params)
|
||||
flash[:notice] = t('views.personal_profiles.successfully_updated')
|
||||
if @profile.update(profile_params)
|
||||
flash[:notice] = t("views.personal_profiles.successfully_updated")
|
||||
redirect_to root_path
|
||||
else
|
||||
render action: 'edit'
|
||||
render action: "edit"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
module Public
|
||||
class VolunteerConfirmationsController < Public::ApplicationController
|
||||
def create
|
||||
@volunteer = Volunteer.find_by!(unique_id: params[:id])
|
||||
|
||||
if ActiveSupport::SecurityUtils.secure_compare(@volunteer.confirmation_token, params[:confirmation_token])
|
||||
@volunteer.transaction do
|
||||
@volunteer.touch(:confirmed_at)
|
||||
@volunteer.update(confirmation_token: nil)
|
||||
end
|
||||
|
||||
@volunteer.send_notification_to_volunteer
|
||||
|
||||
redirect_to edit_volunteer_path(@volunteer.unique_id), notice: I18n.t("views.volunteers.email_confirmed_successfully")
|
||||
else
|
||||
redirect_to root_path, alert: I18n.t("views.volunteers.email_confirmation_error")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,5 +1,6 @@
|
|||
module Public
|
||||
class VolunteersController < Public::ApplicationController
|
||||
before_action :check_honey_pot, only: [:create, :edit]
|
||||
def new
|
||||
@volunteer = current_conference.volunteers.build
|
||||
end
|
||||
|
@ -11,7 +12,7 @@ module Public
|
|||
def create
|
||||
@volunteer = current_conference.volunteers.build volunteer_params
|
||||
if @volunteer.save
|
||||
flash[:notice] = I18n.t('views.volunteers.successful_application')
|
||||
flash[:notice] = I18n.t("views.volunteers.successful_application")
|
||||
redirect_to edit_volunteer_path(@volunteer.unique_id)
|
||||
else
|
||||
render :new, status: :unprocessable_entity
|
||||
|
@ -21,7 +22,7 @@ module Public
|
|||
def update
|
||||
@volunteer = current_conference.volunteers.find_by! unique_id: params[:id]
|
||||
if @volunteer.update volunteer_params
|
||||
flash[:notice] = I18n.t('views.volunteers.successful_application_edit')
|
||||
flash[:notice] = I18n.t("views.volunteers.successful_application_edit")
|
||||
redirect_to edit_volunteer_path(@volunteer.unique_id)
|
||||
else
|
||||
render :edit, status: :unprocessable_entity
|
||||
|
@ -30,11 +31,15 @@ module Public
|
|||
|
||||
private
|
||||
|
||||
def check_honey_pot
|
||||
head :unauthorized unless params.dig(:volunteer_ht, :full_name).blank?
|
||||
end
|
||||
|
||||
def volunteer_params
|
||||
params.require(:volunteer).permit(
|
||||
:name, :picture, :email, :phone, :tshirt_size, :tshirt_cut,
|
||||
:food_preferences, :previous_experience, :notes, :language,
|
||||
volunteer_team_ids: []
|
||||
:terms_accepted, :volunteer_team_id,
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
module Public
|
||||
class VolunteershipsController < Public::ApplicationController
|
||||
before_filter :authenticate_user!, only: [:create, :destroy]
|
||||
before_action :authenticate_user!, only: [:create, :destroy]
|
||||
|
||||
def index
|
||||
@volunteer_teams = current_conference.volunteer_teams
|
||||
|
@ -12,9 +12,9 @@ module Public
|
|||
@volunteership.build_proposition proposer: current_user, status: :undecided
|
||||
|
||||
if @volunteership.save
|
||||
flash[:notice] = I18n.t('views.volunteerships.you_successfully_applied_for', team: @volunteership.volunteer_team.name)
|
||||
flash[:notice] = I18n.t("views.volunteerships.you_successfully_applied_for", team: @volunteership.volunteer_team.name)
|
||||
else
|
||||
flash[:error] = I18n.t('views.volunteerships.an error_occurred_while_applying')
|
||||
flash[:error] = I18n.t("views.volunteerships.an error_occurred_while_applying")
|
||||
end
|
||||
|
||||
after_save_redirect
|
||||
|
@ -24,7 +24,7 @@ module Public
|
|||
@volunteership = current_user.volunteerships.find params[:id]
|
||||
|
||||
if @volunteership.destroy
|
||||
flash[:notice] = I18n.t('views.volunteerships.you_successfully_retracted_your_application_for', team: @volunteership.volunteer_team.name)
|
||||
flash[:notice] = I18n.t("views.volunteerships.you_successfully_retracted_your_application_for", team: @volunteership.volunteer_team.name)
|
||||
end
|
||||
|
||||
redirect_to volunteerships_path
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
class ApplicationDecorator < Draper::Decorator
|
||||
# Define methods for all decorated objects.
|
||||
# Helpers are accessed through `helpers` (aka `h`). For example:
|
||||
#
|
||||
# def percent_amount
|
||||
# h.number_to_percentage object.amount, precision: 2
|
||||
# end
|
||||
end
|
|
@ -0,0 +1,20 @@
|
|||
class EventDecorator < Draper::Decorator
|
||||
delegate_all
|
||||
|
||||
# Define presentation-specific methods here. Helpers are accessed through
|
||||
# `helpers` (aka `h`). You can override attributes, for example:
|
||||
#
|
||||
# def created_at
|
||||
# helpers.content_tag :span, class: 'time' do
|
||||
# object.created_at.strftime("%a %m/%d/%y")
|
||||
# end
|
||||
# end
|
||||
|
||||
def feedback_qr_code
|
||||
RQRCode::QRCode.new(h.new_event_feedback_url(event_id: id), level: :l)
|
||||
end
|
||||
|
||||
def feedback_qr_code_as_svg
|
||||
feedback_qr_code.as_svg(shape_rendering: "crispEdges", module_size: 11, fill: "ffffff", offset: 10)
|
||||
end
|
||||
end
|
|
@ -10,7 +10,7 @@ module ApplicationHelper
|
|||
"undecided" => "default",
|
||||
"approved" => "info",
|
||||
"rejected" => "danger",
|
||||
"backup" => "warning"
|
||||
"backup" => "warning",
|
||||
}.with_indifferent_access[status]
|
||||
end
|
||||
|
||||
|
@ -19,7 +19,7 @@ module ApplicationHelper
|
|||
"undecided" => "question",
|
||||
"approved" => "thumbs-up",
|
||||
"rejected" => "thumbs-down",
|
||||
"backup" => "refresh"
|
||||
"backup" => "refresh",
|
||||
}.with_indifferent_access[status]
|
||||
end
|
||||
|
||||
|
@ -29,38 +29,60 @@ module ApplicationHelper
|
|||
|
||||
def action_buttons(conference, record, actions = [:index, :show, :edit, :destroy])
|
||||
klass = record.class
|
||||
output = ''
|
||||
output = ""
|
||||
|
||||
if actions.include? :index
|
||||
output += link_to(icon(:list), [:management, conference, klass], {
|
||||
title: t('actions.index.button', models: klass.model_name.human(count: 2)),
|
||||
class: 'btn btn-info'
|
||||
title: t("actions.index.button", models: klass.model_name.human(count: 2)),
|
||||
class: "btn btn-info",
|
||||
})
|
||||
end
|
||||
|
||||
if actions.include? :show
|
||||
output += link_to(icon(:eye), [:management, conference, record], {
|
||||
title: t('actions.view.button', model: klass.model_name.human),
|
||||
class: 'btn btn-info'
|
||||
title: t("actions.view.button", model: klass.model_name.human),
|
||||
class: "btn btn-info",
|
||||
})
|
||||
end
|
||||
|
||||
if actions.include? :edit
|
||||
output += link_to(icon(:edit), [:edit, :management, conference, record], {
|
||||
title: t('actions.edit.button', model: klass.model_name.human),
|
||||
class: 'btn btn-warning'
|
||||
})
|
||||
output += link_to(icon(:edit), [:edit, :management, conference, record], {
|
||||
title: t("actions.edit.button", model: klass.model_name.human),
|
||||
class: "btn btn-warning",
|
||||
})
|
||||
end
|
||||
|
||||
if actions.include? :destroy
|
||||
output += link_to(icon(:trash), [:management, conference, record], {
|
||||
method: :delete,
|
||||
data: {confirm: t('actions.are_you_sure')},
|
||||
title: t('actions.destroy.button', model: klass.model_name.human),
|
||||
class: 'btn btn-danger'
|
||||
})
|
||||
output += link_to(icon(:trash), [:management, conference, record], {
|
||||
method: :delete,
|
||||
data: {confirm: t("actions.are_you_sure")},
|
||||
title: t("actions.destroy.button", model: klass.model_name.human),
|
||||
class: "btn btn-danger",
|
||||
})
|
||||
end
|
||||
|
||||
output.html_safe
|
||||
end
|
||||
|
||||
def rating_label_color(rating)
|
||||
return nil if rating.nil?
|
||||
case rating.round
|
||||
when (0...3) then 'primary'
|
||||
when 3 then 'danger'
|
||||
when 4 then 'warning'
|
||||
when 5 then 'info'
|
||||
when 6 then 'success'
|
||||
end
|
||||
end
|
||||
|
||||
def human_rating(rating)
|
||||
return nil if rating.nil?
|
||||
case rating.round
|
||||
when (0...3) then t('ratings.poor')
|
||||
when 3 then t('ratings.average')
|
||||
when 4 then t('ratings.good')
|
||||
when 5 then t('ratings.very_good')
|
||||
when 6 then t('ratings.excellent')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,26 +5,26 @@ module ConferencesHelper
|
|||
start_date = conference.created_at.to_date
|
||||
end_date = Time.zone.now.to_date < conference.start_date.to_date ? Time.zone.now.to_date : conference.start_date.to_date
|
||||
|
||||
chart_data = (start_date..end_date).map do |date|
|
||||
chart_data = (start_date..end_date).map { |date|
|
||||
{
|
||||
created_at: date,
|
||||
new_submissions: submissions_by_day[date].try(:first).try(:number) || 0,
|
||||
new_confirmations: confirmed_by_day[date].try(:first).try(:number) || 0
|
||||
new_confirmations: confirmed_by_day[date].try(:first).try(:number) || 0,
|
||||
}
|
||||
end
|
||||
}
|
||||
|
||||
chart_data.each_with_index do |entry, index|
|
||||
entry[:all_submissions] = if index == 0
|
||||
entry[:new_submissions]
|
||||
else
|
||||
chart_data[index - 1][:all_submissions] + entry[:new_submissions]
|
||||
end
|
||||
entry[:new_submissions]
|
||||
else
|
||||
chart_data[index - 1][:all_submissions] + entry[:new_submissions]
|
||||
end
|
||||
|
||||
entry[:all_confirmations] = if index == 0
|
||||
entry[:new_confirmations]
|
||||
else
|
||||
chart_data[index - 1][:all_confirmations] + entry[:new_confirmations]
|
||||
end
|
||||
entry[:new_confirmations]
|
||||
else
|
||||
chart_data[index - 1][:all_confirmations] + entry[:new_confirmations]
|
||||
end
|
||||
end
|
||||
chart_data
|
||||
end
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
module EventsHelper
|
||||
def links_to_event_participants_for(event)
|
||||
event.participants_with_personal_profiles.map do |participant|
|
||||
event.participants_with_personal_profiles.map { |participant|
|
||||
if participant.has_personal_profile?
|
||||
link_to icon(:user, participant.name),
|
||||
management_conference_personal_profile_path(participant.personal_profile_id, conference_id: event.conference.id)
|
||||
else
|
||||
link_to icon('user-plus', participant.personal_email),
|
||||
link_to icon("user-plus", participant.personal_email),
|
||||
new_management_conference_personal_profile_path(conference_id: event.conference.id,
|
||||
user_id: participant.id),
|
||||
title: t('management.events.event.create_profile'), class: 'bg-danger'
|
||||
title: t("management.events.event.create_profile"), class: "bg-danger"
|
||||
end
|
||||
end.join(', ').html_safe
|
||||
}.join(", ").html_safe
|
||||
end
|
||||
|
||||
def participant_names_with_emails(event)
|
||||
|
@ -25,13 +25,11 @@ module EventsHelper
|
|||
end
|
||||
|
||||
def participant_names(event)
|
||||
event.participants.map do |participant|
|
||||
event.participants.map { |participant|
|
||||
if participant.personal_profile(event.conference).present?
|
||||
profile = participant.personal_profile(event.conference)
|
||||
"#{profile.name}"
|
||||
else
|
||||
nil
|
||||
profile.name.to_s
|
||||
end
|
||||
end.compact
|
||||
}.compact
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,15 +1,21 @@
|
|||
# coding: utf-8
|
||||
class EventMailer < ActionMailer::Base
|
||||
helper ApplicationHelper
|
||||
|
||||
def confirmation_request(event)
|
||||
@event = event
|
||||
@event = event.decorate
|
||||
I18n.locale = @event.proposer.language
|
||||
|
||||
attachments['feedback-link-qr-code.svg'] = {
|
||||
mime_type: 'image/svg+xml',
|
||||
content: @event.feedback_qr_code_as_svg
|
||||
}
|
||||
|
||||
mail to: @event.proposer.email,
|
||||
from: 'program@openfest.org',
|
||||
subject: I18n.t('event_mailer.acceptance_notification.subject',
|
||||
conference: @event.conference.title,
|
||||
submission_type: @event.event_type.name.mb_chars.downcase.to_s,
|
||||
title: @event.title)
|
||||
from: "program@openfest.org",
|
||||
subject: I18n.t("event_mailer.acceptance_notification.subject",
|
||||
conference: @event.conference.title,
|
||||
submission_type: @event.event_type.name.mb_chars.downcase.to_s,
|
||||
title: @event.title)
|
||||
end
|
||||
|
||||
def rejection_notification(event)
|
||||
|
@ -17,11 +23,10 @@ class EventMailer < ActionMailer::Base
|
|||
I18n.locale = @event.proposer.language
|
||||
|
||||
mail to: @event.proposer.email,
|
||||
from: 'program@openfest.org',
|
||||
subject: I18n.t('event_mailer.rejection_notification.subject',
|
||||
conference: @event.conference.title,
|
||||
submission_type: @event.event_type.name.mb_chars.downcase.to_s,
|
||||
title: @event.title)
|
||||
from: "program@openfest.org",
|
||||
subject: I18n.t("event_mailer.rejection_notification.subject",
|
||||
conference: @event.conference.title,
|
||||
submission_type: @event.event_type.name.mb_chars.downcase.to_s,
|
||||
title: @event.title)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
# coding: utf-8
|
||||
class PropositionMailer < ActionMailer::Base
|
||||
def new_proposition_notification(proposition)
|
||||
@proposition = proposition
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
# coding: utf-8
|
||||
class VolunteerMailer < ActionMailer::Base
|
||||
def team_notification(new_volunteer)
|
||||
@volunteer = new_volunteer
|
||||
|
||||
mail(to: @volunteer.conference.email,
|
||||
subject: "Нов доброволец – #{@volunteer.name} <#{@volunteer.email}> за екип(и) #{@volunteer.volunteer_teams.map(&:name).join(', ')}")
|
||||
mail(
|
||||
to: @volunteer.conference.email,
|
||||
subject: "Нов доброволец за #{@volunteer.conference.title} - #{@volunteer.volunteer_team.name}"
|
||||
)
|
||||
end
|
||||
|
||||
def volunteer_notification(new_volunteer)
|
||||
|
@ -12,8 +13,19 @@ class VolunteerMailer < ActionMailer::Base
|
|||
I18n.locale = @volunteer.language
|
||||
mail(to: @volunteer.email,
|
||||
reply_to: @volunteer.conference.email,
|
||||
from: 'no-reply@openfest.org',
|
||||
subject: I18n.t('volunteer_mailer.success_notification.subject',
|
||||
from: "OpenFest <cfp@openfest.org>",
|
||||
subject: I18n.t("volunteer_mailer.success_notification.subject",
|
||||
conference_name: @volunteer.conference.title))
|
||||
end
|
||||
|
||||
def volunteer_email_confirmation(new_volunteer)
|
||||
@volunteer = new_volunteer
|
||||
I18n.locale = @volunteer.language
|
||||
mail(to: @volunteer.email,
|
||||
reply_to: @volunteer.conference.email,
|
||||
from: "OpenFest <cfp@openfest.org>",
|
||||
subject: I18n.t("volunteer_mailer.email_confirmation.subject",
|
||||
conference_name: @volunteer.conference.title))
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -2,7 +2,7 @@ class CallForParticipation < ActiveRecord::Base
|
|||
belongs_to :conference
|
||||
|
||||
def open!
|
||||
self.opens_at = Time.now unless self.opens_at.present?
|
||||
self.opens_at = Time.now unless opens_at.present?
|
||||
self.closes_at = nil
|
||||
save
|
||||
end
|
||||
|
@ -13,14 +13,14 @@ class CallForParticipation < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def open?
|
||||
self.opens_at.present? and self.opens_at < Time.now
|
||||
opens_at.present? && (opens_at < Time.now)
|
||||
end
|
||||
|
||||
def closed?
|
||||
self.closes_at.present? and self.closes_at < Time.now
|
||||
closes_at.present? && (closes_at < Time.now)
|
||||
end
|
||||
|
||||
def in_progress?
|
||||
open? and not closed?
|
||||
open? && !closed?
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
module FeedbackReceiving
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
def average_rating
|
||||
feedbacks.average(:rating)
|
||||
end
|
||||
|
||||
def rated?
|
||||
feedbacks.size > 0
|
||||
end
|
||||
end
|
|
@ -14,30 +14,35 @@ class Conference < ActiveRecord::Base
|
|||
has_many :halls
|
||||
has_many :event_types
|
||||
has_many :events
|
||||
has_many :approved_events, -> { joins(:proposition).approved }, class_name: 'Event'
|
||||
has_many :approved_events, -> { joins(:proposition).approved }, class_name: "Event"
|
||||
has_many :conflict_counts, through: :events
|
||||
has_many :volunteer_teams
|
||||
has_many :volunteers
|
||||
has_one :call_for_participation, dependent: :destroy
|
||||
has_many :participants, -> { uniq }, class_name: 'User', through: :events
|
||||
has_many :participant_profiles, class_name: 'PersonalProfile'
|
||||
has_one :call_for_participation
|
||||
has_many :participants, -> { distinct }, class_name: "User", through: :events
|
||||
has_many :participant_profiles, class_name: "PersonalProfile"
|
||||
has_many :slots, through: :halls
|
||||
has_many :feedbacks, as: :feedback_receiving, dependent: :destroy
|
||||
has_many :editions, primary_key: :host_name, foreign_key: :host_name, class_name: 'Conference'
|
||||
has_many :editions, primary_key: :host_name, foreign_key: :host_name, class_name: "Conference"
|
||||
has_many :events_of_all_editions, through: :editions, source: :events
|
||||
|
||||
include FeedbackReceiving
|
||||
has_many :feedbacks, as: :feedback_receiving
|
||||
has_many :feedbacks_with_comment, -> { where.not(comment: [nil, ""]) }, as: :feedback_receiving, class_name: 'Feedback'
|
||||
has_many :event_feedbacks, through: :events, source: :feedbacks
|
||||
has_many :event_feedbacks_with_comment, through: :events, source: :feedbacks_with_comment
|
||||
|
||||
accepts_nested_attributes_for :tracks, :halls, :event_types, :volunteer_teams,
|
||||
reject_if: :all_blank, allow_destroy: true
|
||||
reject_if: :all_blank, allow_destroy: true
|
||||
|
||||
after_create :create_call_for_participation
|
||||
|
||||
def submissions_grouped_by_day
|
||||
submissions = events.group('date(events.created_at)').select('date(events.created_at) as created_at, count(events.id) as number')
|
||||
submissions = events.group("date(events.created_at)").select("date(events.created_at) as created_at, count(events.id) as number")
|
||||
submissions.group_by { |s| s.created_at.to_date }
|
||||
end
|
||||
|
||||
def submissions_grouped_by_confirmation_day
|
||||
submissions = events.joins(:proposition).approved.confirmed.group('date(propositions.confirmed_at)').select('date(propositions.confirmed_at) as confirmed_at, count(events.id) as number')
|
||||
submissions = events.joins(:proposition).approved.confirmed.group("date(propositions.confirmed_at)").select("date(propositions.confirmed_at) as confirmed_at, count(events.id) as number")
|
||||
submissions.group_by { |s| s.confirmed_at.to_date }
|
||||
end
|
||||
|
||||
|
@ -46,7 +51,7 @@ class Conference < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def has_vote_results?
|
||||
vote_data_updated_at.present? and number_of_ballots_cast > 0
|
||||
vote_data_updated_at.present? && (number_of_ballots_cast > 0)
|
||||
end
|
||||
|
||||
def has_voting_endpoint?
|
||||
|
@ -54,8 +59,8 @@ class Conference < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def update_conflict_data!
|
||||
update_vote_data! or raise ActiveRecord::Rollback
|
||||
events.all? { |event| event.update_conflict_data(false) } or raise ActiveRecord::Rollback
|
||||
update_vote_data! || raise(ActiveRecord::Rollback)
|
||||
events.all? { |event| event.update_conflict_data(false) } || raise(ActiveRecord::Rollback)
|
||||
end
|
||||
|
||||
def most_conflicts
|
||||
|
@ -74,17 +79,16 @@ class Conference < ActiveRecord::Base
|
|||
conflict_counts.unscoped.where(left: approved_events, right: approved_events).order(number_of_conflicts: :asc).first.try(:number_of_conflicts) || 0
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
def planned_cfp_end_date_is_before_start_date
|
||||
if planned_cfp_end_date.present? and start_date.present? and planned_cfp_end_date > start_date
|
||||
if planned_cfp_end_date.present? && start_date.present? && (planned_cfp_end_date > start_date)
|
||||
errors.add(:planned_cfp_end_date, :cannot_be_after_start_date)
|
||||
end
|
||||
end
|
||||
|
||||
def start_date_is_before_end_date
|
||||
if start_date.present? and end_date.present? and start_date > end_date
|
||||
if start_date.present? && end_date.present? && (start_date > end_date)
|
||||
errors.add(:end_date, :cannot_be_before_start_date)
|
||||
end
|
||||
end
|
||||
|
@ -95,38 +99,38 @@ class Conference < ActiveRecord::Base
|
|||
attr_accessor :conference
|
||||
|
||||
def number_of_ballots
|
||||
@number_of_ballots ||= remote_summary_data['number_of_ballots']
|
||||
@number_of_ballots ||= remote_summary_data["number_of_ballots"]
|
||||
end
|
||||
|
||||
def ranking
|
||||
@ranking ||= remote_summary_data['ranking'].map { |ranking_entry| EventRanking.new ranking_entry }
|
||||
@ranking ||= remote_summary_data["ranking"].map { |ranking_entry| EventRanking.new ranking_entry }
|
||||
end
|
||||
|
||||
def conflicts
|
||||
@conflicts ||= remote_summary_data['conflicts'].map { |conflicts_entry| ConflictsForEvent.new conflicts_entry }
|
||||
@conflicts ||= remote_summary_data["conflicts"].map { |conflicts_entry| ConflictsForEvent.new conflicts_entry }
|
||||
end
|
||||
|
||||
def save
|
||||
conference.transaction do
|
||||
conference.number_of_ballots_cast = number_of_ballots
|
||||
conflicts.all?(&:save) or raise ActiveRecord::Rollback
|
||||
ranking.all?(&:save) or raise ActiveRecord::Rollback
|
||||
conflicts.all?(&:save) || raise(ActiveRecord::Rollback)
|
||||
ranking.all?(&:save) || raise(ActiveRecord::Rollback)
|
||||
conference.touch :vote_data_updated_at
|
||||
conference.save or raise ActiveRecord::Rollback
|
||||
conference.save || raise(ActiveRecord::Rollback)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def connection
|
||||
@connection ||= Faraday.new(url: conference.vote_data_endpoint + '/summary.json',
|
||||
headers: {'Content-Type' => 'application/json'})
|
||||
@connection ||= Faraday.new(url: conference.vote_data_endpoint + "/summary.json",
|
||||
headers: {"Content-Type" => "application/json"})
|
||||
end
|
||||
|
||||
def remote_summary_data
|
||||
@remote_summary_data ||= JSON.parse(connection.get do |request|
|
||||
@remote_summary_data ||= JSON.parse(connection.get { |request|
|
||||
request.body = {summary: {talk_ids: conference.events.pluck(:id)}}.to_json
|
||||
end.body)
|
||||
}.body)
|
||||
end
|
||||
|
||||
class ConflictsForEvent
|
||||
|
@ -136,14 +140,13 @@ class Conference < ActiveRecord::Base
|
|||
|
||||
def save
|
||||
@event = Event.find(talk_id)
|
||||
@event.conflict_counts.destroy_all or raise ActiveRecord::Rollback
|
||||
@event.conflict_counts.destroy_all || raise(ActiveRecord::Rollback)
|
||||
conflicts.all? do |right_event_id, number_of_conflicts|
|
||||
ConflictCount.create left_id: talk_id, right_id: right_event_id, number_of_conflicts: number_of_conflicts
|
||||
end or raise ActiveRecord::Rollback
|
||||
end || raise(ActiveRecord::Rollback)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
class EventRanking
|
||||
include ActiveModel::Model
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
class ConflictCount < ActiveRecord::Base
|
||||
belongs_to :left, class_name: 'Event'
|
||||
belongs_to :right, class_name: 'Event'
|
||||
belongs_to :left, class_name: "Event"
|
||||
belongs_to :right, class_name: "Event"
|
||||
has_one :conference, through: :left
|
||||
end
|
||||
|
|
|
@ -6,20 +6,24 @@ class Event < ActiveRecord::Base
|
|||
has_one :slot
|
||||
|
||||
has_many :participations, dependent: :destroy
|
||||
has_many :pending_participations, ->() { pending }, class_name: 'Participation'
|
||||
has_many :approved_participations, ->() { approved }, class_name: 'Participation'
|
||||
has_many :pending_participations, -> { pending }, class_name: "Participation"
|
||||
has_many :approved_participations, -> { approved }, class_name: "Participation"
|
||||
has_many :participants, through: :approved_participations
|
||||
has_many :participants_with_personal_profiles, through: :approved_participations, source: :participant_with_personal_profile
|
||||
has_many :conflict_counts, -> { order(number_of_conflicts: :desc) }, foreign_key: :left_id
|
||||
has_many :feedbacks, as: :feedback_receiving, dependent: :destroy
|
||||
|
||||
has_many :feedbacks, as: :feedback_receiving
|
||||
has_many :feedbacks_with_comment, -> { where.not(comment: [nil, ""]) }, as: :feedback_receiving, class_name: 'Feedback'
|
||||
include FeedbackReceiving
|
||||
|
||||
belongs_to :event_type
|
||||
|
||||
scope :ranked, -> { where.not(ranked: nil).where.not(votes: nil) }
|
||||
scope :approved, -> { where(propositions: {status: Proposition.statuses[:approved]})}
|
||||
scope :approved_joined, -> { joins(:proposition).merge(Proposition.approved) }
|
||||
|
||||
validates :conference, presence: true
|
||||
validates :title, presence: true, length: { maximum: 65 }
|
||||
validates :title, presence: true, length: {maximum: 65}
|
||||
validates :abstract, presence: true
|
||||
validates :description, presence: true
|
||||
validates :agreement, acceptance: true
|
||||
|
@ -61,16 +65,16 @@ class Event < ActiveRecord::Base
|
|||
language: language,
|
||||
abstract: abstract,
|
||||
description: description,
|
||||
notes: notes
|
||||
notes: notes,
|
||||
}
|
||||
end
|
||||
|
||||
def ranked?
|
||||
conference.has_vote_results? and rank.present? and number_of_votes.present?
|
||||
conference.has_vote_results? && rank.present? && number_of_votes.present?
|
||||
end
|
||||
|
||||
def per_cent_of_votes
|
||||
if conference.has_vote_results? and conference.number_of_ballots_cast > 0
|
||||
if conference.has_vote_results? && (conference.number_of_ballots_cast > 0)
|
||||
Rational(number_of_votes * 100, conference.number_of_ballots_cast)
|
||||
else
|
||||
Float::NAN
|
||||
|
@ -80,20 +84,20 @@ class Event < ActiveRecord::Base
|
|||
private
|
||||
|
||||
def event_type_belongs_to_the_selected_conference
|
||||
unless conference.present? and conference.event_types.include?(event_type)
|
||||
unless conference.present? && conference.event_types.include?(event_type)
|
||||
errors.add :event_type, :must_be_a_valid_event_type
|
||||
end
|
||||
end
|
||||
|
||||
def track_belongs_to_the_selected_conference
|
||||
unless conference.present? and conference.tracks.include?(track)
|
||||
unless conference.present? && conference.tracks.include?(track)
|
||||
errors.add :track, :must_be_a_valid_track
|
||||
end
|
||||
end
|
||||
|
||||
def length_is_within_the_permitted_interval
|
||||
if event_type.present?
|
||||
unless length >= event_type.minimum_length and length <= event_type.maximum_length
|
||||
unless (length >= event_type.minimum_length) && (length <= event_type.maximum_length)
|
||||
errors.add :length, :must_be_between, minimum: event_type.minimum_length, maximum: event_type.maximum_length
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,6 +9,6 @@ class EventSearch
|
|||
option(:confirmed) { |scope, value| scope.joins(:proposition).approved.where.not(propositions: {confirmed_at: nil}) }
|
||||
option(:not_confirmed) { |scope, value| scope.joins(:proposition).approved.where(propositions: {confirmed_at: nil}) }
|
||||
|
||||
sort_by 'title'
|
||||
config[:defaults]['sort'] = "#{config[:sort_attributes].first} asc"
|
||||
sort_by "title"
|
||||
config[:defaults]["sort"] = "#{config[:sort_attributes].first} asc"
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
class Feedback < ActiveRecord::Base
|
||||
belongs_to :feedback_receiving, polymorphic: true
|
||||
|
||||
validates :rating, presence: true, inclusion: {in: [2, 3, 4, 5 ,6]}
|
||||
validates :rating, presence: true, inclusion: {in: [2, 3, 4, 5, 6]}
|
||||
|
||||
before_create :destroy_older_feedbacks_by_the_session
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ class Participant < ActiveRecord::Base
|
|||
self.primary_key = :participant_id
|
||||
|
||||
def twitter=(handle)
|
||||
write_attribute :twitter, handle.gsub(/\A@/,'') if handle
|
||||
write_attribute :twitter, handle.gsub(/\A@/, "") if handle
|
||||
end
|
||||
|
||||
def name
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
class Participation < ActiveRecord::Base
|
||||
belongs_to :participant, class_name: User
|
||||
has_one :participant_with_personal_profile, class_name: Participant
|
||||
belongs_to :participant, class_name: "User"
|
||||
has_one :participant_with_personal_profile, class_name: "Participant"
|
||||
belongs_to :event
|
||||
validates :participant_id, presence: true
|
||||
scope :approved, ->() { where approved: true }
|
||||
scope :pending, ->() { where.not approved: true }
|
||||
scope :approved, -> { where approved: true }
|
||||
scope :pending, -> { where.not approved: true }
|
||||
end
|
||||
|
|
|
@ -11,14 +11,14 @@ class PersonalProfile < ActiveRecord::Base
|
|||
validates :twitter, format: {with: /\A[a-z0-9_]{1,15}\z/i}, allow_blank: true
|
||||
validates :github, format: {with: /\A[a-z0-9][a-z0-9\-]*\z/i}, allow_blank: true
|
||||
|
||||
phony_normalize :mobile_phone, default_country_code: 'BG', add_plus: false
|
||||
phony_normalize :mobile_phone, default_country_code: "BG", add_plus: false
|
||||
|
||||
mount_uploader :picture, PictureUploader
|
||||
has_one_attached :picture
|
||||
|
||||
accepts_nested_attributes_for :user
|
||||
|
||||
def twitter=(handle)
|
||||
write_attribute :twitter, handle.gsub(/\A@/,'') if handle
|
||||
write_attribute :twitter, handle.gsub(/\A@/, "") if handle
|
||||
end
|
||||
|
||||
def name
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
class Proposition < ActiveRecord::Base
|
||||
belongs_to :proposer, class_name: 'User'
|
||||
belongs_to :proposer, class_name: "User"
|
||||
belongs_to :proposable, polymorphic: true, dependent: :destroy
|
||||
enum status: [:undecided, :approved, :rejected, :backup]
|
||||
delegate :proposable_title, :proposable_type, :proposable_description, to: :proposable
|
||||
|
||||
after_create :send_creation_notification
|
||||
after_commit :send_creation_notification, on: [:create]
|
||||
before_destroy :send_withdrawal_notification
|
||||
|
||||
def confirm!
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
class Slot < ActiveRecord::Base
|
||||
belongs_to :hall
|
||||
belongs_to :event
|
||||
belongs_to :event, required: false
|
||||
belongs_to :approved_event, -> { joins(:proposition).approved_joined }, class_name: 'Event', foreign_key: 'event_id'
|
||||
end
|
||||
|
|
|
@ -9,7 +9,7 @@ class Track < ActiveRecord::Base
|
|||
translates :name, :description
|
||||
|
||||
def color=(hex_triplet)
|
||||
write_attribute :color, hex_triplet.gsub(/\A#/,'') if hex_triplet
|
||||
write_attribute :color, hex_triplet.gsub(/\A#/, "") if hex_triplet
|
||||
end
|
||||
|
||||
def color
|
||||
|
|
|
@ -2,17 +2,29 @@ class User < ActiveRecord::Base
|
|||
# Include default devise modules. Others available are:
|
||||
# :lockable, :timeoutable and :omniauthable
|
||||
devise :database_authenticatable, :registerable, :confirmable,
|
||||
:recoverable, :rememberable, :trackable, :validatable
|
||||
:recoverable, :rememberable, :trackable, :validatable
|
||||
|
||||
has_many :personal_profiles, dependent: :destroy
|
||||
has_many :lectures
|
||||
has_many :workshops
|
||||
has_many :propositions, foreign_key: :proposer_id
|
||||
has_many :events, through: :propositions, source: :proposable, source_type: 'Event'
|
||||
has_many :events, through: :propositions, source: :proposable, source_type: "Event"
|
||||
has_many :feedbacks, through: :events
|
||||
has_many :feedbacks_with_comment, -> { where.not(comment: [nil, '']) }, through: :events
|
||||
|
||||
has_many :participations, foreign_key: :participant_id
|
||||
has_many :events_participated_in, through: :participations, source: :event
|
||||
has_many :volunteerships, foreign_key: :volunteer_id
|
||||
|
||||
include FeedbackReceiving
|
||||
|
||||
def average_rating
|
||||
return nil unless rated?
|
||||
ratings_per_event = feedbacks.group(:feedback_receiving_type,
|
||||
:feedback_receiving_id).average(:rating).values
|
||||
BigDecimal(ratings_per_event.reduce(&:+)) / BigDecimal(ratings_per_event.size)
|
||||
end
|
||||
|
||||
def find_or_build_personal_profile(conference, params = {})
|
||||
current_profile = personal_profile(conference)
|
||||
if current_profile.present?
|
||||
|
@ -26,7 +38,7 @@ class User < ActiveRecord::Base
|
|||
def build_personal_profile(conference, params = {})
|
||||
if personal_profiles.last.present?
|
||||
new_personal_profile = personal_profiles.last.try(:dup)
|
||||
CopyCarrierwaveFile::CopyFileService.new(personal_profiles.last, new_personal_profile, :picture).set_file
|
||||
new_personal_profile.picture.attach(personal_profiles.last.picture.blob)
|
||||
else
|
||||
new_personal_profile = personal_profiles.build
|
||||
end
|
||||
|
|
|
@ -3,44 +3,63 @@ class Volunteer < ActiveRecord::Base
|
|||
TSHIRT_CUTS = [:unisex, :female]
|
||||
FOOD_PREFERENCES = [:none, :vegetarian, :vegan]
|
||||
|
||||
attachment :picture, type: :image
|
||||
has_one_attached :picture
|
||||
|
||||
validates :name, :language, :tshirt_size, :tshirt_cut, :food_preferences, presence: true
|
||||
validates :tshirt_size, inclusion: {in: TSHIRT_SIZES.map(&:to_s)}
|
||||
validates :tshirt_cut, inclusion: {in: TSHIRT_CUTS.map(&:to_s)}
|
||||
validates :food_preferences, inclusion: {in: FOOD_PREFERENCES.map(&:to_s)}
|
||||
validates :email, format: {with: /\A[^@]+@[^@]+\z/}, presence: true
|
||||
validates :email, format: {with: /\A[^@]+@[^@]+\z/}, presence: true, uniqueness: {scope: :conference_id}
|
||||
validates :phone, presence: true, format: {with: /\A[+\- \(\)0-9]+\z/}
|
||||
validates :volunteer_teams, presence: true
|
||||
validates :volunteer_team, presence: true
|
||||
validates :terms_accepted, acceptance: true
|
||||
validate :volunteer_teams_belong_to_conference
|
||||
|
||||
phony_normalize :phone, default_country_code: 'BG'
|
||||
phony_normalize :phone, default_country_code: "BG"
|
||||
|
||||
belongs_to :conference
|
||||
has_and_belongs_to_many :volunteer_teams
|
||||
belongs_to :volunteer_team
|
||||
has_and_belongs_to_many :additional_volunteer_teams, class_name: "VolunteerTeam"
|
||||
|
||||
before_create :ensure_main_volunteer_team_is_part_of_additional_volunteer_teams
|
||||
before_create :assign_unique_id
|
||||
after_create :send_notification_to_organizers
|
||||
after_create :send_notification_to_volunteer
|
||||
|
||||
private
|
||||
|
||||
def assign_unique_id
|
||||
self.unique_id = Digest::SHA256.hexdigest(SecureRandom.uuid)
|
||||
end
|
||||
|
||||
def send_notification_to_organizers
|
||||
VolunteerMailer.team_notification(self).deliver_later
|
||||
end
|
||||
before_create :assign_confirmation_token
|
||||
after_commit :send_email_confirmation_to_volunteer, on: [:create]
|
||||
after_commit :send_email_to_organisers, on: [:create] # technically the volunteer's email is not confirmed yet
|
||||
|
||||
def send_notification_to_volunteer
|
||||
VolunteerMailer.volunteer_notification(self).deliver_later
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def ensure_main_volunteer_team_is_part_of_additional_volunteer_teams
|
||||
self.additional_volunteer_teams |= [volunteer_team] if volunteer_team
|
||||
end
|
||||
|
||||
def assign_unique_id
|
||||
self.unique_id = Digest::SHA256.hexdigest(SecureRandom.uuid)
|
||||
end
|
||||
|
||||
def assign_confirmation_token
|
||||
self.confirmation_token = Digest::SHA256.hexdigest(SecureRandom.uuid)
|
||||
end
|
||||
|
||||
def send_email_confirmation_to_volunteer
|
||||
VolunteerMailer.volunteer_email_confirmation(self).deliver_later
|
||||
end
|
||||
|
||||
def send_email_to_organisers
|
||||
VolunteerMailer.team_notification(self).deliver_later
|
||||
end
|
||||
|
||||
def volunteer_teams_belong_to_conference
|
||||
conference_volunteer_teams = conference.volunteer_teams
|
||||
unless volunteer_teams.all? { |team| conference_volunteer_teams.include? team }
|
||||
errors.add :volunteer_teams, :invalid_volunteer_team
|
||||
unless additional_volunteer_teams.all? { |team| conference_volunteer_teams.include? team }
|
||||
errors.add :additional_volunteer_teams, :invalid_volunteer_team
|
||||
end
|
||||
unless conference_volunteer_teams.include?(volunteer_team)
|
||||
errors.add :volunteer_team, :invalid_volunteer_team
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
class VolunteerSearch
|
||||
include SearchObject.module(:sorting)
|
||||
|
||||
option(:volunteer_team_id) { |scope, value| scope.joins(:volunteer_teams).where volunteer_teams: {id: value} }
|
||||
option(:volunteer_team_id) { |scope, value| scope.joins(:volunteer_team).where volunteer_team: {id: value} }
|
||||
|
||||
sort_by 'name'
|
||||
config[:defaults]['sort'] = "#{config[:sort_attributes].first} asc"
|
||||
sort_by "name"
|
||||
config[:defaults]["sort"] = "#{config[:sort_attributes].first} asc"
|
||||
end
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
class VolunteerTeam < ActiveRecord::Base
|
||||
belongs_to :conference
|
||||
has_and_belongs_to_many :volunteers
|
||||
has_many :volunteers, inverse_of: :volunteer_team
|
||||
has_and_belongs_to_many :supporters, class_name: "Volunteer", inverse_of: :additional_volunteer_teams
|
||||
|
||||
validates :name, presence: true
|
||||
validates :color, presence: true, format: {with: /\A#?[a-f0-9]{6}\z/i}
|
||||
|
@ -13,7 +14,7 @@ class VolunteerTeam < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def color=(hex_triplet)
|
||||
write_attribute :color, hex_triplet.gsub(/\A#/,'') if hex_triplet
|
||||
write_attribute :color, hex_triplet.gsub(/\A#/, "") if hex_triplet
|
||||
end
|
||||
|
||||
def color
|
||||
|
|
|
@ -2,7 +2,7 @@ class Volunteership < ActiveRecord::Base
|
|||
include Proposable
|
||||
|
||||
belongs_to :volunteer_team
|
||||
belongs_to :volunteer, class_name: 'User'
|
||||
belongs_to :volunteer, class_name: "User"
|
||||
has_one :conference, through: :volunteer_team
|
||||
|
||||
def proposable_title
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
class PictureUploader < CarrierWave::Uploader::Base
|
||||
|
||||
# Include RMagick or MiniMagick support:
|
||||
#include CarrierWave::RMagick
|
||||
include CarrierWave::MiniMagick
|
||||
|
||||
# Choose what kind of storage to use for this uploader:
|
||||
storage :file
|
||||
# storage :fog
|
||||
|
||||
# Override the directory where uploaded files will be stored.
|
||||
# This is a sensible default for uploaders that are meant to be mounted:
|
||||
def store_dir
|
||||
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
|
||||
end
|
||||
|
||||
# Provide a default URL as a default if there hasn't been a file uploaded:
|
||||
def default_url
|
||||
ActionController::Base.helpers.asset_path("fallback/profile_picture/" + [version_name, "default.png"].compact.join('_'))
|
||||
end
|
||||
|
||||
# Process files as they are uploaded:
|
||||
# process :scale => [200, 300]
|
||||
#
|
||||
# def scale(width, height)
|
||||
# # do something
|
||||
# end
|
||||
|
||||
# Create different versions of your uploaded files:
|
||||
|
||||
version :medium do
|
||||
process :resize_to_fit => [171, 180]
|
||||
end
|
||||
|
||||
version :thumb do
|
||||
process :resize_to_fit => [50, 50]
|
||||
end
|
||||
|
||||
version :schedule do
|
||||
process :resize_to_fill => [100, 100]
|
||||
end
|
||||
|
||||
# Add a white list of extensions which are allowed to be uploaded.
|
||||
# For images you might use something like this:
|
||||
def extension_white_list
|
||||
%w(jpg jpeg png)
|
||||
end
|
||||
|
||||
# Override the filename of the uploaded files:
|
||||
# Avoid using model.id or version_name here, see uploader/store.rb for details.
|
||||
# def filename
|
||||
# "something.jpg" if original_filename
|
||||
# end
|
||||
|
||||
end
|
|
@ -0,0 +1 @@
|
|||
json.array! @conferences, :id, :title, :start_date, :end_date, :created_at, :updated_at
|
|
@ -0,0 +1,13 @@
|
|||
json.array! @events, cached: ->(event) { [event, event.track, event.event_type] } do |event|
|
||||
json.id event.id
|
||||
json.title event.title
|
||||
json.abstract event.abstract
|
||||
json.track_id event.track_id
|
||||
|
||||
json.track do
|
||||
json.name event.track.name
|
||||
end
|
||||
json.event_type do
|
||||
json.name event.event_type.name
|
||||
end
|
||||
end
|
|
@ -0,0 +1,24 @@
|
|||
<%
|
||||
cal = Icalendar::Calendar.new
|
||||
cal.add_timezone(Time.zone.tzinfo.ical_timezone(Time.now))
|
||||
|
||||
@events.each do |event|
|
||||
next unless event&.slot&.starts_at
|
||||
|
||||
cal.event do |ical_event|
|
||||
ical_event.dtstart = Icalendar::Values::DateTime.new(event.slot.starts_at, 'tzid' => event.slot.starts_at.time_zone.tzinfo.identifier)
|
||||
ical_event.dtend = Icalendar::Values::DateTime.new(event.slot.ends_at, 'tzid' => event.slot.ends_at.time_zone.tzinfo.identifier)
|
||||
ical_event.summary = event.title
|
||||
ical_event.description = event.description
|
||||
ical_event.created = Icalendar::Values::DateTime.new(event.created_at, 'tzid' => event.created_at.time_zone.tzinfo.identifier)
|
||||
ical_event.last_modified = Icalendar::Values::DateTime.new(event.updated_at, 'tzid' => event.updated_at.time_zone.tzinfo.identifier)
|
||||
ical_event.location = event.slot.hall.name
|
||||
ical_event.alarm do |alarm|
|
||||
alarm.summary = event.title
|
||||
alarm.trigger = "-PT15M"
|
||||
end
|
||||
end
|
||||
end
|
||||
cal.publish
|
||||
-%>
|
||||
<%= raw cal.to_ical %>
|
|
@ -0,0 +1,22 @@
|
|||
@halls.each do |hall|
|
||||
json.set! hall.name do
|
||||
json.days do
|
||||
hall.slots.to_a.sort_by(&:starts_at).group_by { |slot| slot.starts_at.to_date }.each do |day, slots|
|
||||
json.set! day do
|
||||
json.array! slots do |slot|
|
||||
next unless slot.approved_event
|
||||
json.starts_at slot.starts_at
|
||||
json.starts_at_human l(slot.starts_at, format: '%a, %H:%M')
|
||||
json.title slot.approved_event.title
|
||||
json.speakers do
|
||||
json.array! slot.approved_event.participants_with_personal_profiles do |participant|
|
||||
json.name participant.name
|
||||
json.email participant.public_email
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,6 +1,6 @@
|
|||
@speakers.each do |speaker|
|
||||
json.set! speaker.user_id do
|
||||
json.extract! speaker, :twitter, :github, :biography, :public_email, :organisation, :last_name, :first_name
|
||||
json.picture speaker.picture.serializable_hash
|
||||
json.extract! speaker, :twitter, :github, :biography, :public_email, :organisation, :last_name, :first_name, :name
|
||||
json.picture rails_blob_url(speaker.picture.variant(resize_to_fill: [100, 100]))
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,22 +1,15 @@
|
|||
Здравейте,
|
||||
|
||||
Радваме се да Ви съобщим, че предложението Ви за участие в <%= @event.conference.title %> с <%= @event.event_type.name.mb_chars.downcase %> на тема „<%= @event.title %>“ беше одобрено. <% if @event.slot.present? -%>
|
||||
Имаме удоволствието да ви информираме, че Вашето предложение за участие в „<%= @event.conference.title %>“ с <%= @event.event_type.name.mb_chars.downcase %> на тема „<%= @event.title %>“ беше одобрено. <% if @event.slot.present? -%>
|
||||
Ще се проведе на <%= I18n.l @event.slot.starts_at, format: :long %> часа.
|
||||
<% else %>
|
||||
Все още не са избрани час и дата за провеждането му.
|
||||
Определянето на датата и часа на провеждане все още предстои.
|
||||
<% end %>
|
||||
|
||||
Моля, потвърдете участието си възможно най-скоро като кликнете на следния линк:
|
||||
Моля, потвърдете Вашето участие възможно най-скоро като кликнете на следния линк:
|
||||
<%= confirm_event_url @event, host: @event.conference.host_name, protocol: 'https' %>
|
||||
|
||||
Моля пишете на ofvideo@openfest.org, ако имате специфични изисквания, например:
|
||||
|
||||
* да ви осигурим лаптоп за презентация;
|
||||
* звук от презентацията ви;
|
||||
* имате нужда да изпозлвате жична или безжична връзка до Internet за презентацията си;
|
||||
* ползвате macbook.
|
||||
|
||||
Отговорете на този email, ако възникнат някакви въпроси.
|
||||
С приложения QR код към този имейл ще можете да достъпите формуляра за обратна връзка на предложеното от Вас събитие. Моля, включете го в презентацията си.
|
||||
|
||||
Поздрави,
|
||||
Екипът на <%= @event.conference.title %>
|
||||
|
|
|
@ -1,23 +1,17 @@
|
|||
Hello,
|
||||
|
||||
We are happy to notify you that your request for participation in <%= @event.conference.title %> with the <%= @event.event_type.name.downcase %> titled "<%= @event.title %>" was approved. <% if @event.slot.present? -%>
|
||||
We are thrilled to inform you that your request for participation in <%= @event.conference.title %> with the <%= @event.event_type.name.downcase %> titled "<%= @event.title %>" has been approved. <% if @event.slot.present? -%>
|
||||
It has been scheduled for <%= I18n.l @event.slot.starts_at, format: :long %>.
|
||||
<% else %>
|
||||
It has not been scheduled yet.
|
||||
<% end %>
|
||||
|
||||
Please confirm your participation as soon as you can by following the following link:
|
||||
To confirm your participation please follow the link below as soon as you can:
|
||||
<%= confirm_event_url @event, host: @event.conference.host_name, protocol: 'https' %>
|
||||
|
||||
We kindly request that you ensure the inclusion of the QR code attached to this email in your presentation. It links directly to the feedback form for your presentation, making it easier for attendees to provide valuable insights.
|
||||
|
||||
Please email ofvideo@openfest.org if you hav any specific requirements, for example:
|
||||
Should you have any questions or require further information, please do not hesitate to contact us by replying to this email.
|
||||
|
||||
* You need us to provide you with a laptop for your presentation;
|
||||
* You need to play sound for your presentation;
|
||||
* You need either wired or wireless Internet connectivity;
|
||||
* You're using a macbook.
|
||||
|
||||
Please respond to this email in case you have any questions.
|
||||
|
||||
Regards,
|
||||
Best regards,
|
||||
The <%= @event.conference.title %> Team
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
Здравейте,
|
||||
|
||||
За съжаление, поради големия брой предложения за лекции, които получихме тази година, както и ограниченото време и брой зали, с които разполагаме, вашето предложение за <%= @event.event_type.name.mb_chars.downcase %> на тема „<%= @event.title %>“ не влезе в основната програма.
|
||||
За съжаление, поради голямото количество предложения за лекции, които получихме тази година, и ограниченото ни време, предложението ви за <%= @event.event_type.name.mb_chars.downcase %> на тема „<%= @event.title %>“ няма да може да бъде включено в програмата.
|
||||
|
||||
Тъй като темата звучи интересно, бихме ви предложили да се включите с lightning talk (петминутна презентация с или без слайдове) в дните на конференциятa.
|
||||
Обаче, ако желаете, може да представите лекцията си в рамките на 5 минути като част от програмата на Lightning talks (кратки 5 минутни лекции). Записването за тези слотове ще бъде възможно на място.
|
||||
|
||||
Записването тези кратки презентации ще се случва на регистрацията на <%= @event.conference.title %> след откриването на събитието в събота.
|
||||
Благодарим ви за интереса и участието ви в нашето събитие. До скоро!
|
||||
|
||||
До скоро! Екипът на <%= @event.conference.title %>
|
||||
Поздрави,
|
||||
Екипът на <%= @event.conference.title %>
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
Hi,
|
||||
Hello,
|
||||
|
||||
Regretfully, because of the high amount of talk submissions that we've received this year and the limited amounts of time and rooms that we have, your submission for a <%= @event.event_type.name.mb_chars.downcase %> titled "<%= @event.title %>" was not included in the program.
|
||||
We regret to inform you that, due to an overwhelming number of talk submissions and the time constraints, we were unable to include your submission for a <%= @event.event_type.name.mb_chars.downcase %> titled "<%= @event.title %>" in the main schedule.
|
||||
|
||||
As the topic might still be interesting to our audience, it would be possible to join as a lightning talk (a five-minute talk with or without slides) during the conference.
|
||||
However, we have an alternative option available for you. If you're interested, you can present a condensed, 5-minute version of your talk during our Lightning Talks slot at the event venue. You can sign up for Lightning Talks in person during the event.
|
||||
|
||||
The sign-up for these talks happens at the registration of <%= @event.conference.title %> after the opening on Saturday.
|
||||
We appreciate your interest in contributing to <%= @event.conference.title %> and hope to see you there!
|
||||
|
||||
See you soon,
|
||||
<%= @event.conference.title %> team
|
||||
Best regards,
|
||||
<%= @event.conference.title %> Team
|
||||
|
|
|
@ -12,10 +12,10 @@ html
|
|||
- else
|
||||
| Clarion
|
||||
|
||||
= stylesheet_link_tag "management/application"
|
||||
= stylesheet_link_tag "management/application", nopush: false
|
||||
= csrf_meta_tags
|
||||
body
|
||||
main
|
||||
= render 'layouts/management/flash'
|
||||
== yield
|
||||
= javascript_include_tag "management/application"
|
||||
= javascript_include_tag "management/application", nopush: false
|
||||
|
|
|
@ -15,11 +15,11 @@ html
|
|||
- else
|
||||
| Clarion
|
||||
|
||||
= stylesheet_link_tag "management/application"
|
||||
= stylesheet_link_tag "management/application", nopush: false
|
||||
= csrf_meta_tags
|
||||
body
|
||||
= render 'layouts/management/navigation'
|
||||
main
|
||||
= render 'layouts/management/flash'
|
||||
== yield
|
||||
= javascript_include_tag "management/application"
|
||||
= javascript_include_tag "management/application", nopush: false
|
||||
|
|
|
@ -32,7 +32,9 @@ nav.navbar.navbar-static-top.navbar-inverse role="navigation"
|
|||
/ li class="#{'active' if controller_name == 'propositions'}"
|
||||
/ = link_to [:management, current_conference, :propositions] do
|
||||
/ => icon 'question', Proposition.model_name.human(count: 2).mb_chars.capitalize, class: 'fa-fw'
|
||||
|
||||
li class="#{'active' if controller_name == 'feedback'}"
|
||||
= link_to management_conference_feedback_index_path(current_conference) do
|
||||
=> icon 'star-half-o', t('activerecord.models.feedback', count: 2).mb_chars.capitalize, class: 'fa-fw'
|
||||
ul.nav.navbar-nav.navbar-right
|
||||
li.dropdown
|
||||
= link_to '#', class: 'dropdown-toggle', data: {toggle: 'dropdown'} do
|
||||
|
|
|
@ -20,9 +20,12 @@
|
|||
.label.label-info
|
||||
= event.rank
|
||||
=< number_to_percentage(event.per_cent_of_votes, strip_insignificant_zeros: true, precision: 2)
|
||||
|
||||
|
||||
|
||||
- if event.rated?
|
||||
dt = t(".average_rating")
|
||||
dd
|
||||
=> human_rating(event.average_rating)
|
||||
.badge class="badge-#{rating_label_color(event.average_rating)}"
|
||||
= number_with_precision event.average_rating, precision: 2, strip_insignificant_zeros: true
|
||||
td.visible-md.visible-lg.visible-xl
|
||||
= links_to_event_participants_for(event)
|
||||
td.action
|
||||
|
|
|
@ -1,89 +1,123 @@
|
|||
- personal_profile = speaker.personal_profile(@conference) || speaker.personal_profiles.last
|
||||
|
||||
.panel.panel-default
|
||||
.panel-body
|
||||
.media
|
||||
.media-left.hidden-sm.hidden-xs
|
||||
- if personal_profile.present?
|
||||
= image_tag personal_profile.picture.medium.url, class: "profile-image"
|
||||
- else
|
||||
= icon :user, class: 'fa-5x'
|
||||
.media-body
|
||||
.text-center.visible-sm.visible-xs
|
||||
- if personal_profile.present?
|
||||
= image_tag personal_profile.picture.medium.url, class: "profile-image img-thumbnail"
|
||||
- else
|
||||
= icon :user, class: 'fa-5x'
|
||||
- if personal_profile.present?
|
||||
h4.media-heading
|
||||
= personal_profile.name
|
||||
- unless personal_profile.conference == @conference
|
||||
small<
|
||||
| (
|
||||
= t('.profile_from', conference: personal_profile.conference.title)
|
||||
| )
|
||||
hr
|
||||
h4 = PersonalProfile.human_attribute_name(:biography)
|
||||
= simple_format personal_profile.biography
|
||||
|
||||
h4 = t '.contacts'
|
||||
.row
|
||||
.col-sm-4
|
||||
.panel.panel-default
|
||||
- if personal_profile.present?
|
||||
.panel-image
|
||||
= image_tag personal_profile.picture
|
||||
.panel-body
|
||||
.media
|
||||
.media-body
|
||||
h4.media-heading
|
||||
= personal_profile.name
|
||||
hr
|
||||
= simple_format(truncate(personal_profile.biography, omission: '... ', length: 300) { link_to(t('.continue'), [:management, @conference, personal_profile])})
|
||||
ul.list-group
|
||||
- if personal_profile.organisation.present?
|
||||
p #{icon :briefcase} @#{personal_profile.organisation}
|
||||
li.list-group-item
|
||||
h5.list-group-item-heading = PersonalProfile.human_attribute_name :organisation
|
||||
p.list-group-item-text = personal_profile.organisation
|
||||
- if personal_profile.twitter.present?
|
||||
p #{icon :twitter} @#{personal_profile.twitter}
|
||||
- if personal_profile.public_email.present?
|
||||
p #{icon :envelope} #{personal_profile.public_email} (#{PersonalProfile.human_attribute_name(:public_email).mb_chars.downcase})
|
||||
p #{icon :envelope} #{speaker.email} (#{PersonalProfile.human_attribute_name(:email).mb_chars.downcase})
|
||||
p #{glyph :phone} #{Phony.format(personal_profile.mobile_phone, format: :international)}
|
||||
- else
|
||||
h4.media-heading
|
||||
= speaker.email
|
||||
hr
|
||||
p
|
||||
= t('.no_profile')
|
||||
=< link_to icon('user-plus', t('.create_profile')), new_management_conference_personal_profile_path(conference_id: @conference.id, user_id: speaker.id), class: ['btn', 'btn-primary', 'btn-xs']
|
||||
li.list-group-item
|
||||
h5.list-group-item-heading = PersonalProfile.human_attribute_name :twitter
|
||||
p.list-group-item-text
|
||||
= link_to "@#{personal_profile.twitter}", "https://twitter.com/#{personal_profile.twitter}", target: '_blank'
|
||||
- if personal_profile.github.present?
|
||||
li.list-group-item
|
||||
h5.list-group-item-heading = PersonalProfile.human_attribute_name :github
|
||||
p.list-group-item-text
|
||||
= link_to personal_profile.github, "https://github.com/#{personal_profile.github}", target: '_blank'
|
||||
.panel-footer
|
||||
.text-right
|
||||
.btn-group.btn-group-sm
|
||||
- if personal_profile.conference == @conference
|
||||
= action_buttons @conference, personal_profile, [:show, :edit]
|
||||
- else
|
||||
= link_to [:management, @conference, :personal_profiles, {personal_profile: {user_id: speaker.id}}], class: ['btn', 'btn-primary'], title: t('actions.clone.title', model: PersonalProfile.model_name.human), method: :post do
|
||||
=> icon('clone')
|
||||
= link_to [:new, :management, @conference, :personal_profile, {user_id: speaker.id}], class: ['btn', 'btn-primary'], title: t('actions.create.title', model: PersonalProfile.model_name.human) do
|
||||
=> icon('user-plus')
|
||||
- else
|
||||
.panel-image
|
||||
= image_tag 'user-secret-solid.svg'
|
||||
.panel-body
|
||||
.media
|
||||
.media-body
|
||||
h4.media-heading
|
||||
speaker.email
|
||||
hr
|
||||
p = t '.the_participant_has_not_created_a_profile'
|
||||
ul.list-group
|
||||
li.list-group-item
|
||||
h5.list-group-item-heading = t '.private_email'
|
||||
p.list-group-item-text = speaker.email
|
||||
|
||||
.col-sm-8
|
||||
.row
|
||||
.col-md-6
|
||||
.panel.panel-info
|
||||
.panel-heading
|
||||
.row
|
||||
.col-xs-3
|
||||
= icon 'files-o', '', class: 'fa-5x'
|
||||
.col-xs-9.text-right
|
||||
.huge
|
||||
= speaker.events_participated_in.size
|
||||
div
|
||||
= Event.model_name.human(count: speaker.events_participated_in.size)
|
||||
.col-md-6
|
||||
.panel class="panel-#{rating_label_color(speaker.average_rating || 5)}" title=human_rating(speaker.average_rating)
|
||||
.panel-heading
|
||||
.row
|
||||
.col-xs-3
|
||||
= icon 'star', '', class: 'fa-5x'
|
||||
.col-xs-9.text-right
|
||||
.huge
|
||||
= number_with_precision(speaker.average_rating, precision: 2, strip_insignificant_zeros: true) || '–'
|
||||
div
|
||||
= User.human_attribute_name(:average_rating).downcase
|
||||
|
||||
.row
|
||||
.col-xs-12
|
||||
h4 = t '.other_event_propositions'
|
||||
- if speaker.events_participated_in.where.not(id: @event.id).any?
|
||||
h4 = t '.previous_event_propositions'
|
||||
table.table.table-striped.table-hover.record-table
|
||||
thead
|
||||
tr
|
||||
th
|
||||
= Event.human_attribute_name :title
|
||||
th.text-center
|
||||
= Event.human_attribute_name :rank
|
||||
th
|
||||
= Event.human_attribute_name :conference
|
||||
th
|
||||
= Event.human_attribute_name :status
|
||||
th
|
||||
|
||||
tbody
|
||||
- speaker.events_participated_in.where.not(id: @event.id).order(created_at: :desc).each do |event|
|
||||
.panel.panel-default
|
||||
table.table.table-striped.table-hover.record-table
|
||||
thead
|
||||
tr
|
||||
td = event.title
|
||||
td.text-center
|
||||
- if event.ranked?
|
||||
th.main
|
||||
= Event.human_attribute_name :title
|
||||
th.text-center
|
||||
= Event.human_attribute_name :rating
|
||||
th.text-center.hidden-md.hidden-sm.hidden-xs
|
||||
= Event.human_attribute_name :rank
|
||||
th.hidden-md.hidden-sm.hidden-xs
|
||||
= Event.human_attribute_name :conference
|
||||
th.hidden-md.hidden-sm.hidden-xs
|
||||
= Event.human_attribute_name :status
|
||||
th.hidden-md.hidden-sm.hidden-xs
|
||||
|
||||
tbody
|
||||
- speaker.events_participated_in.where.not(id: @event.id).order(created_at: :desc).each do |event|
|
||||
tr
|
||||
td = event.title
|
||||
td.text-center
|
||||
- if event.rated?
|
||||
.large
|
||||
.label.label-info = event.rank
|
||||
td = event.conference.title
|
||||
td
|
||||
span class="label label-lg label-#{proposition_status_class(event.status)}"
|
||||
= icon(proposition_status_glyph(event.status), t("activerecord.attributes.proposition.statuses.#{event.status}"))
|
||||
.label class="label-#{rating_label_color(event.average_rating)}"
|
||||
= number_with_precision event.average_rating, precision: 2, strip_insignificant_zeros: true
|
||||
td.text-center.hidden-md.hidden-sm.hidden-xs
|
||||
- if event.ranked?
|
||||
.large
|
||||
.label.label-info = event.rank
|
||||
td.hidden-md.hidden-sm.hidden-xs = event.conference.title
|
||||
td.hidden-md.hidden-sm.hidden-xs
|
||||
span class="label label-lg label-#{proposition_status_class(event.status)}"
|
||||
= icon(proposition_status_glyph(event.status), t("activerecord.attributes.proposition.statuses.#{event.status}"))
|
||||
|
||||
td.actions
|
||||
.btn-group.btn-group-sm
|
||||
= action_buttons event.conference, event, [:show]
|
||||
|
||||
|
||||
- if personal_profile.present?
|
||||
.panel-footer
|
||||
.text-right
|
||||
.btn-group.btn-group-sm
|
||||
- if personal_profile.conference == @conference
|
||||
= action_buttons @conference, personal_profile, [:show, :edit]
|
||||
- else
|
||||
= link_to [:management, @conference, :personal_profiles, {personal_profile: {user_id: speaker.id}}], class: ['btn', 'btn-primary'], title: t('actions.clone.title', model: PersonalProfile.model_name.human), method: :post do
|
||||
=> icon('clone')
|
||||
= link_to [:new, :management, @conference, :personal_profile, {user_id: speaker.id}], class: ['btn', 'btn-primary'], title: t('actions.create.title', model: PersonalProfile.model_name.human) do
|
||||
=> icon('user-plus')
|
||||
td.actions
|
||||
.btn-group.btn-group-sm
|
||||
= action_buttons event.conference, event, [:show]
|
||||
- else
|
||||
p = t '.no_other_event_propositions'
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<%- csv_headers = %w{id title subtitle type track language paticipants status rank number_of_votes} -%>
|
||||
<%- csv_headers = %w{id title subtitle type track language paticipants length status rank number_of_votes proposer_notes} -%>
|
||||
<%= CSV.generate_line(csv_headers).html_safe -%>
|
||||
<%- @events.each do |event| -%>
|
||||
<%= CSV.generate_line([event.id, event.title, event.subtitle, event.event_type.name, event.track.name, event.language, participant_names_with_emails(event).join(', '), event.status, event.rank, event.number_of_votes]).html_safe -%>
|
||||
<%= CSV.generate_line([event.id, event.title, event.subtitle, event.event_type.name, event.track.name, event.language, participant_names_with_emails(event).join(', '), event.length, event.status, event.rank, event.number_of_votes, event.notes]).html_safe -%>
|
||||
<%- end -%>
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
= Event.model_name.human(count: 2).mb_chars.titleize
|
||||
small<
|
||||
| (
|
||||
= t '.total', current: @events.count, total: current_conference.events.count
|
||||
=< Event.model_name.human(count: current_conference.events.count)
|
||||
= t '.total', current: @events.size, total: @conference.events.size
|
||||
=< Event.model_name.human(count: @conference.events.size)
|
||||
| )
|
||||
.row.visible-sm
|
||||
.col-xs-12
|
||||
|
@ -21,73 +21,73 @@
|
|||
.panel-body
|
||||
ul.nav.nav-pills.nav-stacked
|
||||
= content_tag :li, role: "presentation", class: @filters[:event_type_id].blank? ? 'active' : nil
|
||||
= link_to management_conference_events_path(current_conference, filters: @filters.except(:event_type_id))
|
||||
= link_to management_conference_events_path(@conference, filters: @filters.except(:event_type_id))
|
||||
= t '.all'
|
||||
span.badge.pull-right = current_conference.events.count
|
||||
- current_conference.event_types.each do |event_type|
|
||||
span.badge.pull-right = @conference.events.size
|
||||
- @conference.event_types.each do |event_type|
|
||||
= content_tag :li, role: "presentation", class: @filters[:event_type_id].to_i == event_type.id ? 'active' : nil
|
||||
= link_to management_conference_events_path(current_conference, filters: @filters.merge({event_type_id: event_type.id}))
|
||||
= link_to management_conference_events_path(@conference, filters: @filters.merge({event_type_id: event_type.id}))
|
||||
= event_type.name
|
||||
span.badge.pull-right = current_conference.events.where(event_type: event_type).count
|
||||
span.badge.pull-right = @conference.events.where(event_type: event_type).size
|
||||
.panel.panel-default
|
||||
.panel-heading
|
||||
= Event.human_attribute_name(:track)
|
||||
.panel-body
|
||||
ul.nav.nav-pills.nav-stacked
|
||||
= content_tag :li, role: "presentation", class: @filters[:track_id].blank? ? 'active' : nil
|
||||
= link_to management_conference_events_path(current_conference, filters: @filters.except(:track_id))
|
||||
= link_to management_conference_events_path(@conference, filters: @filters.except(:track_id))
|
||||
= t '.all'
|
||||
span.badge.pull-right = current_conference.events.count
|
||||
- current_conference.tracks.each do |track|
|
||||
span.badge.pull-right = @conference.events.size
|
||||
- @conference.tracks.each do |track|
|
||||
= content_tag :li, role: "presentation", class: @filters[:track_id] == track.id.to_s ? 'active' : nil
|
||||
= link_to management_conference_events_path(current_conference, filters: @filters.merge({track_id: track.id}))
|
||||
= link_to management_conference_events_path(@conference, filters: @filters.merge({track_id: track.id}))
|
||||
= track.name
|
||||
span.badge.pull-right = current_conference.events.where(track: track).count
|
||||
span.badge.pull-right = @conference.events.where(track: track).size
|
||||
.panel.panel-default
|
||||
.panel-heading
|
||||
= Event.human_attribute_name(:language)
|
||||
.panel-body
|
||||
ul.nav.nav-pills.nav-stacked
|
||||
= content_tag :li, role: "presentation", class: @filters[:language].blank? ? 'active' : nil
|
||||
= link_to management_conference_events_path(current_conference, filters: @filters.except(:language))
|
||||
= link_to management_conference_events_path(@conference, filters: @filters.except(:language))
|
||||
= t '.all'
|
||||
span.badge.pull-right = current_conference.events.count
|
||||
span.badge.pull-right = @conference.events.size
|
||||
- I18n.available_locales.map(&:to_s).each do |language|
|
||||
= content_tag :li, role: "presentation", class: @filters[:language] == language ? 'active' : nil
|
||||
= link_to management_conference_events_path(current_conference, filters: @filters.merge({language: language}))
|
||||
= link_to management_conference_events_path(@conference, filters: @filters.merge({language: language}))
|
||||
= t("locales.#{language}")
|
||||
span.badge.pull-right = current_conference.events.where(language: language).count
|
||||
span.badge.pull-right = @conference.events.where(language: language).size
|
||||
.panel.panel-default
|
||||
.panel-heading
|
||||
= Proposition.human_attribute_name(:status)
|
||||
.panel-body
|
||||
ul.nav.nav-pills.nav-stacked
|
||||
= content_tag :li, role: "presentation", class: @filters[:status].blank? ? 'active' : nil
|
||||
= link_to management_conference_events_path(current_conference, filters: @filters.except(:status))
|
||||
= link_to management_conference_events_path(@conference, filters: @filters.except(:status))
|
||||
= t '.all'
|
||||
span.badge.pull-right = current_conference.events.count
|
||||
span.badge.pull-right = @conference.events.size
|
||||
- Proposition.statuses.each do |status_name, status_id|
|
||||
= content_tag :li, role: "presentation", class: @filters[:status] == status_id.to_s ? 'active' : nil
|
||||
= link_to management_conference_events_path(current_conference, filters: @filters.merge({status: status_id}))
|
||||
= link_to management_conference_events_path(@conference, filters: @filters.merge({status: status_id}))
|
||||
= t "activerecord.attributes.proposition.statuses.#{status_name}"
|
||||
span.badge.pull-right = current_conference.events.joins(:proposition).where(propositions: {status: status_id}).count
|
||||
span.badge.pull-right = @conference.events.joins(:proposition).where(propositions: {status: status_id}).size
|
||||
.panel.panel-default
|
||||
.panel-heading
|
||||
= Proposition.human_attribute_name(:confirmed)
|
||||
.panel-body
|
||||
ul.nav.nav-pills.nav-stacked
|
||||
= content_tag :li, role: "presentation", class: @filters[:confirmed].blank? && @filters[:not_confirmed].blank? ? 'active' : nil
|
||||
= link_to management_conference_events_path(current_conference, filters: @filters.except(:confirmed, :not_confirmed))
|
||||
= link_to management_conference_events_path(@conference, filters: @filters.except(:confirmed, :not_confirmed))
|
||||
= t '.all'
|
||||
span.badge.pull-right = current_conference.events.count
|
||||
span.badge.pull-right = @conference.events.size
|
||||
= content_tag :li, role: "presentation", class: @filters[:confirmed].present? ? 'active' : nil
|
||||
= link_to management_conference_events_path(current_conference, filters: @filters.except(:not_confirmed).merge({confirmed: true}))
|
||||
= link_to management_conference_events_path(@conference, filters: @filters.except(:not_confirmed).merge({confirmed: true}))
|
||||
= t "activerecord.attributes.proposition.confirmation.confirmed"
|
||||
span.badge.pull-right = current_conference.events.joins(:proposition).approved.where.not(propositions: {confirmed_at: nil}).count
|
||||
span.badge.pull-right = @conference.events.joins(:proposition).approved.where.not(propositions: {confirmed_at: nil}).size
|
||||
= content_tag :li, role: "presentation", class: @filters[:not_confirmed].present? ? 'active' : nil
|
||||
= link_to management_conference_events_path(current_conference, filters: @filters.except(:confirmed).merge({not_confirmed: true}))
|
||||
= link_to management_conference_events_path(@conference, filters: @filters.except(:confirmed).merge({not_confirmed: true}))
|
||||
= t "activerecord.attributes.proposition.confirmation.not_confirmed"
|
||||
span.badge.pull-right = current_conference.events.joins(:proposition).approved.where(propositions: {confirmed_at: nil}).count
|
||||
span.badge.pull-right = @conference.events.joins(:proposition).approved.where(propositions: {confirmed_at: nil}).size
|
||||
|
||||
.col-md-9
|
||||
.panel.panel-default
|
||||
|
@ -102,5 +102,5 @@
|
|||
tbody
|
||||
= render(partial: 'event', collection: @events) || render(partial: 'no_records')
|
||||
.panel-footer.text-right
|
||||
= link_to management_conference_events_path(current_conference, filters: @filters, format: 'csv'), class: 'btn btn-info'
|
||||
= link_to management_conference_events_path(@conference, filters: @filters, format: 'csv'), class: 'btn btn-info'
|
||||
= icon :download, t('.export')
|
||||
|
|
|
@ -65,52 +65,88 @@
|
|||
h3 = Event.human_attribute_name :participants
|
||||
= render partial: 'speaker', collection: @event.participants
|
||||
|
||||
- if @conference.has_vote_results? or @conference.has_voting_endpoint?
|
||||
.row
|
||||
.col-xs-12
|
||||
h2
|
||||
= t '.conflicts'
|
||||
small< = t '.between_approved_events'
|
||||
.panel.panel-default
|
||||
table.table.table-striped.table-hover.record-table
|
||||
- if @conference.has_vote_results? and @conference.approved_events.count > 2
|
||||
thead
|
||||
tr
|
||||
th.text-right
|
||||
= t '.percent'
|
||||
th
|
||||
= Event.model_name.human.mb_chars.capitalize
|
||||
th
|
||||
tbody
|
||||
- if @conference.has_vote_results?
|
||||
- if @conference.approved_events.count > 2
|
||||
- @event.conflict_counts.where(right_id: @conference.approved_events.pluck(:id)).includes(:right).each do |conflict_count|
|
||||
- conflict_percent = Rational(conflict_count.number_of_conflicts, @conference.number_of_ballots_cast)
|
||||
tr
|
||||
td.text-right
|
||||
.large
|
||||
span.label.label-success data-conflicts="#{conflict_count.number_of_conflicts}" data-most-conflicts="#{@conference.most_conflicts_between_approved_events}" data-least-conflicts="#{@conference.least_conflicts_between_approved_events}"
|
||||
= number_to_percentage(conflict_percent * 100, strip_insignificant_zeros: true, precision: 2)
|
||||
td
|
||||
h4 = conflict_count.right.title
|
||||
h5 = conflict_count.right.subtitle
|
||||
= links_to_event_participants_for(conflict_count.right)
|
||||
- if @conference.start_date.past? || @event.rated?
|
||||
.row
|
||||
.col-xs-12
|
||||
h3 = Event.human_attribute_name :feedbacks
|
||||
- if @event.rated?
|
||||
.row
|
||||
.col-md-10
|
||||
.panel.panel-default
|
||||
.panel-heading = t('.comments')
|
||||
- if @event.feedbacks_with_comment.size > 0
|
||||
table.table.table-striped
|
||||
tbody
|
||||
= render partial: '/management/shared/feedback', collection: @event.feedbacks_with_comment
|
||||
- else
|
||||
.panel-body
|
||||
= t ('.no_comments_received')
|
||||
.col-md-2
|
||||
.panel.panel-info
|
||||
.panel-heading
|
||||
= t '.average_grade'
|
||||
.panel-body.text-right
|
||||
.huge
|
||||
= number_with_precision(@event.average_rating, precision: 2, strip_insignificant_zeros: true) || '–'
|
||||
= t('.total_feedback_grades', total_grades: @event.feedbacks.count, count: @event.feedbacks.count)
|
||||
- else
|
||||
p = t '.no_feedback_received'
|
||||
|
||||
td.actions
|
||||
= action_buttons @conference, conflict_count.right, [:show]
|
||||
|
||||
- if @conference.has_vote_results? or @conference.has_voting_endpoint?
|
||||
.row
|
||||
.col-xs-12
|
||||
h2
|
||||
- if @conference.start_date.future?
|
||||
= t '.conflicts'
|
||||
- else
|
||||
= t '.top_conflicts'
|
||||
small< = t '.between_approved_events'
|
||||
.panel.panel-default
|
||||
table.table.table-striped.table-hover.record-table
|
||||
- if @conference.has_vote_results? and @conference.approved_events.count > 2
|
||||
thead
|
||||
tr
|
||||
th.text-right
|
||||
= t '.percent'
|
||||
th.main
|
||||
= Event.model_name.human.mb_chars.capitalize
|
||||
th
|
||||
tbody
|
||||
- if @conference.has_vote_results?
|
||||
- if @conference.approved_events.count > 2
|
||||
- if @conference.start_date.future?
|
||||
- conflict_counts = @event.conflict_counts.where(right_id: @conference.approved_events.pluck(:id)).includes(:right)
|
||||
- else
|
||||
- conflict_counts = @event.conflict_counts.where(right_id: @conference.approved_events.pluck(:id)).includes(:right).limit(5)
|
||||
- conflict_counts.each do |conflict_count|
|
||||
- conflict_percent = Rational(conflict_count.number_of_conflicts, @conference.number_of_ballots_cast)
|
||||
tr
|
||||
td.text-right
|
||||
.large
|
||||
span.label.label-success data-conflicts="#{conflict_count.number_of_conflicts}" data-most-conflicts="#{@conference.most_conflicts_between_approved_events}" data-least-conflicts="#{@conference.least_conflicts_between_approved_events}"
|
||||
= number_to_percentage(conflict_percent * 100, strip_insignificant_zeros: true, precision: 2)
|
||||
td
|
||||
h4 = conflict_count.right.title
|
||||
h5 = conflict_count.right.subtitle
|
||||
= links_to_event_participants_for(conflict_count.right)
|
||||
|
||||
td.actions
|
||||
= action_buttons @conference, conflict_count.right, [:show]
|
||||
- else
|
||||
tr
|
||||
td colspan="20"
|
||||
= t '.no_approved_events'
|
||||
- else
|
||||
tr
|
||||
td colspan="20"
|
||||
= t '.no_approved_events'
|
||||
- else
|
||||
tr
|
||||
td colspan="20"
|
||||
= t 'management.conferences.vote_results.vote_data_never_updated'
|
||||
= t 'management.conferences.vote_results.vote_data_never_updated'
|
||||
= link_to update_vote_data_management_conference_path(@conference), method: :patch, class: ['btn', 'btn-primary'] do
|
||||
= icon :refresh, t('management.conferences.vote_results.fetch_vote_results')
|
||||
- if @conference.has_vote_results?
|
||||
.panel-footer.text-right
|
||||
.btn-group
|
||||
= link_to conflicts_management_conference_event_path(@event, conference_id: @conference.id), class: ['btn', 'btn-info'] do
|
||||
= icon :percent, t('.conflicts')
|
||||
= link_to update_vote_data_management_conference_path(@conference), method: :patch, class: ['btn', 'btn-primary'] do
|
||||
= icon :refresh, t('management.conferences.vote_results.fetch_vote_results')
|
||||
- if @conference.has_vote_results?
|
||||
.panel-footer.text-right
|
||||
.btn-group
|
||||
= link_to conflicts_management_conference_event_path(@event, conference_id: @conference.id), class: ['btn', 'btn-info'] do
|
||||
= icon :percent, t('.conflicts')
|
||||
= link_to update_vote_data_management_conference_path(@conference), method: :patch, class: ['btn', 'btn-primary'] do
|
||||
= icon :refresh, t('management.conferences.vote_results.fetch_vote_results')
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
<%- csv_headers = %w{id feedback_receiving_type feedback_receiving_id name/title author_email rating comment ip session_id created_at} -%>
|
||||
<%= CSV.generate_line(csv_headers).html_safe -%>
|
||||
<%- @conference.feedbacks.each do |feedback| -%>
|
||||
<%= CSV.generate_line([feedback.id, feedback.feedback_receiving_type, feedback.feedback_receiving_id, feedback.feedback_receiving&.title || feefback.feedback_receiving&.name, feedback.author_email, feedback.rating, feedback.comment, feedback.ip_address, feedback.session_id, feedback.created_at]).html_safe -%>
|
||||
<%- end -%>
|
||||
<%- @conference.event_feedbacks.each do |feedback| -%>
|
||||
<%= CSV.generate_line([feedback.id, feedback.feedback_receiving_type, feedback.feedback_receiving_id, feedback.feedback_receiving&.title || feefback.feedback_receiving&.name, feedback.author_email, feedback.rating, feedback.comment, feedback.ip_address, feedback.session_id, feedback.created_at]).html_safe -%>
|
||||
<%- end -%>
|
|
@ -0,0 +1,62 @@
|
|||
- content_for :title
|
||||
= t '.feedback'
|
||||
|
||||
.row
|
||||
.col-lg-12
|
||||
h1.page-header
|
||||
= t '.feedback'
|
||||
= link_to management_conference_feedback_index_path(@conference, format: 'csv'), class: 'btn btn-info pull-right'
|
||||
= icon :download, t('.export')
|
||||
|
||||
- if @conference.start_date.past? || @conference.rated?
|
||||
.row
|
||||
.col-xs-12
|
||||
h3
|
||||
=< t '.overall_organisation'
|
||||
- if @conference.rated?
|
||||
.row
|
||||
.col-md-10
|
||||
.panel.panel-default
|
||||
.panel-heading = t('.comments')
|
||||
- if @conference.feedbacks_with_comment.order(created_at: :asc).size > 0
|
||||
table.table.table-striped
|
||||
tbody
|
||||
= render partial: '/management/shared/feedback', collection: @conference.feedbacks_with_comment.order(created_at: :asc), locals: {hide_title: true}
|
||||
- else
|
||||
.panel-body
|
||||
= t ('.no_comments_received')
|
||||
.col-md-2
|
||||
.panel.panel-info
|
||||
.panel-heading
|
||||
= t '.average_grade'
|
||||
.panel-body.text-right
|
||||
.huge
|
||||
= number_with_precision(@conference.average_rating, precision: 2, strip_insignificant_zeros: true) || '–'
|
||||
= t('.total_feedback_grades', total_grades: @conference.feedbacks.count, count: @conference.feedbacks.count)
|
||||
- else
|
||||
p = t '.no_feedback_received'
|
||||
|
||||
- if @conference.start_date.past? || @conference.event_feedbacks_with_comment.order(created_at: :asc).size > 0
|
||||
.row
|
||||
.col-xs-12
|
||||
h3
|
||||
=< t '.events'
|
||||
|
||||
- if @conference.event_feedbacks.size > 0
|
||||
.row
|
||||
.col-md-10
|
||||
.panel.panel-default
|
||||
.panel-heading = t('.comments')
|
||||
table.table.table-striped
|
||||
tbody
|
||||
= render partial: '/management/shared/feedback', collection: @conference.event_feedbacks_with_comment.order(created_at: :asc)
|
||||
.col-md-2
|
||||
.panel.panel-info
|
||||
.panel-heading
|
||||
= t '.average_grade'
|
||||
.panel-body.text-right
|
||||
.huge
|
||||
= number_with_precision(@conference.event_feedbacks.average(:rating), precision: 2, strip_insignificant_zeros: true) || '–'
|
||||
= t('.total_feedback_grades', total_grades: @conference.event_feedbacks.count, count: @conference.event_feedbacks.count)
|
||||
- else
|
||||
p = t '.no_comments_received'
|
|
@ -10,9 +10,9 @@
|
|||
.panel-body
|
||||
.row
|
||||
.col-lg-12
|
||||
- if f.object.picture.present?
|
||||
- if f.object.picture.attached?
|
||||
.col-sm-offset-3.col-sm-9
|
||||
= image_tag f.object.picture.medium.url, class: 'img-thumbnail'
|
||||
= image_tag f.object.picture.variant(resize_to_limit: [150, 150]), class: 'img-thumbnail'
|
||||
|
||||
= f.input :picture, wrapper: :horizontal_file_input
|
||||
|
||||
|
|
|
@ -27,10 +27,9 @@
|
|||
.media
|
||||
.media-left
|
||||
- if profile.present?
|
||||
= image_tag(profile.picture.thumb.url)
|
||||
= image_tag(profile.picture.variant(resize_to_fill: [50, 50]))
|
||||
- else
|
||||
= image_tag(PictureUploader.new.thumb.url)
|
||||
|
||||
= image_tag('avatar-placeholder.png')
|
||||
.media-body
|
||||
h4.media-heading
|
||||
- if profile.try(:name).present?
|
||||
|
|
|
@ -5,65 +5,117 @@
|
|||
.col-lg-12
|
||||
h1.page-header
|
||||
= PersonalProfile.model_name.human.mb_chars.capitalize
|
||||
|
||||
.panel.panel-default
|
||||
.panel-body
|
||||
.media
|
||||
.media-left.hidden-sm.hidden-xs
|
||||
= image_tag @profile.picture.medium.url, class: "profile-image"
|
||||
.media-body
|
||||
.text-center.visible-sm.visible-xs
|
||||
= image_tag @profile.picture.medium.url, class: "profile-image img-thumbnail"
|
||||
h4.media-heading
|
||||
= @profile.name
|
||||
hr
|
||||
h4 = PersonalProfile.human_attribute_name(:biography)
|
||||
= simple_format @profile.biography
|
||||
h4 = t '.contacts'
|
||||
.row
|
||||
.col-sm-5.col-md-4
|
||||
.panel.panel-default
|
||||
.panel-image
|
||||
= image_tag @profile.picture
|
||||
.panel-body
|
||||
.media
|
||||
.media-body
|
||||
h4.media-heading
|
||||
= @profile.name
|
||||
hr
|
||||
= simple_format @profile.biography
|
||||
ul.list-group
|
||||
- if @profile.mobile_phone.present?
|
||||
li.list-group-item
|
||||
h5.list-group-item-heading = PersonalProfile.human_attribute_name :mobile_phone
|
||||
p.list-group-item-text = Phony.format(@profile.mobile_phone, format: :international)
|
||||
- if @profile.organisation.present?
|
||||
p = icon :briefcase, @profile.organisation
|
||||
li.list-group-item
|
||||
h5.list-group-item-heading = PersonalProfile.human_attribute_name :organisation
|
||||
p.list-group-item-text = @profile.organisation
|
||||
- if @profile.twitter.present?
|
||||
p = icon :twitter, "@#{@profile.twitter}"
|
||||
li.list-group-item
|
||||
h5.list-group-item-heading = PersonalProfile.human_attribute_name :twitter
|
||||
p.list-group-item-text
|
||||
= link_to "@#{@profile.twitter}", "https://twitter.com/#{@profile.twitter}", target: '_blank'
|
||||
- if @profile.github.present?
|
||||
p = icon :github, @profile.github
|
||||
li.list-group-item
|
||||
h5.list-group-item-heading = PersonalProfile.human_attribute_name :github
|
||||
p.list-group-item-text
|
||||
= link_to @profile.github, "https://github.com/#{@profile.github}", target: '_blank'
|
||||
- if @profile.public_email.present?
|
||||
p = icon :envelope, "#{@profile.public_email} (#{PersonalProfile.human_attribute_name(:public_email).mb_chars.downcase})"
|
||||
p = icon :envelope, "#{@user.email} (#{User.human_attribute_name(:email).mb_chars.downcase})"
|
||||
li.list-group-item
|
||||
h5.list-group-item-heading = PersonalProfile.human_attribute_name :public_email
|
||||
p.list-group-item-text = @profile.public_email
|
||||
li.list-group-item
|
||||
h5.list-group-item-heading = t '.private_email'
|
||||
p.list-group-item-text = @user.email
|
||||
.panel-footer
|
||||
.text-right
|
||||
.btn-group.btn-group-sm
|
||||
= action_buttons @conference, @profile, [:edit, :destroy]
|
||||
.col-sm-7.col-md-8
|
||||
.row
|
||||
.col-md-6
|
||||
.panel.panel-info
|
||||
.panel-heading
|
||||
.row
|
||||
.col-xs-3
|
||||
= icon 'files-o', '', class: 'fa-5x'
|
||||
.col-xs-9.text-right
|
||||
.huge
|
||||
= @user.events_participated_in.size
|
||||
div
|
||||
= Event.model_name.human(count: @user.events_participated_in.size)
|
||||
.col-md-6
|
||||
.panel class="panel-#{rating_label_color(@user.average_rating || 5)}" title=human_rating(@user.average_rating)
|
||||
.panel-heading
|
||||
.row
|
||||
.col-xs-3
|
||||
= icon 'star', '', class: 'fa-5x'
|
||||
.col-xs-9.text-right
|
||||
.huge
|
||||
= number_with_precision(@user.average_rating, precision: 2, strip_insignificant_zeros: true) || '–'
|
||||
div
|
||||
= User.human_attribute_name(:average_rating).downcase
|
||||
|
||||
- if @user.events_participated_in.any?
|
||||
h4 = t '.event_propositions'
|
||||
h2 = t '.talk_history'
|
||||
.panel.panel-default
|
||||
- if @user.events_participated_in.any?
|
||||
table.table.table-striped.table-hover.record-table
|
||||
thead
|
||||
tr
|
||||
th
|
||||
th.main
|
||||
= Event.human_attribute_name :title
|
||||
th.text-center
|
||||
= Event.human_attribute_name :rating
|
||||
th.text-center.hidden-md.hidden-sm.hidden-xs
|
||||
= Event.human_attribute_name :rank
|
||||
th
|
||||
th.hidden-md.hidden-sm.hidden-xs
|
||||
= Event.human_attribute_name :conference
|
||||
th
|
||||
th.hidden-md.hidden-sm.hidden-xs
|
||||
= Event.human_attribute_name :status
|
||||
th
|
||||
|
||||
tbody
|
||||
- @user.events_participated_in.order(created_at: :desc).each do |event|
|
||||
tr
|
||||
td = event.title
|
||||
td.text-center
|
||||
- if event.rated?
|
||||
.large
|
||||
.label class="label-#{rating_label_color(event.average_rating)}" title=human_rating(event.average_rating)
|
||||
= number_with_precision event.average_rating, precision: 2, strip_insignificant_zeros: true
|
||||
td.text-center.hidden-md.hidden-sm.hidden-xs
|
||||
- if event.ranked?
|
||||
.large
|
||||
.label.label-info = event.rank
|
||||
td = event.conference.title
|
||||
td
|
||||
td.hidden-md.hidden-sm.hidden-xs
|
||||
= event.conference.title
|
||||
td.hidden-md.hidden-sm.hidden-xs
|
||||
span class="label label-lg label-#{proposition_status_class(event.status)}"
|
||||
= icon(proposition_status_glyph(event.status), t("activerecord.attributes.proposition.statuses.#{event.status}"))
|
||||
|
||||
td.actions
|
||||
.btn-group.btn-group-sm
|
||||
= action_buttons event.conference, event, [:show]
|
||||
|
||||
|
||||
.panel-footer
|
||||
.text-right
|
||||
.btn-group.btn-group-sm
|
||||
= action_buttons @conference, @profile, [:edit, :destroy]
|
||||
h2 = t '.comments_from_the_audience'
|
||||
- if @user.feedbacks_with_comment.size > 0
|
||||
.panel.panel-default
|
||||
table.table.table-striped
|
||||
tbody
|
||||
= render partial: '/management/shared/feedback', collection: @user.feedbacks_with_comment.order(created_at: :desc)
|
||||
- else
|
||||
p = t '.no_comments_received'
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
tr
|
||||
td.text-center
|
||||
.huge
|
||||
.label class="label-#{rating_label_color(feedback.rating)}" title=human_rating(feedback.rating)
|
||||
= feedback.rating
|
||||
td
|
||||
blockquote
|
||||
= simple_format feedback.comment
|
||||
footer
|
||||
- if feedback.author_email.present?
|
||||
= feedback.author_email
|
||||
- else
|
||||
= t(".anonymous")
|
||||
- if !local_assigns[:hide_title]
|
||||
span<> = t '.about'
|
||||
= link_to feedback.feedback_receiving.title, [:management, current_conference, feedback.feedback_receiving]
|
|
@ -5,13 +5,14 @@
|
|||
.col-lg-12
|
||||
- if f.object.picture.present?
|
||||
.col-sm-offset-3.col-sm-9
|
||||
= attachment_image_tag(@volunteer, :picture, :fill, 150, 150) if @volunteer.picture.present?
|
||||
= @volunteer.picture.variant(resize_to_limit: [150, 150]) if @volunteer.picture.attached?
|
||||
|
||||
= f.input :picture, as: :attachment, wrapper: :horizontal_file_input, direct: true
|
||||
= f.input :picture, as: :file, wrapper: :horizontal_file_input, direct: true
|
||||
|
||||
= f.input :name, autofocus: true
|
||||
= f.input :email
|
||||
= f.association :volunteer_teams, as: :check_boxes, wrapper: :horizontal_radio_and_checkboxes, collection: current_conference.volunteer_teams
|
||||
= f.association :volunteer_team, as: :radio_buttons, wrapper: :horizontal_radio_and_checkboxes, collection: current_conference.volunteer_teams
|
||||
= f.association :additional_volunteer_teams, as: :check_boxes, wrapper: :horizontal_radio_and_checkboxes, collection: current_conference.volunteer_teams
|
||||
= f.input :phone, input_html: {value: @volunteer.phone.try(:phony_formatted, format: :international)}
|
||||
= f.input :language, as: :radio_buttons, wrapper: :horizontal_radio_and_checkboxes, collection: locale_collection, include_blank: false, checked: (@volunteer.language.presence || I18n.locale)
|
||||
= f.input :tshirt_size, collection: Volunteer::TSHIRT_SIZES, as: :radio_buttons, wrapper: :horizontal_radio_and_checkboxes, checked: (@volunteer.tshirt_size.presence || :m)
|
||||
|
@ -19,5 +20,6 @@
|
|||
= f.input :food_preferences, collection: Volunteer::FOOD_PREFERENCES, wrapper: :horizontal_radio_and_checkboxes, as: :radio_buttons, checked: (@volunteer.food_preferences.presence || :none)
|
||||
= f.input :previous_experience
|
||||
= f.input :notes
|
||||
= f.input :terms_accepted
|
||||
.panel-footer.text-right
|
||||
= f.submit class: 'btn btn-primary'
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue