locomotivecms 3.1.0.rc1 → 3.1.0.rc2

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 (43) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/app/api/locomotive/api/entities/site_entity.rb +4 -0
  4. data/app/api/locomotive/api/forms/site_form.rb +1 -1
  5. data/app/api/locomotive/api/middlewares/locale_middleware.rb +8 -0
  6. data/app/api/locomotive/api/resources/current_site_resource.rb +2 -1
  7. data/app/api/locomotive/api/resources/site_resource.rb +1 -0
  8. data/app/assets/javascripts/locomotive/views/editable_elements/page_view.js.coffee +1 -1
  9. data/app/assets/javascripts/locomotive/views/inputs/rte/link_view.js.coffee +1 -1
  10. data/app/assets/javascripts/locomotive/views/inputs/rte/table_view.js.coffee +1 -1
  11. data/app/assets/javascripts/locomotive/views/inputs/rte_view.js.coffee.erb +9 -12
  12. data/app/assets/javascripts/locomotive/views/shared/form_view.js.coffee +10 -14
  13. data/app/assets/javascripts/locomotive/views/shared/sidebar_view.js.coffee +5 -0
  14. data/app/assets/stylesheets/locomotive/application.scss +1 -0
  15. data/app/assets/stylesheets/locomotive/old/form/_datetime_picker.scss +36 -0
  16. data/app/controllers/locomotive/concerns/within_site_controller.rb +1 -0
  17. data/app/helpers/locomotive/base_helper.rb +10 -8
  18. data/app/helpers/locomotive/current_site_metafields_helper.rb +12 -14
  19. data/app/helpers/locomotive/dashboard_helper.rb +2 -0
  20. data/app/helpers/locomotive/shared/site_metafields_helper.rb +35 -0
  21. data/app/models/locomotive/concerns/site/metafields.rb +15 -6
  22. data/app/services/locomotive/content_entry_service.rb +2 -1
  23. data/app/services/locomotive/site_metafields_service.rb +5 -1
  24. data/app/views/locomotive/current_site_metafields/form/_panes.html.slim +2 -2
  25. data/app/views/locomotive/current_site_metafields/form/_tabs.html.slim +2 -2
  26. data/app/views/locomotive/current_site_metafields/index.html.slim +2 -2
  27. data/app/views/locomotive/developers_documentation/_panes.html.slim +4 -0
  28. data/app/views/locomotive/developers_documentation/_tabs.html.slim +2 -0
  29. data/app/views/locomotive/developers_documentation/show.html.slim +2 -6
  30. data/app/views/locomotive/editable_elements/_form.html.slim +1 -1
  31. data/app/views/locomotive/shared/_account_navigation.slim +1 -13
  32. data/app/views/locomotive/shared/_navigation.html.slim +5 -17
  33. data/app/views/locomotive/shared/_sidebar.html.slim +4 -4
  34. data/app/views/locomotive/shared/account/_navigation.html.slim +13 -0
  35. data/config/locales/en.yml +2 -0
  36. data/lib/locomotive/steam/services/api_entry_submission_service.rb +2 -2
  37. data/lib/locomotive/steam_adaptor.rb +1 -1
  38. data/lib/locomotive/version.rb +1 -1
  39. data/spec/lib/locomotive/steam/services/api_entry_submission_service_spec.rb +2 -1
  40. data/spec/models/locomotive/concerns/site/metafields_spec.rb +19 -1
  41. data/spec/requests/locomotive/steam/cache_spec.rb +1 -1
  42. data/vendor/assets/components/locomotive/moment/moment.js +69 -3601
  43. metadata +9 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b4a3cb165ff1bbe1e5b8fea705053581be456012
4
- data.tar.gz: 54fc46777e3a679f2c09244def6b2bfe117d5b2b
3
+ metadata.gz: 68959375952f5af98ae54eaa4803399910c58c4a
4
+ data.tar.gz: a3d522c11a07ba0378869fe223216d49454a7e29
5
5
  SHA512:
6
- metadata.gz: d93e4fe52c4a93bbbe3d5f72035212160b2648edd7980c8b5ee7b686ea234a8d8241c3a68ae1581be69a3dfa712899a95027db65536a57c2afcf54d4aede24ec
7
- data.tar.gz: 89cd938a73f2d8c4fc492d5a8458a7be10756ef5b96a83086b25650914b9a640cceca5262ba24f1a126dad12574047dd1b22d7fba80581dd1b2c45d114031097
6
+ metadata.gz: 7dc2fd75507c0bbd07a43de5f48f447714b46386fa5a1a7df23f018f3c636b481507e4166ba0ee539cc6c6bf4e698549af5cbc0274db72f56f01623ca91cd5dd
7
+ data.tar.gz: 0ae3cb47025dd58f397cddfe2ac438d703e6c95e66bfb04985e1403bb0680c39517471eb3bfa6fe7e513a0d6a51affe4de76d2c48eda3d47f4d6afd54fb849a6
data/Gemfile CHANGED
@@ -25,7 +25,7 @@ group :development do
25
25
  # gem 'locomotivecms_common', github: 'locomotivecms/common', ref: '257047b', require: false
26
26
 
27
27
  # gem 'locomotivecms_steam', path: '../gems/steam', require: false
28
- # gem 'locomotivecms_steam', github: 'locomotivecms/steam', ref: '62c274f', require: false
28
+ # gem 'locomotivecms_steam', github: 'locomotivecms/steam', ref: 'c44f003', require: false
29
29
 
30
30
  # gem 'locomotive_liquid', path: '../gems/liquid' # for Developers
31
31
  # gem 'locomotivecms_solid', path: '../gems/solid' # for Developers
@@ -47,6 +47,10 @@ module Locomotive
47
47
  site.metafields_schema.to_json
48
48
  end
49
49
 
50
+ expose :metafields_ui do |site, opts|
51
+ site.metafields_ui.to_json
52
+ end
53
+
50
54
  end
51
55
 
52
56
  end
@@ -4,7 +4,7 @@ module Locomotive
4
4
 
5
5
  class SiteForm < BaseForm
6
6
 
7
- attrs :name, :handle, :robots_txt, :locales, :domains, :timezone, :picture, :cache_enabled, :private_access, :password, :metafields_schema, :metafields
7
+ attrs :name, :handle, :robots_txt, :locales, :domains, :timezone, :picture, :cache_enabled, :private_access, :password, :metafields_schema, :metafields, :metafields_ui
8
8
  attrs :seo_title, :meta_keywords, :meta_description, localized: true
9
9
 
10
10
  # Make sure locales and domains are in arrays.
@@ -17,6 +17,7 @@ module Locomotive
17
17
  #
18
18
  def call(env)
19
19
  locale = find_locale(env)
20
+ setup_i18n_fallback(env['locomotive.site'])
20
21
  ::Mongoid::Fields::I18n.with_locale(locale) do
21
22
  @app.call(env)
22
23
  end
@@ -32,6 +33,13 @@ module Locomotive
32
33
  Locomotive.config.site_locales.first
33
34
  end
34
35
 
36
+ def setup_i18n_fallback(site)
37
+ ::Mongoid::Fields::I18n.clear_fallbacks
38
+ (site.try(:locales) || []).each do |locale|
39
+ ::Mongoid::Fields::I18n.fallbacks_for(locale, site.locale_fallbacks(locale))
40
+ end
41
+ end
42
+
35
43
  def params(env)
36
44
  @params ||= Rack::Request.new(env).params
37
45
  end
@@ -43,12 +43,13 @@ module Locomotive
43
43
  optional :picture
44
44
  optional :metafields_schema
45
45
  optional :metafields
46
+ optional :metafields_ui
46
47
  end
47
48
  end
48
49
  put do
49
50
  authorize current_site, :update?
50
51
 
51
- current_site_form = Forms::SiteForm.new(permitted_params_from_policy(current_site, :site, [:picture], [:metafields_schema, :metafields]))
52
+ current_site_form = Forms::SiteForm.new(permitted_params_from_policy(current_site, :site, [:picture], [:metafields_ui, :metafields_schema, :metafields]))
52
53
  service.update!(current_site, current_site_form.serializable_hash)
53
54
 
54
55
  present current_site, with: entity_klass
@@ -70,6 +70,7 @@ module Locomotive
70
70
  optional :password
71
71
  optional :metafields_schema
72
72
  optional :metafields
73
+ optional :metafields_ui
73
74
  end
74
75
  end
75
76
  post do
@@ -33,7 +33,7 @@ class Locomotive.Views.EditableElements.PageView extends Backbone.View
33
33
 
34
34
  _scroll_to: (element) ->
35
35
  return false if element.size() == 0
36
- $(@el).animate({ scrollTop: element.offset().top }, 500)
36
+ @$('body').animate({ scrollTop: element.offset().top }, 500)
37
37
 
38
38
  each_elements: (view, callback) ->
39
39
  $form_view = $(view.el).parent()
@@ -25,7 +25,7 @@ class Locomotive.Views.Inputs.Rte.LinkView extends Backbone.View
25
25
  create_popover: ->
26
26
  @$content.show()
27
27
  @$link.popover
28
- container: '.editable-elements'
28
+ container: @$link.parents('fieldset')
29
29
  placement: 'right'
30
30
  content: @$content
31
31
  html: true
@@ -23,7 +23,7 @@ class Locomotive.Views.Inputs.Rte.TableView extends Backbone.View
23
23
  create_popover: ->
24
24
  @$content.show()
25
25
  @$link.popover
26
- container: '.editable-elements'
26
+ container: @$link.parents('fieldset')
27
27
  placement: 'right'
28
28
  content: @$content
29
29
  html: true
@@ -33,17 +33,15 @@ class Locomotive.Views.Inputs.RteView extends Backbone.View
33
33
  @editor.on 'load', @register_editor_events
34
34
 
35
35
  render_views: ->
36
- that = @
37
- setTimeout(
38
- ->
39
- that.views = [
40
- that.build_and_render_view(Locomotive.Views.Inputs.Rte.LinkView),
41
- that.build_and_render_view(Locomotive.Views.Inputs.Rte.FileView),
42
- that.build_and_render_view(Locomotive.Views.Inputs.Rte.ImageView),
43
- that.build_and_render_view(Locomotive.Views.Inputs.Rte.TableView),
44
- that.build_and_render_view(Locomotive.Views.Inputs.Rte.EditTableView)
45
- ]
46
- , 200)
36
+ @editor.on 'load', =>
37
+ @views = [
38
+ @build_and_render_view(Locomotive.Views.Inputs.Rte.LinkView),
39
+ @build_and_render_view(Locomotive.Views.Inputs.Rte.FileView),
40
+ @build_and_render_view(Locomotive.Views.Inputs.Rte.ImageView),
41
+ @build_and_render_view(Locomotive.Views.Inputs.Rte.TableView),
42
+ @build_and_render_view(Locomotive.Views.Inputs.Rte.EditTableView)
43
+ ]
44
+ console.log '[RTE] all views created and rendered'
47
45
 
48
46
  expand: (event) ->
49
47
  event.stopPropagation() & event.preventDefault()
@@ -91,7 +89,6 @@ class Locomotive.Views.Inputs.RteView extends Backbone.View
91
89
  @editor.on 'aftercommand:composer', @on_content_change
92
90
 
93
91
  on_content_change: ->
94
- console.log 'modified'
95
92
  PubSub.publish 'inputs.text_changed',
96
93
  view: @
97
94
  content: @editor.getValue()
@@ -25,7 +25,6 @@ class Locomotive.Views.Shared.FormView extends Backbone.View
25
25
  @enable_file_inputs()
26
26
  @enable_array_inputs()
27
27
  @enable_toggle_inputs()
28
- @enable_date_inputs()
29
28
  @enable_datetime_inputs()
30
29
  @enable_text_inputs()
31
30
  @enable_rte_inputs()
@@ -116,21 +115,18 @@ class Locomotive.Views.Shared.FormView extends Backbone.View
116
115
  onSwitchChange: (event, state) ->
117
116
  $toggle.data('bootstrap-switch').labelText((if state then $toggle.data('off-text') else $toggle.data('on-text')))
118
117
 
119
- enable_date_inputs: ->
120
- @$('.input.date input[type=text]').each ->
121
- $(@).datetimepicker
122
- locale: window.content_locale
123
- widgetParent: $(this).parents('.form-wrapper')
124
- format: $(@).data('format')
125
-
126
118
  enable_datetime_inputs: ->
127
- @$('.input.date-time input[type=text]').each ->
128
- $(@).datetimepicker
129
- locale: window.content_locale
119
+ @$('.input.date input[type=text], .input.date-time input[type=text]').each ->
120
+ format = $(@).data('format')
121
+ datetime = moment($(@).attr('value'), format)
122
+ datetime = null unless datetime.isValid()
123
+
124
+ # https://github.com/Eonasdan/bootstrap-datetimepicker/issues/1290
125
+ $(@).removeAttr('value').datetimepicker
126
+ locale: window.locale
130
127
  widgetParent: $(this).parents('.form-wrapper')
131
- use24hours: true
132
- useseconds: false
133
- format: $(@).data('format')
128
+ format: format
129
+ defaultDate: datetime
134
130
 
135
131
  enable_text_inputs: ->
136
132
  self = @
@@ -17,6 +17,11 @@ class Locomotive.Views.Shared.SidebarView extends Backbone.View
17
17
  @pages_view.render()
18
18
  @collapse_in_sections()
19
19
  @close_sidebar_on_mobile()
20
+ @highlight_active_section()
21
+
22
+ highlight_active_section: ->
23
+ if section = $(@el).data('current-section')
24
+ @$(".sidebar-link.#{section}").addClass('is-active')
20
25
 
21
26
  toggle_sidebar: (event) ->
22
27
  if @is_sidebar_open() then @close_sidebar() else @show_sidebar()
@@ -103,6 +103,7 @@
103
103
  @import "old/form/document_picker";
104
104
  @import "old/form/link";
105
105
  @import "old/form/tags";
106
+ @import "old/form/datetime_picker";
106
107
  @import "new/files";
107
108
 
108
109
  @import "old/search_bars";
@@ -0,0 +1,36 @@
1
+ .simple_form {
2
+ fieldset .input.date, fieldset .input.date-time {
3
+
4
+ .bootstrap-datetimepicker-widget {
5
+
6
+ span.glyphicon {
7
+ font-family: FontAwesome;
8
+ }
9
+
10
+ span.glyphicon.glyphicon-chevron-up:before {
11
+ content: "\f077";
12
+ }
13
+
14
+ span.glyphicon.glyphicon-chevron-down:before {
15
+ content: "\f078";
16
+ }
17
+
18
+ span.glyphicon.glyphicon-chevron-left:before {
19
+ content: "\f053";
20
+ }
21
+
22
+ span.glyphicon.glyphicon-chevron-right:before {
23
+ content: "\f054";
24
+ }
25
+
26
+ span.glyphicon.glyphicon-calendar:before {
27
+ content: "\f073";
28
+ }
29
+
30
+ span.glyphicon.glyphicon-time:before {
31
+ content: "\f017";
32
+ }
33
+ }
34
+
35
+ }
36
+ }
@@ -26,6 +26,7 @@ module Locomotive
26
26
  helper Locomotive::Shared::SitesHelper,
27
27
  Locomotive::Shared::AccountsHelper,
28
28
  Locomotive::Shared::PagesHelper,
29
+ Locomotive::Shared::SiteMetafieldsHelper,
29
30
  Locomotive::ContentTypesHelper
30
31
 
31
32
  end
@@ -34,15 +34,17 @@ module Locomotive
34
34
 
35
35
  #= Sidebar
36
36
 
37
- def sidebar_link_class(section)
38
- highlighted = case section
39
- when :pages then ['pages', 'editable_elements'].include?(self.controller.controller_name)
40
- when :content_types then ['content_types', 'content_entries', 'public_submission_accounts', 'select_options'].include?(self.controller.controller_name)
37
+ def sidebar_current_section_class
38
+ case self.controller.controller_name
39
+ when 'pages', 'editable_elements' then :pages
40
+ when 'content_types', 'content_entries', 'public_submission_accounts', 'select_options' then :content_types
41
41
  else
42
- self.controller.controller_name == section.to_s
42
+ self.controller.controller_name
43
43
  end
44
+ end
44
45
 
45
- ['sidebar-link', highlighted ? 'is-active' : ''].join(' ')
46
+ def sidebar_link_class(section)
47
+ ['sidebar-link', section].join(' ')
46
48
  end
47
49
 
48
50
  #= Form helpers
@@ -196,8 +198,8 @@ module Locomotive
196
198
  .gsub('%d', 'DD')
197
199
  .gsub('%m', 'MM')
198
200
  .gsub('%Y', 'YYYY')
199
- .gsub('%H', 'H')
200
- .gsub('%M', 'm')
201
+ .gsub('%H', 'HH')
202
+ .gsub('%M', 'mm')
201
203
  end
202
204
 
203
205
  # Other helpers
@@ -4,7 +4,7 @@ module Locomotive
4
4
  def current_site_metafields_schema
5
5
  @site_metafields_schema ||= @site.metafields_schema.map do |g|
6
6
  SchemaGroup.new(@site, g)
7
- end.sort_by(&:position)
7
+ end.sort_by(&:_position)
8
8
  end
9
9
 
10
10
  class SchemaGroup
@@ -13,43 +13,41 @@ module Locomotive
13
13
  @site, @attributes = site, attributes
14
14
  end
15
15
 
16
- def name
16
+ def _name
17
17
  @attributes['name'].downcase.underscore.gsub(' ', '_')
18
18
  end
19
19
 
20
- alias :dom_id :name
20
+ alias :dom_id :_name
21
21
 
22
22
  def model_name
23
- ActiveModel::Name.new(self, nil, name)
23
+ ActiveModel::Name.new(self, nil, _name)
24
24
  end
25
25
 
26
- def label
27
- t(@attributes['label'] || @attributes['name'].humanize)
26
+ def _label
27
+ _t(@attributes['label'] || @attributes['name'].humanize)
28
28
  end
29
29
 
30
-
31
- def position
30
+ def _position
32
31
  @attributes['position']
33
32
  end
34
33
 
35
- def fields
34
+ def _fields
36
35
  @fields ||= @attributes['fields'].map do |f|
37
- SchemaField.new(@site, name, f)
36
+ SchemaField.new(@site, _name, f)
38
37
  end.sort_by(&:position)
39
38
  end
40
39
 
41
40
  def method_missing(name, *args, &block)
42
- if field = fields.find { |f| f.name == name.to_s }
41
+ if field = _fields.find { |f| f.name == name.to_s }
43
42
  field.value
44
43
  else
45
44
  super
46
45
  end
47
46
  end
48
47
 
49
-
50
48
  protected
51
49
 
52
- def t(value)
50
+ def _t(value)
53
51
  value.is_a?(Hash) ? value[I18n.locale.to_s] || value['default'] : value
54
52
  end
55
53
 
@@ -108,7 +106,7 @@ module Locomotive
108
106
  def default_input_options
109
107
  {
110
108
  label: self.label,
111
- hint: self.hint,
109
+ hint: self.hint.try(:html_safe),
112
110
  as: self.type,
113
111
  required: false
114
112
  }
@@ -21,6 +21,7 @@ module Locomotive
21
21
  when 'content_entry' then activity.action == 'created_public' ? 'fa-comment' : 'fa-archive'
22
22
  when 'content_asset' then 'fa-file-picture-o'
23
23
  when 'membership' then 'fa-user'
24
+ when 'site_metafields' then current_site_metafields_ui[:icon]
24
25
  end
25
26
  end
26
27
 
@@ -34,6 +35,7 @@ module Locomotive
34
35
  when 'content_asset.created_bulk' then { count: activity_emphasize(params[:assets].size) }
35
36
  when 'content_asset.destroyed' then { name: activity_emphasize(params[:name]) }
36
37
  when 'membership.created' then { name: activity_emphasize(params[:name]) }
38
+ when 'site_metafields.updated' then { label: current_site_metafields_ui[:label].downcase }
37
39
  end
38
40
 
39
41
  activity_key_to_sentence(activity.key, options)
@@ -0,0 +1,35 @@
1
+ module Locomotive
2
+ module Shared
3
+ module SiteMetafieldsHelper
4
+
5
+ def current_site_metafields_ui
6
+ return @site_metafields_ui if @site_metafields_ui
7
+
8
+ _ui = current_site.metafields_ui
9
+
10
+ @site_metafields_ui = {}.tap do |ui|
11
+ # label displayed in the sidebar section
12
+ ui[:label] = current_site_metafields_ui_t(_ui['label'], t('locomotive.shared.sidebar.metafields'))
13
+
14
+ # top title displayed in the metafields view
15
+ ui[:title] = current_site_metafields_ui_t(_ui['label'], t('locomotive.current_site_metafields.index.title'))
16
+
17
+ # hint for the editing properties page
18
+ ui[:hint] = current_site_metafields_ui_t(_ui['hint'], t('locomotive.current_site_metafields.index.help', default: ''))
19
+
20
+ # icon in the sidebar
21
+ ui[:icon] = "fa-#{_ui['icon'].present? ? _ui['icon'] : 'newspaper-o'}"
22
+ end
23
+ end
24
+
25
+ def current_site_metafields_ui_t(value, default = nil)
26
+ (if value.is_a?(Hash)
27
+ value[I18n.locale.to_s] || value['default']
28
+ else
29
+ value
30
+ end || default).html_safe
31
+ end
32
+
33
+ end
34
+ end
35
+ end
@@ -8,8 +8,9 @@ module Locomotive
8
8
  included do
9
9
 
10
10
  ## fields ##
11
- field :metafields, type: Hash, default: {}
12
- field :metafields_schema, type: Array, default: []
11
+ field :metafields, type: Hash, default: {}
12
+ field :metafields_schema, type: Array, default: []
13
+ field :metafields_ui, type: Hash, default: {}
13
14
 
14
15
  ## validations ##
15
16
  validate :validate_metafields_schema
@@ -38,11 +39,15 @@ module Locomotive
38
39
  end
39
40
 
40
41
  def metafields_schema=(schema)
41
- super(schema.is_a?(String) ? ActiveSupport::JSON.decode(schema) : schema)
42
+ super(decode_json(schema))
42
43
  end
43
44
 
44
45
  def metafields=(values)
45
- super(values.is_a?(String) ? ActiveSupport::JSON.decode(values) : values)
46
+ super(decode_json(values))
47
+ end
48
+
49
+ def metafields_ui=(ui)
50
+ super(decode_json(ui))
46
51
  end
47
52
 
48
53
  protected
@@ -64,13 +69,13 @@ module Locomotive
64
69
  'field' => {
65
70
  'type' => 'object',
66
71
  'properties' => {
67
- 'name' => { 'type' => 'string' },
72
+ 'name' => { 'type' => 'string', 'not': { 'enum': ['dom_id', 'model_name', 'method_missing', '_name', '_label', '_position', '_fields', '_t'] } },
68
73
  'label' => { 'type' => ['string', 'object'] },
69
74
  'hint' => { 'type' => ['string', 'object'] },
70
75
  'type' => { 'enum': ['string', 'text', 'integer', 'float', 'file', 'image', 'boolean', 'select', 'color'] },
71
76
  'position' => { 'type' => 'integer' },
72
77
  'select_options' => { 'type' => ['object', 'array'] },
73
- 'localized' => { 'type' => 'boolean' }
78
+ 'localized' => { 'type' => 'boolean' },
74
79
  },
75
80
  'required' => ['name']
76
81
  }
@@ -89,6 +94,10 @@ module Locomotive
89
94
  }
90
95
  end
91
96
 
97
+ def decode_json(input)
98
+ input.is_a?(String) ? ActiveSupport::JSON.decode(input) : input
99
+ end
100
+
92
101
  end
93
102
 
94
103
  end