fae-rails 2.0.0 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +3 -1
- data/app/assets/javascripts/fae/form/_ajax.js +21 -1
- data/app/assets/javascripts/fae/form/_cancel.js +1 -0
- data/app/assets/javascripts/fae/form/_validator.js +22 -12
- data/app/assets/javascripts/fae/form/inputs/_color.js +2 -1
- data/app/assets/javascripts/fae/vendor/jqColorPicker.min.js +0 -1
- data/app/controllers/fae/application_controller.rb +15 -1
- data/app/controllers/fae/users_controller.rb +8 -0
- data/app/helpers/fae/form_helper.rb +13 -4
- data/app/helpers/fae/view_helper.rb +76 -31
- data/app/models/concerns/fae/user_concern.rb +10 -1
- data/app/models/fae/static_page.rb +7 -2
- data/app/models/fae/user.rb +2 -3
- data/app/uploaders/fae/file_uploader.rb +1 -1
- data/app/uploaders/fae/image_uploader.rb +1 -1
- data/app/views/fae/application/_file_uploader.html.slim +4 -1
- data/app/views/fae/application/_global_search_results.html.slim +1 -1
- data/app/views/fae/application/_header.slim +8 -8
- data/app/views/fae/application/_markdown_helper.slim +17 -17
- data/app/views/fae/application/_mobilenav.slim +6 -6
- data/app/views/fae/application/_user_log.html.slim +2 -2
- data/app/views/fae/images/_image_uploader.html.slim +1 -1
- data/app/views/fae/options/_form.html.slim +6 -6
- data/app/views/fae/pages/activity_log.html.slim +11 -11
- data/app/views/fae/pages/disabled_environment.html.slim +2 -2
- data/app/views/fae/pages/error404.html.slim +5 -3
- data/app/views/fae/pages/home.html.slim +9 -8
- data/app/views/fae/setup/first_user.html.slim +3 -3
- data/app/views/fae/shared/_form_header.html.slim +3 -3
- data/app/views/fae/shared/_index_header.html.slim +3 -2
- data/app/views/fae/shared/_nested_table.html.slim +1 -1
- data/app/views/fae/shared/_recent_changes.html.slim +6 -6
- data/app/views/fae/shared/_shared_nested_table.html.slim +1 -1
- data/app/views/fae/static_pages/index.html.slim +2 -2
- data/app/views/fae/users/_form.html.slim +8 -12
- data/app/views/fae/users/index.html.slim +6 -6
- data/config/locales/devise.cs.yml +59 -0
- data/config/locales/fae.cs.yml +125 -0
- data/config/locales/fae.en.yml +109 -0
- data/config/locales/fae.zh-CN.yml +109 -0
- data/lib/fae/version.rb +1 -1
- data/lib/generators/fae/base_generator.rb +46 -3
- data/lib/generators/fae/nested_index_scaffold_generator.rb +1 -0
- data/lib/generators/fae/nested_scaffold_generator.rb +1 -0
- data/lib/generators/fae/page_generator.rb +8 -0
- data/lib/generators/fae/scaffold_generator.rb +1 -0
- data/lib/generators/fae/templates/graphql/graphql_page_type.rb +17 -0
- data/lib/generators/fae/templates/graphql/graphql_type.rb +13 -0
- metadata +9 -5
@@ -42,7 +42,7 @@ module Fae
|
|
42
42
|
languages.each do |lang|
|
43
43
|
# Save with suffix for form fields
|
44
44
|
define_association("#{name}_#{lang}", type)
|
45
|
-
define_validations("#{name}_#{lang}", type, value[:validates]) if
|
45
|
+
define_validations("#{name}_#{lang}", type, value[:validates]) if supports_validation(type, value)
|
46
46
|
end
|
47
47
|
# Save with lookup to have default language return in front-end use (don't need to worry about validations here)
|
48
48
|
default_language = Rails.application.config.i18n.default_locale || languages.first
|
@@ -50,7 +50,7 @@ module Fae
|
|
50
50
|
else
|
51
51
|
# Normal content_blocks
|
52
52
|
define_association(name, type)
|
53
|
-
define_validations(name, type, value[:validates]) if
|
53
|
+
define_validations(name, type, value[:validates]) if supports_validation(type, value)
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
@@ -75,6 +75,11 @@ module Fae
|
|
75
75
|
end
|
76
76
|
end
|
77
77
|
|
78
|
+
def self.supports_validation(type, value)
|
79
|
+
# validations are only supported on Fae::TextField and Fae::TextArea
|
80
|
+
poly_sym(type) == :contentable && value.try(:[], :validates).present?
|
81
|
+
end
|
82
|
+
|
78
83
|
def self.poly_sym(assoc)
|
79
84
|
case assoc.name
|
80
85
|
when 'Fae::TextField', 'Fae::TextArea'
|
data/app/models/fae/user.rb
CHANGED
@@ -16,9 +16,8 @@ module Fae
|
|
16
16
|
presence: true,
|
17
17
|
uniqueness: { message: 'That email address is already in use. Give another one a go.' },
|
18
18
|
format: {
|
19
|
-
with:
|
20
|
-
message: 'is invalid'
|
21
|
-
multiline: true
|
19
|
+
with: Fae.validation_helpers.email_regex,
|
20
|
+
message: 'is invalid'
|
22
21
|
}
|
23
22
|
validates :password,
|
24
23
|
presence: { on: :create },
|
@@ -28,7 +28,10 @@ ruby:
|
|
28
28
|
.asset-actions.-files
|
29
29
|
a.asset-title href=the_file.asset.url target="_blank" = the_file.asset.file.filename
|
30
30
|
|
31
|
-
|
31
|
+
- if the_file.id.present?
|
32
|
+
= link_to '', fae.delete_file_path(the_file.id), class: 'asset-delete js-asset-delete', remote: true, method: :delete, data: { confirm: t('fae.delete_confirmation') }
|
33
|
+
- else
|
34
|
+
a.js-file-clear.asset-delete.js-asset-delete
|
32
35
|
|
33
36
|
.asset-inputs style="#{'display: none;' unless the_file.asset.blank?}"
|
34
37
|
= i.input :asset, as: :file, label: false, input_html: { data: { limit: Fae.max_file_upload_size, exceeded: t('fae.exceeded_upload_limit') } }
|
@@ -19,22 +19,22 @@ header.main-header#js-main-header
|
|
19
19
|
a.grabatar-link href="#"
|
20
20
|
img.grabatar src=fae_avatar alt=current_user.full_name
|
21
21
|
ul
|
22
|
-
li: a href=fae.destroy_user_session_path
|
23
|
-
li: a href=fae.settings_path
|
22
|
+
li: a href=fae.destroy_user_session_path = t('fae.navbar.logout')
|
23
|
+
li: a href=fae.settings_path = t('fae.navbar.your_settings')
|
24
24
|
|
25
25
|
li.utility-dropdown.js-utility-dropdown
|
26
26
|
a href="#"
|
27
27
|
i.icon-settings
|
28
28
|
ul
|
29
29
|
- if current_user.super_admin_or_admin?
|
30
|
-
li: a href=fae.users_path
|
31
|
-
li: a href=fae.activity_log_path
|
30
|
+
li: a href=fae.users_path = t('fae.navbar.users')
|
31
|
+
li: a href=fae.activity_log_path = t('fae.navbar.activity_log')
|
32
32
|
- if current_user.super_admin?
|
33
|
-
li: a href=fae.option_path
|
33
|
+
li: a href=fae.option_path = t('fae.navbar.root_settings')
|
34
34
|
- if @option.live_url.present?
|
35
|
-
li: a href=@option.live_url target="_blank"
|
35
|
+
li: a href=@option.live_url target="_blank" = t('fae.application.live_site')
|
36
36
|
- if @option.stage_url.present?
|
37
|
-
li: a href=@option.stage_url target="_blank"
|
37
|
+
li: a href=@option.stage_url target="_blank" = t('fae.application.stage_site')
|
38
38
|
|
39
39
|
li
|
40
40
|
a href=fae.help_path
|
@@ -45,6 +45,6 @@ header.main-header#js-main-header
|
|
45
45
|
|
46
46
|
.utility-search-hit-area#js-utility-search-wrapper
|
47
47
|
.utility-search-wrapper
|
48
|
-
input#js-global-search type="text" placeholder=
|
48
|
+
input#js-global-search type="text" placeholder=t('fae.navbar.jump_to')
|
49
49
|
|
50
50
|
== render 'global_search_results', show_nav: true
|
@@ -1,41 +1,41 @@
|
|
1
1
|
.markdown-hint
|
2
2
|
.markdown-hint-wrapper
|
3
|
-
h3
|
3
|
+
h3 = t('fae.application.markdown_opts')
|
4
4
|
|
5
|
-
h4
|
5
|
+
h4 = t('fae.application.links')
|
6
6
|
p
|
7
|
-
|
7
|
+
= t('fae.application.links_help')
|
8
8
|
br
|
9
9
|
| Internal Link: [link to about](/about)
|
10
10
|
br
|
11
11
|
| External link: [link to about](http://www.google.com/about)
|
12
12
|
|
13
|
-
h4
|
13
|
+
h4 = t('fae.application.formatting')
|
14
14
|
p
|
15
|
-
|
15
|
+
= t('fae.application.formatting_help')
|
16
16
|
br
|
17
|
-
|
17
|
+
= t('fae.application.bold')
|
18
18
|
br
|
19
|
-
|
19
|
+
= t('fae.application.italic')
|
20
20
|
|
21
|
-
h4
|
21
|
+
h4 = t('fae.application.headers')
|
22
22
|
p
|
23
|
-
|
23
|
+
= t('fae.application.headers_help')
|
24
24
|
br
|
25
|
-
|
25
|
+
= t('fae.apllication.headers_example')
|
26
26
|
br
|
27
|
-
|
27
|
+
= t('fae.application.subheaders_example')
|
28
28
|
|
29
|
-
h4
|
29
|
+
h4 = t('fae.application.list')
|
30
30
|
p
|
31
|
-
|
31
|
+
= t('fae.application.list_help')
|
32
32
|
br
|
33
|
-
span
|
33
|
+
span = t('fae.application.bulleted_list')
|
34
34
|
br
|
35
35
|
== ['* bullet', '* bullet 2'].join('<br />')
|
36
36
|
br
|
37
|
-
span
|
37
|
+
span = t('fae.application.numbered_list')
|
38
38
|
== ['1. line item', '2. line item'].join('<br />')
|
39
39
|
|
40
|
-
h4
|
41
|
-
p
|
40
|
+
h4 = t('fae.application.paragraph_break')
|
41
|
+
p = t('fae.application.paragraph_break_help')
|
@@ -55,12 +55,12 @@ nav.nav.mobilenav
|
|
55
55
|
- if @option.stage_url.present? || @option.live_url.present?
|
56
56
|
li class=view_site_class
|
57
57
|
- if site_urls_are_present
|
58
|
-
a href="#"
|
58
|
+
a href="#" = t('fae.application.view_site')
|
59
59
|
ul.subnav.js-subnav
|
60
|
-
li: span.mobilenav-subheader.js-mobile-back
|
61
|
-
li: a.-viewsite href=@option.stage_url target="_blank"
|
62
|
-
li: a.-viewsite href=@option.live_url target="_blank"
|
60
|
+
li: span.mobilenav-subheader.js-mobile-back = t('fae.application.view_site')
|
61
|
+
li: a.-viewsite href=@option.stage_url target="_blank" = t('fae.application.preview_site')
|
62
|
+
li: a.-viewsite href=@option.live_url target="_blank" = t('fae.application.live_site')
|
63
63
|
- elsif @option.stage_url.present?
|
64
|
-
a.-viewsite href=@option.stage_url target="_blank"
|
64
|
+
a.-viewsite href=@option.stage_url target="_blank" = t('fae.application.preview_site')
|
65
65
|
- elsif @option.live_url.present?
|
66
|
-
a.-viewsite href=@option.live_url target="_blank"
|
66
|
+
a.-viewsite href=@option.live_url target="_blank" = t('fae.application.live_site')
|
@@ -28,9 +28,9 @@
|
|
28
28
|
- if changed.present?
|
29
29
|
tr
|
30
30
|
td = version.created_at
|
31
|
-
td = version.user.present? ? version.user.full_name : content_tag(:em,
|
31
|
+
td = version.user.present? ? version.user.full_name : content_tag(:em, t('fae.application.user_absent'))
|
32
32
|
td = changed.join(', ')
|
33
33
|
|
34
34
|
- else
|
35
35
|
tr
|
36
|
-
td colspan="3"
|
36
|
+
td colspan="3" = t('fae.application.no_logs')
|
@@ -7,7 +7,7 @@ ruby:
|
|
7
7
|
alt_label ||= "#{label} Alt Text"
|
8
8
|
caption_label ||= "#{label} Caption"
|
9
9
|
helper_text ||= ""
|
10
|
-
alt_helper_text ||= '
|
10
|
+
alt_helper_text ||= t('fae.images.alt_helper')
|
11
11
|
caption_helper_text ||= ""
|
12
12
|
show_alt = true if show_alt.nil?
|
13
13
|
show_caption ||= false
|
@@ -2,15 +2,15 @@
|
|
2
2
|
header.content-header.js-content-header
|
3
3
|
h1 Root Settings
|
4
4
|
.content-header-buttons
|
5
|
-
a.button#js-header-cancel href=fae.root_path(cancelled: true)
|
6
|
-
= f.submit '
|
5
|
+
a.button#js-header-cancel href=fae.root_path(cancelled: true) = t('fae.form.cancel')
|
6
|
+
= f.submit t('fae.form.save')
|
7
7
|
|
8
8
|
== render 'flash_messages'
|
9
9
|
|
10
10
|
section.content
|
11
|
-
= fae_input f, :title, label: '
|
11
|
+
= fae_input f, :title, label: t('fae.options.project.name')
|
12
12
|
= fae_input f, :time_zone, wrapper_class: 'select'
|
13
|
-
= fae_input f, :live_url, label: '
|
14
|
-
= fae_input f, :stage_url, label: '
|
15
|
-
= fae_image_form f, :logo, helper_text: '
|
13
|
+
= fae_input f, :live_url, label: t('fae.options.live_url'), helper_text: t('fae.options.url_helper')
|
14
|
+
= fae_input f, :stage_url, label: t('fae.options.stage_url'), helper_text: t('fae.options.url_helper')
|
15
|
+
= fae_image_form f, :logo, helper_text: t('fae.options.logo_helper')
|
16
16
|
= fae_image_form f, :favicon
|
@@ -2,20 +2,20 @@
|
|
2
2
|
|
3
3
|
main.content
|
4
4
|
|
5
|
-
== fae_filter_form title: '
|
6
|
-
== fae_filter_select :user, options: Fae::User.all.map { |u| [u.full_name, u.id] }
|
7
|
-
== fae_filter_select :model, options: Fae::Change.unique_changeable_types
|
8
|
-
== fae_filter_select :type, options: ['created', 'updated', 'deleted']
|
9
|
-
== fae_filter_select :date, options: ['
|
5
|
+
== fae_filter_form title: t('fae.changes.title'), action: fae.activity_log_filter_path do
|
6
|
+
== fae_filter_select :user, options: Fae::User.all.map { |u| [u.full_name, u.id] }, translation_path: 'fae.changes.models'
|
7
|
+
== fae_filter_select :model, options: Fae::Change.unique_changeable_types, translation_path: 'fae.changes.models'
|
8
|
+
== fae_filter_select :type, options: [t('fae.changes.created'), t('fae.changes.updated'), t('fae.changes.deleted')], translation_path: 'fae.changes.models'
|
9
|
+
== fae_filter_select :date, options: [t('fae.changes.last_hour'), t('fae.changes.last_day'), t('fae.changes.last_week'), t('fae.changes.last_month')], placeholder: t('fae.changes.all_time')
|
10
10
|
|
11
11
|
table.js-results-table
|
12
12
|
thead
|
13
13
|
tr
|
14
|
-
th data-sort="user.first_name"
|
15
|
-
th data-sort="changeable_type"
|
16
|
-
th data-sort="change_type"
|
17
|
-
th
|
18
|
-
th data-sort="updated_at"
|
14
|
+
th data-sort="user.first_name" = t('fae.changes.user')
|
15
|
+
th data-sort="changeable_type" = t('fae.changes.item')
|
16
|
+
th data-sort="change_type" = t('fae.changes.type')
|
17
|
+
th = t('fae.changes.attrs')
|
18
|
+
th data-sort="updated_at" = t('fae.changes.modified')
|
19
19
|
tbody
|
20
20
|
- if @items.present?
|
21
21
|
- @items.each do |change|
|
@@ -27,6 +27,6 @@ main.content
|
|
27
27
|
td = fae_datetime_format(change.updated_at)
|
28
28
|
- else
|
29
29
|
tr
|
30
|
-
td colspan=5
|
30
|
+
td colspan=5 = t('fae.changes.no_changes')
|
31
31
|
|
32
32
|
== fae_paginate @items
|
@@ -1,4 +1,4 @@
|
|
1
1
|
.center
|
2
2
|
.sad_face
|
3
|
-
h1
|
4
|
-
p
|
3
|
+
h1 = t('fae.page.disabled_title')
|
4
|
+
p = t('fae.page.disabled_text')
|
@@ -2,6 +2,8 @@
|
|
2
2
|
.sad_face
|
3
3
|
h1 Oops!
|
4
4
|
p
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
= t('fae.page.error_start')
|
6
|
+
|
|
7
|
+
a href=fae.root_path = t('fae.page.click')
|
8
|
+
|
|
9
|
+
= t('fae.page.error_end')
|
@@ -1,7 +1,8 @@
|
|
1
1
|
header.content-header.js-content-header.-dashboard
|
2
2
|
div
|
3
3
|
i.icon-home>
|
4
|
-
|
|
4
|
+
|
|
5
|
+
= t('fae.page.hello')
|
5
6
|
strong< = current_user.full_name
|
6
7
|
|
7
8
|
== render 'flash_messages'
|
@@ -11,9 +12,9 @@ header.content-header.js-content-header.-dashboard
|
|
11
12
|
table.js-sort-column
|
12
13
|
thead
|
13
14
|
tr
|
14
|
-
th
|
15
|
-
th
|
16
|
-
th.-action-wide
|
15
|
+
th = t('fae.common.name')
|
16
|
+
th = t('fae.changes.type')
|
17
|
+
th.-action-wide = t('fae.changes.modified')
|
17
18
|
tbody
|
18
19
|
- @list.each do |item|
|
19
20
|
- begin
|
@@ -28,9 +29,9 @@ header.content-header.js-content-header.-dashboard
|
|
28
29
|
- else
|
29
30
|
section.help-section
|
30
31
|
article.content
|
31
|
-
h2
|
32
|
+
h2 = t('fae.page.welcome')
|
32
33
|
p
|
33
|
-
|
34
|
+
= t('fae.page.no_objs_start')
|
34
35
|
br
|
35
|
-
a href="https://www.faecms.com/documentation/quickstart-guide" target="_blank"
|
36
|
-
'
|
36
|
+
a href="https://www.faecms.com/documentation/quickstart-guide" target="_blank"
|
37
|
+
= t('fae.page.no_objs.end')
|
@@ -1,11 +1,11 @@
|
|
1
1
|
.first_user-form
|
2
|
-
p
|
2
|
+
p = t('fae.setup.prompt')
|
3
3
|
|
4
4
|
= simple_form_for(@user, html: { multipart: true, novalidate: true }, url: fae.first_user_path) do |f|
|
5
5
|
= fae_input f, :first_name
|
6
6
|
= fae_input f, :last_name
|
7
7
|
= fae_input f, :email
|
8
|
-
= fae_input f, :password, helper_text: '
|
8
|
+
= fae_input f, :password, helper_text: t('fae.setup.password')
|
9
9
|
= fae_input f, :password_confirmation
|
10
10
|
.login-form-actions
|
11
|
-
=
|
11
|
+
input name="commit" type="submit" value=t('fae.form.save')
|
@@ -1,9 +1,9 @@
|
|
1
1
|
ruby:
|
2
2
|
require_locals ['header'], local_assigns
|
3
|
-
save_button_text ||= '
|
4
|
-
cancel_button_text ||= '
|
3
|
+
save_button_text ||= t('fae.form.save')
|
4
|
+
cancel_button_text ||= t('fae.form.cancel')
|
5
5
|
cloneable ||= false
|
6
|
-
clone_button_text ||= '
|
6
|
+
clone_button_text ||= t('fae.form.clone')
|
7
7
|
subnav ||= []
|
8
8
|
header_as_string = header.is_a?(String) ? header : header.class.name.split('::').last
|
9
9
|
header_as_string = header_as_string.singularize
|
@@ -3,7 +3,8 @@ ruby:
|
|
3
3
|
title ||= @klass_humanized.pluralize.titleize
|
4
4
|
new_button = !local_assigns[:new_button].eql?(false)
|
5
5
|
new_path ||= "new_#{fae_path}_#{@klass_singular}_path"
|
6
|
-
button_text ||=
|
6
|
+
button_text ||= t('fae.common.add', title: title.singularize)
|
7
|
+
export_text ||= t('fae.common.csv_export')
|
7
8
|
csv ||= false
|
8
9
|
breadcrumb = !local_assigns[:breadcrumbs].eql?(false)
|
9
10
|
|
@@ -15,7 +16,7 @@ header.content-header.js-content-header
|
|
15
16
|
|
16
17
|
.content-header-buttons
|
17
18
|
- if csv && @items.present?
|
18
|
-
a.button href="#{@index_path}.csv"
|
19
|
+
a.button href="#{@index_path}.csv" = export_text
|
19
20
|
|
20
21
|
- if new_button
|
21
22
|
- if nested
|
@@ -10,7 +10,7 @@ ruby:
|
|
10
10
|
# optional locals
|
11
11
|
assoc_name ||= assoc.to_s # 'restaurant_bars'
|
12
12
|
title ||= assoc_name.titleize # 'Restaurant Bars'
|
13
|
-
add_button_text ||=
|
13
|
+
add_button_text ||= t('fae.common.add', title: title.singularize)
|
14
14
|
ordered ||= false
|
15
15
|
has_thumb ||= false
|
16
16
|
edit_column ||= false
|
@@ -1,14 +1,14 @@
|
|
1
1
|
- unless params[:action] == 'new'
|
2
2
|
.content#recent_changes
|
3
|
-
h2
|
3
|
+
h2 = t('fae.changes.recent')
|
4
4
|
section.addedit-form.js-addedit-form
|
5
5
|
table
|
6
6
|
thead
|
7
7
|
tr
|
8
|
-
th
|
9
|
-
th
|
10
|
-
th
|
11
|
-
th.-action-wide
|
8
|
+
th = t('fae.changes.user')
|
9
|
+
th = t('fae.changes.type')
|
10
|
+
th = t('fae.changes.attrs')
|
11
|
+
th.-action-wide t('fea.changes.modified')
|
12
12
|
tbody
|
13
13
|
- if @item.try(:tracked_changes).present?
|
14
14
|
- @item.tracked_changes.each do |change|
|
@@ -19,4 +19,4 @@
|
|
19
19
|
td = fae_datetime_format(change.updated_at)
|
20
20
|
- else
|
21
21
|
tr
|
22
|
-
td colspan="4"
|
22
|
+
td colspan="4" = t('fae.changes.no_changes')
|
@@ -33,7 +33,7 @@ table class=table_class
|
|
33
33
|
= td_columns(options_for_td)
|
34
34
|
- if edit_column
|
35
35
|
td
|
36
|
-
a.js-edit-link.js-tooltip.table-action title=
|
36
|
+
a.js-edit-link.js-tooltip.table-action title=t('fae.common.edit') href=self.send(edit_path, item)
|
37
37
|
i.icon-edit
|
38
38
|
td = fae_delete_button item, "/#{fae_path}/#{assoc_name}/#{item.id.to_s}", class: 'js-tooltip table-action js-delete-link', remote: true
|
39
39
|
|