admin_widgets 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,11 @@
1
+ .bundle
2
+ db/*.sqlite3
3
+ log/*.log
4
+ tmp/
5
+ .sass-cache/
6
+ .DS_Store
7
+ ._*
8
+ Gemfile.lock
9
+ .AppleDouble
10
+ test/config/*.yml
11
+ *.gem
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in admin_widgets.gemspec
4
+ gemspec
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "admin_widgets/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "admin_widgets"
7
+ s.version = AdminWidgets::VERSION
8
+ s.authors = ["DanX~"]
9
+ s.email = ["danx.exe@gmail.com"]
10
+ s.homepage = "http://www.mobvox.com.br"
11
+ s.summary = "Awesome Admin Widgets"
12
+ s.description = "Super Awesome Admin Widgets"
13
+
14
+ s.rubyforge_project = "admin_widgets"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ # specify any dependencies here; for example:
22
+ # s.add_development_dependency "rspec"
23
+ # s.add_runtime_dependency "rest-client"
24
+
25
+ s.add_runtime_dependency "apotomo"
26
+ end
@@ -0,0 +1,8 @@
1
+ require 'admin_widgets/version'
2
+ require 'admin_widgets/engine'
3
+
4
+ require 'admin_widgets/extensions/action_view_ext.rb'
5
+ require 'admin_widgets/extensions/simple_form_ext.rb'
6
+
7
+ module AdminWidgets
8
+ end
@@ -0,0 +1,65 @@
1
+ module AdminWidgets
2
+ class BaseFormWidget < BaseWidget
3
+
4
+ attr_reader :form
5
+
6
+ # TODO: WTF? Who the hell is overriding the 'form' method?
7
+ def builder
8
+ form
9
+ end
10
+
11
+ memoize :resource_class, proc { helper.resource_class }
12
+ memoize :resource, proc { helper.resource }
13
+ memoize :params, proc { helper.params }
14
+ memoize :as, nil
15
+ memoize :url, proc { '' }
16
+ memoize :cancel_url, proc { helper.respond_to?(:collection_path) ? helper.collection_path : false }
17
+ memoize :css_class, 'form'
18
+
19
+ delegate :object, :to => :form
20
+
21
+ def content
22
+ rawtext around_form
23
+ end
24
+
25
+ def around_form
26
+ form_method = @form ? :simple_fields_for : :simple_form_for
27
+
28
+ helper.send(form_method, resource, :url => url, :as => as, :class => css_class, :html => @html) do |f|
29
+ @form = f # IMPORTANT!
30
+
31
+ capture do
32
+ form_content
33
+ end
34
+ end
35
+ end
36
+
37
+ def form_content
38
+ content_block
39
+ buttons
40
+ end
41
+
42
+ # FIXME: Beware, arcane magic below. We are polluting the root widget with a instance variable, is there a better way to do this?
43
+ def autofocus_done?
44
+ root.instance_variable_get(:@autofocus_done)
45
+ end
46
+ def autofocus!(options = {})
47
+ root.instance_variable_set(:@autofocus_done, true)
48
+ { autofocus: true }.merge(options)
49
+ end
50
+
51
+ # DSL methods
52
+
53
+ def field(name, options = {})
54
+ options = autofocus!(options) unless autofocus_done?
55
+
56
+ condition = options[:if]
57
+ return if (condition.present? && !resource.instance_eval(&condition))
58
+
59
+ form = (options[:nested] === false && self.respond_to?(:parent)) ? parent.form : self.form
60
+
61
+ rawtext form.input(name, options)
62
+ end
63
+
64
+ end
65
+ end
@@ -0,0 +1,33 @@
1
+ module AdminWidgets
2
+ class BaseWidget < Erector::Widget
3
+ extend AdminWidgets::Memoization
4
+ extend AdminWidgets::Delegation
5
+
6
+ # Outputs to a new buffer
7
+ def capture(&block)
8
+ original, @_output = output, Erector::Output.new
9
+ instance_eval &block
10
+ original.widgets.concat(output.widgets)
11
+ output.to_s
12
+ ensure
13
+ @_output = original
14
+ end
15
+
16
+ def root
17
+ parent and parent.root or self
18
+ end
19
+
20
+ def helper
21
+ @controller.view_context
22
+ end
23
+
24
+ def method_missing(method_name, *args, &block)
25
+ rawtext helper.send(method_name, *args, &block)
26
+ end
27
+
28
+ def content_block
29
+ instance_eval &@block if @block
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,20 @@
1
+ module AdminWidgets
2
+ module Delegation
3
+ def delegate(*methods)
4
+ options = methods.last
5
+ keys = methods[0..-2]
6
+
7
+ if options.is_a?(Hash) and options[:hash]
8
+ keys.each do |key|
9
+ define_method key do
10
+ hash = self.send(options[:to])
11
+ hash.send(:[], key)
12
+ end
13
+ end
14
+ else
15
+ super *methods
16
+ end
17
+
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,22 @@
1
+ module AdminWidgets
2
+ class Engine < Rails::Engine
3
+ config.to_prepare do
4
+ require_dependency 'admin_widgets/helper'
5
+ require_dependency 'admin_widgets/memoization'
6
+ require_dependency 'admin_widgets/delegation'
7
+ require_dependency 'admin_widgets/base_widget'
8
+ require_dependency 'admin_widgets/base_form_widget'
9
+ require_dependency 'admin_widgets/form_widget'
10
+ require_dependency 'admin_widgets/form/fieldset_widget'
11
+ require_dependency 'admin_widgets/wizard_widget'
12
+ require_dependency 'admin_widgets/list_widget'
13
+ require_dependency 'admin_widgets/scopes_widget'
14
+ require_dependency 'admin_widgets/filters_widget'
15
+ require_dependency 'admin_widgets/show_widget'
16
+ require_dependency 'admin_widgets/show/fieldset_widget'
17
+
18
+ ActionView::Base.send :include, AdminWidgets::Helper
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,14 @@
1
+ module ActionView::Helpers::FormOptionsHelper
2
+ def options_from_collection_for_select(collection, value_method, text_method, selected = nil)
3
+ options = collection.map do |element|
4
+ option_html_attributes = (Array === element && element.size == 3 ? element.last : nil)
5
+ [element.send(text_method), element.send(value_method), option_html_attributes].compact
6
+ end
7
+ selected, disabled = extract_selected_and_disabled(selected)
8
+ select_deselect = {}
9
+ select_deselect[:selected] = extract_values_from_collection(collection, value_method, selected)
10
+ select_deselect[:disabled] = extract_values_from_collection(collection, value_method, disabled)
11
+
12
+ options_for_select(options, select_deselect)
13
+ end
14
+ end
@@ -0,0 +1,16 @@
1
+ class SimpleForm::Inputs::CollectionInput
2
+ def detect_common_display_methods
3
+ collection_classes = detect_collection_classes
4
+
5
+ if collection_classes.include?(Array)
6
+ { :label => :first, :value => :second }
7
+ elsif collection_includes_basic_objects?(collection_classes)
8
+ { :label => :to_s, :value => :to_s }
9
+ else
10
+ sample = collection.first || collection.last
11
+
12
+ { :label => SimpleForm.collection_label_methods.find { |m| sample.respond_to?(m) },
13
+ :value => SimpleForm.collection_value_methods.find { |m| sample.respond_to?(m) } }
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,59 @@
1
+ module AdminWidgets
2
+ class FiltersWidget < BaseFormWidget
3
+
4
+ memoize :resource, nil
5
+ memoize :as, 'search'
6
+ memoize :resource, 'search'
7
+ memoize :url, proc { helper.search_resources_path }
8
+ memoize :method, 'post'
9
+
10
+ def form_content
11
+ hidden_fields
12
+ content_block
13
+ buttons
14
+ end
15
+
16
+ # DSL methods
17
+
18
+ def field(name, operator, options = {})
19
+ field_name = "#{name}_#{operator}"
20
+ field_label = resource_class.human_attribute_name(name)
21
+ field_value = params[as][field_name] rescue ''
22
+
23
+ multiple = [:in, :all].include?(operator.to_sym)
24
+ field_value = field_value.to_s.split(',') if multiple && field_value && !field_value.is_a?(Array)
25
+
26
+ if options[:collection].present?
27
+ value = nil
28
+ selected = field_value
29
+ include_blank = true
30
+ else
31
+ value = field_value
32
+ selected = nil
33
+ include_blank = nil
34
+ end
35
+
36
+ default_options = { :required => false, :label => field_label, :input_html => { :value => value, :multiple => multiple }, :selected => selected, :include_blank => include_blank, :hidden_field => false }
37
+ rawtext form.input(field_name, default_options.merge(options))
38
+ end
39
+
40
+ def hidden_fields
41
+ div :class => ['hidden-fields'] do
42
+ %w[scope sort_field sort_direction].each do |hidden_field|
43
+ rawtext form.input(hidden_field, :input_html => { :name => hidden_field, :value => params[hidden_field] }, :as => :hidden)
44
+ end
45
+ end
46
+ end
47
+
48
+ def buttons
49
+ div :class => ['group', 'navform', 'wat-cf'] do
50
+ rawtext helper.button_tag(:class => 'button', :name => 'filter', :value => as) {
51
+ helper.image_tag('search-button.png') +
52
+ helper.t('resources.actions.filter')
53
+ }
54
+ rawtext helper.link_to(helper.t('resources.actions.reset_filter'), cancel_url, :class => "text_button_padding link_button") if cancel_url
55
+ end
56
+ end
57
+
58
+ end
59
+ end
@@ -0,0 +1,102 @@
1
+ module AdminWidgets::Form
2
+ class FieldsetWidget < AdminWidgets::FormWidget
3
+
4
+ attr_reader :parent
5
+ attr_reader :name
6
+
7
+ def resource
8
+ form.object
9
+ end
10
+
11
+ delegate :helper, :to => :parent
12
+
13
+ memoize :repeatable, false
14
+ memoize :nested, true
15
+ memoize :legend, proc { resource_class.human_attribute_name(name) }
16
+ memoize :wrapper_html, {}
17
+
18
+ def visible
19
+ return @visible = true if @visible.nil?
20
+ return @visible = @visible.call(resource) if @visible.respond_to? :call
21
+ @visible
22
+ end
23
+
24
+ def content
25
+ return simple_fieldset unless nested
26
+
27
+ around_form do
28
+ around_repeatable_collection do
29
+ parent.form.simple_fields_for(name) do |form|
30
+ @form = form # IMPORTANT!
31
+
32
+ around_repeatable_group do
33
+ content_block
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+
40
+ def before
41
+ @before = capture do
42
+ div :class => 'before' do
43
+ yield
44
+ end
45
+ end
46
+ nil
47
+ end
48
+
49
+ def after
50
+ @after = capture do
51
+ div :class => 'after' do
52
+ yield
53
+ end
54
+ end
55
+ nil
56
+ end
57
+
58
+ def simple_fieldset
59
+ @form = parent.form
60
+ around_form do
61
+ content_block
62
+ end
63
+ end
64
+
65
+ def around_form
66
+ wrapper_attrs = { :class => 'fieldset-wrapper' }
67
+ wrapper_attrs.merge! :style => 'display: none' unless visible
68
+ wrapper_attrs.merge! wrapper_html
69
+
70
+ div wrapper_attrs do
71
+ if legend
72
+ element('fieldset') do
73
+ element('legend', legend)
74
+ inside = capture { yield }
75
+ rawtext @before
76
+ rawtext inside
77
+ rawtext @after
78
+ end
79
+ else
80
+ yield
81
+ end
82
+ end
83
+ end
84
+
85
+ def around_repeatable_collection
86
+ return yield unless repeatable
87
+
88
+ div :class => 'repeatable-collection', :'data-repeatable' => repeatable do
89
+ yield
90
+ end
91
+ end
92
+
93
+ def around_repeatable_group
94
+ return yield unless repeatable
95
+
96
+ div :class => ['repeatable-group', form.object.class.name.underscore], :id => form.object._id do
97
+ yield
98
+ end
99
+ end
100
+
101
+ end
102
+ end
@@ -0,0 +1,24 @@
1
+ module AdminWidgets
2
+ class FormWidget < BaseFormWidget
3
+
4
+ memoize :url, proc { helper.respond_to?(:resource_or_collection_path) ? helper.resource_or_collection_path : '' }
5
+ memoize :save_button, true
6
+
7
+ # DSL methods
8
+
9
+ def fieldset(name, options = {}, &block)
10
+ widget AdminWidgets::Form::FieldsetWidget.new(options.merge(:name => name, :parent => self, :block => block))
11
+ end
12
+
13
+ def buttons
14
+ div :class => ['group', 'navform', 'wat-cf'] do
15
+ rawtext helper.button_tag(:class => 'button') {
16
+ helper.image_tag('icons/tick.png') +
17
+ helper.t('resources.actions.save')
18
+ } if save_button
19
+ rawtext helper.link_to(helper.t('resources.actions.cancel'), cancel_url, :class => "text_button_padding link_button") if cancel_url
20
+ end
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,11 @@
1
+ module AdminWidgets
2
+ module Helper
3
+
4
+ def admin_widget(name, options = {}, &block)
5
+ widget_class = "::AdminWidgets::#{name.to_s.camelize}Widget".constantize
6
+ options = options.merge(:controller => controller, :block => block)
7
+ widget_class.new(options).to_html
8
+ end
9
+
10
+ end
11
+ end
@@ -0,0 +1,210 @@
1
+ module AdminWidgets
2
+ class ListWidget < BaseWidget
3
+
4
+ attr_accessor :table_class
5
+ attr_reader :fields
6
+
7
+ # Options
8
+
9
+ memoize :table_id, proc { "#{resource_name}-table" }
10
+ memoize :table_class, 'table'
11
+ memoize :th_class, 'table-column'
12
+ memoize :pagination_class, ['actions-bar', 'wat-cf']
13
+ memoize :row_class, ActionView::Helpers::TextHelper::Cycle.new(:odd, :even)
14
+ memoize :resource_class, proc { helper.resource_class }
15
+ memoize :resource_name, proc { resource_class.name.underscore.pluralize }
16
+ memoize :params, proc { helper.params }
17
+
18
+ memoize :row_actions, true
19
+
20
+ memoize :page_param, :page
21
+ memoize :per_page_param, :per_page
22
+ memoize :page, proc { params[page_param].presence || 1 }
23
+ memoize :per_page, proc { params[per_page_param].presence || 25 }
24
+
25
+ memoize :column_sorting, true
26
+ memoize :sort_field_param, :sort_field
27
+ memoize :sort_direction_param, :sort_direction
28
+ memoize :sort_field, proc { params[sort_field_param].presence || :created_at }
29
+ memoize :sort_direction, proc { params[sort_direction_param].presence || :desc }
30
+
31
+ memoize :search_param, :search
32
+ memoize :search, proc { params[search_param] }
33
+
34
+ memoize :collection, proc { helper.collection }
35
+ memoize :scoped_collection, proc { collection.send(sort_direction, sort_field).page(page).per(per_page) }
36
+
37
+
38
+ delegate :edit_resource_path, :to => :helper
39
+ delegate :resource_path, :to => :helper
40
+
41
+ def initialize(*attrs)
42
+ super(*attrs)
43
+
44
+ @fields = []
45
+ end
46
+
47
+ def content
48
+ content_block
49
+ div :class => 'table-wrapper' do
50
+ div :class => 'table-controls'
51
+ div :class => 'table-content' do
52
+ table :class => table_class, :id => table_id, :'data-highlight-id' => helper.flash[:highlight_id] do
53
+ header
54
+ body
55
+ end
56
+ end
57
+ end
58
+ pagination
59
+ end
60
+
61
+
62
+ # Content methods
63
+
64
+ def header
65
+ thead do
66
+ tr do
67
+ th :class => 'first'
68
+ fields.each do |field|
69
+ th :class => th_class, :'data-field-name' => field.name do
70
+ header = Header.new(self, field)
71
+ rawtext(column_sorting ? helper.link_to(header.label, header.url, :class => ['sortable', header.css_class]) : header.label)
72
+ end
73
+ end
74
+ th :class => 'last'
75
+ end
76
+ end
77
+ end
78
+
79
+ def body
80
+ tbody do
81
+ scoped_collection.each do |object|
82
+ tr :class => row_class, :'data-id' => object.id do
83
+ td :class => 'first'
84
+ fields.each do |field|
85
+ td field.value_for(object)
86
+ end
87
+ td :class => 'last' do
88
+ row_actions_for(object) if row_actions
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
94
+
95
+ def pagination
96
+ div :class => pagination_class do
97
+ div :class => 'results' do
98
+ count = [scoped_collection.count(true), scoped_collection.total_count].join(I18n.t('of', :scope => 'views.pagination'))
99
+ label = helper.t('views.pagination.results')
100
+ rawtext "#{label} #{count}"
101
+ end
102
+ rawtext helper.paginate scoped_collection, :outer_window => 1, :inner_window => 5, :params => { :search => nil }, :param_name => page_param
103
+ end
104
+ end
105
+
106
+ def row_actions_for(object)
107
+ rawtext helper.link_to(label = helper.t('resources.actions.edit'), edit_resource_path(object), :class => 'edit', :alt => label)
108
+ rawtext helper.link_to(label = helper.t('resources.actions.destroy'), resource_path(object), :method => :delete, :confirm => helper.t('resources.destroy.confirm'), :class => 'destroy', :alt => label)
109
+ end
110
+
111
+
112
+ # DSL methods
113
+
114
+ def field(name, options = {}, &block)
115
+
116
+ value_callback = lambda do |name, options|
117
+ attribute_path = name.to_s.split('.')
118
+ value = attribute_path.inject(self) {|r, v| r.try(v) rescue '' }
119
+
120
+ # FIXME: This is bad code and I should feel bad. Extract it to a presenter maybe?
121
+ if value.is_a? Time
122
+ I18n.l(value, :format => :short)
123
+ elsif value.is_a? Date
124
+ I18n.l(value, :format => :default)
125
+ elsif value.is_a? Array
126
+ value.join(', ')
127
+ elsif options[:i18n]
128
+ I18n.t(value, :scope => options[:i18n])
129
+ else
130
+ value
131
+ end
132
+ end
133
+
134
+ @fields << Field.new(self, name, options, value_callback)
135
+
136
+ # Haml support hack
137
+ ''
138
+ end
139
+
140
+
141
+ # Helper classes
142
+
143
+ class Field
144
+ attr_accessor :parent, :name, :options, :value_callback
145
+
146
+ def initialize(parent, name, options, value_callback)
147
+ @parent, @name, @options, @value_callback = parent, name, options, value_callback
148
+ end
149
+
150
+ def value_for(object)
151
+ object.instance_exec(name, options, &value_callback)
152
+ end
153
+ end
154
+
155
+ class Header
156
+ extend AdminWidgets::Delegation
157
+
158
+ attr_accessor :parent, :field
159
+
160
+ def initialize(parent, field)
161
+ @parent, @field = parent, field
162
+ end
163
+
164
+ delegate :helper, :params, :resource_class, :to => :parent
165
+ with_options :to => :params, :hash => true do |c|
166
+ c.delegate :sort_direction
167
+ c.delegate :per_page
168
+ c.delegate :page
169
+ c.delegate :where
170
+ c.delegate :scope
171
+ end
172
+
173
+ def sort_field
174
+ field.name
175
+ end
176
+
177
+ def current_sort_field?
178
+ helper.params[:sort_field] == sort_field.to_s
179
+ end
180
+
181
+ def next_sort_direction
182
+ (current_sort_field? && sort_direction == 'asc') ? 'desc' : 'asc'
183
+ end
184
+
185
+ def sort_params
186
+ {
187
+ :sort_field => sort_field,
188
+ :sort_direction => next_sort_direction,
189
+ :per_page => per_page,
190
+ :page => page,
191
+ :where => where,
192
+ :scope => scope
193
+ }
194
+ end
195
+
196
+ def label
197
+ resource_class.human_attribute_name(field.name)
198
+ end
199
+
200
+ def url
201
+ helper.collection_path(sort_params)
202
+ end
203
+
204
+ def css_class
205
+ sort_direction if current_sort_field?
206
+ end
207
+ end
208
+
209
+ end
210
+ end
@@ -0,0 +1,15 @@
1
+ module AdminWidgets
2
+ module Memoization
3
+ def memoize(attribute, val_or_callback)
4
+ ivar = "@#{attribute}"
5
+
6
+ define_method attribute do
7
+ if (current_val = instance_variable_get(ivar)).nil?
8
+ value = val_or_callback.respond_to?(:call) ? instance_eval(&val_or_callback) : val_or_callback
9
+ current_val = instance_variable_set(ivar, value)
10
+ end
11
+ current_val
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,62 @@
1
+ module AdminWidgets
2
+ class ScopesWidget < BaseWidget
3
+
4
+ def content
5
+ div :class => 'scopes' do
6
+ content_block
7
+ end
8
+ end
9
+
10
+
11
+ # DSL methods
12
+
13
+ def scope(name, options = {})
14
+ rawtext Scope.new(self, name, options).to_html
15
+
16
+ # Haml support hack
17
+ ''
18
+ end
19
+
20
+
21
+ # Options
22
+
23
+ memoize :collection, proc { helper.collection }
24
+ memoize :resource_class, proc { helper.resource_class }
25
+ memoize :current_scope, proc { helper.current_scope }
26
+ memoize :params, proc { helper.params.reject{ |k,v| k == 'search' } }
27
+ memoize :i18n_scope, proc { "mongoid.scopes.#{resource_class.to_s.underscore}" }
28
+
29
+
30
+ # Helper classes
31
+
32
+ class Scope < BaseWidget
33
+ attr_accessor :parent, :name, :options
34
+
35
+ def initialize(parent, name, options = {})
36
+ super options.merge(:parent => parent, :name => name)
37
+ end
38
+
39
+ delegate :helper, :collection, :current_scope, :i18n_scope, :to => :parent
40
+
41
+ memoize :label, proc { I18n.t(name, :scope => i18n_scope) }
42
+ memoize :full_label, proc { label }
43
+ memoize :default, false
44
+ memoize :scope, proc { default ? nil : name }
45
+ memoize :current_css_class, proc { 'current' if current? }
46
+ memoize :css_class, proc { ['scope', current_css_class] }
47
+
48
+ def current?
49
+ (current_scope.nil? && default) || (current_scope.to_s == name.to_s)
50
+ end
51
+
52
+ def params
53
+ parent.params.merge(:scope => scope)
54
+ end
55
+
56
+ def content
57
+ rawtext helper.link_to(full_label, params, :class => css_class)
58
+ end
59
+ end
60
+
61
+ end
62
+ end
@@ -0,0 +1,27 @@
1
+ module AdminWidgets::Show
2
+ class FieldsetWidget < AdminWidgets::ShowWidget
3
+
4
+ attr_reader :parent
5
+ attr_reader :name
6
+
7
+ memoize :resource, proc { parent.resource.send(name) }
8
+ memoize :legend, proc { parent.resource_class.human_attribute_name(name) }
9
+
10
+ delegate :helper, :to => :parent
11
+
12
+ def content
13
+ rawtext(around_fieldset do
14
+ super
15
+ end)
16
+ end
17
+
18
+ def around_fieldset
19
+ element('fieldset') do
20
+ element('legend', legend)
21
+
22
+ yield
23
+ end
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,35 @@
1
+ module AdminWidgets
2
+ class ShowWidget < BaseWidget
3
+
4
+ attr_reader :builder
5
+
6
+ memoize :resource, proc { helper.resource }
7
+ memoize :resource_class, proc { resource.class }
8
+
9
+ def content
10
+ rawtext show
11
+ end
12
+
13
+ def show
14
+ helper.show_for(resource) do |builder|
15
+ @builder = builder
16
+
17
+ capture do
18
+ content_block
19
+ end
20
+ end
21
+ end
22
+
23
+ def field(name, options = {})
24
+ condition = options[:if]
25
+ return if (condition.present? && !resource.instance_eval(&condition))
26
+
27
+ rawtext resource.reflect_on_association(name) ? builder.association(name, options) : builder.attribute(name, options)
28
+ end
29
+
30
+ def fieldset(name, options = {}, &block)
31
+ widget AdminWidgets::Show::FieldsetWidget.new(options.merge(:name => name, :parent => self, :block => block))
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,3 @@
1
+ module AdminWidgets
2
+ VERSION = "0.0.3"
3
+ end
@@ -0,0 +1,49 @@
1
+ module AdminWidgets
2
+ class ViewProxy < ActiveSupport::BasicObject
3
+
4
+ attr_accessor :widget
5
+
6
+ def initialize(view, widget)
7
+ @widget = widget
8
+ @view = buffered_view(view)
9
+ end
10
+
11
+ def method_missing(method_name, *args, &block)
12
+ target = case
13
+ when widget.dsl_methods.include?(method_name.to_sym) then @widget
14
+ else @view
15
+ end
16
+
17
+ target.send(method_name, *args, &block)
18
+ end
19
+
20
+ private
21
+
22
+ # Manually initialize output buffers
23
+ # This is needed for ActionView::Helpers::CaptureHelper
24
+ def buffered_view(view)
25
+ @view || begin
26
+ init_output_buffer!(view)
27
+ init_haml_buffer!(view)
28
+
29
+ view
30
+ end
31
+ end
32
+
33
+ def init_output_buffer!(view)
34
+ view.output_buffer = ::ActionView::OutputBuffer.new
35
+ end
36
+
37
+ def init_haml_buffer!(view)
38
+ return unless defined? ::Haml
39
+
40
+ class << view
41
+ include ::Haml::Helpers unless included_modules.to_a.include?(::Haml::Helpers)
42
+ end
43
+
44
+ view.init_haml_helpers
45
+ view.instance_variable_set :@haml_buffer, ::Haml::Buffer.new(nil, :preserve => [], :encoding => 'UTF-8')
46
+ end
47
+
48
+ end
49
+ end
@@ -0,0 +1,79 @@
1
+ module AdminWidgets
2
+ class WizardWidget < BaseFormWidget
3
+
4
+ memoize :url, proc { helper.resource_or_collection_path }
5
+ memoize :resource, proc { helper.resource }
6
+ memoize :resource_plural_name, proc { resource.class.name.underscore.pluralize }
7
+ memoize :display_finish_button, proc { true }
8
+
9
+ attr_reader :current_step
10
+
11
+ # DSL methods
12
+
13
+ def fieldset(name, options = {}, &block)
14
+ widget AdminWidgets::Form::FieldsetWidget.new(options.merge(:name => name, :parent => self, :block => block))
15
+ end
16
+
17
+ def steps_header
18
+
19
+ # Default button
20
+ rawtext helper.button_tag(:class => "default-step-button", :style => 'border:0;display:block;height:0;overflow:hidden;padding:0;', :name => 'change_step', :value => (@current_step.to_i + 1)) { 'Next' }
21
+
22
+ ul :class => 'steps' do
23
+ @steps.each_with_index do |step, index|
24
+ li do
25
+ active = @current_step == index + 1 ? ' active' : ''
26
+ rawtext helper.button_tag(:class => "step#{active}", :name => 'change_step', :value => index + 1) {
27
+ helper.t(step, :scope => "wizards.#{resource_plural_name}.steps", :index => index + 1)
28
+ }
29
+ end
30
+ end
31
+ end
32
+ end
33
+
34
+ def form_content
35
+ content_block
36
+ steps_header
37
+ rawtext @content_buffer
38
+ buttons
39
+ end
40
+
41
+ def buttons
42
+ div :class => ['group', 'navform', 'wat-cf'] do
43
+ rawtext helper.button_tag(:class => 'big button finish', :name => 'change_step', :value => @steps.size + 1) {
44
+ helper.image_tag('icons/tick.png') +
45
+ helper.t('resources.actions.finish')
46
+ } if display_finish_button && @current_step == @steps.count
47
+ rawtext helper.button_tag(:class => 'big button next', :name => 'change_step', :value => @current_step + 1) {
48
+ helper.image_tag('icons/next.png') +
49
+ helper.t('resources.actions.next')
50
+ } if @current_step < @steps.count
51
+ rawtext helper.button_tag(:class => 'big button previous', :name => 'change_step', :value => @current_step - 1) {
52
+ helper.image_tag('icons/previous.png') +
53
+ helper.t('resources.actions.previous')
54
+ } if @current_step > 1
55
+ end
56
+ end
57
+
58
+ def step(name, &block)
59
+ @current_step ||= 1
60
+ @content_buffer ||= ''
61
+ @steps = [] if !@steps
62
+ @steps << name
63
+ @content_buffer += capture do
64
+ div :class => 'step' do
65
+ instance_eval &block if block
66
+ end if @current_step == @steps.count
67
+ end
68
+ end
69
+
70
+ def view(&block)
71
+ @content_buffer ||= ''
72
+
73
+ @content_buffer += capture do
74
+ instance_eval &block if block
75
+ end
76
+ end
77
+
78
+ end
79
+ end
metadata ADDED
@@ -0,0 +1,80 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: admin_widgets
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - DanX~
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-10-17 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: apotomo
16
+ requirement: &2157956000 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *2157956000
25
+ description: Super Awesome Admin Widgets
26
+ email:
27
+ - danx.exe@gmail.com
28
+ executables: []
29
+ extensions: []
30
+ extra_rdoc_files: []
31
+ files:
32
+ - .gitignore
33
+ - Gemfile
34
+ - Rakefile
35
+ - admin_widgets.gemspec
36
+ - lib/admin_widgets.rb
37
+ - lib/admin_widgets/base_form_widget.rb
38
+ - lib/admin_widgets/base_widget.rb
39
+ - lib/admin_widgets/delegation.rb
40
+ - lib/admin_widgets/engine.rb
41
+ - lib/admin_widgets/extensions/action_view_ext.rb
42
+ - lib/admin_widgets/extensions/simple_form_ext.rb
43
+ - lib/admin_widgets/filters_widget.rb
44
+ - lib/admin_widgets/form/fieldset_widget.rb
45
+ - lib/admin_widgets/form_widget.rb
46
+ - lib/admin_widgets/helper.rb
47
+ - lib/admin_widgets/list_widget.rb
48
+ - lib/admin_widgets/memoization.rb
49
+ - lib/admin_widgets/scopes_widget.rb
50
+ - lib/admin_widgets/show/fieldset_widget.rb
51
+ - lib/admin_widgets/show_widget.rb
52
+ - lib/admin_widgets/version.rb
53
+ - lib/admin_widgets/view_proxy.rb
54
+ - lib/admin_widgets/wizard_widget.rb
55
+ homepage: http://www.mobvox.com.br
56
+ licenses: []
57
+ post_install_message:
58
+ rdoc_options: []
59
+ require_paths:
60
+ - lib
61
+ required_ruby_version: !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ! '>='
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ! '>='
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
73
+ requirements: []
74
+ rubyforge_project: admin_widgets
75
+ rubygems_version: 1.8.10
76
+ signing_key:
77
+ specification_version: 3
78
+ summary: Awesome Admin Widgets
79
+ test_files: []
80
+ has_rdoc: