From 0333a1ad68f7960b3e1283fce27543ef717cf853 Mon Sep 17 00:00:00 2001 From: echarp Date: Sat, 28 Feb 2015 17:28:05 +0100 Subject: [PATCH] Organisation can now be organised in kinds, and easily modified by moderators --- Gemfile | 2 +- Gemfile.lock | 6 +- app/assets/stylesheets/_awesome_mixins.scss | 42 ----- app/assets/stylesheets/all.css.sass | 23 +++ app/assets/stylesheets/application.css.sass | 19 ++- app/assets/stylesheets/events.css.sass | 97 ----------- app/assets/stylesheets/form.css.sass | 97 +++++++++++ app/assets/stylesheets/maps.css.sass | 2 +- app/assets/stylesheets/orgas.css.sass | 4 +- app/controllers/events_controller.rb | 2 +- app/controllers/orgas_controller.rb | 48 +++++- app/models/kind.rb | 4 + app/models/orga.rb | 17 ++ app/views/events/_form.html.haml | 16 +- app/views/events/new.html.haml | 2 +- app/views/events/show.html.haml | 20 ++- app/views/orgas/_form.html.haml | 59 +++++++ app/views/orgas/edit.html.haml | 9 ++ app/views/orgas/index.html.haml | 7 +- app/views/orgas/new.html.haml | 9 ++ app/views/orgas/show.html.haml | 153 ++++++++++-------- config/locales/models/en.yml | 18 ++- config/locales/models/fr.yml | 13 ++ config/locales/views/en.yml | 38 +++-- config/locales/views/fr.yml | 40 +++-- config/routes.rb | 2 +- db/migrate/20150215172000_create_kinds.rb | 18 +++ .../20150215172739_add_data_to_orgas.rb | 15 ++ db/schema.rb | 35 +++- db/seeds.rb | 6 + test/controllers/orgas_controller_test.rb | 35 ++++ test/fixtures/kinds.yml | 21 +++ test/fixtures/orgas.yml | 20 ++- test/models/kind_test.rb | 7 + 34 files changed, 630 insertions(+), 276 deletions(-) delete mode 100644 app/assets/stylesheets/_awesome_mixins.scss create mode 100644 app/assets/stylesheets/form.css.sass create mode 100644 app/models/kind.rb create mode 100644 app/views/orgas/_form.html.haml create mode 100644 app/views/orgas/edit.html.haml create mode 100644 app/views/orgas/new.html.haml create mode 100644 db/migrate/20150215172000_create_kinds.rb create mode 100644 db/migrate/20150215172739_add_data_to_orgas.rb create mode 100644 test/fixtures/kinds.yml create mode 100644 test/models/kind_test.rb diff --git a/Gemfile b/Gemfile index 38f3624f..8720fd89 100644 --- a/Gemfile +++ b/Gemfile @@ -57,7 +57,7 @@ gem 'i18n-active_record', gem 'http_accept_language' # A superb font to use as icons -gem 'font-awesome-rails' +gem 'font-awesome-sass' # Validate mails submitted gem 'email_validator' # Email address obfuscation diff --git a/Gemfile.lock b/Gemfile.lock index 6c77a256..2d82eeae 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -146,8 +146,8 @@ GEM multipart-post (>= 1.2, < 3) fastercsv (1.5.5) ffi (1.9.6) - font-awesome-rails (4.3.0.0) - railties (>= 3.2, < 5.0) + font-awesome-sass (4.3.1) + sass (~> 3.2) formatador (0.2.5) formtastic (3.1.3) actionpack (>= 3.2.13) @@ -426,7 +426,7 @@ DEPENDENCIES devise-i18n differ email_validator - font-awesome-rails + font-awesome-sass geocoder guard-brakeman guard-bundler diff --git a/app/assets/stylesheets/_awesome_mixins.scss b/app/assets/stylesheets/_awesome_mixins.scss deleted file mode 100644 index 9de5bbe2..00000000 --- a/app/assets/stylesheets/_awesome_mixins.scss +++ /dev/null @@ -1,42 +0,0 @@ -// Mixins -// -------------------------- - -@mixin fa-icon-rotate($degrees, $rotation) { - filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation}); - -webkit-transform: rotate($degrees); - -moz-transform: rotate($degrees); - -ms-transform: rotate($degrees); - -o-transform: rotate($degrees); - transform: rotate($degrees); -} - -@mixin fa-icon-flip($horiz, $vert, $rotation) { - filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation}); - -webkit-transform: scale($horiz, $vert); - -moz-transform: scale($horiz, $vert); - -ms-transform: scale($horiz, $vert); - -o-transform: scale($horiz, $vert); - transform: scale($horiz, $vert); -} - -@mixin fa-icon-base() { - &:before { - display: inline-block; - font-family: FontAwesome; - font-style: normal; - font-weight: normal; - line-height: 1; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - margin-right: 5px; - } -} - -@mixin fa-icon($icon-char) { - @include fa-icon-base(); - &:before { - @if($icon-char != null) { - content: $icon-char; - } - } -} diff --git a/app/assets/stylesheets/all.css.sass b/app/assets/stylesheets/all.css.sass index bbbf7449..968fa3b2 100644 --- a/app/assets/stylesheets/all.css.sass +++ b/app/assets/stylesheets/all.css.sass @@ -1,4 +1,5 @@ @import compass +@import font-awesome-sprockets @import font-awesome * @@ -134,6 +135,28 @@ main, body.mce-content-body min-height: 100% font-family: Palatino, 'URW Palladio L', 'dejavu serif', georgia, serif +aside + float: right + width: 16em + border: 1px solid #96CFFF + margin: 0 1.2em + padding: 5px + font-size: 0.7em + margin-right: -4em + background-color: #D6ECFF + +box-shadow(4px 4px 1em gray) + +border-radius(10px) + h1 + font-weight: normal + border-bottom: 1px black solid + padding-bottom: 0.3em + h2 + margin: 0 + font-size: larger + a + padding: 0.5em 0 + display: block + iframe border: none max-width: 100% diff --git a/app/assets/stylesheets/application.css.sass b/app/assets/stylesheets/application.css.sass index 353d4506..c9051d88 100644 --- a/app/assets/stylesheets/application.css.sass +++ b/app/assets/stylesheets/application.css.sass @@ -14,17 +14,22 @@ *= require_tree . */ -@import 'awesome_mixins' +@import font-awesome-sprockets +@import font-awesome body.application &.infos h4 text-align: left - &.infos main h2:first-child - +fa-icon('') + &.infos, &.contact, &.rules + main h2:first-child:before + +fa-icon() + margin-right: 0.4em + &.infos main h2:first-child:before + content: $fa-var-info - &.contact main h2:first-child - +fa-icon('') + &.contact main h2:first-child:before + content: $fa-var-envelope - &.rules main h2:first-child - +fa-icon('') + &.rules main h2:first-child:before + content: $fa-var-gavel diff --git a/app/assets/stylesheets/events.css.sass b/app/assets/stylesheets/events.css.sass index 28ed156d..5e4b59be 100644 --- a/app/assets/stylesheets/events.css.sass +++ b/app/assets/stylesheets/events.css.sass @@ -1,5 +1,4 @@ @import compass -@import awesome_mixins header.calendar-header font-size: 1.5em @@ -116,28 +115,6 @@ body.events.show main h2 margin-top: 1em -aside#orga-list - float: right - width: 16em - border: 1px solid #96CFFF - margin: 0 1.2em - padding: 5px - font-size: 0.7em - margin-right: -4em - background-color: #D6ECFF - +box-shadow(4px 4px 1em gray) - +border-radius(10px) - h1 - font-weight: normal - border-bottom: 1px black solid - padding-bottom: 0.3em - h2 - margin: 0 - font-size: larger - a - padding: 0.5em 0 - display: block - #advises border: 1px solid #FFB578 padding-left: 10px @@ -150,80 +127,6 @@ aside#orga-list a color: #8F4900 -.events form, .moderations form - .field, .actions - max-width: 70em - text-align: left - margin-left: auto - margin-right: auto - * - vertical-align: middle - .helper p - color: gray - margin: 0 - font-style: italic - margin-left: 8em - padding-left: 0.4em - label - width: 8em - +inline-block() - input, select, .select2-container ul - +border-top-left-radius(0) - +border-bottom-left-radius(0) - input[type=radio] + label - width: 20em - &:after - content: '' - - input[type=text], input[type=url], input[type=email], - .select2-container, .select2-container ul, .mce-tinymce - min-width: 22em - - .mce-tinymce - font-size: inherit - font-family: inherit - +inline-block() - +border-radius(0.4em) - +border-top-left-radius(0) - +border-bottom-left-radius(0) - .mce-container-body - .mce-panel.mce-first - +border-top-right-radius(0.4em) - .mce-panel.mce-last - +border-bottom-right-radius(0.4em) - - .field label:before - color: gray - .field.title label - +fa-icon('') - .field.start_time label - +fa-icon('') - .field.end_time label - +fa-icon('') - .field.description label - +fa-icon('') - .field.address label - +fa-icon('') - .field.city label - +fa-icon('') - .field.region label - +fa-icon('') - .field.locality label - +fa-icon('') - .field.contact label - +fa-icon('') - .field.submitter label - +fa-icon('') - .field.url label - +fa-icon('') - .field.tags label - +fa-icon('') - - .actions - text-align: center - input - font-size: x-large - .description, body.mce-content-body img margin-left: 1% diff --git a/app/assets/stylesheets/form.css.sass b/app/assets/stylesheets/form.css.sass new file mode 100644 index 00000000..bf3c3739 --- /dev/null +++ b/app/assets/stylesheets/form.css.sass @@ -0,0 +1,97 @@ +@import compass +@import font-awesome-sprockets +@import font-awesome + +.events form, .moderations form, .orgas form + .field, .actions + max-width: 70em + text-align: left + margin-left: auto + margin-right: auto + .helper p + color: gray + margin: 0 + font-style: italic + margin-left: 8em + padding-left: 0.4em + label + width: 8em + +inline-block() + input, select, .select2-container ul + +border-top-left-radius(0) + +border-bottom-left-radius(0) + input[type=radio] + label + width: 20em + &:after + content: '' + + input[type=text], input[type=url], input[type=email], + .select2-container, .select2-container ul, .mce-tinymce + min-width: 22em + + .mce-tinymce + font-size: inherit + font-family: inherit + +inline-block() + +border-radius(0.4em) + +border-top-left-radius(0) + +border-bottom-left-radius(0) + .mce-container-body + .mce-panel.mce-first + +border-top-right-radius(0.4em) + .mce-panel.mce-last + +border-bottom-right-radius(0.4em) + + .field label:before + color: gray + margin-right: 0.4em + +fa-icon() + .field.title label:before + content: $fa-var-newspaper-o + .field.start_time label:before + content: $fa-var-toggle-on + .field.end_time label:before + content: $fa-var-toggle-off + .field.description label:before + content: $fa-var-pencil-square-o + .field.address label:before + content: $fa-var-map-marker + .field.city label:before + content: $fa-var-compress + .field.region label:before + content: $fa-var-shield + .field.locality > label:before + content: $fa-var-expand + .field.contact label:before + content: $fa-var-envelope + .field.submitter label:before + content: $fa-var-envelope-o + .field.url label:before + content: $fa-var-external-link + .field.tags label:before + content: $fa-var-tags + + .field.kind > label:before + content: $fa-var-cubes + .field.feed label:before + content: $fa-var-rss + + .field .radios label + width: auto !important + margin-right: 1em + + [type=radio] + display: none + [type=radio] + label:before + color: black + content: $fa-var-circle-o + font-size: larger + [type=radio]:checked + label:before + color: black + content: $fa-var-dot-circle-o + +text-shadow(0 0 1px gray) + + .actions + text-align: center + input + font-size: x-large diff --git a/app/assets/stylesheets/maps.css.sass b/app/assets/stylesheets/maps.css.sass index 58e7e471..aa1c2b60 100644 --- a/app/assets/stylesheets/maps.css.sass +++ b/app/assets/stylesheets/maps.css.sass @@ -14,7 +14,7 @@ &.event height: 20em -.tags, .orgas +.tags #map width: 40% height: 60em diff --git a/app/assets/stylesheets/orgas.css.sass b/app/assets/stylesheets/orgas.css.sass index bc3784e6..c843de31 100644 --- a/app/assets/stylesheets/orgas.css.sass +++ b/app/assets/stylesheets/orgas.css.sass @@ -40,7 +40,9 @@ form#orga_search span.label display: none -body.show main +body.orgas.show main + fieldset.orga + min-width: 60em dl, iframe, fieldset min-width: 30em +inline-block() diff --git a/app/controllers/events_controller.rb b/app/controllers/events_controller.rb index 26cd63ff..6531c97d 100644 --- a/app/controllers/events_controller.rb +++ b/app/controllers/events_controller.rb @@ -20,7 +20,7 @@ class EventsController < ApplicationController end end - # GET /users/new + # GET /events/new def new @event = Event.new start_time: Time.now.change(min: 0) + 1.day + 1.hour, end_time: Time.now.change(min: 0) + 1.day + 2.hour diff --git a/app/controllers/orgas_controller.rb b/app/controllers/orgas_controller.rb index 68119b71..ccebc98a 100644 --- a/app/controllers/orgas_controller.rb +++ b/app/controllers/orgas_controller.rb @@ -1,6 +1,7 @@ # Groups life cycle class OrgasController < ApplicationController - before_action :set_orga, only: [:show] + before_action :authenticate_user!, only: [:new, :edit, :update, :destroy] + before_action :set_orga, except: [:index, :new, :create] def index @search = Orga.search params[:q] @@ -8,6 +9,28 @@ class OrgasController < ApplicationController @orgas = @search.result.page params[:page] end + # GET /orgas/new + def new + @orga = Orga.new + end + + # POST /orgas + # POST /orgas.json + def create + @orga = Orga.new orga_params + respond_to do |format| + if @orga.save # && send_creation_mails + format.html { redirect_to :root, notice: t('.ok') } + # 201 means :created + format.json { render action: 'show', status: 201, location: @orga } + else + format.html { render action: 'new' } + # 422 means :unprocessable_entity + format.json { render json: @orga.errors, status: 422 } + end + end + end + def show @search = Orga.search params[:q] @@ -15,10 +38,33 @@ class OrgasController < ApplicationController @events_past = Event.moderated.past.tag @orga.name end + # PATCH/PUT /orgas/1 + # PATCH/PUT /orgas/1.json + def update + respond_to do |format| + if @orga.update(orga_params) # && send_update_mails + format.html { redirect_to @orga, notice: t('.ok') } + format.json { head :no_content } + else + format.html { render action: 'edit' } + # 422 means :unprocessable_entity + format.json { render json: @orga.errors, status: 422 } + end + end + end + private # Use callbacks to share common setup or constraints between actions. def set_orga @orga = Orga.find params[:id] end + + # Never trust parameters from the scary internet, only allow the white list + # through + def orga_params + params.require(:orga) + .permit :lock_version, :kind_id, :name, :city, :department, :region_id, + :url, :feed, :contact, :submitter + end end diff --git a/app/models/kind.rb b/app/models/kind.rb new file mode 100644 index 00000000..3958ef59 --- /dev/null +++ b/app/models/kind.rb @@ -0,0 +1,4 @@ +# Gives the possibility to organise organisations! :) +class Kind < ActiveRecord::Base + has_many :orgas +end diff --git a/app/models/orga.rb b/app/models/orga.rb index e65eec1a..fd5432b1 100644 --- a/app/models/orga.rb +++ b/app/models/orga.rb @@ -1,4 +1,21 @@ # Groups related to this agenda class Orga < ActiveRecord::Base belongs_to :region + belongs_to :kind + + validates :kind, presence: true + validates :name, presence: true + validates :region, presence: true + validates :url, format: %r{\Ahttps?:\/\/.*\..*\z} + validates :feed, allow_blank: true, format: %r{\Ahttps?:\/\/.*\..*\z} + validates :contact, allow_blank: true, email: true + validates :submitter, allow_blank: true, email: true + + before_validation on: :create do + self.submission_time = DateTime.now + self.decision_time = DateTime.now + + # Populate submitter using contact info if absent + self.submitter ||= contact + end end diff --git a/app/views/events/_form.html.haml b/app/views/events/_form.html.haml index 86389e32..ed3e6303 100644 --- a/app/views/events/_form.html.haml +++ b/app/views/events/_form.html.haml @@ -43,14 +43,18 @@ %option= city .field.region = f.label :region - = f.select :region_id, - options_from_collection_for_select(Region.all, 'id', 'name', - @event.region_id) + = f.collection_select :region_id, Region.all, :id, :name .field.locality = f.label :locality - = f.select :locality, - options_for_select([[t('attributes.locality_0'), 0], - [t('attributes.locality_1'), 1]], @event.locality) + %span.radios + = f.radio_button :locality, 0 + = f.label 'locality_0' do + %em.fa.fa-shield + = t 'attributes.locality_0' + = f.radio_button :locality, 1 + = f.label 'locality_1' do + %em.fa.fa-globe + = t 'attributes.locality_1' .field.url .helper diff --git a/app/views/events/new.html.haml b/app/views/events/new.html.haml index 83888379..1a49034b 100644 --- a/app/views/events/new.html.haml +++ b/app/views/events/new.html.haml @@ -19,6 +19,6 @@ %fieldset %legend - %em.fa.fa-pencil + %em.fa.fa-plus =t '.edit' = render 'form' diff --git a/app/views/events/show.html.haml b/app/views/events/show.html.haml index d6d3eb96..bc1136e3 100644 --- a/app/views/events/show.html.haml +++ b/app/views/events/show.html.haml @@ -14,11 +14,14 @@ %h1 %em.fa.fa-users = t '.orga-list' - - if @event.region - %ul - - @event.region.orgas.order(department: :asc).each do |orga| - %li - = link_to orga.name, orga + %ul.fa-ul + - @event.region.orgas.each do |orga| + %li + = link_to orga do + - if orga.kind + %em.fa.fa-li{ class: "fa-#{orga.kind.icon}", + title: Kind.human_attribute_name("name_#{orga.kind.name}") } + = orga.name (#{orga.department}) = link_to orga.url do = image_tag orga.url + '/favicon.ico', alt: '', class: :favicon @@ -84,11 +87,15 @@ tags: %w(p h1 h2 h3 h4 br table tr th td ul ol li a strong b em i img), attributes: %w(href src width height style) -%h3= t '.infos' +%h3 + %em.fa.fa-info-circle + = t '.infos' %p + %em.fa.fa-external-link %span.label= Event.human_attribute_name :url = link_to @event.url, @event.url %p + %em.fa.fa-envelope %span.label= Event.human_attribute_name :contact = mail_to @event.contact, nil, encode: (request.format == 'text/html' ? :javascript : nil), @@ -96,6 +103,7 @@ - if @event.tags && @event.tags.present? %p.tags + %em.fa.fa-tags %span.label= Event.human_attribute_name :tags - @event.tags.split.each do |tag| = link_to tag, tag_path(tag), rel: :tag diff --git a/app/views/orgas/_form.html.haml b/app/views/orgas/_form.html.haml new file mode 100644 index 00000000..c95aa1c6 --- /dev/null +++ b/app/views/orgas/_form.html.haml @@ -0,0 +1,59 @@ += form_for @orga do |f| + - if @orga.errors.any? + #flash_messages + - @orga.errors.full_messages.each do |msg| + %p.flash.alert= msg + + .field.kind + = f.label :kind + %span.radios + - Kind.all.each do |kind| + = f.radio_button :kind_id, kind.id + = f.label "kind_id_#{kind.id}" do + %em.fa{ class: "fa-#{kind.icon}" } + = Kind.human_attribute_name "name_#{kind.name}" + .field.name + = f.label :name + = f.text_field :name, required: true + .field.city + = f.label :city + = f.text_field :city, list: :cities + %datalist#cities + - Event.group(:city).order('count(city) desc').pluck(:city).each do |city| + %option= city + .field.department + = f.label :department + = f.text_field :department + .field.region + = f.label :region + = f.collection_select :region_id, Region.all, :id, :name + + .field.url + .helper + :markdown + #{t '.url_helper'} + = f.label :url + = f.url_field :url, placeholder: 'Ex: http://april.org' + .field.feed + .helper + :markdown + #{t '.feed_helper'} + = f.label :feed + = f.url_field :feed, placeholder: 'Ex: http://april.org/index.rss' + .field.contact + .helper + :markdown + #{t '.contact_helper'} + = f.label :contact + = f.email_field :contact + .field.submitter + .helper + :markdown + #{t '.submitter_helper'} + = f.label :submitter + = f.email_field :submitter + + .actions + = f.button do + %em.fa.fa-check + = t '.save' diff --git a/app/views/orgas/edit.html.haml b/app/views/orgas/edit.html.haml new file mode 100644 index 00000000..99456dff --- /dev/null +++ b/app/views/orgas/edit.html.haml @@ -0,0 +1,9 @@ +%h2 + %em.fa.fa-users + = title t '.title' + +%fieldset + %legend + %em.fa.fa-pencil + = t '.edit' + = render 'form' diff --git a/app/views/orgas/index.html.haml b/app/views/orgas/index.html.haml index 3f4029ec..3b55ee34 100644 --- a/app/views/orgas/index.html.haml +++ b/app/views/orgas/index.html.haml @@ -6,6 +6,7 @@ %table.list.autopagerize_page_element %thead + %th= sort_link @search, :kind_name, Orga.human_attribute_name(:kind) %th= sort_link @search, :name %th= sort_link @search, :city %th= sort_link @search, :department @@ -17,9 +18,13 @@ - @orgas.each do |orga| %tr %td + - if orga.kind + %em.fa{ class: "fa-#{orga.kind.icon}", + title: Kind.human_attribute_name("name_#{orga.kind.name}") } + %td + = orga.name - if orga.url =~ /^http/ = image_tag orga.url + '/favicon.ico', alt: '', class: :favicon - = orga.name %td = orga.city %td diff --git a/app/views/orgas/new.html.haml b/app/views/orgas/new.html.haml new file mode 100644 index 00000000..99456dff --- /dev/null +++ b/app/views/orgas/new.html.haml @@ -0,0 +1,9 @@ +%h2 + %em.fa.fa-users + = title t '.title' + +%fieldset + %legend + %em.fa.fa-pencil + = t '.edit' + = render 'form' diff --git a/app/views/orgas/show.html.haml b/app/views/orgas/show.html.haml index 741392da..456c8d5c 100644 --- a/app/views/orgas/show.html.haml +++ b/app/views/orgas/show.html.haml @@ -2,84 +2,97 @@ = render 'search' -%h2 - = image_tag @orga.url + '/favicon.ico', alt: '', class: :favicon - = title @orga.name - %nav = link_to orgas_path(q: params[:q], page: params[:page]), class: :back do %em.fa.fa-arrow-left = Orga.model_name.human.pluralize - \/ - = link_to events_path tag: @orga.name do - %em.fa.fa-calendar - Agenda - \/ - = link_to events_path format: :rss, tag: @orga.name do - %em.fa.fa-rss - RSS - \/ - = link_to events_path format: :ics, tag: @orga.name do - %em.fa.fa-th-list - iCal - \/ - = link_to maps_path tag: @orga.name do - %em.fa.fa-map-marker - OpenStreetMap - \/ - = link_to maps_path format: :json, tag: @orga.name do - %em.fa.fa-dot-circle-o - GeoJSON -%dl - - if @orga.city.present? - %dt= Orga.human_attribute_name :city - %dd= @orga.city - - if @orga.department.present? - %dt= Orga.human_attribute_name :department - %dd= @orga.department - - if @orga.region.present? - %dt= Orga.human_attribute_name :region - %dd= @orga.region - - if @orga.url.present? - %dt= Orga.human_attribute_name :url - %dd= link_to @orga.url, @orga.url +%fieldset.orga + %aside + %h1 + %em.fa.fa-link + = t '.links' -%iframe{ src: @orga.url, width: '1280', height: '300', frameborder: 'none', - allowTransparency: 'true' } + %ul.fa-ul + %li + = link_to events_path tag: @orga.name do + %em.fa.fa-li.fa-calendar + Agenda -- if @events_future.any? || @events_past.any? - %fieldset - %legend - %em.fa.fa-calendar - = Event.model_name.human.pluralize + %li + = link_to events_path format: :rss, tag: @orga.name do + %em.fa.fa-li.fa-rss + RSS + + %li + = link_to events_path format: :ics, tag: @orga.name do + %em.fa.fa-li.fa-th-list + iCal + + %li + = link_to maps_path tag: @orga.name do + %em.fa.fa-li.fa-map-marker + OpenStreetMap + + %li + = link_to maps_path format: :json, tag: @orga.name do + %em.fa.fa-li.fa-dot-circle-o + GeoJSON + + - if user_signed_in? + %h1 + %em.fa.fa-wrench + = t '.actions' + %h2 + = link_to edit_orga_path @orga do + %em.fa.fa-lg.fa-pencil + = t '.edit' + + %h2 + - if @orga.kind + %em.fa{ class: "fa-#{@orga.kind.icon}", + title: Kind.human_attribute_name("name_#{@orga.kind.name}") } + = title @orga.name + = image_tag @orga.url + '/favicon.ico', alt: '', class: :favicon + + %dl + - if @orga.city.present? + %dt + %em.fa.fa-compress + = Orga.human_attribute_name :city + %dd= @orga.city + - if @orga.department.present? + %dt= Orga.human_attribute_name :department + %dd= @orga.department + - if @orga.region.present? + %dt + %em.fa.fa-shield + = Orga.human_attribute_name :region + %dd= @orga.region + - if @orga.url.present? + %dt + %em.fa.fa-external-link + = Orga.human_attribute_name :url + %dd= link_to @orga.url, @orga.url + - if @orga.feed.present? + %dt + %em.fa.fa-rss + = Orga.human_attribute_name :feed + %dd= link_to @orga.feed, @orga.feed + - if @orga.contact.present? + %dt + %em.fa.fa-envelope + = Event.human_attribute_name :contact + %dd= mail_to @orga.contact, nil, + encode: (request.format == 'text/html' ? :javascript : nil), + replace_at: ' CHEZ ', replace_dot: ' POINT ' - if @events_future.any? - %h3= raw t 'future', count: @events_future.count - %ul.fa-ul - - @events_future.order('start_time asc').each do |event| - %li - = link_to event do - - if event.locality? - %em.locality.fa-li.fa.fa-globe(title="#{Event.human_attribute_name :locality} #{t 'attributes.locality_1'}") - - else - %em.locality.fa-li.fa.fa-shield(title="#{Event.human_attribute_name :locality} #{t 'attributes.locality_0'}") - %em.city= event.city - = event.title - .date= display_date event - + %dt= t '.future' + %dd= t '.count', count: @events_future.count - if @events_past.any? - %h3= raw t 'past', count: @events_past.count - %ul.fa-ul - - @events_past.order('start_time desc').each do |event| - %li - = link_to event do - - if event.locality? - %em.locality.fa-li.fa.fa-globe(title="#{Event.human_attribute_name :locality} #{t 'attributes.locality_1'}") - - else - %em.locality.fa-li.fa.fa-shield(title="#{Event.human_attribute_name :locality} #{t 'attributes.locality_0'}") - %em.city= event.city - = event.title - .date= display_date event + %dt= t '.past' + %dd= t '.count', count: @events_past.count -.events#map{ data: { url: maps_path(format: :json, tag: @orga.name) } } +.events#map{ data: { url: maps_path(format: :json, tag: @orga.name, + future: false) } } diff --git a/config/locales/models/en.yml b/config/locales/models/en.yml index e6f1257b..83056a75 100644 --- a/config/locales/models/en.yml +++ b/config/locales/models/en.yml @@ -33,10 +33,22 @@ en: inseecode: INSEE code regioncode: Region code orga: - region: Region - department: Department - url: Web address + kind: Type + name: Name city: City + department: Department + region: Region + url: Web address + feed: Syndication + contact: Contact + submitter: Soumetteur + submission_time: En attente depuis + kind: + name_association: Association + name_enterprise: Enterprise + name_lug: LUG + name_provider: ISP + name_institution: Institution event: title: Title start_time: Start diff --git a/config/locales/models/fr.yml b/config/locales/models/fr.yml index e8dda278..c932ebc6 100644 --- a/config/locales/models/fr.yml +++ b/config/locales/models/fr.yml @@ -16,6 +16,7 @@ fr: event: Événement user: Modérateur orga: Asso + kind: Type city: Ville region: Région admin_user: Admin @@ -33,10 +34,22 @@ fr: inseecode: Code INSEE regioncode: Code région orga: + kind: Type + name: Nom city: Ville department: Département region: Région url: Adresse web + feed: Syndication + contact: Contact + submitter: Soumetteur + submission_time: En attente depuis + kind: + name_association: Association + name_enterprise: Entreprise + name_lug: GUL + name_provider: FAI + name_institution: Institution event: title: Titre start_time: Début diff --git a/config/locales/views/en.yml b/config/locales/views/en.yml index 0fc4a81f..27331487 100644 --- a/config/locales/views/en.yml +++ b/config/locales/views/en.yml @@ -9,14 +9,6 @@ en: logout: Disconnect staleObjectError: Sorry, your modification was rejected because someone else already intervened - future: - zero: - one: "In the future, %{count} event:" - other: "In the future, %{count} evens:" - past: - zero: - one: "In the past, %{count} event:" - other: "In the past, %{count} events:" # Translatings screens layouts: @@ -42,7 +34,7 @@ en: calendar_in: This calendar in %{rss}, %{webcal} or %{ical} nb_events: "%{count} events" show: - orga-list: Region's associations + orga-list: Region's orgas add_to_calendar: Add to my calendar copy: Duplicate event at: At @@ -76,7 +68,7 @@ telegraphic style. it more readable or agreable. " preview: Previsualisation - edit: Edition + edit: Creation create: ok: Your event was added to the lists of events waiting for moderation. It will appear online as soon as a moderator validates it. @@ -242,6 +234,32 @@ description." search: title: Find your %{entity}! label: Search + show: + links: Links + actions: Actions + edit: Edit + future: Coming + past: In the past + count: + zero: + one: one event + other: "%{count} events" + new: + title: Organisation + edit: Creation + edit: + title: Organisation + edit: Edition + form: + url_helper: Link toe the organisation's website + feed_helper: "**Direct** link to a syndication feed, RSS or atom" + contact_helper: Contact's email address, obfuscated so that spammers + won't understand it + submitter_helper: Submitter's email address. It will only be used by the + moderators to contact the person who proposed the event, to inform her + about her acceptation or rejection. If this address is absent, the + contact's will be used + save: Save devise: sessions: diff --git a/config/locales/views/fr.yml b/config/locales/views/fr.yml index bdb7aee4..34fbdf7f 100644 --- a/config/locales/views/fr.yml +++ b/config/locales/views/fr.yml @@ -9,14 +9,6 @@ fr: logout: Se déconnecter staleObjectError: Désolé, votre modification est rejetée car une autre personne est déjà intervenue - future: - zero: - one: "Prochainement, %{count} événement:" - other: "Prochainement, %{count} événements:" - past: - zero: - one: "Dans le passé, %{count} événement:" - other: "Dans le passé, %{count} événements:" # Traductions des écrans layouts: @@ -42,7 +34,7 @@ fr: calendar_in: Ce calendrier en %{rss}, %{webcal} ou %{ical} nb_events: "%{count} événements" show: - orga-list: Asso de la région + orga-list: Orgas de la région add_to_calendar: Ajouter à mon calendrier copy: Dupliquer événement at: À @@ -60,14 +52,14 @@ fr: description: Description infos: Informations new: - title: Soumettre un événement + title: Proposer un événement subtitle: Cette page permet de soumettre un événement dans l'Agenda du Libre. Celui-ci n'apparaîtra pas automatiquement dans l'Agenda, il sera tout d'abord validé par un modérateur. Un courrier électronique sera envoyé à l'adresse e-mail du soumetteur donnée ci-dessous lorsque l'événement aura été modéré. preview: Prévisualisation - edit: Édition + edit: Création create: ok: Votre événement a bien été ajouté à la liste des événements en attente de modération. Il apparaîtra en ligne dès qu'un modérateur @@ -244,6 +236,32 @@ description plus complète." search: title: Trouve ton %{entity}! label: Recherche + show: + links: Liens + actions: Actions + edit: Éditer + future: Prochainement + past: Dans le passé + count: + zero: + one: Un événement + other: "%{count} événements" + new: + title: Organisation + edit: Création + edit: + title: Organisation + edit: Édition + form: + url_helper: Lien vers le site web de l'organisation + feed_helper: Lien **direct** vers un flux de syndication, type RSS ou atom + contact_helper: Adresse e-mail de contact, affichée de manière peu + compréhensible par les spammeurs + submitter_helper: Adresse e-mail du soumetteur de l'organisation. + Utilisée par les modérateurs pour informer de sa validation ou de son + rejet. Si cette adresse n'est pas présente, l'adresse de contact sera + utilisée + save: Envoyer devise: sessions: diff --git a/config/routes.rb b/config/routes.rb index ad2bc7d1..a76fcb77 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -19,7 +19,7 @@ Rails.application.routes.draw do resources :regions, only: [:index] resources :tags, only: [:index, :show] resources :maps, only: [:index] - resources :orgas, only: [:index, :show] + resources :orgas # Manage former php pages get 'showevent.php', to: redirect { |_, req| "events/#{req.params[:id]}" } diff --git a/db/migrate/20150215172000_create_kinds.rb b/db/migrate/20150215172000_create_kinds.rb new file mode 100644 index 00000000..3f39aa5a --- /dev/null +++ b/db/migrate/20150215172000_create_kinds.rb @@ -0,0 +1,18 @@ +# Setting up organisations' kinds +class CreateKinds < ActiveRecord::Migration + def change + create_table :kinds do |t| + t.string :name, unique: true, null: false + t.string :icon + + t.timestamps null: false + end + + # Create the relevant organisation kinds + Kind.create name: 'association', icon: 'sitemap' + Kind.create name: 'enterprise', icon: 'building' + Kind.create name: 'lug', icon: 'support' + Kind.create name: 'provider', icon: 'tty' + Kind.create name: 'institution', icon: 'institution' + end +end diff --git a/db/migrate/20150215172739_add_data_to_orgas.rb b/db/migrate/20150215172739_add_data_to_orgas.rb new file mode 100644 index 00000000..a4e9201e --- /dev/null +++ b/db/migrate/20150215172739_add_data_to_orgas.rb @@ -0,0 +1,15 @@ +# The relation between orga and their kind +class AddDataToOrgas < ActiveRecord::Migration + def change + add_reference :orgas, :kind, index: true + add_foreign_key :orgas, :kinds + add_column :orgas, :feed, :string + add_column :orgas, :contact, :string + add_column :orgas, :submitter, :string + add_column :orgas, :moderated, :boolean, default: false + add_column :orgas, :submission_time, :datetime + add_column :orgas, :decision_time, :datetime + add_column :orgas, :secret, :string + add_column :orgas, :deleted, :boolean, default: false, null: false + end +end diff --git a/db/schema.rb b/db/schema.rb index 619ad80c..05231776 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -1,5 +1,4 @@ # encoding: UTF-8 -# rubocop:disable all # This file is auto-generated from the current state of the database. Instead # of editing this file, please use the migrations feature of Active Record to # incrementally modify your database, and then regenerate this schema definition. @@ -12,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20150215151059) do +ActiveRecord::Schema.define(version: 20150215172739) do create_table "active_admin_comments", force: :cascade do |t| t.string "namespace", limit: 255 @@ -85,6 +84,13 @@ ActiveRecord::Schema.define(version: 20150215151059) do add_index "events", ["start_time", "end_time"], name: "events_date" + create_table "kinds", force: :cascade do |t| + t.string "name", null: false + t.string "icon" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + create_table "notes", force: :cascade do |t| t.text "contents", null: false t.datetime "date", null: false @@ -93,13 +99,28 @@ ActiveRecord::Schema.define(version: 20150215151059) do end create_table "orgas", force: :cascade do |t| - t.integer "region_id", default: 0, null: false - t.integer "department", default: 0, null: false - t.string "name", limit: 255, default: "", null: false - t.string "url", limit: 255, default: "", null: false - t.string "city", limit: 255, default: "", null: false + t.integer "region_id", default: 0, null: false + t.integer "department", default: 0, null: false + t.string "name", limit: 255, default: "", null: false + t.string "url", limit: 255, default: "", null: false + t.string "city", limit: 255, default: "", null: false + t.string "place" + t.string "address" + t.integer "orga_kind_id" + t.integer "kind_id" + t.string "feed" + t.string "contact" + t.string "submitter" + t.boolean "moderated", default: false + t.datetime "submission_time" + t.datetime "decision_time" + t.string "secret" + t.boolean "deleted", default: false, null: false end + add_index "orgas", ["kind_id"], name: "index_orgas_on_kind_id" + add_index "orgas", ["orga_kind_id"], name: "index_orgas_on_orga_kind_id" + create_table "regions", force: :cascade do |t| t.string "name", limit: 255, default: "", null: false end diff --git a/db/seeds.rb b/db/seeds.rb index 8f8a985d..37f6ad18 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -18,6 +18,12 @@ User.create login: 'admin@example.com', email: 'admin@example.com', AdminUser.create email: 'admin@example.com', password: 'password' +Kind.create name: 'association', icon: 'sitemap' +Kind.create name: 'enterprise', icon: 'building' +Kind.create name: 'lug', icon: 'support' +Kind.create name: 'provider', icon: 'tty' +Kind.create name: 'institution', icon: 'institution' + # rubocop:disable Metrics/LineLength I18n::Backend::ActiveRecord::Translation.create([ { locale: 'fr', key: 'mail_suffix', value: '[AdL] ' }, diff --git a/test/controllers/orgas_controller_test.rb b/test/controllers/orgas_controller_test.rb index e023fbb6..9a9a4ed1 100644 --- a/test/controllers/orgas_controller_test.rb +++ b/test/controllers/orgas_controller_test.rb @@ -2,6 +2,7 @@ require 'test_helper' # Free Software groups life cycle class OrgasControllerTest < ActionController::TestCase + include Devise::TestHelpers setup do @orga = orgas :one end @@ -11,6 +12,40 @@ class OrgasControllerTest < ActionController::TestCase assert_response :success end + test 'should get new' do + sign_in users(:one) + get :new + assert_response :success + end + + test 'should create orga' do + sign_in users(:one) + assert_difference 'Orga.count' do + post :create, orga: { + kind_id: @orga.kind_id, + name: @orga.name, + city: @orga.city, + region_id: @orga.region.id, + url: @orga.url, + feed: @orga.feed, + contact: @orga.contact + } + + assert_empty assigns(:orga).errors.messages + end + + assert_redirected_to :root + end + + test 'should not create orga' do + sign_in users(:one) + assert_no_difference 'Orga.count' do + post :create, orga: { url: @orga.url } + + assert_not_empty assigns(:orga).errors.messages + end + end + test 'should get show' do get :show, id: @orga assert_response :success diff --git a/test/fixtures/kinds.yml b/test/fixtures/kinds.yml new file mode 100644 index 00000000..8545b12b --- /dev/null +++ b/test/fixtures/kinds.yml @@ -0,0 +1,21 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + name: Association + icon: sitemap + +two: + name: Enterprise + icon: building + +lug: + name: Lug + icon: support + +provider: + name: Provider + icon: tty + +institution: + name: Institution + icon: institution diff --git a/test/fixtures/orgas.yml b/test/fixtures/orgas.yml index c190d8ed..7d24fb1e 100644 --- a/test/fixtures/orgas.yml +++ b/test/fixtures/orgas.yml @@ -1,15 +1,23 @@ # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html one: - region: region_one + kind: lug + name: MyString city: Jolie ville department: 1 - name: MyString - url: MyString + region: region_one + url: http://april.org + feed: http://april.org/index.rss + contact: test@exemple.com + submitter: test@exemple.com two: - region: region_two + kind: provider + name: MyString city: Jolie ville department: 1 - name: MyString - url: MyString + region: region_two + url: http://april.org + feed: http://april.org/index.rss + contact: test@exemple.com + submitter: test@exemple.com diff --git a/test/models/kind_test.rb b/test/models/kind_test.rb new file mode 100644 index 00000000..a4dbe7a8 --- /dev/null +++ b/test/models/kind_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class KindTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end