admin_widgets 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: