breeze_cms 0.9.5

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.
Files changed (151) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +24 -0
  4. data/Rakefile +6 -0
  5. data/app/assets/config/breeze_manifest.js +2 -0
  6. data/app/assets/images/breeze/breeze_logo.png +0 -0
  7. data/app/assets/images/breeze/card_preview/card_feature_box.png +0 -0
  8. data/app/assets/images/breeze/card_preview/card_feature_normal.png +0 -0
  9. data/app/assets/images/breeze/card_preview/card_full_image.png +0 -0
  10. data/app/assets/images/breeze/card_preview/card_gap_square.png +0 -0
  11. data/app/assets/images/breeze/card_preview/card_large_image.png +0 -0
  12. data/app/assets/images/breeze/card_preview/card_normal_round.png +0 -0
  13. data/app/assets/images/breeze/card_preview/card_normal_square.png +0 -0
  14. data/app/assets/images/breeze/card_preview/card_wide_square.png +0 -0
  15. data/app/assets/images/breeze/card_preview/form_field.png +0 -0
  16. data/app/assets/images/breeze/home.jpg +0 -0
  17. data/app/assets/images/breeze/section_preview/blog_header.png +0 -0
  18. data/app/assets/images/breeze/section_preview/form_section.png +0 -0
  19. data/app/assets/images/breeze/section_preview/section_cards.png +0 -0
  20. data/app/assets/images/breeze/section_preview/section_feature.png +0 -0
  21. data/app/assets/images/breeze/section_preview/section_full_image.png +0 -0
  22. data/app/assets/images/breeze/section_preview/section_full_up.png +0 -0
  23. data/app/assets/images/breeze/section_preview/section_half_image.png +0 -0
  24. data/app/assets/images/breeze/section_preview/section_large_image.png +0 -0
  25. data/app/assets/images/breeze/section_preview/section_news.png +0 -0
  26. data/app/assets/images/breeze/section_preview/section_slider.png +0 -0
  27. data/app/assets/images/breeze/section_preview/section_small_image.png +0 -0
  28. data/app/assets/images/breeze/section_preview/section_spacer.png +0 -0
  29. data/app/assets/images/breeze/section_preview/section_text.png +0 -0
  30. data/app/assets/javascript/breeze_application.js.rb +101 -0
  31. data/app/assets/javascript/marked.js +6 -0
  32. data/app/assets/stylesheets/breeze/breeze.css +3633 -0
  33. data/app/assets/stylesheets/breeze/breeze.email.css +1344 -0
  34. data/app/assets/stylesheets/breeze.tailwind.css +2 -0
  35. data/app/assets/stylesheets/breeze_tailwind_styles.css +21 -0
  36. data/app/assets/stylesheets/tailwind_base.css +3 -0
  37. data/app/controllers/breeze/application_controller.rb +4 -0
  38. data/app/controllers/breeze/breeze_controller.rb +16 -0
  39. data/app/controllers/breeze/cards_controller.rb +58 -0
  40. data/app/controllers/breeze/changes_controller.rb +45 -0
  41. data/app/controllers/breeze/form_controller.rb +67 -0
  42. data/app/controllers/breeze/images_controller.rb +100 -0
  43. data/app/controllers/breeze/pages_controller.rb +66 -0
  44. data/app/controllers/breeze/sections_controller.rb +96 -0
  45. data/app/controllers/breeze/styles_controller.rb +11 -0
  46. data/app/controllers/breeze/translations_controller.rb +56 -0
  47. data/app/controllers/breeze/view_controller.rb +10 -0
  48. data/app/helpers/breeze/breeze_helper.rb +54 -0
  49. data/app/helpers/breeze/cards_helper.rb +11 -0
  50. data/app/helpers/breeze/changes_helper.rb +29 -0
  51. data/app/helpers/breeze/form_helper.rb +5 -0
  52. data/app/helpers/breeze/images_helper.rb +57 -0
  53. data/app/helpers/breeze/options_helper.rb +120 -0
  54. data/app/helpers/breeze/pages_helper.rb +5 -0
  55. data/app/helpers/breeze/sections_helper.rb +14 -0
  56. data/app/helpers/breeze/styles_helper.rb +4 -0
  57. data/app/helpers/breeze/translations_helper.rb +14 -0
  58. data/app/helpers/breeze/view_helper.rb +74 -0
  59. data/app/jobs/breeze/application_job.rb +4 -0
  60. data/app/mailers/breeze/application_mailer.rb +6 -0
  61. data/app/models/breeze/active_base.rb +34 -0
  62. data/app/models/breeze/active_yaml.rb +143 -0
  63. data/app/models/breeze/card.rb +90 -0
  64. data/app/models/breeze/card_style.rb +12 -0
  65. data/app/models/breeze/change_set.rb +58 -0
  66. data/app/models/breeze/image.rb +104 -0
  67. data/app/models/breeze/option_definition.rb +43 -0
  68. data/app/models/breeze/page.rb +97 -0
  69. data/app/models/breeze/page_style.rb +12 -0
  70. data/app/models/breeze/section.rb +137 -0
  71. data/app/models/breeze/section_style.rb +17 -0
  72. data/app/models/breeze/shared_base.rb +20 -0
  73. data/app/models/breeze/style.rb +17 -0
  74. data/app/models/breeze/translation.rb +83 -0
  75. data/app/models/breeze/view_base.rb +134 -0
  76. data/app/views/breeze/cards/index.haml +84 -0
  77. data/app/views/breeze/changes/index.haml +52 -0
  78. data/app/views/breeze/form/_editor.haml +33 -0
  79. data/app/views/breeze/form/form.haml +8 -0
  80. data/app/views/breeze/images/_editor.haml +144 -0
  81. data/app/views/breeze/images/index.haml +83 -0
  82. data/app/views/breeze/images/new.haml +12 -0
  83. data/app/views/breeze/images/show.haml +60 -0
  84. data/app/views/breeze/pages/_sections.rabl +4 -0
  85. data/app/views/breeze/pages/index.haml +49 -0
  86. data/app/views/breeze/pages/show.haml +85 -0
  87. data/app/views/breeze/sections/_option_form_date.haml +4 -0
  88. data/app/views/breeze/sections/_option_form_select.haml +4 -0
  89. data/app/views/breeze/sections/_option_form_text.haml +4 -0
  90. data/app/views/breeze/sections/_overlay.haml +33 -0
  91. data/app/views/breeze/sections/_section.rabl +5 -0
  92. data/app/views/breeze/sections/_sections_pagination.haml +29 -0
  93. data/app/views/breeze/sections/index.haml +88 -0
  94. data/app/views/breeze/sections/new.haml +12 -0
  95. data/app/views/breeze/sections/select_card_template.haml +13 -0
  96. data/app/views/breeze/sections/select_template.haml +15 -0
  97. data/app/views/breeze/sections/show.haml +91 -0
  98. data/app/views/breeze/styles/_options.haml +9 -0
  99. data/app/views/breeze/styles/index.haml +84 -0
  100. data/app/views/breeze/translations/_row.haml +29 -0
  101. data/app/views/breeze/translations/show.haml +79 -0
  102. data/app/views/breeze/view/_blog_header.haml +13 -0
  103. data/app/views/breeze/view/_form_section.haml +21 -0
  104. data/app/views/breeze/view/_section_cards.haml +17 -0
  105. data/app/views/breeze/view/_section_feature.haml +13 -0
  106. data/app/views/breeze/view/_section_full_image.haml +10 -0
  107. data/app/views/breeze/view/_section_full_up.haml +11 -0
  108. data/app/views/breeze/view/_section_half_image.haml +13 -0
  109. data/app/views/breeze/view/_section_large_image.haml +13 -0
  110. data/app/views/breeze/view/_section_news.haml +16 -0
  111. data/app/views/breeze/view/_section_slider.haml +51 -0
  112. data/app/views/breeze/view/_section_small_image.haml +11 -0
  113. data/app/views/breeze/view/_section_spacer.haml +1 -0
  114. data/app/views/breeze/view/_section_text.haml +17 -0
  115. data/app/views/breeze/view/cards/_card_feature_box.haml +13 -0
  116. data/app/views/breeze/view/cards/_card_feature_normal.haml +7 -0
  117. data/app/views/breeze/view/cards/_card_full_image.haml +10 -0
  118. data/app/views/breeze/view/cards/_card_gap_square.haml +11 -0
  119. data/app/views/breeze/view/cards/_card_large_image.haml +6 -0
  120. data/app/views/breeze/view/cards/_card_normal_round.haml +8 -0
  121. data/app/views/breeze/view/cards/_card_normal_square.haml +9 -0
  122. data/app/views/breeze/view/cards/_card_wide_square.haml +8 -0
  123. data/app/views/breeze/view/cards/_form_field.haml +8 -0
  124. data/app/views/breeze/view/elements/_button.haml +4 -0
  125. data/app/views/breeze/view/page.haml +2 -0
  126. data/app/views/layouts/breeze/_header.haml +37 -0
  127. data/app/views/layouts/breeze/_messages.haml +28 -0
  128. data/app/views/layouts/breeze/application.haml +20 -0
  129. data/app/views/layouts/mailer.html.haml +8 -0
  130. data/app/views/layouts/mailer.text.erb +1 -0
  131. data/config/breeze/card_styles.yml +129 -0
  132. data/config/breeze/option_definitions.yml +129 -0
  133. data/config/breeze/page_styles.yml +12 -0
  134. data/config/breeze/section_styles.yml +199 -0
  135. data/config/initializers/breeze.rb +13 -0
  136. data/config/initializers/rabl.rb +31 -0
  137. data/config/initializers/simple_form.rb +212 -0
  138. data/config/routes.rb +40 -0
  139. data/config/tailwind.config.js +17 -0
  140. data/config/tailwind.email.js +14 -0
  141. data/lib/breeze/engine.rb +97 -0
  142. data/lib/breeze/shared_helper.rb +44 -0
  143. data/lib/breeze/version.rb +3 -0
  144. data/lib/breeze.rb +104 -0
  145. data/lib/generators/breeze/install/install_generator.rb +19 -0
  146. data/lib/generators/breeze/install/templates/empty.yml +1 -0
  147. data/lib/generators/breeze/install/templates/initializer.rb +70 -0
  148. data/lib/generators/breeze/update/update_generator.rb +11 -0
  149. data/lib/tasks/condense.rake +60 -0
  150. data/lib/tasks/consistency.rake +84 -0
  151. metadata +371 -0
@@ -0,0 +1,57 @@
1
+ module Breeze
2
+
3
+ module ImagesHelper
4
+
5
+ def text_for_index
6
+ if(section_id)
7
+ section = Section.find(section_id)
8
+ "Select image for Section #{section.index} : #{section.header}"
9
+ elsif(card_id)
10
+ card = Card.find(card_id)
11
+ "Select image for Card #{card.index} : #{card.header}"
12
+ else
13
+ "All Images"
14
+ end
15
+ end
16
+
17
+ def text_for_new
18
+ if(section_id)
19
+ section = Section.find(section_id)
20
+ "Add image for Section: #{section.header}"
21
+ elsif(card_id)
22
+ card = Card.find(card_id)
23
+ "Select image for Card: #{card.header}"
24
+ else
25
+ "New Image"
26
+ end
27
+ end
28
+
29
+ def new_link_params
30
+ if(params[:section_id])
31
+ return {section_id: params[:section_id]}
32
+ end
33
+ if(params[:card_id])
34
+ return {card_id: params[:card_id]}
35
+ end
36
+ nil
37
+ end
38
+ def hidden_for_select_image
39
+ if(section_id)
40
+ hidden_field_tag :section_id , section_id
41
+ elsif(card_id)
42
+ hidden_field_tag :card_id , card_id
43
+ else
44
+ ""
45
+ end
46
+ end
47
+
48
+ private
49
+ def section_id
50
+ params[:section_id]
51
+ end
52
+ def card_id
53
+ params[:card_id]
54
+ end
55
+
56
+ end
57
+ end
@@ -0,0 +1,120 @@
1
+ module Breeze
2
+ module OptionsHelper
3
+
4
+ # use options with as many option names as neccessary
5
+ def options(section, *args )
6
+ all = {}
7
+ extra_class = ""
8
+ extra_class = args.pop if args.last.is_a?(String)
9
+ args.each do |option_name|
10
+ hash = send "#{option_name}_option".to_sym , section
11
+ all.merge!(hash) { |key, one, two| one.to_s + " " + two.to_s }
12
+ end
13
+ all[:class] = all[:class] + " #{extra_class}"
14
+ all
15
+ end
16
+
17
+ def date_precision(element , date_name)
18
+ precision = element.option("date_precision")
19
+ date = element.option(date_name)
20
+ if( precision == "precise")
21
+ return date.to_formatted_s(:short) + " " + date.year.to_s
22
+ end
23
+ return Date.today if date.blank?
24
+ if(date.day < 10)
25
+ attr = "Beginning"
26
+ elsif date.day < 20
27
+ attr = "Middle"
28
+ else
29
+ attr = "End"
30
+ end
31
+ "#{attr} of #{date.strftime('%B')} #{date.year}"
32
+ end
33
+
34
+ # adds prose irrespective of options
35
+ def prose_option(section)
36
+ prose_classes
37
+ end
38
+
39
+ def order_option(section , clazz = "")
40
+ if section.has_option?("order")
41
+ clazz += " order-last" if section.option('order') == "right"
42
+ end
43
+ {class: clazz}
44
+ end
45
+
46
+ def text_align_option(section , clazz = "")
47
+ if section.has_option?("text_align")
48
+ # text-center , text-left , text-right , leave comment for tailwind
49
+ clazz += " text-#{section.option('text_align')}"
50
+ end
51
+ {class: clazz}
52
+ end
53
+
54
+ def item_align_option(section , clazz = "")
55
+ if section.has_option?("item_align")
56
+ case section.option("item_align")
57
+ when "left"
58
+ clazz += " " + " justify-start"
59
+ when "right"
60
+ clazz += " " + " justify-end"
61
+ else
62
+ clazz += " " + " justify-center"
63
+ end
64
+ end
65
+ {class: clazz }
66
+ end
67
+
68
+ def background_option(section , clazz = "")
69
+ if section.has_option?("background")
70
+ option = section.option('background')
71
+ clazz += " " + (Breeze.background[section.option('background')] || "")
72
+ end
73
+ {class: clazz}
74
+ end
75
+
76
+ def margin_option(section , clazz = "")
77
+ return {class: clazz} unless section.has_option?("margin")
78
+ margin = Breeze.margin[section.option("margin")] || ""
79
+ {class: clazz + margin}
80
+ end
81
+
82
+ def text_color_option(section , clazz = "")
83
+ if section.has_option?("text_color")
84
+ clazz += " " + (Breeze.text_color[section.option("text_color")] || "")
85
+ end
86
+ {class: clazz }
87
+ end
88
+
89
+ def shade_option(section , clazz = "")
90
+ if section.has_option?("shade_color")
91
+ clazz += " " + (Breeze.shade_color[section.option("shade_color")] || "")
92
+ end
93
+ {class: clazz }
94
+ end
95
+
96
+ def text_columns_option( section , clazz = "")
97
+ if section.has_option?("text_columns")
98
+ clazz += " " + (Breeze.text_columns[section.option("text_columns")] || "")
99
+ end
100
+ {class: clazz }
101
+ end
102
+
103
+ def slider_columns_option( section , clazz = "")
104
+ if section.has_option?("slider_columns")
105
+ Breeze.slider_columns[section.option("slider_columns")]
106
+ else
107
+ Breeze.slider_columns["1"]
108
+ end
109
+ end
110
+
111
+ def column_option( section , clazz = "" )
112
+ if section.has_option?("columns")
113
+ clazz += " " + (Breeze.columns[section.option("columns")] || "")
114
+ end
115
+ {class: clazz }
116
+ end
117
+
118
+
119
+ end
120
+ end
@@ -0,0 +1,5 @@
1
+ module Breeze
2
+ module PagesHelper
3
+ include ViewHelper #for previews
4
+ end
5
+ end
@@ -0,0 +1,14 @@
1
+ module Breeze
2
+ module SectionsHelper
3
+ include ViewHelper #for previews
4
+
5
+ #image tag for the preview, passing options through
6
+ def section_preview(section , options)
7
+ image_tag("breeze/section_preview/#{section.template}" , options)
8
+ end
9
+
10
+ def card_preview(section , options)
11
+ image_tag("breeze/card_preview/#{section.card_template}" , options)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,4 @@
1
+ module Breeze
2
+ module StylesHelper
3
+ end
4
+ end
@@ -0,0 +1,14 @@
1
+ module Breeze
2
+ module TranslationsHelper
3
+ def language_bg lang
4
+ case lang
5
+ when "fi"
6
+ "border-blue-800"
7
+ when "sv"
8
+ "border-yellow-400"
9
+ else
10
+ ""
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,74 @@
1
+ module Breeze
2
+ module ViewHelper
3
+ include BreezeHelper
4
+
5
+ def current_lang
6
+ params[:lang]
7
+ end
8
+
9
+ def render_section(section)
10
+ template = "breeze/view/" + section.template
11
+ render( template , section: section)
12
+ end
13
+
14
+ # background image as inline style
15
+ def bg(section , clazz = "")
16
+ return {class: clazz} if section.image.blank?
17
+ img = asset_url( section.image.asset_name )
18
+ style = "background-image: url('#{img}');"
19
+ if(section.option("fixed") == "on")
20
+ clazz += " bg-fixed"
21
+ end
22
+ if(align = section.option("image_align"))
23
+ # for tailwind: bg-left-top bg-left bg-left-bottom
24
+ # bg-top bg-center bg-bottom bg-right-top bg-right bg-right-bottom
25
+ clazz += " bg-#{align}"
26
+ end
27
+ {class: clazz , style: style}
28
+ end
29
+
30
+ # works for with sections and cards that respond to .image
31
+ def image_for(element , classes = "")
32
+ return "" if element.image.blank?
33
+ image = element.image
34
+ image_tag(image.asset_name , alt: image.name , class: classes )
35
+ end
36
+
37
+ def button_classes
38
+ "inline-block rounded-lg px-3 py-2 text-base font-medium border border-gray-500 hover:border-black"
39
+ end
40
+
41
+ def view_button(element , extra_classes = "")
42
+ return "" unless element.has_option?("button_link")
43
+ ["<button class='#{button_classes} ",
44
+ extra_classes,
45
+ "'>" ,
46
+ "<a href='" ,
47
+ element.option("button_link") ,
48
+ "'>" ,
49
+ element.option("button_text") ,
50
+ "</a>",
51
+ " </button>"].join.html_safe
52
+ end
53
+ # just for tailwind bg-cyan-200
54
+
55
+ def self.last_blog
56
+ blog = Page.find_by_type(:blog)
57
+ return nil unless blog
58
+ blog.sections.last
59
+ end
60
+ def last_blog
61
+ PagesHelper.last_blog
62
+ end
63
+
64
+ def header_list
65
+ return "" unless blog_section = last_blog
66
+ blog = blog_section.page
67
+ headers = blog.sections.collect{|s| "- " + s.header}
68
+ headers.shift
69
+ return "" if headers.empty?
70
+ markdown headers.join("\n")
71
+ end
72
+
73
+ end
74
+ end
@@ -0,0 +1,4 @@
1
+ module Breeze
2
+ class ApplicationJob < ActiveJob::Base
3
+ end
4
+ end
@@ -0,0 +1,6 @@
1
+ module Breeze
2
+ class ApplicationMailer < ActionMailer::Base
3
+ default from: "from@example.com"
4
+ layout "mailer"
5
+ end
6
+ end
@@ -0,0 +1,34 @@
1
+ module Breeze
2
+ class ActiveBase < ActiveYaml
3
+ fields :updated_at , :updated_by
4
+
5
+ def edit_save( editor )
6
+ self.updated_at = Time.now
7
+ self.updated_by = editor
8
+ edit_save!(editor)
9
+ end
10
+
11
+ def edit_save!(editor)
12
+ ChangeSet.current.edit(self.class.name , self.change_name, editor)
13
+ self.class.save_all
14
+ end
15
+
16
+ def add_save( editor )
17
+ self.updated_at = Time.now
18
+ self.updated_by = editor
19
+ add_save!(editor)
20
+ end
21
+
22
+ def add_save!(editor)
23
+ ChangeSet.current.add(self.class.name , self.change_name, editor)
24
+ self.class.save_all
25
+ end
26
+
27
+ def delete_save!(editor)
28
+ ChangeSet.current.delete(self.class.name , self.change_name,editor)
29
+ self.class.delete(self.id)
30
+ self.class.save_all
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,143 @@
1
+ module Breeze
2
+ class ActiveYaml
3
+ attr :data #data of the instance, hash
4
+
5
+ # retain the given hash data instance
6
+ def initialize(data)
7
+ @data = data
8
+ # some checks, eg values are only fields
9
+ end
10
+
11
+ def id
12
+ data[:id]
13
+ end
14
+ def id=(new_id)
15
+ raise "Id must be number not (#{new_id})" unless new_id.is_a?(Integer)
16
+ data[:id] = new_id
17
+ end
18
+
19
+ extend ActiveModel::Naming
20
+ include ActiveModel::Conversion
21
+
22
+ def persisted?
23
+ true
24
+ end
25
+
26
+ class_attribute :path # usually rails root, where data is stored
27
+ class_attribute :yaml_file # the loaded data as array
28
+ class_attribute :field_names # methos name for accessing / allowed fields
29
+
30
+ class << self
31
+ #return all yaml data converted
32
+ def all
33
+ self.reload if self.yaml_file.blank?
34
+ yaml_file.collect{|item| self.new(item) }
35
+ end
36
+
37
+ def primary_key
38
+ "id"
39
+ end
40
+
41
+ # loads the data from path, name implicit in class_name
42
+ def set_root_path(path)
43
+ self.path = path
44
+ end
45
+
46
+ def reload
47
+ self.yaml_file = load_file
48
+ end
49
+
50
+ def first
51
+ self.new(yaml_file.first)
52
+ end
53
+
54
+ def find( id )
55
+ id = id.to_i unless id.is_a?(Integer)
56
+ find_by( :id , id )
57
+ end
58
+
59
+ def find_by( field , value )
60
+ found = yaml_file.detect { |record| record[field] == value }
61
+ return nil unless found
62
+ self.new(found)
63
+ end
64
+
65
+ def find_all( field , value )
66
+ found = yaml_file.find_all { |record| record[field] == value }
67
+ found.collect {|f| self.new(f)}
68
+ end
69
+
70
+ def define_access(field)
71
+ define_method(field) do
72
+ data[field]
73
+ end
74
+ define_method(:"#{field}=") do |new_val|
75
+ data[field] = new_val
76
+ end
77
+ assoc , id = field.to_s.split("_") # ie field image_id
78
+ define_association(assoc) if id == "id" #creates method image
79
+ end
80
+
81
+ # aka belongs_to
82
+ # define a method by given name that used id value and
83
+ # name of association to get a model instance of the id
84
+ def define_association(assoc)
85
+ clazz = "Breeze::#{assoc.to_s.capitalize}".constantize
86
+ define_method(assoc) do
87
+ id = data[:"#{assoc}_id"]
88
+ clazz.find( id )
89
+ end
90
+ end
91
+
92
+ # class defines fields, we define access methods and finder for each
93
+ def fields(*fields)
94
+ self.field_names = fields
95
+ raise "Fields must be Array not #{fields.class}" unless fields.is_a?(Array)
96
+ fields.each do |field|
97
+ define_access(field)
98
+ the_meta_class.define_method(:"find_by_#{field}") do |arg|
99
+ find_by(field , arg)
100
+ end
101
+ end
102
+ end
103
+
104
+ # load the yaml data from path and class_name
105
+ def load_file
106
+ YAML.load(File.read(full_path) , permitted_classes: [Time , Symbol],aliases: true)
107
+ end
108
+
109
+ # filename for the data (load and save)
110
+ # made up of the set dir (set_root_path) plus tableized class name
111
+ def full_path
112
+ mod , filename = self.name.split("::").collect{|p| p.underscore}
113
+ full_name = mod + "/" + filename.tableize + ".yml"
114
+ File.join(self.path , full_name )
115
+ end
116
+
117
+ #create a new data point by adding the hash
118
+ def append(data)
119
+ largest = 0
120
+ yaml_file.each { |item| largest = item[:id] if item[:id] > largest }
121
+ data[:id] = largest + 1
122
+ yaml_file << data
123
+ largest + 1
124
+ end
125
+
126
+ def save_all
127
+ File.write( full_path , yaml_file.to_yaml)
128
+ end
129
+
130
+ def delete(id)
131
+ yaml_file.delete_if{|record| record[:id] == id.to_i}
132
+ true
133
+ end
134
+
135
+ def the_meta_class
136
+ class << self
137
+ self
138
+ end
139
+ end
140
+
141
+ end
142
+ end
143
+ end
@@ -0,0 +1,90 @@
1
+ module Breeze
2
+
3
+ class Card < ViewBase
4
+
5
+ set_root_path Rails.root.join(Breeze.data_dir)
6
+
7
+ fields :id , :index , :section_id
8
+ fields :text , :header, :image_name
9
+
10
+ def change_name
11
+ pagename = section ? section.page_name : section_id.to_s
12
+ "#{pagename}:#{header}"
13
+ end
14
+
15
+ def missing_translations
16
+ sum = 0
17
+ Breeze.language_strings.each do |lang|
18
+ sum += 1 if get_translation(lang)&.is_old?
19
+ end
20
+ sum
21
+ end
22
+
23
+ def move_up
24
+ swap_index_with(previous_card)
25
+ end
26
+
27
+ def move_down
28
+ swap_index_with(next_card)
29
+ end
30
+
31
+ def previous_card
32
+ section.cards.find{|card| card.index == index - 1}
33
+ end
34
+
35
+ def next_card
36
+ section.cards.find{|card| card.index == index + 1}
37
+ end
38
+
39
+ # card templates are stored in the section so the all cards
40
+ # have the same
41
+ def template
42
+ section.card_template
43
+ end
44
+
45
+ def template_style
46
+ CardStyle.find_by_template( self.template )
47
+ end
48
+
49
+ def allowed_fields
50
+ super + [:section_id]
51
+ end
52
+
53
+ def delete_and_reset_index(editor)
54
+ delete_save!(editor)
55
+ Section.find(section_id).reset_index
56
+ Card.save_all
57
+ end
58
+
59
+ def object_type
60
+ "Card"
61
+ end
62
+
63
+ def index_name
64
+ "#{section.index}.#{self.index}"
65
+ end
66
+
67
+ def delete(editor)
68
+ delete_translations(editor)
69
+ delete_save!(editor)
70
+ end
71
+
72
+ def self.new_card(card_template , section_id , index)
73
+ data = { section_id: section_id , index: index}
74
+ template = CardStyle.find_by_template( card_template )
75
+ template.fields.each do |key|
76
+ data[key.to_sym] = "NEW"
77
+ end
78
+ new_id = Card.append(data)
79
+ card = Card.new(data)
80
+ card.add_default_options(template.options_definitions)
81
+ card
82
+ end
83
+
84
+ def self.reload
85
+ res = super()
86
+ self.fix_translations
87
+ end
88
+
89
+ end
90
+ end
@@ -0,0 +1,12 @@
1
+ module Breeze
2
+ class CardStyle < Style
3
+ set_root_path Rails.root.join(Breeze.data_dir)
4
+
5
+ fields :template , :text , :header, :fields
6
+
7
+ def card_preview
8
+ "breeze/card_preview/" + template
9
+ end
10
+
11
+ end
12
+ end
@@ -0,0 +1,58 @@
1
+ module Breeze
2
+ class ChangeSet
3
+
4
+
5
+ def self.current
6
+ @@current ||= ChangeSet.new
7
+ end
8
+ attr_reader :adds , :edits , :deletes , :last , :last_editor
9
+
10
+ def initialize
11
+ zero
12
+ end
13
+
14
+ def zero
15
+ @adds = Set.new
16
+ @edits = Set.new
17
+ @deletes = Set.new
18
+ @last = nil
19
+ @last_editor = nil
20
+ end
21
+
22
+ def touch(editor)
23
+ @last = Time.now
24
+ @last_editor = editor
25
+ end
26
+
27
+ def add( type , text , editor)
28
+ touch(editor)
29
+ @adds << [typed(type) , text ]
30
+ end
31
+
32
+ def edit( type , text, editor)
33
+ touch(editor)
34
+ @edits << [typed(type) , text ]
35
+ end
36
+ def delete( type , text, editor)
37
+ touch(editor)
38
+ @deletes << [typed(type) , text ]
39
+ end
40
+
41
+ def added( type )
42
+ type = type.to_sym
43
+ @adds.select { |a| a.first == type }
44
+ end
45
+ def edited( type )
46
+ type = type.to_sym
47
+ @edits.select { |a| a.first == type }
48
+ end
49
+ def deleted( type )
50
+ type = type.to_sym
51
+ @deletes.select { |a| a.first == type }
52
+ end
53
+
54
+ def typed(class_name)
55
+ class_name.split("::").last.to_sym
56
+ end
57
+ end
58
+ end