dorsale 1.0.4 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. data/app/assets/javascripts/dorsale/application.js +0 -12
  2. data/app/assets/javascripts/dorsale/tabs_loader.coffee +7 -0
  3. data/app/assets/stylesheets/dorsale/all.sass +11 -0
  4. data/app/assets/stylesheets/dorsale/contexts.sass +44 -0
  5. data/app/assets/stylesheets/dorsale/filters.sass +3 -0
  6. data/app/assets/stylesheets/dorsale/forms.sass +15 -0
  7. data/app/assets/stylesheets/dorsale/styles.sass +16 -0
  8. data/app/assets/stylesheets/dorsale/tables.sass +17 -0
  9. data/app/controllers/dorsale/small_data/filters_controller.rb +25 -0
  10. data/app/helpers/dorsale/comments_helper.rb +1 -1
  11. data/app/helpers/dorsale/context_helper.rb +37 -0
  12. data/app/helpers/dorsale/form_helper.rb +26 -0
  13. data/app/helpers/dorsale/text_helper.rb +15 -0
  14. data/app/models/dorsale/comment.rb +0 -1
  15. data/app/models/dorsale/small_data/filter.rb +50 -0
  16. data/app/models/dorsale/small_data/filter_strategy.rb +27 -0
  17. data/app/views/dorsale/_actions.html.slim +22 -0
  18. data/app/views/dorsale/_contextual.html.slim +5 -0
  19. data/config/routes.rb +4 -0
  20. data/lib/dorsale/engine.rb +17 -0
  21. data/lib/dorsale/polymorphic_id.rb +38 -0
  22. data/lib/dorsale/simple_form.rb +166 -0
  23. data/lib/dorsale/simple_form_bootstrap.rb +136 -0
  24. data/lib/dorsale/version.rb +1 -1
  25. data/spec/dummy/log/test.log +2198 -0
  26. data/spec/routing/dorsale/small_data_routing_spec.rb +15 -0
  27. data/spec/spec_helper.rb +5 -0
  28. metadata +153 -24
  29. data/app/assets/javascripts/dorsale/addresses.js +0 -2
  30. data/app/assets/stylesheets/dorsale/addresses.css +0 -4
  31. data/app/assets/stylesheets/dorsale/application.css +0 -13
@@ -1,13 +1 @@
1
- // This is a manifest file that'll be compiled into application.js, which will include all the files
2
- // listed below.
3
- //
4
- // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
- // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
6
- //
7
- // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
- // compiled file.
9
- //
10
- // Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
11
- // about supported directives.
12
- //
13
1
  //= require_tree .
@@ -0,0 +1,7 @@
1
+ $(document).on "ready page:load", ->
2
+ if window.location.hash
3
+ activeTab = $('[href=' + window.location.hash + ']')
4
+ activeTab && activeTab.tab('show')
5
+
6
+ $('.nav-tabs a').on 'click', (e) ->
7
+ window.location.hash = e.target.hash
@@ -0,0 +1,11 @@
1
+ @import bootstrap
2
+ @import bootstrap-sprockets
3
+ @import font-awesome
4
+ @import font-awesome-sprockets
5
+
6
+ @import dorsale/comments
7
+ @import dorsale/tables
8
+ @import dorsale/contexts
9
+ @import dorsale/forms
10
+ @import dorsale/styles
11
+ @import dorsale/filters
@@ -0,0 +1,44 @@
1
+ .context
2
+ @extend .well
3
+ text-align: center
4
+ position: relative
5
+ margin-bottom: 15px !important
6
+
7
+ .fa
8
+ @extend .fa-fw
9
+
10
+ > .fa
11
+ font-size: 400%
12
+ color: black
13
+ padding: 10px
14
+ margin: auto
15
+ display: block
16
+
17
+ strong, h2
18
+ @extend .text-muted
19
+
20
+ h2
21
+ margin: 10px
22
+ font-size: 150%
23
+ font-weight: bold
24
+
25
+ p.infos
26
+ margin: 5px
27
+ text-align: left
28
+
29
+ strong
30
+ display: inline-block
31
+ width: 50%
32
+
33
+ .btn-group
34
+ position: absolute
35
+ top: 0
36
+ right: 0
37
+
38
+ .btn
39
+ border-top: 0
40
+ border-right: 0
41
+ border-radius: 0 0 0 3px
42
+
43
+ img
44
+ max-width: 100%
@@ -0,0 +1,3 @@
1
+ .filters
2
+ @extend .well
3
+ padding: 5px 15px
@@ -0,0 +1,15 @@
1
+ form
2
+ .actions
3
+ text-align: center
4
+ border-top: 1px solid #DDD
5
+ margin-top: 25px
6
+ padding-top: 20px
7
+
8
+ .btn
9
+ margin: 5px
10
+
11
+ textarea
12
+ height: 15em !important // 10 lines
13
+
14
+ .btn
15
+ @extend .btn-default
@@ -0,0 +1,16 @@
1
+ .left
2
+ text-align: left
3
+
4
+ .right
5
+ text-align: right
6
+
7
+ .center
8
+ text-align: center
9
+
10
+ .nostyle
11
+ margin: 0
12
+ padding: 0
13
+ background: none
14
+ border: none
15
+ outline: none
16
+ border-radius: 0
@@ -0,0 +1,17 @@
1
+ table.default
2
+ @extend .table
3
+ @extend .table-striped
4
+ @extend .table-bordered
5
+ @extend .table-hover
6
+
7
+ th
8
+ text-align: center
9
+ vertical-align: middle !important
10
+
11
+ td[class*="date"]
12
+ width: 8em
13
+ text-align: center
14
+
15
+ td[class*="count"]
16
+ width: 1em
17
+ text-align: center
@@ -0,0 +1,25 @@
1
+ module Dorsale
2
+ module SmallData
3
+ class FiltersController < ApplicationController
4
+
5
+ def create
6
+ filters = params[:filters] || {}
7
+
8
+ filters.each do |key, value|
9
+ filters[key] = "" if value == "0"
10
+ end
11
+
12
+ Filter.new(cookies).store(filters)
13
+
14
+ urls = [
15
+ params[:back_url],
16
+ request.referer,
17
+ (main_app.root_path rescue nil)
18
+ ]
19
+
20
+ redirect_to urls.select(&:present?).first
21
+ end
22
+
23
+ end
24
+ end
25
+ end
@@ -3,7 +3,7 @@ module Dorsale
3
3
  def comment_form_for(commentable)
4
4
  render partial: "dorsale/comments/form", locals: {commentable: commentable}
5
5
  end
6
-
6
+
7
7
  def comments_for(commentable)
8
8
  render partial: "dorsale/comments/comments", locals: {commentable: commentable}
9
9
  end
@@ -0,0 +1,37 @@
1
+ module Dorsale
2
+ module ContextHelper
3
+ def context_icon(id)
4
+ icon(id)
5
+ end
6
+
7
+ def context_title(title)
8
+ content_tag(:h2){ title }
9
+ end
10
+
11
+ def context_info(name, info)
12
+ return if info.blank?
13
+ %(<p class="infos"><strong>#{name} : </strong>#{info}</p>).html_safe
14
+ end
15
+
16
+ def actions_for(obj, opts={})
17
+ url = opts[:url]
18
+ edit_url = opts[:edit_url]
19
+ delete_url = opts[:delete_url]
20
+
21
+ url = polymorphic_path(obj) if url.nil?
22
+ edit_url = url + "/edit" if edit_url.nil?
23
+ delete_url = url if delete_url.nil?
24
+
25
+ render partial: "dorsale/actions", locals: {
26
+ :obj => obj,
27
+ :url => url,
28
+ :edit_url => edit_url,
29
+ :delete_url => delete_url,
30
+ }
31
+ end
32
+
33
+ def render_contextual
34
+ render "dorsale/contextual"
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,26 @@
1
+ module Dorsale
2
+ module FormHelper
3
+ def form_buttons(opts = {})
4
+ back_url = opts[:back_url]
5
+ back_url = url_for(:back).html_safe if back_url.nil?
6
+
7
+ content_tag("div", class: "actions cdiv") do
8
+ submit = tag("input", type: "submit", class: "btn btn-success btn-sm", value: "Valider", id: "submit")
9
+ cancel = content_tag("a", href: back_url, class: "btn btn-primary btn-sm"){ "Annuler" }
10
+ cancel = "" if back_url == false
11
+ submit + cancel
12
+ end
13
+ end
14
+
15
+ def horizontal_form_for(obj, opts={}, &block)
16
+ opts = {
17
+ :wrapper => "horizontal_form",
18
+ :html => {
19
+ :class => "form-horizontal"
20
+ }
21
+ }.deep_merge(opts)
22
+
23
+ simple_form_for(obj, opts, &block)
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,15 @@
1
+ module Dorsale
2
+ module TextHelper
3
+ def euros(n)
4
+ number_to_currency(n)
5
+ end
6
+
7
+ def percentage(n)
8
+ number_to_percentage(n, precision: 2, format: "%n %")
9
+ end
10
+
11
+ def text2html(str)
12
+ h(str).gsub("\r", "").gsub("\n", "<br />").html_safe
13
+ end
14
+ end
15
+ end
@@ -2,7 +2,6 @@ module Dorsale
2
2
  class Comment < ActiveRecord::Base
3
3
  belongs_to :user, polymorphic: true
4
4
  belongs_to :commentable, polymorphic: true
5
- has_many :events, as: :eventable, dependent: :destroy
6
5
 
7
6
  validates :commentable, presence: true
8
7
  validates :text, presence: true
@@ -0,0 +1,50 @@
1
+ module Dorsale
2
+ module SmallData
3
+ class Filter
4
+
5
+ def initialize(jar)
6
+ @jar = jar
7
+ end
8
+
9
+ def store(filters)
10
+ @jar['filters'] = filters.to_json
11
+ end
12
+
13
+ def read
14
+ if @jar['filters']
15
+ begin
16
+ JSON.parse @jar['filters']
17
+ rescue JSON::ParserError
18
+ {}
19
+ end
20
+ else
21
+ {}
22
+ end
23
+ end
24
+
25
+ def get(key)
26
+ read[key.to_s]
27
+ end
28
+
29
+ def set(key, value)
30
+ array = read
31
+ array[key.to_s] = value
32
+ store(array)
33
+ end
34
+
35
+ def apply(query)
36
+ read.each do |key, value|
37
+ filter = strategy(key)
38
+
39
+ if filter && filter.applies?(self.target)
40
+ filter.set(key, value)
41
+ query = filter.apply(query)
42
+ end
43
+ end
44
+
45
+ return query
46
+ end
47
+
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,27 @@
1
+ module Dorsale
2
+ module SmallData
3
+ class FilterStrategy
4
+ def initialize(target)
5
+ @target = target
6
+ end
7
+
8
+ def set(key, value)
9
+ @key = key
10
+ @value = value
11
+ return self
12
+ end
13
+
14
+ def apply(query)
15
+ if @value and @value != ''
16
+ do_apply(query)
17
+ else
18
+ query
19
+ end
20
+ end
21
+
22
+ def applies?(target)
23
+ @target == target
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,22 @@
1
+ .btn-group
2
+ button.btn.btn-default.btn-sm.dropdown-toggle.actions data-toggle="dropdown"
3
+ = "Actions "
4
+ = icon :"caret-down"
5
+ ul.dropdown-menu
6
+ - if url && url != request.path_info
7
+ li
8
+ a.link_edit href=url
9
+ = icon :"file-o"
10
+ = " Afficher"
11
+
12
+ - if edit_url && edit_url != request.path_info
13
+ li
14
+ a.link_edit href=edit_url
15
+ = icon :pencil
16
+ = " Editer"
17
+
18
+ - if delete_url
19
+ li
20
+ a.link_delete href=delete_url data-method="delete" data-confirm="Confirmer ?"
21
+ = icon :trash
22
+ = " Supprimer"
@@ -0,0 +1,5 @@
1
+ .row
2
+ aside.col-sm-4.col-xs-12
3
+ = yield :context
4
+ .col-sm-8.col-xs-12
5
+ = yield :main
data/config/routes.rb CHANGED
@@ -1,4 +1,8 @@
1
1
  Dorsale::Engine.routes.draw do
2
2
  resources :addresses
3
3
  resources :comments, only: [:create]
4
+
5
+ namespace :small_data do
6
+ resources :filters, only: [:create]
7
+ end
4
8
  end
@@ -1,3 +1,20 @@
1
+ require "slim-rails"
2
+ require "sass-rails"
3
+ require "bootstrap-sass"
4
+ require "font-awesome-sass"
5
+ require "simple_form"
6
+ require "coffee-rails"
7
+ require "jquery-rails"
8
+ require "kaminari"
9
+ require "turbolinks"
10
+ require "bootstrap-kaminari-views"
11
+ require "bh"
12
+ require "rails-i18n"
13
+ require "cancan"
14
+
15
+ require "dorsale/simple_form"
16
+ require "dorsale/simple_form_bootstrap"
17
+
1
18
  module Dorsale
2
19
  class Engine < ::Rails::Engine
3
20
  isolate_namespace Dorsale
@@ -0,0 +1,38 @@
1
+ module Dorsale
2
+ module PolymorphicId
3
+ module ClassMethods
4
+ def polymorphic_id_for(relation_name)
5
+ module_src = File.read(__FILE__).split("__END__").last
6
+ module_src = module_src.gsub("relation", relation_name.to_s)
7
+ send :include, eval(module_src)
8
+ end
9
+ end
10
+
11
+ def self.included(model)
12
+ model.send(:extend, Dorsale::PolymorphicId::ClassMethods)
13
+ end
14
+
15
+ def guid
16
+ return nil if new_record?
17
+
18
+ "#{self.class}-#{self.id}"
19
+ end
20
+ end
21
+ end
22
+
23
+ # __END__
24
+
25
+ Module.new do
26
+ def relation_guid
27
+ return nil if relation_type.blank? || relation_id.blank?
28
+
29
+ "#{relation_type}-#{relation_id}"
30
+ end
31
+
32
+ def relation_guid=(guid)
33
+ return self.relation = nil if guid.blank?
34
+
35
+ type, id = guid.split("-")
36
+ self.relation = type.constantize.find(id)
37
+ end
38
+ end
@@ -0,0 +1,166 @@
1
+ # Use this setup block to configure all options available in SimpleForm.
2
+ SimpleForm.setup do |config|
3
+ # Wrappers are used by the form builder to generate a
4
+ # complete input. You can remove any component from the
5
+ # wrapper, change the order or even add your own to the
6
+ # stack. The options given below are used to wrap the
7
+ # whole input.
8
+ config.wrappers :default, class: :input,
9
+ hint_class: :field_with_hint, error_class: :field_with_errors do |b|
10
+ ## Extensions enabled by default
11
+ # Any of these extensions can be disabled for a
12
+ # given input by passing: `f.input EXTENSION_NAME => false`.
13
+ # You can make any of these extensions optional by
14
+ # renaming `b.use` to `b.optional`.
15
+
16
+ # Determines whether to use HTML5 (:email, :url, ...)
17
+ # and required attributes
18
+ b.use :html5
19
+
20
+ # Calculates placeholders automatically from I18n
21
+ # You can also pass a string as f.input placeholder: "Placeholder"
22
+ b.use :placeholder
23
+
24
+ ## Optional extensions
25
+ # They are disabled unless you pass `f.input EXTENSION_NAME => true`
26
+ # to the input. If so, they will retrieve the values from the model
27
+ # if any exists. If you want to enable any of those
28
+ # extensions by default, you can change `b.optional` to `b.use`.
29
+
30
+ # Calculates maxlength from length validations for string inputs
31
+ b.optional :maxlength
32
+
33
+ # Calculates pattern from format validations for string inputs
34
+ b.optional :pattern
35
+
36
+ # Calculates min and max from length validations for numeric inputs
37
+ b.optional :min_max
38
+
39
+ # Calculates readonly automatically from readonly attributes
40
+ b.optional :readonly
41
+
42
+ ## Inputs
43
+ b.use :label_input
44
+ b.use :hint, wrap_with: { tag: :span, class: :hint }
45
+ b.use :error, wrap_with: { tag: :span, class: :error }
46
+
47
+ ## full_messages_for
48
+ # If you want to display the full error message for the attribute, you can
49
+ # use the component :full_error, like:
50
+ #
51
+ # b.use :full_error, wrap_with: { tag: :span, class: :error }
52
+ end
53
+
54
+ # The default wrapper to be used by the FormBuilder.
55
+ config.default_wrapper = :default
56
+
57
+ # Define the way to render check boxes / radio buttons with labels.
58
+ # Defaults to :nested for bootstrap config.
59
+ # inline: input + label
60
+ # nested: label > input
61
+ config.boolean_style = :nested
62
+
63
+ # Default class for buttons
64
+ config.button_class = 'btn'
65
+
66
+ # Method used to tidy up errors. Specify any Rails Array method.
67
+ # :first lists the first message for each field.
68
+ # Use :to_sentence to list all errors for each field.
69
+ # config.error_method = :first
70
+
71
+ # Default tag used for error notification helper.
72
+ config.error_notification_tag = :div
73
+
74
+ # CSS class to add for error notification helper.
75
+ config.error_notification_class = 'error_notification'
76
+
77
+ # ID to add for error notification helper.
78
+ # config.error_notification_id = nil
79
+
80
+ # Series of attempts to detect a default label method for collection.
81
+ # config.collection_label_methods = [ :to_label, :name, :title, :to_s ]
82
+
83
+ # Series of attempts to detect a default value method for collection.
84
+ # config.collection_value_methods = [ :id, :to_s ]
85
+
86
+ # You can wrap a collection of radio/check boxes in a pre-defined tag, defaulting to none.
87
+ # config.collection_wrapper_tag = nil
88
+
89
+ # You can define the class to use on all collection wrappers. Defaulting to none.
90
+ # config.collection_wrapper_class = nil
91
+
92
+ # You can wrap each item in a collection of radio/check boxes with a tag,
93
+ # defaulting to :span. Please note that when using :boolean_style = :nested,
94
+ # SimpleForm will force this option to be a label.
95
+ # config.item_wrapper_tag = :span
96
+
97
+ # You can define a class to use in all item wrappers. Defaulting to none.
98
+ # config.item_wrapper_class = nil
99
+
100
+ # How the label text should be generated altogether with the required text.
101
+ # config.label_text = lambda { |label, required, explicit_label| "#{required} #{label}" }
102
+
103
+ # You can define the class to use on all labels. Default is nil.
104
+ # config.label_class = nil
105
+
106
+ # You can define the default class to be used on forms. Can be overriden
107
+ # with `html: { :class }`. Defaulting to none.
108
+ # config.default_form_class = nil
109
+
110
+ # You can define which elements should obtain additional classes
111
+ # config.generate_additional_classes_for = [:wrapper, :label, :input]
112
+
113
+ # Whether attributes are required by default (or not). Default is true.
114
+ # config.required_by_default = true
115
+
116
+ # Tell browsers whether to use the native HTML5 validations (novalidate form option).
117
+ # These validations are enabled in SimpleForm's internal config but disabled by default
118
+ # in this configuration, which is recommended due to some quirks from different browsers.
119
+ # To stop SimpleForm from generating the novalidate option, enabling the HTML5 validations,
120
+ # change this configuration to true.
121
+ config.browser_validations = false
122
+
123
+ # Collection of methods to detect if a file type was given.
124
+ # config.file_methods = [ :mounted_as, :file?, :public_filename ]
125
+
126
+ # Custom mappings for input types. This should be a hash containing a regexp
127
+ # to match as key, and the input type that will be used when the field name
128
+ # matches the regexp as value.
129
+ # config.input_mappings = { /count/ => :integer }
130
+
131
+ # Custom wrappers for input types. This should be a hash containing an input
132
+ # type as key and the wrapper that will be used for all inputs with specified type.
133
+ # config.wrapper_mappings = { string: :prepend }
134
+
135
+ # Namespaces where SimpleForm should look for custom input classes that
136
+ # override default inputs.
137
+ # config.custom_inputs_namespaces << "CustomInputs"
138
+
139
+ # Default priority for time_zone inputs.
140
+ # config.time_zone_priority = nil
141
+
142
+ # Default priority for country inputs.
143
+ # config.country_priority = nil
144
+
145
+ # When false, do not use translations for labels.
146
+ # config.translate_labels = true
147
+
148
+ # Automatically discover new inputs in Rails' autoload path.
149
+ # config.inputs_discovery = true
150
+
151
+ # Cache SimpleForm inputs discovery
152
+ # config.cache_discovery = !Rails.env.development?
153
+
154
+ # Default class for inputs
155
+ # config.input_class = nil
156
+
157
+ # Define the default class of the input wrapper of the boolean input.
158
+ config.boolean_label_class = 'checkbox'
159
+
160
+ # Defines if the default input wrapper class should be included in radio
161
+ # collection wrappers.
162
+ # config.include_default_input_wrapper_class = true
163
+
164
+ # Defines which i18n scope will be used in Simple Form.
165
+ # config.i18n_scope = 'simple_form'
166
+ end