pageflow 15.7.1 → 16.0.0

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 (201) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +33 -243
  3. data/README.md +1 -9
  4. data/Rakefile +4 -1
  5. data/admins/pageflow/accounts.rb +12 -16
  6. data/admins/pageflow/entry.rb +57 -28
  7. data/admins/pageflow/entry_templates.rb +5 -7
  8. data/admins/pageflow/sites.rb +50 -0
  9. data/admins/pageflow/user.rb +7 -0
  10. data/app/assets/javascripts/pageflow/admin/entries.js +53 -4
  11. data/app/assets/stylesheets/pageflow/admin/permalink_input.scss +65 -0
  12. data/app/assets/stylesheets/pageflow/admin.scss +1 -0
  13. data/app/assets/stylesheets/pageflow/editor/base.scss +2 -6
  14. data/app/assets/stylesheets/pageflow/editor/dialogs.scss +2 -0
  15. data/app/assets/stylesheets/pageflow/editor/drop_down_button.scss +9 -0
  16. data/app/assets/stylesheets/pageflow/editor/info_box.scss +13 -3
  17. data/app/assets/stylesheets/pageflow/mixins/buttons.scss +1 -0
  18. data/app/assets/stylesheets/pageflow/page.scss +0 -2
  19. data/app/assets/stylesheets/pageflow/themes/default/page.scss +1 -1
  20. data/app/assets/stylesheets/pageflow/ui/forms.scss +4 -1
  21. data/app/controllers/pageflow/editor/file_import_controller.rb +32 -42
  22. data/app/controllers/pageflow/entries_controller.rb +27 -3
  23. data/app/helpers/pageflow/admin/permalinks_helper.rb +15 -0
  24. data/app/helpers/pageflow/common_entry_seed_helper.rb +1 -1
  25. data/app/helpers/pageflow/embed_code_helper.rb +1 -1
  26. data/app/helpers/pageflow/entries_helper.rb +25 -17
  27. data/app/helpers/pageflow/sites_helper.rb +11 -0
  28. data/app/helpers/pageflow/social_share_helper.rb +2 -2
  29. data/app/inputs/pageflow_permalink_input.rb +47 -0
  30. data/app/models/concerns/pageflow/permalinkable.rb +12 -0
  31. data/app/models/concerns/pageflow/reusable_file.rb +5 -0
  32. data/app/models/concerns/pageflow/uploadable_file.rb +4 -0
  33. data/app/models/pageflow/account.rb +7 -33
  34. data/app/models/pageflow/{cname_theming_request_scope.rb → cname_site_request_scope.rb} +3 -3
  35. data/app/models/pageflow/customized_theme.rb +5 -3
  36. data/app/models/pageflow/entry.rb +8 -4
  37. data/app/models/pageflow/entry_at_revision.rb +4 -3
  38. data/app/models/pageflow/entry_duplicate.rb +8 -1
  39. data/app/models/pageflow/entry_template.rb +4 -4
  40. data/app/models/pageflow/home_button.rb +7 -7
  41. data/app/models/pageflow/image_file_url_templates.rb +2 -2
  42. data/app/models/pageflow/permalink.rb +39 -0
  43. data/app/models/pageflow/permalink_directory.rb +10 -0
  44. data/app/models/pageflow/published_entry.rb +19 -2
  45. data/app/models/pageflow/revision.rb +1 -1
  46. data/app/models/pageflow/site.rb +59 -0
  47. data/app/models/pageflow/theme_customization.rb +1 -1
  48. data/app/models/pageflow/theme_customization_file.rb +6 -1
  49. data/app/policies/pageflow/account_policy.rb +2 -2
  50. data/app/policies/pageflow/entry_policy.rb +2 -2
  51. data/app/policies/pageflow/entry_template_policy.rb +1 -1
  52. data/app/policies/pageflow/{theming_policy.rb → site_policy.rb} +13 -11
  53. data/app/views/admin/accounts/_entry_template_details.html.arb +1 -1
  54. data/app/views/admin/accounts/_form.html.erb +4 -22
  55. data/app/views/admin/accounts/_site_defaults_inline_help.html.erb +5 -0
  56. data/app/views/admin/entries/_form.html.erb +11 -12
  57. data/app/views/admin/entries/_permalink_inputs.html.erb +6 -0
  58. data/app/views/admin/entries/_site_input.html.erb +15 -0
  59. data/app/views/admin/entries/{entry_type_name_input.html.erb → entry_site_and_type_name_input.html.erb} +3 -0
  60. data/app/views/admin/entries/permalink_inputs.html.erb +7 -0
  61. data/app/views/admin/entry_templates/_form.html.erb +5 -5
  62. data/app/views/admin/sites/_attributes_table.html.arb +9 -0
  63. data/app/views/admin/sites/_fields.html.erb +17 -0
  64. data/app/views/admin/sites/_form.html.erb +5 -0
  65. data/app/views/components/pageflow/admin/entries_tab.rb +1 -2
  66. data/app/views/components/pageflow/admin/entry_templates_tab.rb +10 -11
  67. data/app/views/components/pageflow/admin/features_tab.rb +1 -1
  68. data/app/views/components/pageflow/admin/sites_tab.rb +32 -0
  69. data/app/views/components/pageflow/admin/users_tab.rb +1 -2
  70. data/app/views/pageflow/editor/entries/seed.json.erb +1 -1
  71. data/app/views/pageflow/editor/file_import/start_import_job.json.jbuilder +10 -0
  72. data/app/views/pageflow/editor/sites/_site.json.jbuilder +1 -0
  73. data/app/views/pageflow/entries/{_theming.css.erb → _site.css.erb} +0 -0
  74. data/app/views/pageflow/entries/stylesheet.css.erb +1 -1
  75. data/app/views/pageflow/files/_file.json.jbuilder +1 -0
  76. data/app/views/pageflow/social_share/_entry_meta_tags.html.erb +1 -1
  77. data/app/views/pageflow/social_share/_page_meta_tags.html.erb +1 -1
  78. data/config/initializers/admin_resource_tabs.rb +29 -12
  79. data/config/initializers/mime_types.rb +1 -0
  80. data/config/locales/de.yml +19 -17
  81. data/config/locales/en.yml +19 -17
  82. data/config/routes.rb +8 -5
  83. data/db/migrate/20221024100724_create_pageflow_permalink_directories.rb +10 -0
  84. data/db/migrate/20221025074049_add_permalink_attributes_to_entries.rb +5 -0
  85. data/db/migrate/20221027065022_create_pageflow_permalinks.rb +12 -0
  86. data/db/migrate/20221215101134_rename_theming_to_site.rb +9 -0
  87. data/db/migrate/20221215120856_associate_entry_templates_with_sites.rb +34 -0
  88. data/db/migrate/20221219203023_add_name_to_sites.rb +5 -0
  89. data/db/migrate/20230103155934_associate_theme_customizations_with_sites.rb +27 -0
  90. data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/editor.js +176 -179
  91. data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/frontend.js +49 -7
  92. data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/react-client.js +5 -5
  93. data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/react-server.js +1 -1
  94. data/entry_types/paged/config/initializers/features.rb +2 -0
  95. data/entry_types/paged/config/locales/{new/help.de.yml → de.yml} +74 -65
  96. data/entry_types/paged/config/locales/{new/help.en.yml → en.yml} +66 -56
  97. data/entry_types/scrolled/app/helpers/pageflow_scrolled/favicon_helper.rb +39 -13
  98. data/entry_types/scrolled/app/helpers/pageflow_scrolled/generated_media_queries_helper.rb +55 -0
  99. data/entry_types/scrolled/app/helpers/pageflow_scrolled/themes_helper.rb +6 -2
  100. data/entry_types/scrolled/app/views/pageflow_scrolled/editor/entries/_head.html.erb +2 -0
  101. data/entry_types/scrolled/app/views/pageflow_scrolled/entries/_manifest.json.jbuilder +16 -0
  102. data/entry_types/scrolled/app/views/pageflow_scrolled/entries/show.html.erb +9 -3
  103. data/entry_types/scrolled/app/views/pageflow_scrolled/entry_json_seed/_entry.json.jbuilder +5 -5
  104. data/entry_types/scrolled/app/views/pageflow_scrolled/favicons/_entry.html.erb +16 -10
  105. data/entry_types/scrolled/config/locales/de.yml +265 -76
  106. data/entry_types/scrolled/config/locales/en.yml +266 -77
  107. data/entry_types/scrolled/lib/pageflow_scrolled/configuration.rb +3 -3
  108. data/entry_types/scrolled/lib/pageflow_scrolled/plugin.rb +14 -0
  109. data/entry_types/scrolled/lib/pageflow_scrolled/react_widget_type.rb +1 -1
  110. data/entry_types/scrolled/lib/pageflow_scrolled/seeds.rb +1 -1
  111. data/entry_types/scrolled/lib/pageflow_scrolled/web_app_manifest.rb +11 -0
  112. data/entry_types/scrolled/lib/pageflow_scrolled.rb +39 -1
  113. data/entry_types/scrolled/lib/tasks/pageflow_scrolled/storybook.rake +3 -2
  114. data/entry_types/scrolled/package/contentElements-editor.js +124 -38
  115. data/entry_types/scrolled/package/contentElements-frontend.css +1 -1
  116. data/entry_types/scrolled/package/contentElements-frontend.js +321 -27
  117. data/entry_types/scrolled/package/editor.js +1345 -739
  118. data/entry_types/scrolled/package/frontend/EditableInlineText.module-14c7b097.js +5314 -0
  119. data/entry_types/scrolled/package/frontend/{PhonePlatformContext-9fb97827.js → PhonePlatformContext-f6093cc6.js} +87 -223
  120. data/entry_types/scrolled/package/frontend/{Viewer-e2290ea0.js → Viewer-b6becc57.js} +6 -40
  121. data/entry_types/scrolled/package/frontend/arrowRight-78a7cee4.js +42 -0
  122. data/entry_types/scrolled/package/frontend/{components-6ab26015.js → components-b3160dd7.js} +546 -361
  123. data/entry_types/scrolled/package/frontend/index.css +1 -1
  124. data/entry_types/scrolled/package/frontend/index.js +398 -3692
  125. data/entry_types/scrolled/package/package.json +3 -2
  126. data/entry_types/scrolled/package/testHelpers.js +12 -2
  127. data/entry_types/scrolled/package/widgets/defaultNavigation.css +2 -2
  128. data/entry_types/scrolled/package/widgets/defaultNavigation.js +50 -40
  129. data/entry_types/scrolled/spec/fixtures/image.ico +0 -0
  130. data/lib/pageflow/ability_mixin.rb +16 -8
  131. data/lib/pageflow/admin/attributes_table_rows.rb +1 -1
  132. data/lib/pageflow/admin/form_inputs.rb +1 -1
  133. data/lib/pageflow/admin/tabs.rb +1 -1
  134. data/lib/pageflow/configuration/permissions.rb +3 -3
  135. data/lib/pageflow/configuration.rb +17 -17
  136. data/lib/pageflow/entry_export_import/entry_serialization.rb +1 -1
  137. data/lib/pageflow/entry_type.rb +6 -2
  138. data/lib/pageflow/primary_domain_entry_redirect.rb +7 -7
  139. data/lib/pageflow/seeds.rb +10 -10
  140. data/lib/pageflow/theme_customizations.rb +10 -10
  141. data/lib/pageflow/version.rb +1 -1
  142. data/package/editor.js +129 -156
  143. data/package/frontend.js +19 -2
  144. data/package/testHelpers.js +39 -6
  145. data/spec/factories/accounts.rb +5 -2
  146. data/spec/factories/draft_entries.rb +2 -2
  147. data/spec/factories/entries.rb +18 -1
  148. data/spec/factories/entry_templates.rb +1 -1
  149. data/spec/factories/permalink_directory.rb +6 -0
  150. data/spec/factories/permalinks.rb +4 -0
  151. data/spec/factories/published_entries.rb +4 -2
  152. data/spec/factories/sites.rb +9 -0
  153. metadata +50 -62
  154. data/app/assets/javascripts/pageflow/dist/editor.js +0 -11890
  155. data/app/assets/javascripts/pageflow/dist/frontend.js +0 -5800
  156. data/app/assets/javascripts/pageflow/dist/react-client.js +0 -22
  157. data/app/assets/javascripts/pageflow/dist/react-server.js +0 -19
  158. data/app/helpers/pageflow/themings_helper.rb +0 -11
  159. data/app/models/pageflow/theming.rb +0 -29
  160. data/app/views/admin/accounts/_theming_defaults_inline_help.html.erb +0 -5
  161. data/app/views/admin/accounts/_theming_details.html.arb +0 -5
  162. data/app/views/pageflow/editor/themings/_theming.json.jbuilder +0 -1
  163. data/entry_types/paged/config/locales/new/video_contain.de.yml +0 -7
  164. data/entry_types/paged/config/locales/new/video_contain.en.yml +0 -7
  165. data/entry_types/scrolled/config/locales/new/before_after_slider.de.yml +0 -8
  166. data/entry_types/scrolled/config/locales/new/before_after_slider.en.yml +0 -8
  167. data/entry_types/scrolled/config/locales/new/center_ragged.de.yml +0 -8
  168. data/entry_types/scrolled/config/locales/new/center_ragged.en.yml +0 -9
  169. data/entry_types/scrolled/config/locales/new/consent.de.yml +0 -25
  170. data/entry_types/scrolled/config/locales/new/consent.en.yml +0 -24
  171. data/entry_types/scrolled/config/locales/new/content_element_categories.de.yml +0 -39
  172. data/entry_types/scrolled/config/locales/new/content_element_categories.en.yml +0 -39
  173. data/entry_types/scrolled/config/locales/new/default_transition.de.yml +0 -14
  174. data/entry_types/scrolled/config/locales/new/default_transition.en.yml +0 -14
  175. data/entry_types/scrolled/config/locales/new/header_line_breaks.de.yml +0 -28
  176. data/entry_types/scrolled/config/locales/new/header_line_breaks.en.yml +0 -27
  177. data/entry_types/scrolled/config/locales/new/header_size.de.yml +0 -17
  178. data/entry_types/scrolled/config/locales/new/header_size.en.yml +0 -17
  179. data/entry_types/scrolled/config/locales/new/iframe_embed.de.yml +0 -39
  180. data/entry_types/scrolled/config/locales/new/iframe_embed.en.yml +0 -39
  181. data/entry_types/scrolled/config/locales/new/inline_loops.de.yml +0 -26
  182. data/entry_types/scrolled/config/locales/new/inline_loops.en.yml +0 -26
  183. data/entry_types/scrolled/config/locales/new/portrait_inline_image.de.yml +0 -9
  184. data/entry_types/scrolled/config/locales/new/portrait_inline_image.en.yml +0 -9
  185. data/entry_types/scrolled/config/locales/new/section_width.de.yml +0 -10
  186. data/entry_types/scrolled/config/locales/new/section_width.en.yml +0 -10
  187. data/entry_types/scrolled/config/locales/new/typography_variants.de.yml +0 -7
  188. data/entry_types/scrolled/config/locales/new/typography_variants.en.yml +0 -7
  189. data/entry_types/scrolled/config/locales/new/video_embed_poster.de.yml +0 -8
  190. data/entry_types/scrolled/config/locales/new/video_embed_poster.en.yml +0 -8
  191. data/entry_types/scrolled/config/locales/new/waveform_styles.de.yml +0 -11
  192. data/entry_types/scrolled/config/locales/new/waveform_styles.en.yml +0 -12
  193. data/entry_types/scrolled/config/locales/new/widgets.de.yml +0 -6
  194. data/entry_types/scrolled/config/locales/new/widgets.en.yml +0 -6
  195. data/entry_types/scrolled/lib/generators/pageflow_scrolled/install/templates/theme/favicons/browserconfig.xml +0 -9
  196. data/entry_types/scrolled/lib/generators/pageflow_scrolled/install/templates/theme/favicons/mstile-150x150.png +0 -0
  197. data/entry_types/scrolled/lib/generators/pageflow_scrolled/install/templates/theme/favicons/safari-pinned-tab.svg +0 -46
  198. data/entry_types/scrolled/lib/generators/pageflow_scrolled/install/templates/theme/favicons/site.webmanifest +0 -19
  199. data/entry_types/scrolled/package/frontend/EditableInlineText.module-b9923660.js +0 -993
  200. data/entry_types/scrolled/package/frontend/usePhonePlatform-2857c22b.js +0 -34
  201. data/spec/factories/themings.rb +0 -7
@@ -0,0 +1,50 @@
1
+ module Pageflow
2
+ ActiveAdmin.register Site, as: 'Site' do
3
+ belongs_to :account
4
+
5
+ menu false
6
+ actions :index, :show, :new, :edit, :create, :update
7
+
8
+ show do
9
+ render 'attributes_table', site: site
10
+
11
+ tabs_view(Pageflow.config.admin_resource_tabs.find_by_resource(site),
12
+ i18n: 'pageflow.admin.resource_tabs',
13
+ authorize: :see_site_admin_tab,
14
+ build_args: [site])
15
+ end
16
+
17
+ form partial: 'form'
18
+
19
+ permit_params do
20
+ [
21
+ :name,
22
+ :cname,
23
+ :additional_cnames,
24
+ :imprint_link_url,
25
+ :imprint_link_label,
26
+ :copyright_link_url,
27
+ :copyright_link_label,
28
+ :privacy_link_url,
29
+ :home_url
30
+ ] + permitted_admin_form_input_params
31
+ end
32
+
33
+ controller do
34
+ helper Pageflow::Admin::FormHelper
35
+
36
+ def index
37
+ redirect_to admin_account_path(parent, tab: 'sites')
38
+ end
39
+
40
+ private
41
+
42
+ def permitted_admin_form_input_params
43
+ Pageflow
44
+ .config_for(parent)
45
+ .admin_form_inputs
46
+ .permitted_attributes_for(:site)
47
+ end
48
+ end
49
+ end
50
+ end
@@ -101,6 +101,10 @@ module Pageflow
101
101
 
102
102
  form(partial: 'form')
103
103
 
104
+ after_update do |user|
105
+ Pageflow.config.hooks.invoke(:user_changed, user)
106
+ end
107
+
104
108
  collection_action :invitation, method: [:get, :post] do
105
109
  @page_title = I18n.t('pageflow.admin.users.invite_user')
106
110
  @invitation_form = InvitationForm.new(invitation_form_params.fetch(:invitation_form, {}),
@@ -109,6 +113,7 @@ module Pageflow
109
113
 
110
114
  if request.post?
111
115
  if @invitation_form.save
116
+ Pageflow.config.hooks.invoke(:user_changed, @invitation_form.target_user)
112
117
  redirect_to(admin_user_path(@invitation_form.target_user))
113
118
  else
114
119
  render status: 422
@@ -130,6 +135,8 @@ module Pageflow
130
135
 
131
136
  if request.patch?
132
137
  if @user.update_with_password(user_profile_params)
138
+ Pageflow.config.hooks.invoke(:user_changed, @user)
139
+
133
140
  bypass_sign_in @user, scope: :user
134
141
  redirect_to admin_root_path, notice: I18n.t('pageflow.admin.users.me.updated')
135
142
  end
@@ -88,18 +88,67 @@ jQuery(function($) {
88
88
 
89
89
  $('.admin_entries form.pageflow_entry').each(function() {
90
90
  var accountSelect = $('#entry_account_id', this);
91
+ var siteSelect = $('#entry_site_id', this);
92
+ var titleInput = $('#entry_title', this);
91
93
 
92
- function updateEntryTypeInput() {
94
+ function updateSiteAndEntryTypeInput() {
93
95
  var selectedAccountId = accountSelect.val();
94
96
 
95
- $.get('/admin/entries/entry_type_name_input' +
97
+ $.get('/admin/entries/entry_site_and_type_name_input' +
96
98
  '?account_id=' + selectedAccountId +
97
99
  '&entry_type_name=' + $('[name="entry[type_name]"]').val())
98
100
  .done(function(response) {
99
- $('#entry_type_name_input').replaceWith(response);
101
+ $('#entry_type_name_input').replaceWith($(response).filter('#entry_type_name_input'));
102
+ $('#entry_site_input').replaceWith($(response).filter('#entry_site_input'));
103
+
104
+ // Set up searchable select
105
+ $(document).trigger('page:load');
106
+
107
+ siteSelect = $('#entry_site_id');
108
+ siteSelect.on('change', updatePermalinkInput);
109
+
110
+ updatePermalinkInput();
100
111
  });
101
112
  }
102
113
 
103
- accountSelect.on('change', updateEntryTypeInput);
114
+ function updatePermalinkInput() {
115
+ fetchPermalinkInput(function(response) {
116
+ $('#entry_permalink_attributes_permalink_input').replaceWith(response);
117
+ });
118
+ }
119
+
120
+ function updateSlugPlaceholder() {
121
+ fetchPermalinkInput(function(response) {
122
+ $('#entry_permalink_attributes_permalink_input input[placeholder]')
123
+ .attr('placeholder',
124
+ $(response).find('input[placeholder]').attr('placeholder'));
125
+ });
126
+ }
127
+
128
+ function fetchPermalinkInput(callback) {
129
+ $.get('/admin/entries/permalink_inputs' +
130
+ '?entry[account_id]=' + accountSelect.val() +
131
+ (siteSelect.val() ? '&entry[site_id]=' + siteSelect.val() : '') +
132
+ '&entry[title]=' + encodeURIComponent(titleInput.val()))
133
+ .done(callback);
134
+ }
135
+
136
+ accountSelect.on('change', updateSiteAndEntryTypeInput);
137
+
138
+ accountSelect.on('change', updatePermalinkInput);
139
+ siteSelect.on('change', updatePermalinkInput);
140
+
141
+ titleInput.on('change keyup', debounce(updateSlugPlaceholder, 300));
104
142
  });
105
143
  });
144
+
145
+ function debounce(func, timeout){
146
+ var timer;
147
+
148
+ return function() {
149
+ var args = arguments;
150
+
151
+ clearTimeout(timer);
152
+ timer = setTimeout(function() { func.apply(this, args); }, timeout);
153
+ };
154
+ }
@@ -0,0 +1,65 @@
1
+ $pageflow-permalink-input-padding: 8px 10px 7px !default;
2
+ $pageflow-permalink-input-line-height: 1.15 !default;
3
+ $pageflow-permalink-input-border-color: #c9d0d6 !default;
4
+ $pageflow-permalink-input-border-radius: 3px !default;
5
+ $pageflow-permalink-input-focus-border-color: #99a2aa !default;
6
+ $pageflow-permalink-input-focus-box-shadow: 0 0 4px #99a2aa !default;
7
+ $pageflow-permalink-input-background-color: #fff !default;
8
+ $pageflow-permalink-input-min-width: 30% !default;
9
+
10
+ $pageflow-permalink-input-base-url-background-color: #f4f4f4 !default;
11
+ $pageflow-permalink-input-base-url-color: null !default;
12
+
13
+ $pageflow-permalink-input-directory-padding-left: 7px !default;
14
+ $pageflow-permalink-input-directory-padding-right: 7px !default;
15
+ $pageflow-permalink-input-directory-margin-h: 3px !default;
16
+ $pageflow-permalink-input-directory-background-position: null !default;
17
+
18
+ .pageflow_permalink.input {
19
+ .permalink {
20
+ display: inline-flex;
21
+ border: 1px solid $pageflow-permalink-input-border-color;
22
+ border-radius: $pageflow-permalink-input-border-radius;
23
+ background-color: $pageflow-permalink-input-background-color;
24
+ box-sizing: border-box;
25
+ min-width: $pageflow-permalink-input-min-width;
26
+ overflow: hidden;
27
+ width: 100%;
28
+
29
+ &:focus-within {
30
+ border-color: $pageflow-permalink-input-focus-border-color;
31
+ box-shadow: $pageflow-permalink-input-focus-box-shadow;
32
+ }
33
+ }
34
+
35
+ .permalink_base_url {
36
+ padding: $pageflow-permalink-input-padding;
37
+ line-height: $pageflow-permalink-input-line-height;
38
+ background-color: $pageflow-permalink-input-base-url-background-color;
39
+ color: $pageflow-permalink-input-base-url-color;
40
+ }
41
+
42
+ select,
43
+ input {
44
+ width: auto;
45
+ border: 0;
46
+
47
+ &:focus {
48
+ border: 0;
49
+ box-shadow: none;
50
+ }
51
+ }
52
+
53
+ select {
54
+ background-color: $pageflow-permalink-input-background-color;
55
+ background-position: $pageflow-permalink-input-directory-background-position;
56
+ padding-left: $pageflow-permalink-input-directory-padding-left;
57
+ padding-right: $pageflow-permalink-input-directory-padding-right;
58
+ margin: 0 $pageflow-permalink-input-directory-margin-h;
59
+ }
60
+
61
+ input {
62
+ padding-left: 0;
63
+ flex: 1;
64
+ }
65
+ }
@@ -31,6 +31,7 @@ $pageflow-hint-color: #666 !default;
31
31
  @import "pageflow/admin/hint";
32
32
  @import "pageflow/admin/icon_button";
33
33
  @import "pageflow/admin/icon_link";
34
+ @import "pageflow/admin/permalink_input";
34
35
  @import "pageflow/admin/publication_state_indicator";
35
36
  @import "pageflow/admin/quotas";
36
37
  @import "pageflow/admin/status_tags";
@@ -40,7 +40,7 @@
40
40
  padding: 0;
41
41
  }
42
42
 
43
- h2 {
43
+ .sidebar-header {
44
44
  font-size: inherit;
45
45
  font-weight: 500;
46
46
  margin: 15px 0 5px 0;
@@ -159,12 +159,8 @@ main.ui-layout-pane {
159
159
  border-bottom-right-radius: rounded(lg);
160
160
  }
161
161
 
162
- main > div {
162
+ #entry_preview {
163
163
  height: 100%;
164
-
165
- > .container {
166
- height: 100%;
167
- }
168
164
  }
169
165
 
170
166
  #help_entries_seed {
@@ -56,6 +56,8 @@
56
56
  }
57
57
 
58
58
  .dialog-sub_header {
59
+ font-size: inherit;
60
+ font-weight: 500;
59
61
  border-bottom: solid 1px var(--ui-on-surface-color-lighter);
60
62
  margin: 0;
61
63
  padding: space(1) 0;
@@ -9,6 +9,14 @@
9
9
  > button.has_icon_only {
10
10
  @include icon-only-button;
11
11
  }
12
+
13
+ &.full_width {
14
+ width: 100%;
15
+
16
+ > button {
17
+ width: 100%;
18
+ }
19
+ }
12
20
  }
13
21
 
14
22
  .drop_down_button_menu {
@@ -24,6 +32,7 @@
24
32
  border-radius: rounded(sm);
25
33
  box-shadow: var(--ui-box-shadow);
26
34
  background-color: var(--ui-surface-color);
35
+ box-sizing: border-box;
27
36
 
28
37
  &.is_visible {
29
38
  @include transition(visibility 0ms, opacity 100ms);
@@ -5,8 +5,9 @@
5
5
 
6
6
  .shortcuts {
7
7
  dt {
8
- display: inline-block;
9
- margin-top: 0.5em;
8
+ display: block;
9
+ margin: space(3) 0 space(2.5);
10
+ position: relative;
10
11
  }
11
12
 
12
13
  dd {
@@ -17,8 +18,17 @@
17
18
  border: solid 1px currentColor;
18
19
  border-radius: 4px;
19
20
  padding: 3px 5px;
20
- display: inline-block;
21
21
  font-size: 11px;
22
22
  }
23
23
  }
24
+
25
+ .inline_help {
26
+ padding-top: 36px;
27
+ }
28
+
29
+ // Make sure the label is on top when an inline help text is displayed
30
+ dt:hover .shortcut {
31
+ z-index: 4;
32
+ position: relative;
33
+ }
24
34
  }
@@ -59,6 +59,7 @@
59
59
  color: var(--ui-on-error-color);
60
60
  }
61
61
  } @else {
62
+ &.hover:not(:disabled):not(.disabled),
62
63
  &:hover:not(:disabled):not(.disabled) {
63
64
  border: 1px solid var(--ui-primary-color);
64
65
  }
@@ -39,7 +39,6 @@
39
39
  }
40
40
 
41
41
  .scroller > div {
42
- pointer-events: none;
43
42
  width: 75%;
44
43
 
45
44
  @include mobile {
@@ -70,7 +69,6 @@
70
69
  }
71
70
 
72
71
  .scroller > div {
73
- pointer-events: none;
74
72
  width: 100%;
75
73
 
76
74
  @include mobile {
@@ -9,7 +9,7 @@ $page-typography: () !default;
9
9
  $page-content-text-typography: () !default;
10
10
 
11
11
  /// Typography for content text in phone layout.
12
- $page-content-text-phone-typography: () !default
12
+ $page-content-text-phone-typography: () !default;
13
13
 
14
14
  /// Base font size for page content
15
15
  $page-content-font-size: 1em !default;
@@ -32,7 +32,8 @@ textarea,
32
32
  [type="tel"],
33
33
  [type="time"],
34
34
  [type="week"],
35
- [multiple] {
35
+ [multiple],
36
+ button[aria-haspopup] {
36
37
  font-size: 13px;
37
38
  display: block;
38
39
  width: 100%;
@@ -43,6 +44,7 @@ textarea,
43
44
  border-radius: rounded();
44
45
  color: var(--ui-on-surface-color);
45
46
 
47
+ &[aria-expanded=true],
46
48
  &:focus {
47
49
  border-color: var(--ui-on-surface-color-light);
48
50
  box-shadow: 0 0 0 2px var(--ui-selection-color-light);
@@ -222,6 +224,7 @@ textarea.short {
222
224
  }
223
225
 
224
226
  .input-disabled {
227
+ button,
225
228
  select,
226
229
  input,
227
230
  textarea,
@@ -4,7 +4,6 @@ module Pageflow
4
4
  # appropriate file importer
5
5
  class FileImportController < Pageflow::ApplicationController
6
6
  before_action :authenticate_user!
7
- respond_to :json
8
7
 
9
8
  def search
10
9
  result = file_importer.search file_importer_credentials, search_query
@@ -12,30 +11,35 @@ module Pageflow
12
11
  end
13
12
 
14
13
  def files_meta_data
15
- result = file_importer.files_meta_data file_importer_credentials, selected_files
14
+ result = file_importer.files_meta_data(file_importer_credentials,
15
+ params.require(:files))
16
16
  render json: {data: result}
17
17
  end
18
18
 
19
19
  def start_import_job
20
20
  entry = DraftEntry.find(entry_name)
21
- result = []
22
- selected_files.each do |key, file|
23
- file = key if file.nil?
24
- file = file.permit(:file_name,
25
- :rights,
26
- :content_type,
27
- :file_size,
28
- :url,
29
- configuration: :alt)
30
- entry_file, import_model = create_import_model entry, file
31
- FileImportJob.perform_later import_model.id, file_importer_credentials
32
- result.push file_response(entry_file, file)
21
+ authorize!(:edit, entry.to_model)
22
+
23
+ @items = files_params.map do |file_params|
24
+ file = entry.create_file!(file_type, file_params.except(:url))
25
+ file_import = create_file_import(file, file_params)
26
+
27
+ FileImportJob.perform_later(file_import.id, file_importer_credentials)
28
+
29
+ {file: file, source_url: file_params[:url]}
33
30
  end
34
- render json: {data: result}
35
31
  end
36
32
 
37
33
  private
38
34
 
35
+ def create_file_import(file, file_params)
36
+ FileImport.create!(entry: file.entry,
37
+ file_id: file.id,
38
+ file_type: file_type.model.name,
39
+ file_importer: file_importer.name,
40
+ download_options: file_params.to_json)
41
+ end
42
+
39
43
  def authentication_provider
40
44
  file_importer.authentication_provider
41
45
  end
@@ -48,35 +52,21 @@ module Pageflow
48
52
  params.require(:entry_id)
49
53
  end
50
54
 
51
- def selected_files
52
- params.require(:files)
53
- end
54
-
55
- def collection_name
56
- params.require(:collection)
57
- end
58
-
59
- def create_import_model(entry, file)
60
- entry_file, file_type = create_entry_file entry, file
61
- download_options = file.as_json
62
- import_model = FileImport.create!(entry: entry_file.entry,
63
- file_id: entry_file.id,
64
- file_type: file_type.model.name,
65
- file_importer: file_importer.name,
66
- download_options: download_options.to_json)
67
- [entry_file, import_model]
68
- end
69
-
70
- def create_entry_file(entry, file)
71
- file_type = Pageflow.config.file_types.find_by_collection_name!(collection_name)
72
- [entry.create_file!(file_type, file.except(:url)), file_type]
55
+ def files_params
56
+ params
57
+ .permit(files: [:file_name,
58
+ :rights,
59
+ :content_type,
60
+ :file_size,
61
+ :url,
62
+ configuration: :alt])
63
+ .require(:files)
73
64
  end
74
65
 
75
- def file_response(entry_file, file)
76
- entry_file = entry_file.as_json
77
- entry_file['type'] = params[:collection]
78
- entry_file['source_url'] = file[:url]
79
- entry_file
66
+ def file_type
67
+ @file_type ||= Pageflow.config.file_types.find_by_collection_name!(
68
+ params.require(:collection)
69
+ )
80
70
  end
81
71
 
82
72
  def file_importer
@@ -6,15 +6,15 @@ module Pageflow
6
6
  include EntryPasswordProtection
7
7
 
8
8
  def index
9
- theming = Theming.for_request(request).with_home_url.first!
9
+ site = Site.for_request(request).with_home_url.first!
10
10
 
11
- redirect_to(theming.home_url)
11
+ redirect_to(site.home_url)
12
12
  end
13
13
 
14
14
  def show
15
15
  respond_to do |format|
16
16
  format.html do
17
- entry = PublishedEntry.find(params[:id], entry_request_scope)
17
+ entry = find_by_permalink || find_by_slug
18
18
 
19
19
  return if redirect_according_to_entry_redirect(entry)
20
20
  return if redirect_according_to_public_https_mode
@@ -25,6 +25,18 @@ module Pageflow
25
25
  end
26
26
  end
27
27
 
28
+ def manifest
29
+ respond_to do |format|
30
+ format.webmanifest do
31
+ entry = PublishedEntry.find(params[:id], entry_request_scope)
32
+
33
+ return head :not_found unless entry.entry_type.web_app_manifest
34
+
35
+ render json: entry.entry_type.web_app_manifest.call(entry)
36
+ end
37
+ end
38
+ end
39
+
28
40
  def stylesheet
29
41
  respond_to do |format|
30
42
  format.css do
@@ -42,6 +54,18 @@ module Pageflow
42
54
 
43
55
  protected
44
56
 
57
+ def find_by_permalink
58
+ PublishedEntry.find_by_permalink(
59
+ directory: params[:directory],
60
+ slug: params[:id],
61
+ scope: entry_request_scope
62
+ )
63
+ end
64
+
65
+ def find_by_slug
66
+ PublishedEntry.find(params[:id], entry_request_scope)
67
+ end
68
+
45
69
  def entry_request_scope
46
70
  Pageflow.config.public_entry_request_scope.call(Entry, request)
47
71
  end
@@ -0,0 +1,15 @@
1
+ module Pageflow
2
+ module Admin
3
+ # @api private
4
+ module PermalinksHelper
5
+ def collection_for_permalink_directories(site, permalink)
6
+ options_from_collection_for_select(
7
+ site.permalink_directories,
8
+ 'id',
9
+ 'path',
10
+ permalink.directory_id
11
+ )
12
+ end
13
+ end
14
+ end
15
+ end
@@ -10,7 +10,7 @@ module Pageflow
10
10
  config = Pageflow.config_for(entry)
11
11
 
12
12
  json.locale entry.locale
13
- json.theming entry.theming.as_json(only: [:privacy_link_url])
13
+ json.site entry.site.as_json(only: [:privacy_link_url])
14
14
  json.enabled_feature_names entry.enabled_feature_names
15
15
  json.page_types PageTypesSeed.new(config).as_json
16
16
 
@@ -24,7 +24,7 @@ module Pageflow
24
24
 
25
25
  def entry_embed_url_options(entry)
26
26
  options = Pageflow.config.entry_embed_url_options
27
- options = options.call(entry.theming) if options.respond_to?(:call)
27
+ options = options.call(entry.site) if options.respond_to?(:call)
28
28
  options
29
29
  end
30
30
  end
@@ -1,7 +1,7 @@
1
1
  module Pageflow
2
2
  module EntriesHelper
3
3
  def pretty_entry_title(entry)
4
- [entry.title, entry.theming.cname_domain.presence].compact.join(' - ')
4
+ [entry.title, entry.site.cname_domain.presence].compact.join(' - ')
5
5
  end
6
6
 
7
7
  def pretty_entry_url(entry, options = {})
@@ -20,23 +20,31 @@ module Pageflow
20
20
  private
21
21
 
22
22
  def with_custom_canonical_url_prefix(entry)
23
- return if entry.theming.canonical_entry_url_prefix.blank?
23
+ return if entry.site.canonical_entry_url_prefix.blank?
24
24
  entry = ensure_entry_with_revision(entry)
25
25
 
26
26
  [
27
- entry.theming.canonical_entry_url_prefix.gsub(':locale', entry.locale),
27
+ entry.site.canonical_entry_url_prefix.gsub(':locale', entry.locale),
28
28
  entry.to_param,
29
- entry.theming.trailing_slash_in_canonical_urls ? '/' : ''
29
+ entry.site.trailing_slash_in_canonical_urls ? '/' : ''
30
30
  ].join
31
31
  end
32
32
 
33
33
  def default(routes, entry, options)
34
34
  params =
35
35
  options
36
- .reverse_merge(trailing_slash: entry.theming.trailing_slash_in_canonical_urls)
37
- .reverse_merge(Pageflow.config.theming_url_options(entry.theming) || {})
38
-
39
- routes.short_entry_url(entry.to_model, params)
36
+ .reverse_merge(trailing_slash: entry.site.trailing_slash_in_canonical_urls)
37
+ .reverse_merge(Pageflow.config.site_url_options(entry.site) || {})
38
+
39
+ if entry.permalink.present?
40
+ routes.permalink_url(
41
+ entry.permalink.directory&.path || '',
42
+ entry.permalink.slug,
43
+ params
44
+ )
45
+ else
46
+ routes.short_entry_url(entry.to_model, params)
47
+ end
40
48
  end
41
49
 
42
50
  def ensure_entry_with_revision(entry)
@@ -49,8 +57,8 @@ module Pageflow
49
57
  end
50
58
 
51
59
  def entry_privacy_link_url(entry)
52
- return unless entry.theming.privacy_link_url.present?
53
- "#{entry.theming.privacy_link_url}?lang=#{entry.locale}"
60
+ return unless entry.site.privacy_link_url.present?
61
+ "#{entry.site.privacy_link_url}?lang=#{entry.locale}"
54
62
  end
55
63
 
56
64
  def entry_file_rights(entry)
@@ -72,23 +80,23 @@ module Pageflow
72
80
  def entry_global_links(entry)
73
81
  links = []
74
82
 
75
- if entry.theming.imprint_link_label.present? && entry.theming.imprint_link_url.present?
76
- links << link_to(raw(entry.theming.imprint_link_label),
77
- entry.theming.imprint_link_url,
83
+ if entry.site.imprint_link_label.present? && entry.site.imprint_link_url.present?
84
+ links << link_to(raw(entry.site.imprint_link_label),
85
+ entry.site.imprint_link_url,
78
86
  target: '_blank',
79
87
  tabindex: 2,
80
88
  class: 'legal')
81
89
  end
82
90
 
83
- if entry.theming.copyright_link_label.present? && entry.theming.copyright_link_url.present?
84
- links << link_to(raw(entry.theming.copyright_link_label),
85
- entry.theming.copyright_link_url,
91
+ if entry.site.copyright_link_label.present? && entry.site.copyright_link_url.present?
92
+ links << link_to(raw(entry.site.copyright_link_label),
93
+ entry.site.copyright_link_url,
86
94
  target: '_blank',
87
95
  tabindex: 2,
88
96
  class: 'copy')
89
97
  end
90
98
 
91
- if entry.theming.privacy_link_url.present?
99
+ if entry.site.privacy_link_url.present?
92
100
  links << link_to(I18n.t('pageflow.public.privacy_notice'),
93
101
  entry_privacy_link_url(entry),
94
102
  target: '_blank',
@@ -0,0 +1,11 @@
1
+ module Pageflow
2
+ module SitesHelper
3
+ DEFAULT_PUBLIC_ENTRY_OPTIONS = lambda do |site|
4
+ site.cname.present? ? {host: site.cname} : nil
5
+ end
6
+
7
+ def pretty_site_url(site)
8
+ pageflow.public_root_url(Pageflow.config.site_url_options(site))
9
+ end
10
+ end
11
+ end