Compare commits
No commits in common. "master" and "maintenance" have entirely different histories.
master
...
maintenanc
|
@ -1,43 +0,0 @@
|
|||
# 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,29 +7,18 @@
|
|||
# Ignore bundler config.
|
||||
/.bundle
|
||||
|
||||
# Ignore all environment files (except templates).
|
||||
/.env*
|
||||
!/.env*.erb
|
||||
# Ignore the default SQLite database.
|
||||
/db/*.sqlite3
|
||||
/db/*.sqlite3-journal
|
||||
|
||||
# Ignore all logfiles and tempfiles.
|
||||
/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
|
||||
/log/*.log
|
||||
/tmp
|
||||
/config/database.yml
|
||||
/config/secrets.yml
|
||||
/db/schema.rb
|
||||
/erd.pdf
|
||||
/public/uploads/tmp/*
|
||||
/public/uploads/personal_profile/*
|
||||
.sass-cache/
|
||||
/coverage/
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
require: standard
|
||||
|
||||
inherit_gem:
|
||||
standard: config/base.yml
|
||||
|
||||
AllCops:
|
||||
DisabledByDefault: true
|
|
@ -1 +0,0 @@
|
|||
3.3.5
|
13
.travis.yml
13
.travis.yml
|
@ -1,16 +1,7 @@
|
|||
language: ruby
|
||||
dist: xenial
|
||||
cache: bundler
|
||||
rvm:
|
||||
- 3.3
|
||||
- 2.4.5
|
||||
script:
|
||||
- RAILS_ENV=test bundle exec rake --trace bootstrap spec
|
||||
addons:
|
||||
chrome: stable
|
||||
apt:
|
||||
packages:
|
||||
- chromium-chromedriver
|
||||
services:
|
||||
- postgresql
|
||||
before_script:
|
||||
- ln -s /usr/lib/chromium-browser/chromedriver ~/bin/chromedriver
|
||||
sudo: false
|
||||
|
|
22
Capfile
22
Capfile
|
@ -1,11 +1,8 @@
|
|||
# Load DSL and set up stages
|
||||
require "capistrano/setup"
|
||||
require 'capistrano/setup'
|
||||
|
||||
# Include default deployment tasks
|
||||
require "capistrano/deploy"
|
||||
|
||||
require "capistrano/scm/git"
|
||||
install_plugin Capistrano::SCM::Git
|
||||
require 'capistrano/deploy'
|
||||
|
||||
# Include tasks from other gems included in your Gemfile
|
||||
#
|
||||
|
@ -18,19 +15,16 @@ install_plugin Capistrano::SCM::Git
|
|||
# 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"
|
||||
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/bundler'
|
||||
require 'capistrano/rails/assets'
|
||||
require 'capistrano/rails/migrations'
|
||||
require 'capistrano/puma'
|
||||
# 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 }
|
||||
|
|
62
Dockerfile
62
Dockerfile
|
@ -1,62 +0,0 @@
|
|||
# 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,92 +1,95 @@
|
|||
source "https://rubygems.org"
|
||||
source 'https://rubygems.org'
|
||||
|
||||
gem "rails", "~> 7.1.0"
|
||||
gem "bootsnap"
|
||||
gem "sprockets"
|
||||
gem 'rails', '~> 4.2.11'
|
||||
|
||||
gem "sqlite3"
|
||||
gem "pg"
|
||||
gem 'sqlite3'
|
||||
gem 'pg'
|
||||
|
||||
gem "sass-rails"
|
||||
gem 'sass-rails'
|
||||
|
||||
gem "uglifier"
|
||||
gem "coffee-rails"
|
||||
gem "jquery-rails"
|
||||
gem 'uglifier'
|
||||
gem 'coffee-rails'
|
||||
gem 'mini_racer', platforms: :ruby
|
||||
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"
|
||||
gem "phony_rails"
|
||||
gem 'phony_rails'
|
||||
|
||||
gem "puma", group: :production
|
||||
# Picture uploads
|
||||
gem 'carrierwave'
|
||||
#gem 'rmagick'
|
||||
gem "mini_magick"
|
||||
|
||||
gem "globalize"
|
||||
gem "refile", require: ['refile/rails', 'refile/simple_form']
|
||||
gem "refile-mini_magick"
|
||||
|
||||
gem "yaml_db"
|
||||
gem 'puma', group: :production
|
||||
|
||||
gem "bootstrap-sass"
|
||||
gem "bootstrap-sass-extras"
|
||||
gem "bootswatch-rails"
|
||||
gem "autoprefixer-rails"
|
||||
gem "font-awesome-sass", "~> 4.6.2"
|
||||
gem 'globalize'
|
||||
|
||||
gem "nested_form"
|
||||
gem "jquery-datatables-rails"
|
||||
# gem "morrisjs-rails"
|
||||
gem "raphael-rails"
|
||||
gem 'yaml_db'
|
||||
|
||||
gem "copy_carrierwave_file"
|
||||
gem 'bootstrap-sass'
|
||||
gem 'bootstrap-sass-extras'
|
||||
gem 'bootswatch-rails'
|
||||
gem 'autoprefixer-rails'
|
||||
gem 'font-awesome-sass'
|
||||
|
||||
gem "jbuilder"
|
||||
gem 'nested_form'
|
||||
gem 'jquery-datatables-rails'
|
||||
gem 'morrisjs-rails'
|
||||
gem 'raphael-rails'
|
||||
|
||||
gem "search_object"
|
||||
gem 'copy_carrierwave_file'
|
||||
|
||||
gem "faraday"
|
||||
gem 'jbuilder'
|
||||
|
||||
gem "rqrcode"
|
||||
gem 'search_object'
|
||||
|
||||
gem "draper"
|
||||
gem 'faraday'
|
||||
|
||||
gem "icalendar", require: ['icalendar', 'icalendar/tzinfo']
|
||||
gem 'rqrcode'
|
||||
|
||||
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 "better_errors"
|
||||
gem "binding_of_caller"
|
||||
gem 'awesome_print'
|
||||
gem 'quiet_assets'
|
||||
gem 'capistrano'
|
||||
gem 'capistrano-rails'
|
||||
# gem 'capistrano-rvm'
|
||||
gem 'capistrano3-puma'
|
||||
gem 'better_errors'
|
||||
gem 'binding_of_caller'
|
||||
end
|
||||
|
||||
group :development, :test do
|
||||
gem "rspec-rails"
|
||||
gem "faker"
|
||||
gem "capybara"
|
||||
gem "selenium-webdriver"
|
||||
gem 'rspec-rails'
|
||||
gem 'factory_girl_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 "standard"
|
||||
gem 'delorean'
|
||||
end
|
||||
|
||||
group :test do
|
||||
gem "database_cleaner"
|
||||
gem "factory_bot_rails"
|
||||
gem 'database_cleaner'
|
||||
end
|
||||
|
||||
gem "thruster", "~> 0.1.8"
|
||||
|
|
773
Gemfile.lock
773
Gemfile.lock
|
@ -1,208 +1,158 @@
|
|||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
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)
|
||||
actionmailer (4.2.11)
|
||||
actionpack (= 4.2.11)
|
||||
actionview (= 4.2.11)
|
||||
activejob (= 4.2.11)
|
||||
mail (~> 2.5, >= 2.5.4)
|
||||
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)
|
||||
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)
|
||||
builder (~> 3.1)
|
||||
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)
|
||||
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)
|
||||
builder (~> 3.1)
|
||||
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)
|
||||
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)
|
||||
rack (>= 0.9.0)
|
||||
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)
|
||||
binding_of_caller (0.7.2)
|
||||
debug_inspector (>= 0.0.1)
|
||||
bootsnap (1.18.3)
|
||||
msgpack (~> 1.2)
|
||||
bootstrap-sass (3.4.1)
|
||||
bootstrap-sass (3.3.7)
|
||||
autoprefixer-rails (>= 5.2.1)
|
||||
sassc (>= 2.0.0)
|
||||
bootstrap-sass-extras (0.1.0)
|
||||
sass (>= 3.3.4)
|
||||
bootstrap-sass-extras (0.0.7)
|
||||
rails (>= 3.1.0)
|
||||
bootswatch-rails (3.3.5)
|
||||
railties (>= 3.1)
|
||||
builder (3.2.4)
|
||||
byebug (11.1.3)
|
||||
capybara (3.40.0)
|
||||
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)
|
||||
addressable
|
||||
matrix
|
||||
mini_mime (>= 0.1.3)
|
||||
nokogiri (~> 1.11)
|
||||
nokogiri (~> 1.8)
|
||||
rack (>= 1.6.0)
|
||||
rack-test (>= 0.6.3)
|
||||
regexp_parser (>= 1.5, < 3.0)
|
||||
regexp_parser (~> 1.2)
|
||||
xpath (~> 3.2)
|
||||
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)
|
||||
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)
|
||||
choice (0.2.0)
|
||||
chronic (0.10.2)
|
||||
chunky_png (1.4.0)
|
||||
coderay (1.1.3)
|
||||
coffee-rails (5.0.0)
|
||||
chunky_png (1.3.8)
|
||||
coderay (1.1.1)
|
||||
coffee-rails (4.2.1)
|
||||
coffee-script (>= 2.2.0)
|
||||
railties (>= 5.2.0)
|
||||
railties (>= 4.0.0, < 5.2.x)
|
||||
coffee-script (2.4.1)
|
||||
coffee-script-source
|
||||
execjs
|
||||
coffee-script-source (1.12.2)
|
||||
concurrent-ruby (1.2.3)
|
||||
connection_pool (2.4.1)
|
||||
coffee-script-source (1.10.0)
|
||||
concurrent-ruby (1.1.4)
|
||||
copy_carrierwave_file (1.3.0)
|
||||
carrierwave (>= 0.9)
|
||||
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)
|
||||
crass (1.0.4)
|
||||
database_cleaner (1.7.0)
|
||||
debug_inspector (0.0.2)
|
||||
delorean (2.1.0)
|
||||
chronic
|
||||
devise (4.9.3)
|
||||
devise (4.2.0)
|
||||
bcrypt (~> 3.0)
|
||||
orm_adapter (~> 0.1)
|
||||
railties (>= 4.1.0)
|
||||
railties (>= 4.1.0, < 5.1)
|
||||
responders
|
||||
warden (~> 1.2.3)
|
||||
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)
|
||||
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)
|
||||
font-awesome-sass (4.6.2)
|
||||
sass (>= 3.2)
|
||||
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.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 (>= 0.2.4)
|
||||
listen (>= 2.7, < 4.0)
|
||||
lumberjack (>= 1.0.12, < 2.0)
|
||||
lumberjack (~> 1.0)
|
||||
nenv (~> 0.1)
|
||||
notiffany (~> 0.0)
|
||||
pry (>= 0.13.0)
|
||||
pry (>= 0.9.12)
|
||||
shellany (~> 0.0)
|
||||
thor (>= 0.18.1)
|
||||
guard-compat (1.2.1)
|
||||
|
@ -210,309 +160,241 @@ GEM
|
|||
guard (~> 2.1)
|
||||
guard-compat (~> 1.1)
|
||||
rspec (>= 2.99.0, < 4.0)
|
||||
highline (3.0.1)
|
||||
i18n (1.14.1)
|
||||
highline (1.7.8)
|
||||
http-cookie (1.0.3)
|
||||
domain_name (~> 0.5)
|
||||
i18n (0.9.5)
|
||||
concurrent-ruby (~> 1.0)
|
||||
i18n-tasks (1.0.13)
|
||||
i18n-tasks (0.9.5)
|
||||
activesupport (>= 4.0.2)
|
||||
ast (>= 2.1.0)
|
||||
better_html (>= 1.0, < 3.0)
|
||||
erubi
|
||||
highline (>= 2.0.0)
|
||||
easy_translate (>= 0.5.0)
|
||||
erubis
|
||||
highline (>= 1.7.3)
|
||||
i18n
|
||||
parser (>= 3.2.2.1)
|
||||
rails-i18n
|
||||
rainbow (>= 2.2.2, < 4.0)
|
||||
parser (>= 2.2.3.0)
|
||||
term-ansicolor (>= 1.3.2)
|
||||
terminal-table (>= 1.5.1)
|
||||
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)
|
||||
jbuilder (2.6.0)
|
||||
activesupport (>= 3.0.0, < 5.1)
|
||||
multi_json (~> 1.2)
|
||||
jquery-datatables-rails (3.4.0)
|
||||
actionpack (>= 3.1)
|
||||
jquery-rails
|
||||
railties (>= 3.1)
|
||||
sass-rails
|
||||
jquery-rails (4.6.0)
|
||||
jquery-rails (4.2.1)
|
||||
rails-dom-testing (>= 1, < 3)
|
||||
railties (>= 4.2.0)
|
||||
thor (>= 0.14, < 2.0)
|
||||
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)
|
||||
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)
|
||||
crass (~> 1.0.2)
|
||||
nokogiri (>= 1.12.0)
|
||||
lumberjack (1.2.10)
|
||||
mail (2.8.1)
|
||||
nokogiri (>= 1.5.9)
|
||||
lumberjack (1.0.10)
|
||||
mail (2.7.1)
|
||||
mini_mime (>= 0.1.1)
|
||||
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)
|
||||
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)
|
||||
nenv (0.3.0)
|
||||
nested_form (0.3.2)
|
||||
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)
|
||||
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)
|
||||
nenv (~> 0.1)
|
||||
shellany (~> 0.0)
|
||||
orm_adapter (0.5.0)
|
||||
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)
|
||||
parser (2.3.1.4)
|
||||
ast (~> 2.2)
|
||||
pg (0.19.0)
|
||||
phony (2.15.32)
|
||||
phony_rails (0.14.4)
|
||||
activesupport (>= 3.0)
|
||||
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)
|
||||
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)
|
||||
choice (~> 0.2.0)
|
||||
ruby-graphviz (~> 1.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)
|
||||
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)
|
||||
raphael-rails (2.1.2)
|
||||
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)
|
||||
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)
|
||||
chunky_png (~> 1.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)
|
||||
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)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.13.0)
|
||||
rspec-mocks (3.13.0)
|
||||
rspec-support (~> 3.5.0)
|
||||
rspec-mocks (3.5.0)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
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)
|
||||
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)
|
||||
shellany (0.0.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)
|
||||
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)
|
||||
actionpack (>= 3.1)
|
||||
railties (>= 3.1)
|
||||
slim (>= 3.0, < 6.0, != 5.0.0)
|
||||
smart_properties (1.17.0)
|
||||
spring (4.1.3)
|
||||
slim (~> 3.0)
|
||||
slop (3.6.0)
|
||||
spring (2.0.0)
|
||||
activesupport (>= 4.2)
|
||||
spring-commands-rspec (1.0.4)
|
||||
spring (>= 0.9.1)
|
||||
sprockets (4.2.1)
|
||||
sprockets (3.7.2)
|
||||
concurrent-ruby (~> 1.0)
|
||||
rack (>= 2.2.4, < 4)
|
||||
sprockets-rails (3.4.2)
|
||||
actionpack (>= 5.2)
|
||||
activesupport (>= 5.2)
|
||||
rack (> 1, < 3)
|
||||
sprockets-rails (3.2.1)
|
||||
actionpack (>= 4.0)
|
||||
activesupport (>= 4.0)
|
||||
sprockets (>= 3.0.0)
|
||||
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)
|
||||
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)
|
||||
execjs (>= 0.3.0, < 3)
|
||||
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)
|
||||
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)
|
||||
xpath (3.2.0)
|
||||
nokogiri (~> 1.8)
|
||||
yaml_db (0.7.0)
|
||||
rails (>= 3.0)
|
||||
yaml_db (0.4.2)
|
||||
rails (>= 3.0, < 5.1)
|
||||
rake (>= 0.8.7)
|
||||
zeitwerk (2.6.13)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
@ -522,40 +404,46 @@ 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
|
||||
draper
|
||||
factory_bot_rails
|
||||
factory_girl_rails
|
||||
faker
|
||||
faraday
|
||||
font-awesome-sass (~> 4.6.2)
|
||||
font-awesome-sass
|
||||
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
|
||||
rails (~> 7.1.0)
|
||||
quiet_assets
|
||||
rails (~> 4.2.11)
|
||||
rails-erd
|
||||
rails-i18n
|
||||
raphael-rails
|
||||
refile
|
||||
refile-mini_magick
|
||||
rqrcode
|
||||
rspec-rails
|
||||
sass-rails
|
||||
|
@ -566,12 +454,9 @@ DEPENDENCIES
|
|||
slim-rails
|
||||
spring
|
||||
spring-commands-rspec
|
||||
sprockets
|
||||
sqlite3
|
||||
standard
|
||||
thruster (~> 0.1.8)
|
||||
uglifier
|
||||
yaml_db
|
||||
|
||||
BUNDLED WITH
|
||||
2.5.6
|
||||
1.17.1
|
||||
|
|
14
Guardfile
14
Guardfile
|
@ -1,20 +1,18 @@
|
|||
# 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,31 +1,11 @@
|
|||
# Clarion
|
||||
Clarion
|
||||
=======
|
||||
|
||||
A CfP automation system for OpenFest.
|
||||
|
||||
## Installation
|
||||
Installation
|
||||
------------
|
||||
|
||||
### 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.
|
||||
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`
|
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,11 +17,12 @@
|
|||
- 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?
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
//= 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.
Before Width: | Height: | Size: 2.8 KiB |
|
@ -1,37 +0,0 @@
|
|||
<?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>
|
Before Width: | Height: | Size: 1.9 KiB |
|
@ -3,5 +3,6 @@
|
|||
//= require jquery_nested_form
|
||||
//= require bootstrap-sprockets
|
||||
//= require raphael
|
||||
//= require morris
|
||||
//= require chroma-js/chroma
|
||||
//= require_directory .
|
||||
|
|
|
@ -22,10 +22,6 @@ 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,10 +1,24 @@
|
|||
.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;
|
||||
.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
@import "bootstrap";
|
||||
@import "bootswatch/simplex/bootswatch";
|
||||
|
||||
/* @import "morris"; */
|
||||
@import "morris";
|
||||
|
||||
@import "users";
|
||||
@import "colors";
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
class Api::ConferencesController < Api::ApplicationController
|
||||
include ::PublicApiExposing
|
||||
|
||||
def index
|
||||
@conferences = Conference.all
|
||||
fresh_when @conferences
|
||||
end
|
||||
end
|
|
@ -1,10 +1,9 @@
|
|||
class Api::EventTypesController < Api::ApplicationController
|
||||
include ::CurrentConferenceAssigning
|
||||
include ::PublicApiExposing
|
||||
before_action :require_current_conference!
|
||||
before_filter :require_current_conference!
|
||||
|
||||
def index
|
||||
@event_types = current_conference.event_types.includes(:translations)
|
||||
fresh_when @event_types
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
class Api::EventsController < Api::ApplicationController
|
||||
include ::CurrentConferenceAssigning
|
||||
include ::PublicApiExposing
|
||||
before_action :require_current_conference!
|
||||
before_filter :require_current_conference!
|
||||
|
||||
def index
|
||||
@events = current_conference.events.approved.joins(:proposition).includes(:participations)
|
||||
end
|
||||
|
||||
def halfnarp_friendly
|
||||
@events = current_conference.events.joins(:proposition).includes(:track, :event_type).where.not(propositions: {status: :rejected})
|
||||
@events = current_conference.events.includes(:track, :event_type)
|
||||
render json: @events, include: [:track, :event_type]
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
class Api::HallsController < Api::ApplicationController
|
||||
include ::CurrentConferenceAssigning
|
||||
include ::PublicApiExposing
|
||||
before_action :require_current_conference!
|
||||
before_filter :require_current_conference!
|
||||
|
||||
def index
|
||||
@halls = current_conference.halls
|
||||
fresh_when @halls
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
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,11 +1,9 @@
|
|||
class Api::SlotsController < Api::ApplicationController
|
||||
include ::CurrentConferenceAssigning
|
||||
include ::PublicApiExposing
|
||||
before_action :require_current_conference!
|
||||
before_filter :require_current_conference!
|
||||
|
||||
def index
|
||||
@slots = current_conference.slots
|
||||
|
||||
fresh_when @slots
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
class Api::SpeakersController < Api::ApplicationController
|
||||
include ::CurrentConferenceAssigning
|
||||
include ::PublicApiExposing
|
||||
before_action :require_current_conference!
|
||||
before_filter :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,10 +1,9 @@
|
|||
class Api::TracksController < Api::ApplicationController
|
||||
include ::CurrentConferenceAssigning
|
||||
include ::PublicApiExposing
|
||||
before_action :require_current_conference!
|
||||
before_filter :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_action :configure_permitted_parameters, if: :devise_controller?
|
||||
before_filter :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? && (current_user.language != I18n.locale)
|
||||
if user_signed_in? and 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 =~ /^localhost$/
|
||||
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/
|
||||
|
||||
end
|
||||
|
||||
protected
|
||||
|
|
|
@ -11,8 +11,8 @@ module CurrentConferenceAssigning
|
|||
end
|
||||
|
||||
def current_conference
|
||||
unless @current_conference
|
||||
if @conference && !@conference.new_record?
|
||||
if not @current_conference
|
||||
if @conference and not @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!
|
||||
unless current_conference?
|
||||
raise ActionController::RoutingError.new("Not Found")
|
||||
if not 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_back fallback_location: [:management, current_conference]
|
||||
redirect_to :back
|
||||
end
|
||||
|
||||
def destroy
|
||||
current_conference.call_for_participation.close!
|
||||
redirect_back fallback_location: [:management, current_conference]
|
||||
redirect_to :back
|
||||
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_back fallback_location: [:management, @conference]
|
||||
rescue => e
|
||||
flash[:alert] = t(".error_during_connection_with_voting_endpoint", error: e.message)
|
||||
redirect_to :back
|
||||
rescue StandardError => 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,15 +2,8 @@ module Management
|
|||
class EventsController < ManagementController
|
||||
def index
|
||||
@conference = find_conference
|
||||
@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
|
||||
|
||||
@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
|
||||
# @events = @conference.events.order(:title).includes(:proposition, :proposer, :track, :event_type)
|
||||
end
|
||||
|
||||
|
@ -29,10 +22,10 @@ module Management
|
|||
@event = @conference.events.find(params[:id])
|
||||
|
||||
if @event.update(event_params)
|
||||
flash[:notice] = t(".event_successfully_updated")
|
||||
flash[:notice] = 'Event was successfully updated.'
|
||||
redirect_to [:management, @conference, @event]
|
||||
else
|
||||
render action: "edit"
|
||||
render action: 'edit'
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -53,38 +46,27 @@ module Management
|
|||
private
|
||||
|
||||
def find_conference
|
||||
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,
|
||||
)
|
||||
Conference.find(params[:conference_id])
|
||||
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
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
module Management
|
||||
class FeedbackController < ManagementController
|
||||
def index
|
||||
@conference = find_conference
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_conference
|
||||
Conference.find(params[:conference_id])
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,18 +1,14 @@
|
|||
require "csv"
|
||||
require 'csv'
|
||||
module Management
|
||||
class ManagementController < ::ApplicationController
|
||||
before_action :authenticate_user!, :authorize_user!
|
||||
|
||||
layout "management"
|
||||
layout 'management'
|
||||
|
||||
private
|
||||
|
||||
def authorize_user!
|
||||
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
|
||||
head :forbidden unless current_user.admin?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -10,7 +10,7 @@ module Management
|
|||
@user = find_profile.user
|
||||
|
||||
@user.toggle_admin!
|
||||
redirect_back fallback_location: {action: :show}
|
||||
redirect_to :back
|
||||
end
|
||||
|
||||
def show
|
||||
|
@ -18,7 +18,7 @@ module Management
|
|||
@profile = find_profile
|
||||
@user = @profile.user
|
||||
|
||||
unless @profile
|
||||
if not @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(profile_params)
|
||||
if @profile.update_attributes(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_back fallback_location: [:management, current_conference, @proposition]
|
||||
redirect_to :back
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -3,8 +3,8 @@ module Management
|
|||
include CurrentConferenceAssigning
|
||||
|
||||
def index
|
||||
@filters = filter_params || {}
|
||||
@volunteers = VolunteerSearch.new(scope: Volunteer.where(conference: current_conference).eager_load(:volunteer_team), filters: params[:filters]).results
|
||||
@filters = params[:filters] || {}
|
||||
@volunteers = VolunteerSearch.new(scope: Volunteer.where(conference: current_conference).eager_load(:volunteer_teams), filters: params[:filters]).results
|
||||
end
|
||||
|
||||
def show
|
||||
|
@ -15,12 +15,6 @@ 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])
|
||||
|
||||
|
@ -32,18 +26,12 @@ 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, :terms_accepted,
|
||||
:volunteer_team_id,
|
||||
additional_volunteer_team_ids: [])
|
||||
:tshirt_size, :tshirt_cut,
|
||||
:food_preferences, :previous_experience,
|
||||
:notes, :language,
|
||||
volunteer_team_ids: [])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
module Public
|
||||
class ApplicationController < ::ApplicationController
|
||||
include ::CurrentConferenceAssigning
|
||||
before_action :require_current_conference!
|
||||
before_filter :require_current_conference!
|
||||
|
||||
def current_conference
|
||||
@current_conference ||= Conference.order(created_at: :desc).find_by(host_name: request.host)
|
||||
|
|
|
@ -2,32 +2,33 @@ 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.to_s).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).distinct
|
||||
|
||||
@rated_events = @conference.events
|
||||
.joins(:proposition).approved
|
||||
.joins(:feedbacks)
|
||||
.where(feedbacks: {session_id: session.id.to_s}).distinct
|
||||
.joins(:proposition).approved
|
||||
.joins(:feedbacks)
|
||||
.where(feedbacks: {session_id: session.id}).distinct
|
||||
|
||||
end
|
||||
|
||||
def new
|
||||
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
|
||||
if current_conference.feedbacks.where(session_id: session.id).exists?
|
||||
@feedback = current_conference.feedbacks.where(session_id: session.id).order(updated_at: :asc).last
|
||||
else
|
||||
@feedback = current_conference.feedbacks.build
|
||||
@feedback.author_email = Feedback.where(session_id: session.id.to_s).order(updated_at: :asc).last.try(:author_email)
|
||||
@feedback.author_email = Feedback.where(session_id: session.id).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.to_s
|
||||
@feedback.session_id = session.id
|
||||
|
||||
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,10 +1,11 @@
|
|||
class Public::EventFeedbackQrcodesController < Public::ApplicationController
|
||||
def show
|
||||
event = current_conference.events.joins(:proposition).approved.find(params[:event_id]).decorate
|
||||
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)
|
||||
|
||||
respond_to do |format|
|
||||
format.svg do
|
||||
render(inline: event.feedback_qr_code_as_svg,
|
||||
render(inline: @qr.as_svg(shape_rendering: 'crispEdges', module_size: 11, fill: 'ffffff', offset: 10),
|
||||
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.to_s).exists?
|
||||
@feedback = event.feedbacks.where(session_id: session.id.to_s).order(updated_at: :asc).last
|
||||
if event.feedbacks.where(session_id: session.id).exists?
|
||||
@feedback = event.feedbacks.where(session_id: session.id).order(updated_at: :asc).last
|
||||
else
|
||||
@feedback = event.feedbacks.build
|
||||
@feedback.author_email = Feedback.where(session_id: session.id.to_s).order(updated_at: :asc).last.try(:author_email)
|
||||
@feedback.author_email = Feedback.where(session_id: session.id).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.to_s
|
||||
@feedback.session_id = session.id
|
||||
|
||||
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_action :authenticate_user!
|
||||
before_filter :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_action :authenticate_user!
|
||||
before_filter :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(profile_params)
|
||||
flash[:notice] = t("views.personal_profiles.successfully_updated")
|
||||
if @profile.update_attributes(profile_params)
|
||||
flash[:notice] = t('views.personal_profiles.successfully_updated')
|
||||
redirect_to root_path
|
||||
else
|
||||
render action: "edit"
|
||||
render action: 'edit'
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
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,6 +1,5 @@
|
|||
module Public
|
||||
class VolunteersController < Public::ApplicationController
|
||||
before_action :check_honey_pot, only: [:create, :edit]
|
||||
def new
|
||||
@volunteer = current_conference.volunteers.build
|
||||
end
|
||||
|
@ -12,7 +11,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
|
||||
|
@ -22,7 +21,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
|
||||
|
@ -31,15 +30,11 @@ 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,
|
||||
:terms_accepted, :volunteer_team_id,
|
||||
volunteer_team_ids: []
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
module Public
|
||||
class VolunteershipsController < Public::ApplicationController
|
||||
before_action :authenticate_user!, only: [:create, :destroy]
|
||||
before_filter :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
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
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
|
|
@ -1,20 +0,0 @@
|
|||
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,60 +29,38 @@ 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 { |date|
|
||||
chart_data = (start_date..end_date).map do |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 { |participant|
|
||||
event.participants_with_personal_profiles.map do |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
|
||||
}.join(", ").html_safe
|
||||
end.join(', ').html_safe
|
||||
end
|
||||
|
||||
def participant_names_with_emails(event)
|
||||
|
@ -25,11 +25,13 @@ module EventsHelper
|
|||
end
|
||||
|
||||
def participant_names(event)
|
||||
event.participants.map { |participant|
|
||||
event.participants.map do |participant|
|
||||
if participant.personal_profile(event.conference).present?
|
||||
profile = participant.personal_profile(event.conference)
|
||||
profile.name.to_s
|
||||
"#{profile.name}"
|
||||
else
|
||||
nil
|
||||
end
|
||||
}.compact
|
||||
end.compact
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,21 +1,15 @@
|
|||
# coding: utf-8
|
||||
class EventMailer < ActionMailer::Base
|
||||
helper ApplicationHelper
|
||||
|
||||
def confirmation_request(event)
|
||||
@event = event.decorate
|
||||
@event = event
|
||||
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)
|
||||
|
@ -23,10 +17,11 @@ 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,3 +1,4 @@
|
|||
# coding: utf-8
|
||||
class PropositionMailer < ActionMailer::Base
|
||||
def new_proposition_notification(proposition)
|
||||
@proposition = proposition
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
# coding: utf-8
|
||||
class VolunteerMailer < ActionMailer::Base
|
||||
def team_notification(new_volunteer)
|
||||
@volunteer = new_volunteer
|
||||
|
||||
mail(
|
||||
to: @volunteer.conference.email,
|
||||
subject: "Нов доброволец за #{@volunteer.conference.title} - #{@volunteer.volunteer_team.name}"
|
||||
)
|
||||
mail(to: @volunteer.conference.email,
|
||||
subject: "Нов доброволец – #{@volunteer.name} <#{@volunteer.email}> за екип(и) #{@volunteer.volunteer_teams.map(&:name).join(', ')}")
|
||||
end
|
||||
|
||||
def volunteer_notification(new_volunteer)
|
||||
|
@ -13,19 +12,8 @@ class VolunteerMailer < ActionMailer::Base
|
|||
I18n.locale = @volunteer.language
|
||||
mail(to: @volunteer.email,
|
||||
reply_to: @volunteer.conference.email,
|
||||
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",
|
||||
from: 'no-reply@openfest.org',
|
||||
subject: I18n.t('volunteer_mailer.success_notification.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 opens_at.present?
|
||||
self.opens_at = Time.now unless self.opens_at.present?
|
||||
self.closes_at = nil
|
||||
save
|
||||
end
|
||||
|
@ -13,14 +13,14 @@ class CallForParticipation < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def open?
|
||||
opens_at.present? && (opens_at < Time.now)
|
||||
self.opens_at.present? and self.opens_at < Time.now
|
||||
end
|
||||
|
||||
def closed?
|
||||
closes_at.present? && (closes_at < Time.now)
|
||||
self.closes_at.present? and self.closes_at < Time.now
|
||||
end
|
||||
|
||||
def in_progress?
|
||||
open? && !closed?
|
||||
open? and not closed?
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
module FeedbackReceiving
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
def average_rating
|
||||
feedbacks.average(:rating)
|
||||
end
|
||||
|
||||
def rated?
|
||||
feedbacks.size > 0
|
||||
end
|
||||
end
|
|
@ -14,35 +14,30 @@ 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
|
||||
has_many :participants, -> { distinct }, class_name: "User", through: :events
|
||||
has_many :participant_profiles, class_name: "PersonalProfile"
|
||||
has_one :call_for_participation, dependent: :destroy
|
||||
has_many :participants, -> { uniq }, class_name: 'User', through: :events
|
||||
has_many :participant_profiles, class_name: 'PersonalProfile'
|
||||
has_many :slots, through: :halls
|
||||
has_many :editions, primary_key: :host_name, foreign_key: :host_name, class_name: "Conference"
|
||||
has_many :feedbacks, as: :feedback_receiving, dependent: :destroy
|
||||
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
|
||||
|
||||
|
@ -51,7 +46,7 @@ class Conference < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def has_vote_results?
|
||||
vote_data_updated_at.present? && (number_of_ballots_cast > 0)
|
||||
vote_data_updated_at.present? and number_of_ballots_cast > 0
|
||||
end
|
||||
|
||||
def has_voting_endpoint?
|
||||
|
@ -59,8 +54,8 @@ class Conference < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def update_conflict_data!
|
||||
update_vote_data! || raise(ActiveRecord::Rollback)
|
||||
events.all? { |event| event.update_conflict_data(false) } || raise(ActiveRecord::Rollback)
|
||||
update_vote_data! or raise ActiveRecord::Rollback
|
||||
events.all? { |event| event.update_conflict_data(false) } or raise ActiveRecord::Rollback
|
||||
end
|
||||
|
||||
def most_conflicts
|
||||
|
@ -79,16 +74,17 @@ 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? && start_date.present? && (planned_cfp_end_date > start_date)
|
||||
if planned_cfp_end_date.present? and start_date.present? and 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? && end_date.present? && (start_date > end_date)
|
||||
if start_date.present? and end_date.present? and start_date > end_date
|
||||
errors.add(:end_date, :cannot_be_before_start_date)
|
||||
end
|
||||
end
|
||||
|
@ -99,38 +95,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) || raise(ActiveRecord::Rollback)
|
||||
ranking.all?(&:save) || raise(ActiveRecord::Rollback)
|
||||
conflicts.all?(&:save) or raise ActiveRecord::Rollback
|
||||
ranking.all?(&:save) or raise ActiveRecord::Rollback
|
||||
conference.touch :vote_data_updated_at
|
||||
conference.save || raise(ActiveRecord::Rollback)
|
||||
conference.save or 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 { |request|
|
||||
@remote_summary_data ||= JSON.parse(connection.get do |request|
|
||||
request.body = {summary: {talk_ids: conference.events.pluck(:id)}}.to_json
|
||||
}.body)
|
||||
end.body)
|
||||
end
|
||||
|
||||
class ConflictsForEvent
|
||||
|
@ -140,13 +136,14 @@ class Conference < ActiveRecord::Base
|
|||
|
||||
def save
|
||||
@event = Event.find(talk_id)
|
||||
@event.conflict_counts.destroy_all || raise(ActiveRecord::Rollback)
|
||||
@event.conflict_counts.destroy_all or 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 || raise(ActiveRecord::Rollback)
|
||||
end or 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,24 +6,20 @@ 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
|
||||
has_many :feedbacks_with_comment, -> { where.not(comment: [nil, ""]) }, as: :feedback_receiving, class_name: 'Feedback'
|
||||
include FeedbackReceiving
|
||||
has_many :feedbacks, as: :feedback_receiving, dependent: :destroy
|
||||
|
||||
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
|
||||
|
@ -65,16 +61,16 @@ class Event < ActiveRecord::Base
|
|||
language: language,
|
||||
abstract: abstract,
|
||||
description: description,
|
||||
notes: notes,
|
||||
notes: notes
|
||||
}
|
||||
end
|
||||
|
||||
def ranked?
|
||||
conference.has_vote_results? && rank.present? && number_of_votes.present?
|
||||
conference.has_vote_results? and rank.present? and number_of_votes.present?
|
||||
end
|
||||
|
||||
def per_cent_of_votes
|
||||
if conference.has_vote_results? && (conference.number_of_ballots_cast > 0)
|
||||
if conference.has_vote_results? and conference.number_of_ballots_cast > 0
|
||||
Rational(number_of_votes * 100, conference.number_of_ballots_cast)
|
||||
else
|
||||
Float::NAN
|
||||
|
@ -84,20 +80,20 @@ class Event < ActiveRecord::Base
|
|||
private
|
||||
|
||||
def event_type_belongs_to_the_selected_conference
|
||||
unless conference.present? && conference.event_types.include?(event_type)
|
||||
unless conference.present? and 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? && conference.tracks.include?(track)
|
||||
unless conference.present? and 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) && (length <= event_type.maximum_length)
|
||||
unless length >= event_type.minimum_length and 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
|
||||
|
||||
has_one_attached :picture
|
||||
mount_uploader :picture, PictureUploader
|
||||
|
||||
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_commit :send_creation_notification, on: [:create]
|
||||
after_create :send_creation_notification
|
||||
before_destroy :send_withdrawal_notification
|
||||
|
||||
def confirm!
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
class Slot < ActiveRecord::Base
|
||||
belongs_to :hall
|
||||
belongs_to :event, required: false
|
||||
belongs_to :approved_event, -> { joins(:proposition).approved_joined }, class_name: 'Event', foreign_key: 'event_id'
|
||||
belongs_to :event
|
||||
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,29 +2,17 @@ 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 :feedbacks, through: :events
|
||||
has_many :feedbacks_with_comment, -> { where.not(comment: [nil, '']) }, through: :events
|
||||
|
||||
has_many :events, through: :propositions, source: :proposable, source_type: 'Event'
|
||||
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?
|
||||
|
@ -38,7 +26,7 @@ class User < ActiveRecord::Base
|
|||
def build_personal_profile(conference, params = {})
|
||||
if personal_profiles.last.present?
|
||||
new_personal_profile = personal_profiles.last.try(:dup)
|
||||
new_personal_profile.picture.attach(personal_profiles.last.picture.blob)
|
||||
CopyCarrierwaveFile::CopyFileService.new(personal_profiles.last, new_personal_profile, :picture).set_file
|
||||
else
|
||||
new_personal_profile = personal_profiles.build
|
||||
end
|
||||
|
|
|
@ -3,63 +3,44 @@ class Volunteer < ActiveRecord::Base
|
|||
TSHIRT_CUTS = [:unisex, :female]
|
||||
FOOD_PREFERENCES = [:none, :vegetarian, :vegan]
|
||||
|
||||
has_one_attached :picture
|
||||
attachment :picture, type: :image
|
||||
|
||||
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, uniqueness: {scope: :conference_id}
|
||||
validates :email, format: {with: /\A[^@]+@[^@]+\z/}, presence: true
|
||||
validates :phone, presence: true, format: {with: /\A[+\- \(\)0-9]+\z/}
|
||||
validates :volunteer_team, presence: true
|
||||
validates :terms_accepted, acceptance: true
|
||||
validates :volunteer_teams, presence: true
|
||||
validate :volunteer_teams_belong_to_conference
|
||||
|
||||
phony_normalize :phone, default_country_code: "BG"
|
||||
phony_normalize :phone, default_country_code: 'BG'
|
||||
|
||||
belongs_to :conference
|
||||
belongs_to :volunteer_team
|
||||
has_and_belongs_to_many :additional_volunteer_teams, class_name: "VolunteerTeam"
|
||||
has_and_belongs_to_many :volunteer_teams
|
||||
|
||||
before_create :ensure_main_volunteer_team_is_part_of_additional_volunteer_teams
|
||||
before_create :assign_unique_id
|
||||
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
|
||||
after_create :send_notification_to_organizers
|
||||
after_create :send_notification_to_volunteer
|
||||
|
||||
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
|
||||
def send_notification_to_organizers
|
||||
VolunteerMailer.team_notification(self).deliver_later
|
||||
end
|
||||
|
||||
def send_notification_to_volunteer
|
||||
VolunteerMailer.volunteer_notification(self).deliver_later
|
||||
end
|
||||
|
||||
def volunteer_teams_belong_to_conference
|
||||
conference_volunteer_teams = conference.volunteer_teams
|
||||
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
|
||||
unless volunteer_teams.all? { |team| conference_volunteer_teams.include? team }
|
||||
errors.add :volunteer_teams, :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_team).where volunteer_team: {id: value} }
|
||||
option(:volunteer_team_id) { |scope, value| scope.joins(:volunteer_teams).where volunteer_teams: {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,7 +1,6 @@
|
|||
class VolunteerTeam < ActiveRecord::Base
|
||||
belongs_to :conference
|
||||
has_many :volunteers, inverse_of: :volunteer_team
|
||||
has_and_belongs_to_many :supporters, class_name: "Volunteer", inverse_of: :additional_volunteer_teams
|
||||
has_and_belongs_to_many :volunteers
|
||||
|
||||
validates :name, presence: true
|
||||
validates :color, presence: true, format: {with: /\A#?[a-f0-9]{6}\z/i}
|
||||
|
@ -14,7 +13,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
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
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
|
|
@ -1 +0,0 @@
|
|||
json.array! @conferences, :id, :title, :start_date, :end_date, :created_at, :updated_at
|
|
@ -1,13 +0,0 @@
|
|||
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
|
|
@ -1,24 +0,0 @@
|
|||
<%
|
||||
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 %>
|
|
@ -1,22 +0,0 @@
|
|||
@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, :name
|
||||
json.picture rails_blob_url(speaker.picture.variant(resize_to_fill: [100, 100]))
|
||||
json.extract! speaker, :twitter, :github, :biography, :public_email, :organisation, :last_name, :first_name
|
||||
json.picture speaker.picture.serializable_hash
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,15 +1,22 @@
|
|||
Здравейте,
|
||||
|
||||
Имаме удоволствието да ви информираме, че Вашето предложение за участие в „<%= @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' %>
|
||||
|
||||
С приложения QR код към този имейл ще можете да достъпите формуляра за обратна връзка на предложеното от Вас събитие. Моля, включете го в презентацията си.
|
||||
Моля пишете на ofvideo@openfest.org, ако имате специфични изисквания, например:
|
||||
|
||||
* да ви осигурим лаптоп за презентация;
|
||||
* звук от презентацията ви;
|
||||
* имате нужда да изпозлвате жична или безжична връзка до Internet за презентацията си;
|
||||
* ползвате macbook.
|
||||
|
||||
Отговорете на този email, ако възникнат някакви въпроси.
|
||||
|
||||
Поздрави,
|
||||
Екипът на <%= @event.conference.title %>
|
||||
|
|
|
@ -1,17 +1,23 @@
|
|||
Hello,
|
||||
|
||||
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? -%>
|
||||
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? -%>
|
||||
It has been scheduled for <%= I18n.l @event.slot.starts_at, format: :long %>.
|
||||
<% else %>
|
||||
It has not been scheduled yet.
|
||||
<% end %>
|
||||
|
||||
To confirm your participation please follow the link below as soon as you can:
|
||||
Please confirm your participation as soon as you can by following the following link:
|
||||
<%= 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.
|
||||
|
||||
Should you have any questions or require further information, please do not hesitate to contact us by replying to this email.
|
||||
Please email ofvideo@openfest.org if you hav any specific requirements, for example:
|
||||
|
||||
Best regards,
|
||||
* 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,
|
||||
The <%= @event.conference.title %> Team
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
Здравейте,
|
||||
|
||||
За съжаление, поради голямото количество предложения за лекции, които получихме тази година, и ограниченото ни време, предложението ви за <%= @event.event_type.name.mb_chars.downcase %> на тема „<%= @event.title %>“ няма да може да бъде включено в програмата.
|
||||
За съжаление, поради големия брой предложения за лекции, които получихме тази година, както и ограниченото време и брой зали, с които разполагаме, вашето предложение за <%= @event.event_type.name.mb_chars.downcase %> на тема „<%= @event.title %>“ не влезе в основната програма.
|
||||
|
||||
Обаче, ако желаете, може да представите лекцията си в рамките на 5 минути като част от програмата на Lightning talks (кратки 5 минутни лекции). Записването за тези слотове ще бъде възможно на място.
|
||||
Тъй като темата звучи интересно, бихме ви предложили да се включите с lightning talk (петминутна презентация с или без слайдове) в дните на конференциятa.
|
||||
|
||||
Благодарим ви за интереса и участието ви в нашето събитие. До скоро!
|
||||
Записването тези кратки презентации ще се случва на регистрацията на <%= @event.conference.title %> след откриването на събитието в събота.
|
||||
|
||||
Поздрави,
|
||||
Екипът на <%= @event.conference.title %>
|
||||
До скоро! Екипът на <%= @event.conference.title %>
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
Hello,
|
||||
Hi,
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
We appreciate your interest in contributing to <%= @event.conference.title %> and hope to see you there!
|
||||
The sign-up for these talks happens at the registration of <%= @event.conference.title %> after the opening on Saturday.
|
||||
|
||||
Best regards,
|
||||
<%= @event.conference.title %> Team
|
||||
See you soon,
|
||||
<%= @event.conference.title %> team
|
||||
|
|
|
@ -12,10 +12,10 @@ html
|
|||
- else
|
||||
| Clarion
|
||||
|
||||
= stylesheet_link_tag "management/application", nopush: false
|
||||
= stylesheet_link_tag "management/application"
|
||||
= csrf_meta_tags
|
||||
body
|
||||
main
|
||||
= render 'layouts/management/flash'
|
||||
== yield
|
||||
= javascript_include_tag "management/application", nopush: false
|
||||
= javascript_include_tag "management/application"
|
||||
|
|
|
@ -15,11 +15,11 @@ html
|
|||
- else
|
||||
| Clarion
|
||||
|
||||
= stylesheet_link_tag "management/application", nopush: false
|
||||
= stylesheet_link_tag "management/application"
|
||||
= csrf_meta_tags
|
||||
body
|
||||
= render 'layouts/management/navigation'
|
||||
main
|
||||
= render 'layouts/management/flash'
|
||||
== yield
|
||||
= javascript_include_tag "management/application", nopush: false
|
||||
= javascript_include_tag "management/application"
|
||||
|
|
|
@ -32,9 +32,7 @@ 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,12 +20,9 @@
|
|||
.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,123 +1,89 @@
|
|||
- personal_profile = speaker.personal_profile(@conference) || speaker.personal_profiles.last
|
||||
|
||||
.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
|
||||
.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'
|
||||
- if personal_profile.organisation.present?
|
||||
li.list-group-item
|
||||
h5.list-group-item-heading = PersonalProfile.human_attribute_name :organisation
|
||||
p.list-group-item-text = personal_profile.organisation
|
||||
p #{icon :briefcase} @#{personal_profile.organisation}
|
||||
- if personal_profile.twitter.present?
|
||||
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?
|
||||
.panel.panel-default
|
||||
table.table.table-striped.table-hover.record-table
|
||||
thead
|
||||
tr
|
||||
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 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]
|
||||
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
|
||||
p = t '.no_other_event_propositions'
|
||||
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']
|
||||
|
||||
- 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|
|
||||
tr
|
||||
td = event.title
|
||||
td.text-center
|
||||
- if event.ranked?
|
||||
.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}"))
|
||||
|
||||
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')
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<%- csv_headers = %w{id title subtitle type track language paticipants length status rank number_of_votes proposer_notes} -%>
|
||||
<%- csv_headers = %w{id title subtitle type track language paticipants status rank number_of_votes} -%>
|
||||
<%= 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.length, event.status, event.rank, event.number_of_votes, event.notes]).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.status, event.rank, event.number_of_votes]).html_safe -%>
|
||||
<%- end -%>
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
= Event.model_name.human(count: 2).mb_chars.titleize
|
||||
small<
|
||||
| (
|
||||
= t '.total', current: @events.size, total: @conference.events.size
|
||||
=< Event.model_name.human(count: @conference.events.size)
|
||||
= t '.total', current: @events.count, total: current_conference.events.count
|
||||
=< Event.model_name.human(count: current_conference.events.count)
|
||||
| )
|
||||
.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(@conference, filters: @filters.except(:event_type_id))
|
||||
= link_to management_conference_events_path(current_conference, filters: @filters.except(:event_type_id))
|
||||
= t '.all'
|
||||
span.badge.pull-right = @conference.events.size
|
||||
- @conference.event_types.each do |event_type|
|
||||
span.badge.pull-right = current_conference.events.count
|
||||
- current_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(@conference, filters: @filters.merge({event_type_id: event_type.id}))
|
||||
= link_to management_conference_events_path(current_conference, filters: @filters.merge({event_type_id: event_type.id}))
|
||||
= event_type.name
|
||||
span.badge.pull-right = @conference.events.where(event_type: event_type).size
|
||||
span.badge.pull-right = current_conference.events.where(event_type: event_type).count
|
||||
.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(@conference, filters: @filters.except(:track_id))
|
||||
= link_to management_conference_events_path(current_conference, filters: @filters.except(:track_id))
|
||||
= t '.all'
|
||||
span.badge.pull-right = @conference.events.size
|
||||
- @conference.tracks.each do |track|
|
||||
span.badge.pull-right = current_conference.events.count
|
||||
- current_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(@conference, filters: @filters.merge({track_id: track.id}))
|
||||
= link_to management_conference_events_path(current_conference, filters: @filters.merge({track_id: track.id}))
|
||||
= track.name
|
||||
span.badge.pull-right = @conference.events.where(track: track).size
|
||||
span.badge.pull-right = current_conference.events.where(track: track).count
|
||||
.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(@conference, filters: @filters.except(:language))
|
||||
= link_to management_conference_events_path(current_conference, filters: @filters.except(:language))
|
||||
= t '.all'
|
||||
span.badge.pull-right = @conference.events.size
|
||||
span.badge.pull-right = current_conference.events.count
|
||||
- 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(@conference, filters: @filters.merge({language: language}))
|
||||
= link_to management_conference_events_path(current_conference, filters: @filters.merge({language: language}))
|
||||
= t("locales.#{language}")
|
||||
span.badge.pull-right = @conference.events.where(language: language).size
|
||||
span.badge.pull-right = current_conference.events.where(language: language).count
|
||||
.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(@conference, filters: @filters.except(:status))
|
||||
= link_to management_conference_events_path(current_conference, filters: @filters.except(:status))
|
||||
= t '.all'
|
||||
span.badge.pull-right = @conference.events.size
|
||||
span.badge.pull-right = current_conference.events.count
|
||||
- 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(@conference, filters: @filters.merge({status: status_id}))
|
||||
= link_to management_conference_events_path(current_conference, filters: @filters.merge({status: status_id}))
|
||||
= t "activerecord.attributes.proposition.statuses.#{status_name}"
|
||||
span.badge.pull-right = @conference.events.joins(:proposition).where(propositions: {status: status_id}).size
|
||||
span.badge.pull-right = current_conference.events.joins(:proposition).where(propositions: {status: status_id}).count
|
||||
.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(@conference, filters: @filters.except(:confirmed, :not_confirmed))
|
||||
= link_to management_conference_events_path(current_conference, filters: @filters.except(:confirmed, :not_confirmed))
|
||||
= t '.all'
|
||||
span.badge.pull-right = @conference.events.size
|
||||
span.badge.pull-right = current_conference.events.count
|
||||
= content_tag :li, role: "presentation", class: @filters[:confirmed].present? ? 'active' : nil
|
||||
= link_to management_conference_events_path(@conference, filters: @filters.except(:not_confirmed).merge({confirmed: true}))
|
||||
= link_to management_conference_events_path(current_conference, filters: @filters.except(:not_confirmed).merge({confirmed: true}))
|
||||
= t "activerecord.attributes.proposition.confirmation.confirmed"
|
||||
span.badge.pull-right = @conference.events.joins(:proposition).approved.where.not(propositions: {confirmed_at: nil}).size
|
||||
span.badge.pull-right = current_conference.events.joins(:proposition).approved.where.not(propositions: {confirmed_at: nil}).count
|
||||
= content_tag :li, role: "presentation", class: @filters[:not_confirmed].present? ? 'active' : nil
|
||||
= link_to management_conference_events_path(@conference, filters: @filters.except(:confirmed).merge({not_confirmed: true}))
|
||||
= link_to management_conference_events_path(current_conference, filters: @filters.except(:confirmed).merge({not_confirmed: true}))
|
||||
= t "activerecord.attributes.proposition.confirmation.not_confirmed"
|
||||
span.badge.pull-right = @conference.events.joins(:proposition).approved.where(propositions: {confirmed_at: nil}).size
|
||||
span.badge.pull-right = current_conference.events.joins(:proposition).approved.where(propositions: {confirmed_at: nil}).count
|
||||
|
||||
.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(@conference, filters: @filters, format: 'csv'), class: 'btn btn-info'
|
||||
= link_to management_conference_events_path(current_conference, filters: @filters, format: 'csv'), class: 'btn btn-info'
|
||||
= icon :download, t('.export')
|
||||
|
|
|
@ -65,88 +65,52 @@
|
|||
h3 = Event.human_attribute_name :participants
|
||||
= render partial: 'speaker', collection: @event.participants
|
||||
|
||||
- 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'
|
||||
|
||||
|
||||
- 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
|
||||
.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 colspan="20"
|
||||
= t '.no_approved_events'
|
||||
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 '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
|
||||
= t '.no_approved_events'
|
||||
- else
|
||||
tr
|
||||
td colspan="20"
|
||||
= t 'management.conferences.vote_results.vote_data_never_updated'
|
||||
= 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')
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
<%- 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 -%>
|
|
@ -1,62 +0,0 @@
|
|||
- 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.attached?
|
||||
- if f.object.picture.present?
|
||||
.col-sm-offset-3.col-sm-9
|
||||
= image_tag f.object.picture.variant(resize_to_limit: [150, 150]), class: 'img-thumbnail'
|
||||
= image_tag f.object.picture.medium.url, class: 'img-thumbnail'
|
||||
|
||||
= f.input :picture, wrapper: :horizontal_file_input
|
||||
|
||||
|
|
|
@ -27,9 +27,10 @@
|
|||
.media
|
||||
.media-left
|
||||
- if profile.present?
|
||||
= image_tag(profile.picture.variant(resize_to_fill: [50, 50]))
|
||||
= image_tag(profile.picture.thumb.url)
|
||||
- else
|
||||
= image_tag('avatar-placeholder.png')
|
||||
= image_tag(PictureUploader.new.thumb.url)
|
||||
|
||||
.media-body
|
||||
h4.media-heading
|
||||
- if profile.try(:name).present?
|
||||
|
|
|
@ -5,117 +5,65 @@
|
|||
.col-lg-12
|
||||
h1.page-header
|
||||
= PersonalProfile.model_name.human.mb_chars.capitalize
|
||||
.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?
|
||||
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?
|
||||
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?
|
||||
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?
|
||||
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
|
||||
|
||||
h2 = t '.talk_history'
|
||||
.panel.panel-default
|
||||
- if @user.events_participated_in.any?
|
||||
.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'
|
||||
- if @profile.organisation.present?
|
||||
p = icon :briefcase, @profile.organisation
|
||||
- if @profile.twitter.present?
|
||||
p = icon :twitter, "@#{@profile.twitter}"
|
||||
- if @profile.github.present?
|
||||
p = icon :github, @profile.github
|
||||
- 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})"
|
||||
|
||||
- if @user.events_participated_in.any?
|
||||
h4 = t '.event_propositions'
|
||||
table.table.table-striped.table-hover.record-table
|
||||
thead
|
||||
tr
|
||||
th.main
|
||||
th
|
||||
= 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
|
||||
th
|
||||
= Event.human_attribute_name :conference
|
||||
th.hidden-md.hidden-sm.hidden-xs
|
||||
th
|
||||
= 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.hidden-md.hidden-sm.hidden-xs
|
||||
= event.conference.title
|
||||
td.hidden-md.hidden-sm.hidden-xs
|
||||
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}"))
|
||||
|
||||
td.actions
|
||||
.btn-group.btn-group-sm
|
||||
= action_buttons event.conference, event, [:show]
|
||||
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'
|
||||
|
||||
|
||||
.panel-footer
|
||||
.text-right
|
||||
.btn-group.btn-group-sm
|
||||
= action_buttons @conference, @profile, [:edit, :destroy]
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
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,14 +5,13 @@
|
|||
.col-lg-12
|
||||
- if f.object.picture.present?
|
||||
.col-sm-offset-3.col-sm-9
|
||||
= @volunteer.picture.variant(resize_to_limit: [150, 150]) if @volunteer.picture.attached?
|
||||
= attachment_image_tag(@volunteer, :picture, :fill, 150, 150) if @volunteer.picture.present?
|
||||
|
||||
= f.input :picture, as: :file, wrapper: :horizontal_file_input, direct: true
|
||||
= f.input :picture, as: :attachment, wrapper: :horizontal_file_input, direct: true
|
||||
|
||||
= f.input :name, autofocus: true
|
||||
= f.input :email
|
||||
= 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.association :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)
|
||||
|
@ -20,6 +19,5 @@
|
|||
= 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