interview 0.1.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. checksums.yaml +4 -4
  2. data/interview.gemspec +1 -0
  3. data/lib/{generators/interview/install/templates → assets/javascripts}/interview.js.coffee +17 -25
  4. data/lib/{generators/interview/install/templates/bootstrap_interview.css.scss → assets/stylesheets/interview.css.scss} +3 -2
  5. data/lib/generators/interview/install/install_generator.rb +0 -2
  6. data/lib/generators/interview/install/templates/interview.rb +1 -1
  7. data/lib/interview.rb +65 -51
  8. data/lib/interview/association_methods.rb +2 -0
  9. data/lib/interview/builder.rb +32 -24
  10. data/lib/interview/control.rb +25 -7
  11. data/lib/interview/controls/actionbar.rb +41 -0
  12. data/lib/interview/controls/alert.rb +15 -0
  13. data/lib/interview/{association_attribute.rb → controls/association_attribute.rb} +8 -8
  14. data/lib/interview/{association_list_attribute.rb → controls/association_list_attribute.rb} +10 -9
  15. data/lib/interview/controls/attribute.rb +80 -0
  16. data/lib/interview/controls/auto_attribute.rb +16 -0
  17. data/lib/interview/controls/boolean_attribute.rb +20 -0
  18. data/lib/interview/controls/breadcrumbs.rb +15 -0
  19. data/lib/interview/controls/button.rb +25 -0
  20. data/lib/interview/controls/caret.rb +9 -0
  21. data/lib/interview/controls/collapse_container.rb +16 -0
  22. data/lib/interview/controls/container.rb +5 -0
  23. data/lib/interview/controls/container_attribute.rb +28 -0
  24. data/lib/interview/controls/date_attribute.rb +23 -0
  25. data/lib/interview/controls/datetime_attribute.rb +22 -0
  26. data/lib/interview/controls/decimal_attribute.rb +12 -0
  27. data/lib/interview/controls/dropdown.rb +35 -0
  28. data/lib/interview/controls/form.rb +35 -0
  29. data/lib/interview/controls/form_errors.rb +20 -0
  30. data/lib/interview/controls/glyphicon.rb +19 -0
  31. data/lib/interview/controls/grid.rb +62 -0
  32. data/lib/interview/controls/hidden_attribute.rb +11 -0
  33. data/lib/interview/controls/horizontal_form_container.rb +13 -0
  34. data/lib/interview/controls/html_control.rb +13 -0
  35. data/lib/interview/controls/html_doctype.rb +9 -0
  36. data/lib/interview/controls/html_headers.rb +12 -0
  37. data/lib/interview/{html_text_attribute.rb → controls/html_text_attribute.rb} +9 -5
  38. data/lib/interview/controls/image_attribute.rb +61 -0
  39. data/lib/interview/controls/image_gallery_attribute.rb +72 -0
  40. data/lib/interview/controls/image_light_box.rb +17 -0
  41. data/lib/interview/{integer_attribute.rb → controls/integer_attribute.rb} +0 -0
  42. data/lib/interview/controls/link.rb +90 -0
  43. data/lib/interview/controls/list.rb +20 -0
  44. data/lib/interview/controls/media_object.rb +37 -0
  45. data/lib/interview/controls/navigation.rb +11 -0
  46. data/lib/interview/controls/navigation_item.rb +33 -0
  47. data/lib/interview/controls/nested_form.rb +45 -0
  48. data/lib/interview/controls/nested_form_add_images.rb +15 -0
  49. data/lib/interview/controls/nested_form_add_link.rb +29 -0
  50. data/lib/interview/controls/nested_form_remove_link.rb +12 -0
  51. data/lib/interview/{option_attribute.rb → controls/option_attribute.rb} +19 -19
  52. data/lib/interview/controls/pagination.rb +12 -0
  53. data/lib/interview/controls/panel.rb +13 -0
  54. data/lib/interview/{polymorphic_add_link.rb → controls/polymorphic_add_link.rb} +1 -1
  55. data/lib/interview/controls/polymorphic_nested_form.rb +17 -0
  56. data/lib/interview/{nested_form_add_link.rb → controls/polymorphic_nested_form_add_link.rb} +12 -28
  57. data/lib/interview/controls/progress_bar.rb +18 -0
  58. data/lib/interview/controls/scaffold_card.rb +27 -0
  59. data/lib/interview/controls/scaffold_form.rb +108 -0
  60. data/lib/interview/controls/search_form.rb +25 -0
  61. data/lib/interview/controls/section.rb +16 -0
  62. data/lib/interview/{space.rb → controls/space.rb} +5 -6
  63. data/lib/interview/{string_attribute.rb → controls/string_attribute.rb} +0 -0
  64. data/lib/interview/controls/submit.rb +14 -0
  65. data/lib/interview/controls/tab.rb +27 -0
  66. data/lib/interview/controls/tab_box.rb +21 -0
  67. data/lib/interview/controls/text.rb +33 -0
  68. data/lib/interview/{text_attribute.rb → controls/text_attribute.rb} +7 -5
  69. data/lib/interview/controls/tooltip.rb +21 -0
  70. data/lib/interview/{tree.rb → controls/tree.rb} +2 -3
  71. data/lib/interview/{view.rb → controls/view.rb} +4 -6
  72. data/lib/interview/engine.rb +4 -0
  73. data/lib/interview/handler.rb +15 -0
  74. data/lib/interview/has_html_options.rb +29 -0
  75. data/lib/interview/meta_control.rb +18 -0
  76. data/lib/interview/nested_buildable.rb +17 -0
  77. data/lib/interview/version.rb +1 -1
  78. metadata +84 -54
  79. data/lib/interview/actionbar.rb +0 -39
  80. data/lib/interview/attribute.rb +0 -166
  81. data/lib/interview/boolean_attribute.rb +0 -59
  82. data/lib/interview/breadcrumbs.rb +0 -21
  83. data/lib/interview/button.rb +0 -29
  84. data/lib/interview/collapse_container.rb +0 -31
  85. data/lib/interview/condition_container.rb +0 -19
  86. data/lib/interview/container.rb +0 -13
  87. data/lib/interview/container_attribute.rb +0 -30
  88. data/lib/interview/date_attribute.rb +0 -20
  89. data/lib/interview/datetime_attribute.rb +0 -20
  90. data/lib/interview/decimal_attribute.rb +0 -10
  91. data/lib/interview/dropdown.rb +0 -39
  92. data/lib/interview/form.rb +0 -64
  93. data/lib/interview/form_errors.rb +0 -22
  94. data/lib/interview/grid.rb +0 -54
  95. data/lib/interview/has_controls.rb +0 -40
  96. data/lib/interview/hidden_attribute.rb +0 -15
  97. data/lib/interview/html_control.rb +0 -21
  98. data/lib/interview/image_attribute.rb +0 -59
  99. data/lib/interview/image_gallery_attribute.rb +0 -79
  100. data/lib/interview/image_light_box.rb +0 -19
  101. data/lib/interview/link.rb +0 -134
  102. data/lib/interview/list.rb +0 -26
  103. data/lib/interview/media_object.rb +0 -27
  104. data/lib/interview/navigation.rb +0 -55
  105. data/lib/interview/navigation_item.rb +0 -41
  106. data/lib/interview/navigation_item_old.rb +0 -26
  107. data/lib/interview/nested_form.rb +0 -66
  108. data/lib/interview/nested_form_add_images.rb +0 -33
  109. data/lib/interview/nested_form_remove_link.rb +0 -28
  110. data/lib/interview/panel.rb +0 -18
  111. data/lib/interview/progress_bar.rb +0 -25
  112. data/lib/interview/search_form.rb +0 -21
  113. data/lib/interview/tab.rb +0 -21
  114. data/lib/interview/tab_box.rb +0 -30
  115. data/lib/interview/text.rb +0 -45
  116. data/lib/interview/tooltip.rb +0 -38
@@ -0,0 +1,20 @@
1
+ module Interview
2
+ class List < Control
3
+
4
+ attr_accessor :object, :objects, :empty_message
5
+
6
+ def build(b)
7
+ objects = @objects || find_attribute!(:objects)
8
+ objects.each do |object|
9
+ @object = object
10
+ yield if block_given?
11
+ end
12
+ if objects.empty? and @empty_message != :hide
13
+ object = @object || find_attribute!(:object)
14
+ empty_message = @empty_message || "Keine #{object.class.human_name(count: 2)} vorhanden." # todo
15
+ b.text text: empty_message, style: 'p', html_class: 'text-center text-muted'
16
+ end
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,37 @@
1
+ module Interview
2
+ class MediaObject < Control
3
+
4
+ def build(b)
5
+ b.section html_class: 'media' do
6
+ b.meta_control pointer: self do
7
+ @child_no = 0
8
+ yield if block_given?
9
+ end
10
+ b << '</div>' if @child_no >= 2
11
+ end
12
+ end
13
+
14
+ def build_child(b, control, &block)
15
+ @child_no += 1
16
+ if @child_no == 1
17
+ if control.respond_to? :html_class
18
+ control.html_class = 'pull-left'
19
+ super
20
+ else
21
+ b.section html_class: 'pull-left' do
22
+ super
23
+ end
24
+ end
25
+
26
+ elsif @child_no == 2
27
+ b << '<div class="media-body">'
28
+ control.html_class = 'media-heading' if control.respond_to? :html_class
29
+ super
30
+
31
+ else
32
+ super
33
+ end
34
+ end
35
+
36
+ end
37
+ end
@@ -0,0 +1,11 @@
1
+ module Interview
2
+ class Navigation < Control
3
+
4
+ def build(b)
5
+ b.section style: 'ul', html_class: 'nav nav-pills nav-stacked' do
6
+ yield if block_given?
7
+ end
8
+ end
9
+
10
+ end
11
+ end
@@ -0,0 +1,33 @@
1
+ module Interview
2
+ class NavigationItem < Link
3
+
4
+ attr_accessor :active, :level, :badge_formula
5
+
6
+ def build(b)
7
+ set_level
8
+ html_class = ["level#{@level}"]
9
+ html_class << 'active' if @active
10
+ b.section style: 'li', html_class: html_class do
11
+ super(b) do
12
+ badge = @badge_formula.call if @badge_formula
13
+ unless badge.nil? or badge == 0 or badge == ''
14
+ b.text text: badge.to_s, style: 'span', html_class: 'badge pull-right'
15
+ end
16
+ end
17
+ end
18
+ yield if block_given?
19
+ end
20
+
21
+ protected
22
+
23
+ def set_level
24
+ return if @level
25
+ if level = find_attribute(:level)
26
+ @level = level + 1
27
+ else
28
+ @level = 0
29
+ end
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,45 @@
1
+ module Interview
2
+ class NestedForm < Control
3
+
4
+ include NestedBuildable
5
+
6
+ attr_accessor :image_based # todo: move to an other control?
7
+ attr_reader :form_builder, :object
8
+
9
+ def build(b, &block)
10
+ assoc_form_builder = find_attribute! :form_builder
11
+ assoc_method = find_attribute! :assoc_method
12
+
13
+ b.section html_class: 'nested_form_container' do # todo: class überarbeiten
14
+ if @image_based
15
+ b.nested_form_add_images
16
+ end
17
+ b << assoc_form_builder.fields_for(assoc_method.to_sym) do |form_builder|
18
+ render_nested_form(b, form_builder, &block)
19
+ end
20
+ b.section style: 'script', html_class: 'nested_form_script', html_options: { type: 'text/x-tmpl' } do
21
+ new_object = assoc_form_builder.object.association(assoc_method.to_sym).build # todo: polymorphic add link
22
+ b << assoc_form_builder.fields_for(assoc_method.to_sym, new_object, :child_index => "${index}") do |form_builder|
23
+ render_nested_form(b, form_builder, &block)
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ def render_nested_form(b, form_builder)
30
+ create_nested_builder(b)
31
+ @form_builder = form_builder
32
+ @object = form_builder.object
33
+ b.section html_class: 'nested_form collapse in' do
34
+ yield if block_given?
35
+ b << form_builder.hidden_field(:id)
36
+ b << form_builder.hidden_field(:_destroy, class: 'nested_form_destroy')
37
+ if @image_based
38
+ b << form_builder.hidden_field(:upload_buffer_id, class: 'upload_buffer_id')
39
+ end
40
+ end
41
+ return render_nested_builder(b)
42
+ end
43
+
44
+ end
45
+ end
@@ -0,0 +1,15 @@
1
+ module Interview
2
+ class NestedFormAddImages < Control
3
+
4
+ def build(b)
5
+ b.section html_class: "clearfix" do
6
+ b.section style: 'span', html_class: "btn btn-default fileinput-button" do
7
+ b.text text: "Bilder hinzufügen", style: 'span' # todo
8
+ b << h.file_field_tag("upload_buffer[attachment]", class: 'nested_form_add_images',
9
+ multiple: true, data: {url: "/upload_buffers.json", type: 'POST'})
10
+ end
11
+ end
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,29 @@
1
+ module Interview
2
+ class NestedFormAddLink < Control
3
+
4
+ def build(b)
5
+ form_builder = find_attribute! :form_builder
6
+ assoc_method = find_attribute!(:assoc_method).to_sym
7
+ text = h.t('views.nested_form_add', association: find_attribute!(:singular_title))
8
+ html = render_form(b, form_builder, assoc_method)
9
+ b.link capion: text, html_options: { href: '#', class: 'nested_form_add_link', data: { content: CGI::escapeHTML(html) } }
10
+ end
11
+
12
+ protected
13
+
14
+ def render_form(b, form_builder, assoc_method, new_object=nil)
15
+ new_object ||= form_builder.object.association(assoc_method.to_sym).build
16
+ new_object.assign_attributes(new_object.class.defaults)
17
+ if new_object_assoc = new_object.class.reflect_on_all_associations.find { |a|
18
+ a.foreign_key == form_builder.object.association(assoc_method.to_sym).reflection.foreign_key }
19
+ new_object.association(new_object_assoc.name).target ||= form_builder.object
20
+ end
21
+
22
+ nested_form = find_attribute! :nested_form
23
+ return form_builder.fields_for(assoc_method, new_object, :child_index => "new_association") do |builder|
24
+ nested_form.render_nested_form(b, builder)
25
+ end
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,12 @@
1
+ module Interview
2
+ class NestedFormRemoveLink < Control
3
+
4
+ def build(b)
5
+ assoc_object = find_attribute! :assoc_object
6
+ assoc_method = find_attribute!(:assoc_method).to_s
7
+ text = h.t('views.nested_form_remove', association: assoc_object.class.human_attribute_name(assoc_method.singularize)) # todo: in view auslagern
8
+ b.link caption: text, url: '#', class: 'nested_form_remove_link'
9
+ end
10
+
11
+ end
12
+ end
@@ -3,48 +3,48 @@ module Interview
3
3
 
4
4
  attr_accessor :html_class, :use_radios
5
5
 
6
- def render_read
7
- return '' if value.nil? or value == ''
8
- object = find_attribute! :object
6
+ protected
7
+
8
+ def build_read(b)
9
+ return if value.nil? or value == ''
10
+ object = @object || find_attribute!(:object)
9
11
  if object.class.superclass.name == 'ActiveRecord::Base'
10
12
  model = object.class.name.underscore
11
13
  else
12
14
  model = object.class.superclass.name.underscore
13
15
  end
14
- return h.t "activerecord.options.#{model}.#{@method}.#{value}"
16
+ b << h.t("activerecord.options.#{model}.#{@method}.#{value}")
15
17
  end
16
18
 
17
- def render_write
19
+ def build_write(b)
18
20
  if @use_radios
19
- render_radios
21
+ build_radios(b)
20
22
  else
21
- render_select
23
+ build_select(b)
22
24
  end
23
25
  end
24
26
 
25
- def render_select
26
- object = find_attribute!(:object)
27
+ def build_select(b)
28
+ object = @object || find_attribute!(:object)
27
29
  options = [[h.t('helpers.select.prompt'), nil]]
28
30
  options += get_options(object)
29
31
 
30
32
  html_class = 'form-control'
31
33
  html_class += " #{@html_class}" if @html_class
32
- form_builder.select @method, options, {}, {class: html_class}
34
+ b << form_builder.select(@method, options, {}, {class: html_class})
33
35
  end
34
36
 
35
- def render_radios
36
- object = find_attribute!(:object)
37
- html = ::Builder::XmlMarkup.new
37
+ def build_radios(b)
38
+ object = @object || find_attribute!(:object)
38
39
  get_options(object).each do |option|
39
- html.div class: 'radio' do
40
- html.label do
41
- html << form_builder.radio_button(@method, option[1])
42
- html.text! ' '
43
- html.text! option[0]
40
+ b.section html_class: 'radio' do
41
+ b.section style: 'label' do
42
+ b << form_builder.radio_button(@method, option[1])
43
+ b.space
44
+ b.text text: option[0]
44
45
  end
45
46
  end
46
47
  end
47
- return html.target!
48
48
  end
49
49
 
50
50
  def get_options(object)
@@ -0,0 +1,12 @@
1
+ module Interview
2
+ class Pagination < Control
3
+
4
+ attr_accessor :objects
5
+
6
+ def build(b)
7
+ objects = @objects || find_attribute!(:objects)
8
+ b << h.paginate(objects)
9
+ end
10
+
11
+ end
12
+ end
@@ -0,0 +1,13 @@
1
+ module Interview
2
+ class Panel < Control
3
+
4
+ def build(b)
5
+ b.section html_class: 'panel panel-default' do
6
+ b.section html_class: 'panel-body' do
7
+ yield if block_given?
8
+ end
9
+ end
10
+ end
11
+
12
+ end
13
+ end
@@ -1,5 +1,5 @@
1
1
  module Interview
2
- class PolymorphicAddLink < Control
2
+ class PolymorphicAddLink < Control # todo
3
3
 
4
4
  attr_accessor :object, :style, :nested_resource
5
5
 
@@ -0,0 +1,17 @@
1
+ module Interview
2
+ class PolymorphicNestedForm < NestedForm
3
+
4
+ def render_nested_form(b, form_builder)
5
+ create_nested_builder(b)
6
+ object = form_builder.object
7
+ if klass = "#{object.class.name}NestedForm".safe_constantize
8
+ nested_form = klass.new(parent: self)
9
+ b << nested_form.render_nested_form(b, form_builder, &block)
10
+ else
11
+ super
12
+ end
13
+ return render_nested_builder(b)
14
+ end
15
+
16
+ end
17
+ end
@@ -1,37 +1,23 @@
1
1
  module Interview
2
- class NestedFormAddLink < Control
2
+ class PolymorphicNestedFormAddLink < Control # todo
3
3
 
4
- attr_accessor :style, :polymorphic_classes
4
+ attr_accessor :polymorphic_classes # todo
5
5
 
6
- def render
7
- if @style and @style.to_sym == :horizontal_form
8
- html = ::Builder::XmlMarkup.new # todo: in eigenes Objekt auslagern?
9
- html.div class: 'row' do
10
- html.div class: 'col-xs-9 col-xs-offset-3' do
11
- html << render_link
12
- end
13
- end
14
- return html.target!
15
- else
16
- return render_link
17
- end
18
- end
19
-
20
- def render_link
6
+ def build(b)
21
7
  form_builder = find_attribute! :form_builder
22
8
  assoc_method = find_attribute!(:assoc_method).to_sym
23
9
  if @polymorphic_classes
24
- return render_polymorphic_link(form_builder, assoc_method)
10
+ build_polymorphic_link(b, form_builder, assoc_method)
25
11
  else
26
- html = render_form(form_builder, assoc_method)
27
12
  text = h.t('views.nested_form_add', association: find_attribute!(:singular_title))
28
- return h.content_tag :a, text, { href: '#', class: 'nested_form_add_link', data: { content: CGI::escapeHTML(html) } }, false
13
+ html = render_form(form_builder, assoc_method)
14
+ b.link capion: text, html_options: { href: '#', class: 'nested_form_add_link', data: { content: CGI::escapeHTML(html) } }
29
15
  end
30
16
  end
31
17
 
32
18
  protected
33
19
 
34
- def render_polymorphic_link(form_builder, assoc_method)
20
+ def build_polymorphic_link(b, form_builder, assoc_method)
35
21
  poly_classes = @polymorphic_classes.map do |poly_class|
36
22
  poly_class.is_a?(String) ? poly_class.camelcase.constantize : poly_class
37
23
  end
@@ -48,14 +34,12 @@ module Interview
48
34
  data_content[poly_class.model_name.singular] = html
49
35
  end
50
36
 
51
- html = ::Builder::XmlMarkup.new
52
- html.div do
53
- html << h.select_tag("add_link_class", h.options_for_select(select_options), class: 'form-control', style: 'display: inline; width: auto;')
54
- html.text! ' '
55
- html << h.content_tag(:a, h.t('views.add'), {href: '#', class: 'nested_form_polymorphic_add_link btn btn-default',
56
- data: { content: CGI::escapeHTML(data_content.to_json) } }, false)
37
+ b.section do
38
+ b << h.select_tag("add_link_class", h.options_for_select(select_options), class: 'form-control', style: 'display: inline; width: auto;')
39
+ b.space
40
+ b << h.content_tag(:a, h.t('views.add'), {href: '#', class: 'nested_form_polymorphic_add_link btn btn-default',
41
+ data: { content: CGI::escapeHTML(data_content.to_json) } }, false)
57
42
  end
58
- return html.target!
59
43
  end
60
44
 
61
45
  def render_form(form_builder, assoc_method, new_object=nil)
@@ -0,0 +1,18 @@
1
+ module Interview
2
+ class ProgressBar < Control
3
+
4
+ include HasHtmlOptions
5
+
6
+ attr_accessor :hidden # todo: löschen?
7
+
8
+ def build(b)
9
+ html_class = @html_class
10
+ html_class << 'progress'
11
+ html_class << 'collapse' if @hidden
12
+ b.section html_class: html_class, html_options: @html_options do
13
+ b.section html_class: 'progress-bar bar', html_options: { style: 'width: 0%' }
14
+ end
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,27 @@
1
+ module Interview
2
+ class ScaffoldCard < Control
3
+
4
+ def build(b)
5
+ b.meta_control pointer: self do
6
+ yield if block_given?
7
+ end
8
+ end
9
+
10
+ def build_child(b, control, &block)
11
+ control.parent = self
12
+ b.section html_class: 'row' do
13
+ b.section style: 'p', html_class: 'col-xs-3' do
14
+ b.text text: control.caption, style: 'b' unless control.caption == :hide
15
+ if control.tooltip != :hide
16
+ b.tooltip tooltip: control.tooltip, style: :popover
17
+ end
18
+ end
19
+ b.section style: 'p', html_class: 'col-xs-9' do
20
+ control.style = 'read' unless control.style
21
+ super
22
+ end
23
+ end
24
+ end
25
+
26
+ end
27
+ end