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 FormErrors < Control
3
+
4
+ def build(b)
5
+ object = find_attribute!(:object)
6
+
7
+ if object.errors.any?
8
+ b.section html_class: 'alert alert-danger' do
9
+ b.text text: h.translate("errors.template.header", count: object.errors.count, model: object.class.model_name.human), style: 'h4'
10
+ b.section style: 'ul' do
11
+ object.errors.full_messages.each do |msg|
12
+ b.text text: msg, style: 'li'
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,19 @@
1
+ module Interview
2
+ class Glyphicon < Control
3
+
4
+ include HasHtmlOptions
5
+
6
+ attr_accessor :image
7
+
8
+ def build(b)
9
+ html_class = @html_class
10
+ if @image == 'caret'
11
+ html_class << 'caret'
12
+ else
13
+ html_class += ["glyphicon", "glyphicon-#{@image}"]
14
+ end
15
+ b.section style: 'span', html_class: html_class, html_options: @html_options
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,62 @@
1
+ module Interview
2
+ class Grid < Control
3
+
4
+ attr_accessor :objects, :sortable
5
+ attr_reader :object
6
+
7
+ def build(b)
8
+ objects = @objects || find_attribute!(:objects)
9
+ @object = find_attribute!(:object)
10
+
11
+ sortable_id = "sortable_#{@object.class.model_name.plural}" if @sortable
12
+ b.section style: 'table', html_class: 'table' do
13
+ b.section style: 'thead' do
14
+ b.section style: 'tr' do
15
+ b.section style: 'th' if @sortable
16
+ @build_captions = true
17
+ b.meta_control pointer: self do
18
+ yield if block_given?
19
+ end
20
+ end
21
+ end
22
+ html_opts = {}
23
+ html_opts[:id] = sortable_id if @sortable
24
+ b.section style: 'tbody', html_options: html_opts do
25
+ objects.each do |object|
26
+ @object = object
27
+ html_opts = {}
28
+ html_opts[:id] = "#{sortable_id}_#{object.id}" if @sortable
29
+ b.section style: 'tr', htl_options: html_opts do
30
+ if @sortable
31
+ b.section style: 'td' do
32
+ b.glyphicon style: 'resize-vertical', html_class: 'handle'
33
+ end
34
+ end
35
+ @build_captions = false
36
+ b.meta_control pointer: self do
37
+ yield if block_given?
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ if objects.empty?
44
+ b.text text: "Keine #{@object.class.human_name(count: 2)} vorhanden.", style: 'p',
45
+ html_class: 'text-center text-muted'
46
+ end
47
+ end
48
+
49
+ def build_child(b, control, &block)
50
+ if @build_captions
51
+ b.section style: 'th' do
52
+ control.build_caption(b)
53
+ end
54
+ else
55
+ b.section style: 'td' do
56
+ super
57
+ end
58
+ end
59
+ end
60
+
61
+ end
62
+ end
@@ -0,0 +1,11 @@
1
+ module Interview
2
+ class HiddenAttribute < Attribute
3
+
4
+ protected
5
+
6
+ def build_write(b)
7
+ b << form_builder.hidden_field(@method)
8
+ end
9
+
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ module Interview
2
+ class HorizontalFormContainer < Control
3
+
4
+ def build(b)
5
+ b.section html_class: 'row' do
6
+ b.section html_class: 'col-xs-9 col-xs-offset-3' do
7
+ yield if block_given?
8
+ end
9
+ end
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ module Interview
2
+ class HtmlControl < Control
3
+
4
+ def build(b)
5
+ html = ::Builder::XmlMarkup.new
6
+ if block_given?
7
+ yield html
8
+ end
9
+ b << html.target!
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,9 @@
1
+ module Interview
2
+ class HtmlDoctype < Control
3
+
4
+ def build(b)
5
+ b.text text: '<!DOCTYPE html>', html_safe: true
6
+ end
7
+
8
+ end
9
+ end
@@ -0,0 +1,12 @@
1
+ module Interview
2
+ class HtmlHeaders < Control
3
+
4
+ def build(b)
5
+ b << h.stylesheet_link_tag("application", media: "all", "data-turbolinks-track" => true)
6
+ b << h.javascript_include_tag("application", "data-turbolinks-track" => true)
7
+ b << h.csrf_meta_tags
8
+ b.section style: 'meta', html_options: { name: 'viewport', content: "width=device-width, initial-scale=1, maximum-scale=1" }
9
+ end
10
+
11
+ end
12
+ end
@@ -1,18 +1,22 @@
1
1
  module Interview
2
2
  class HtmlTextAttribute < Attribute
3
3
 
4
+ # todo: in eigenes gem auslagern?
5
+
4
6
  attr_accessor :plain_text, :cut
5
7
 
6
- def render_read
7
- return '' if value.nil?
8
+ protected
9
+
10
+ def build_read(b)
11
+ return if value.nil?
8
12
  val = value
9
13
  val.gsub! /<.+?>/, ' ' if @plain_text
10
14
  val = val[0..29] + '...' if @cut and val.size > 30
11
- return val.html_safe
15
+ b << val.html_safe
12
16
  end
13
17
 
14
- def render_write
15
- form_builder.cktext_area @method, class: 'form-control'
18
+ def build_write(b)
19
+ b << form_builder.cktext_area(@method, class: 'form-control')
16
20
  end
17
21
 
18
22
  end
@@ -0,0 +1,61 @@
1
+ module Interview
2
+ class ImageAttribute < Attribute
3
+
4
+ # - Modul UploadBuffer muss für write vorhanden sein
5
+ # - json ansicht auf bild muss vorhanden sein
6
+
7
+ # todo: in eigenes gem auslagern?
8
+
9
+ include HasHtmlOptions
10
+
11
+ attr_accessor :image_style, :hide_if_not_exists, :object
12
+
13
+ protected
14
+
15
+ def build_read(b)
16
+ image_style = @image_style || :thumb
17
+ html_class = @html_class
18
+ html_class << "image_#{image_style}"
19
+
20
+ return if value.nil? and @hide_if_not_exists
21
+
22
+ b.section html_class: html_class, html_options: @html_options do
23
+ if value
24
+ b << h.image_tag(value.url(image_style), class: 'image img-responsive')
25
+ else
26
+ b << h.image_tag('missing_thumb.png', class: 'image img-responsive')
27
+ end
28
+ end
29
+ end
30
+
31
+ def build_write(b)
32
+ image_style = @image_style || :thumb
33
+
34
+ b.section html_class: 'image_attribute_container' do
35
+ unless value.nil? and @hide_if_not_exists
36
+ b.section html_class: 'inline-block' do
37
+ b << h.image_tag(value.url(image_style), class: 'image img-responsive')
38
+ end
39
+ end
40
+
41
+ b.section html_class: 'inline-block' do
42
+ b.section html_class: "clearfix" do
43
+ b.section style: 'span', html_class: "btn btn-default fileinput-button" do
44
+ b.text text: "Bild hochladen", style: 'span' # todo
45
+ b << h.file_field_tag("upload_buffer[attachment]", class: 'upload_image',
46
+ data: {url: "/upload_buffers.json", type: 'POST'})
47
+ end
48
+ end
49
+ b.progress_bar hidden: true
50
+ b << form_builder.hidden_field(:upload_buffer_id, class: 'upload_buffer_id')
51
+
52
+ # if attachment.exists?
53
+ # b << form_builder.check_box("destroy_#{@method}")
54
+ # b.text text: ' Datei löschen'
55
+ # end
56
+ end
57
+ end
58
+ end
59
+
60
+ end
61
+ end
@@ -0,0 +1,72 @@
1
+ module Interview
2
+ class ImageGalleryAttribute < Attribute
3
+
4
+ attr_accessor :object, :submethod, :image_style, :light_box_image_style
5
+
6
+ protected
7
+
8
+ def build_read(b)
9
+ submethod = @submethod || 'attachment'
10
+ image_style = @image_style || :thumb
11
+ images = value
12
+
13
+ b.section html_class: 'image-gallery' do
14
+ images.each do |image|
15
+ b.link url: image.send(submethod).url(@light_box_image_style), html_class: 'img-link' do
16
+ b << h.image_tag(image.send(submethod).url(image_style), class: 'img-thumb')
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ def build_write(b)
23
+ object = @object || find_attribute(:object)
24
+ submethod = @submethod || 'attachment'
25
+ image_style = @image_style || :thumb
26
+ images = object.send @method
27
+ model = images.klass.model_name.singular
28
+
29
+ b.section html_class: 'image-upload-group' do
30
+
31
+ b << form_builder.hidden_field("#{@method.singularize}_ids", class: 'image-ids')
32
+
33
+ # render_gallery(html, images, submethod, image_style, @light_box_image_style)
34
+ #
35
+ # light_box_image_url = @light_box_image_style ? "#{@light_box_image_style}_url" : 'url'
36
+ # html.script id: 'image-thumb-script', type: 'text/x-tmpl' do
37
+ # html.a href: "{%=o.#{light_box_image_url}%}", class: 'img-link' do
38
+ # html.img class: 'img-thumb', src: "{%=o.thumb_url%}"
39
+ # end
40
+ # end
41
+
42
+ b.section html_class: "clearfix" do
43
+ b.section style: 'span', html_class: "btn btn-default fileinput-button" do
44
+ b.text text: "Bilder hinzufügen", style: 'span' # todo
45
+ b << h.file_field_tag("#{model}[#{submethod}]", class: 'multiple-image-upload', multiple: true,
46
+ data: {url: "/#{model.pluralize}.json", type: 'POST'})
47
+ end
48
+ end
49
+
50
+ b.section class: 'upload-progress' do
51
+ end
52
+
53
+ b.section style: 'script', html_options: { id: 'upload-progress-script', type: 'text/x-tmpl' } do
54
+ b.section do
55
+ b.section html_class: 'inline-block' do
56
+ b << h.image_tag('missing_180x180.png', class: 'img-thumb')
57
+ end
58
+ b.section html_class: 'inline-block' do
59
+ b.text text: "{%=o.name%}"
60
+ b.section html_class: 'progress' do
61
+ b.section html_class: 'progress-bar bar', html_options: { style: 'width: 0%' }
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
67
+
68
+ return html.target!
69
+ end
70
+
71
+ end
72
+ end
@@ -0,0 +1,17 @@
1
+ module Interview
2
+ class ImageLightBox < Control
3
+
4
+ def build(b)
5
+ b.section html_class: 'blueimp-gallery', html_options: { id: 'blueimp-gallery' } do
6
+ b.section html_class: "slides"
7
+ b.section html_class: "title"
8
+ b.text text: '‹', style: 'a', html_class: "prev"
9
+ b.text text: '›', style: 'a', html_class: "next"
10
+ b.text text: '×', style: 'a', html_class: "close"
11
+ b.text style: 'a', html_class: "play-pause"
12
+ b.section style: 'ol', html_class: "indicator"
13
+ end
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,90 @@
1
+ module Interview
2
+ class Link < Control
3
+
4
+ include HasHtmlOptions, NestedBuildable
5
+
6
+ attr_accessor :image, :caption, :style, :active, :hint,
7
+ :url, :object, :assoc_object, :action, :options, :http_method,
8
+ :nested_resource, :new_site
9
+ attr_reader :url_params
10
+
11
+ def initialize(params={})
12
+ @options = {}
13
+ super
14
+ end
15
+
16
+ def build(b)
17
+ html_options = @html_options.dup
18
+ html_class = @html_class.dup
19
+
20
+ url = get_url
21
+
22
+ if @action == 'destroy'
23
+ html_options[:method] = :delete
24
+ html_options[:data] = {} unless html_options[:data]
25
+ html_options[:data][:confim] = 'Are you sure?' # todo
26
+ end
27
+
28
+ if @http_method
29
+ html_options[:method] = @http_method.to_sym
30
+ end
31
+
32
+ if @hint
33
+ html_options[:title] = @hint
34
+ end
35
+
36
+ if @style == 'button'
37
+ html_class += %w(btn btn-default)
38
+ elsif @style == 'primary_button'
39
+ html_class += %w(btn btn-primary)
40
+ end
41
+
42
+ if @new_site
43
+ html_options[:target] = 'blank'
44
+ end
45
+
46
+ add_list_item(b) do
47
+ b << h.link_to(url, options_to_html(html_options, html_class)) do
48
+ create_nested_builder(b)
49
+ b.glyphicon image: @image if @image
50
+ b.space if @image and @caption
51
+ b.text text: @caption if @caption
52
+ yield if block_given?
53
+ render_nested_builder(b)
54
+ end
55
+ end
56
+ end
57
+
58
+ protected
59
+
60
+ def get_url
61
+ options = @options.dup
62
+ if @url
63
+ url = @url
64
+ url = "/#{url}" if url[0..3] != 'http' and url[0] != '/' and url[0] != '#'
65
+ else
66
+ options[:action] = @action if @action and not %w(index show create update destroy).include? @action
67
+ object = @object || find_attribute!(:object)
68
+ if @nested_resource or @assoc_object
69
+ assoc_object = @assoc_object || find_attribute!(:assoc_object)
70
+ url = h.polymorphic_path [assoc_object, object], options
71
+ else
72
+ url = h.polymorphic_path object, options
73
+ end
74
+ end
75
+ return url
76
+ end
77
+
78
+ def add_list_item(b) # todo: wird das gebraucht?
79
+ if @style == 'list'
80
+ li_class = @active ? 'active' : ''
81
+ b.section style: 'li', html_class: li_class do
82
+ yield
83
+ end
84
+ else
85
+ yield
86
+ end
87
+ end
88
+
89
+ end
90
+ end