pageflow 12.0.4 → 12.1.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of pageflow might be problematic. Click here for more details.

Files changed (217) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +158 -374
  3. data/README.md +24 -3
  4. data/Rakefile +2 -2
  5. data/admins/pageflow/accounts.rb +30 -4
  6. data/admins/pageflow/entry.rb +59 -9
  7. data/admins/pageflow/membership.rb +57 -6
  8. data/admins/pageflow/user.rb +25 -4
  9. data/app/assets/images/pageflow/themes/default/preview.png +0 -0
  10. data/app/assets/images/pageflow/themes/default/preview_thumbnail.png +0 -0
  11. data/app/assets/javascripts/pageflow/admin/entries.js +5 -3
  12. data/app/assets/javascripts/pageflow/admin/users.js +33 -0
  13. data/app/assets/javascripts/pageflow/admin.js +4 -1
  14. data/app/assets/javascripts/pageflow/audio_context.js +28 -0
  15. data/app/assets/javascripts/pageflow/audio_player/get_media_element_method.js +5 -0
  16. data/app/assets/javascripts/pageflow/audio_player.js +2 -0
  17. data/app/assets/javascripts/pageflow/base.js +4 -22
  18. data/app/assets/javascripts/pageflow/dist/react.js +323 -242
  19. data/app/assets/javascripts/pageflow/editor/api/widget_type.js +23 -0
  20. data/app/assets/javascripts/pageflow/editor/api/widget_types.js +53 -0
  21. data/app/assets/javascripts/pageflow/editor/api.js +9 -1
  22. data/app/assets/javascripts/pageflow/editor/base.js +0 -1
  23. data/app/assets/javascripts/pageflow/editor/collections/pages_collection.js +1 -0
  24. data/app/assets/javascripts/pageflow/editor/collections/subset_collection.js +21 -1
  25. data/app/assets/javascripts/pageflow/editor/collections/themes_collection.js +13 -0
  26. data/app/assets/javascripts/pageflow/editor/collections/widgets_collection.js +23 -8
  27. data/app/assets/javascripts/pageflow/editor/controllers/sidebar_controller.js +7 -1
  28. data/app/assets/javascripts/pageflow/editor/initializers/setup_collections.js +10 -3
  29. data/app/assets/javascripts/pageflow/editor/initializers/setup_widget_types.js +5 -1
  30. data/app/assets/javascripts/pageflow/editor/initializers/stylesheet_reloading.js +8 -3
  31. data/app/assets/javascripts/pageflow/editor/models/edit_lock_container.js +1 -1
  32. data/app/assets/javascripts/pageflow/editor/models/entry.js +7 -4
  33. data/app/assets/javascripts/pageflow/editor/models/entry_configuration.js +1 -1
  34. data/app/assets/javascripts/pageflow/editor/models/file_stage.js +1 -0
  35. data/app/assets/javascripts/pageflow/editor/models/page.js +3 -1
  36. data/app/assets/javascripts/pageflow/editor/models/preview_entry_data.js +2 -2
  37. data/app/assets/javascripts/pageflow/editor/models/theme.js +25 -0
  38. data/app/assets/javascripts/pageflow/editor/models/theming.js +1 -19
  39. data/app/assets/javascripts/pageflow/editor/models/widget.js +22 -1
  40. data/app/assets/javascripts/pageflow/editor/models/widget_configuration.js +5 -0
  41. data/app/assets/javascripts/pageflow/editor/routers/sidebar_router.js +1 -0
  42. data/app/assets/javascripts/pageflow/editor/templates/change_theme_dialog.jst.ejs +23 -0
  43. data/app/assets/javascripts/pageflow/editor/templates/edit_widget.jst.ejs +1 -2
  44. data/app/assets/javascripts/pageflow/editor/templates/inputs/reference.jst.ejs +2 -2
  45. data/app/assets/javascripts/pageflow/editor/templates/static_thumbnail.jst.ejs +1 -0
  46. data/app/assets/javascripts/pageflow/editor/templates/theme_item.jst.ejs +5 -0
  47. data/app/assets/javascripts/pageflow/editor/templates/widget_item.jst.ejs +3 -0
  48. data/app/assets/javascripts/pageflow/editor/utils/stylesheet.js +23 -0
  49. data/app/assets/javascripts/pageflow/editor/views/change_theme_dialog_view.js +76 -0
  50. data/app/assets/javascripts/pageflow/editor/views/configuration_editors/groups/options.js +4 -2
  51. data/app/assets/javascripts/pageflow/editor/views/edit_meta_data_view.js +17 -4
  52. data/app/assets/javascripts/pageflow/editor/views/edit_widget_view.js +11 -21
  53. data/app/assets/javascripts/pageflow/editor/views/edit_widgets_view.js +1 -3
  54. data/app/assets/javascripts/pageflow/editor/views/file_meta_data_item_value_view.js +10 -1
  55. data/app/assets/javascripts/pageflow/editor/views/inputs/reference_input_view.js +36 -4
  56. data/app/assets/javascripts/pageflow/editor/views/inputs/theme_input_view.js +26 -0
  57. data/app/assets/javascripts/pageflow/editor/views/model_thumbnail_view.js +28 -14
  58. data/app/assets/javascripts/pageflow/editor/views/static_thumbnail_view.js +20 -0
  59. data/app/assets/javascripts/pageflow/editor/views/theme_item_view.js +41 -0
  60. data/app/assets/javascripts/pageflow/editor/views/widget_item_view.js +49 -0
  61. data/app/assets/javascripts/pageflow/history.js +7 -1
  62. data/app/assets/javascripts/pageflow/media_player/volume_fading/interval.js +65 -0
  63. data/app/assets/javascripts/pageflow/media_player/volume_fading/noop.js +5 -0
  64. data/app/assets/javascripts/pageflow/media_player/volume_fading/web_audio.js +109 -0
  65. data/app/assets/javascripts/pageflow/media_player/volume_fading.js +14 -65
  66. data/app/assets/javascripts/pageflow/slideshow/dom_order_scroll_navigator.js +5 -2
  67. data/app/assets/javascripts/pageflow/slideshow.js +19 -8
  68. data/app/assets/javascripts/pageflow/ui/views/configuration_editor_view.js +4 -0
  69. data/app/assets/javascripts/pageflow/ui/views/inputs/text_area_input_view.js +10 -5
  70. data/app/assets/javascripts/pageflow/ui/views/inputs/text_input_view.js +4 -48
  71. data/app/assets/javascripts/pageflow/ui/views/mixins/input_with_placeholder_text.js +58 -0
  72. data/app/assets/javascripts/pageflow/vendor.js +16 -0
  73. data/app/assets/javascripts/pageflow/video_player/get_media_element_method.js +6 -0
  74. data/app/assets/javascripts/pageflow/video_player.js +2 -0
  75. data/app/assets/stylesheets/pageflow/admin/entries.scss +1 -1
  76. data/app/assets/stylesheets/pageflow/admin/quotas.scss +1 -1
  77. data/app/assets/stylesheets/pageflow/admin.scss +2 -0
  78. data/app/assets/stylesheets/pageflow/base.scss +0 -1
  79. data/app/assets/stylesheets/pageflow/editor/base.scss +2 -0
  80. data/app/assets/stylesheets/pageflow/editor/change_theme.scss +114 -0
  81. data/app/assets/stylesheets/pageflow/editor/static_thumbnails.scss +4 -0
  82. data/app/assets/stylesheets/pageflow/editor/widgets.scss +26 -2
  83. data/app/assets/stylesheets/pageflow/page.scss +1 -14
  84. data/app/assets/stylesheets/pageflow/themes/default/indicators.scss +12 -0
  85. data/app/assets/stylesheets/pageflow/themes/default/loading_spinner.scss +11 -0
  86. data/app/assets/stylesheets/pageflow/themes/default/logo/alignment.scss +27 -0
  87. data/app/assets/stylesheets/pageflow/themes/default/logo/variant/background_image.scss +20 -2
  88. data/app/assets/stylesheets/pageflow/themes/default/logo/variant/watermark.scss +4 -1
  89. data/app/assets/stylesheets/pageflow/themes/default/page/line_lengths.scss +113 -0
  90. data/app/assets/stylesheets/pageflow/themes/default/page.scss +1 -0
  91. data/app/controllers/pageflow/editor/widgets_controller.rb +15 -1
  92. data/app/controllers/pageflow/entries_controller.rb +1 -1
  93. data/app/helpers/pageflow/admin/entries_helper.rb +0 -9
  94. data/app/helpers/pageflow/admin/memberships_helper.rb +43 -123
  95. data/app/helpers/pageflow/admin/users_helper.rb +15 -0
  96. data/app/helpers/pageflow/entries_helper.rb +3 -1
  97. data/app/helpers/pageflow/entry_json_seed_helper.rb +9 -3
  98. data/app/helpers/pageflow/public_i18n_helper.rb +2 -2
  99. data/app/helpers/pageflow/quota_helper.rb +2 -2
  100. data/app/helpers/pageflow/social_share_helper.rb +3 -2
  101. data/app/helpers/pageflow/themes_helper.rb +11 -3
  102. data/app/helpers/pageflow/widgets_helper.rb +10 -2
  103. data/app/jobs/pageflow/prune_auto_snapshots_job.rb +9 -0
  104. data/app/mailers/pageflow/user_mailer.rb +11 -1
  105. data/app/models/concerns/pageflow/feature_target.rb +1 -1
  106. data/app/models/concerns/pageflow/hosted_file.rb +9 -0
  107. data/app/models/concerns/pageflow/output_source.rb +2 -1
  108. data/app/models/concerns/pageflow/serialization_blacklist.rb +19 -0
  109. data/app/models/concerns/pageflow/serialized_configuration.rb +17 -0
  110. data/app/models/concerns/pageflow/theme_referencer.rb +23 -0
  111. data/app/models/pageflow/account.rb +6 -1
  112. data/app/models/pageflow/account_member_query.rb +6 -12
  113. data/app/models/pageflow/account_role_query.rb +68 -0
  114. data/app/models/pageflow/application_query.rb +13 -0
  115. data/app/models/pageflow/application_record.rb +5 -0
  116. data/app/models/pageflow/audio_file.rb +1 -1
  117. data/app/models/pageflow/auto_snapshot_pruning.rb +26 -0
  118. data/app/models/pageflow/chapter.rb +4 -8
  119. data/app/models/pageflow/draft_entry.rb +2 -1
  120. data/app/models/pageflow/edit_lock.rb +11 -5
  121. data/app/models/pageflow/encoding_confirmation.rb +2 -1
  122. data/app/models/pageflow/entry.rb +13 -2
  123. data/app/models/pageflow/entry_publication.rb +2 -0
  124. data/app/models/pageflow/entry_role_query.rb +24 -9
  125. data/app/models/pageflow/entry_title_or_account_name_query.rb +33 -0
  126. data/app/models/pageflow/file_usage.rb +3 -7
  127. data/app/models/pageflow/folder.rb +1 -1
  128. data/app/models/pageflow/home_button.rb +1 -1
  129. data/app/models/pageflow/image_file.rb +22 -4
  130. data/app/models/pageflow/invitation_form.rb +10 -4
  131. data/app/models/pageflow/managed_user_query.rb +44 -0
  132. data/app/models/pageflow/membership.rb +1 -1
  133. data/app/models/pageflow/overview_button.rb +3 -4
  134. data/app/models/pageflow/page.rb +3 -7
  135. data/app/models/pageflow/potential_memberships.rb +112 -0
  136. data/app/models/pageflow/published_entry.rb +2 -1
  137. data/app/models/pageflow/revision.rb +13 -4
  138. data/app/models/pageflow/storyline.rb +3 -4
  139. data/app/models/pageflow/text_track_file.rb +1 -1
  140. data/app/models/pageflow/theming.rb +15 -10
  141. data/app/models/pageflow/url_template.rb +8 -2
  142. data/app/models/pageflow/user_name_query.rb +30 -0
  143. data/app/models/pageflow/video_file.rb +5 -1
  144. data/app/models/pageflow/widget.rb +3 -1
  145. data/app/models/pageflow/zencoder_attachment.rb +16 -5
  146. data/app/policies/pageflow/account_policy.rb +31 -61
  147. data/app/policies/pageflow/application_policy.rb +6 -0
  148. data/app/policies/pageflow/entry_policy.rb +11 -3
  149. data/app/policies/pageflow/membership_policy.rb +1 -2
  150. data/app/policies/pageflow/user_policy.rb +20 -1
  151. data/app/views/admin/accounts/_form.html.erb +4 -4
  152. data/app/views/admin/accounts/_theming_defaults_inline_help.html.erb +5 -0
  153. data/app/views/admin/memberships/_form.html.erb +9 -14
  154. data/app/views/admin/memberships/_role_hint.html.arb +1 -1
  155. data/app/views/admin/users/invitation.html.erb +18 -9
  156. data/app/views/admin/users/me.html.erb +2 -2
  157. data/app/views/admin/users/quota_state.html.erb +1 -0
  158. data/app/views/components/pageflow/admin/add_membership_button.rb +81 -0
  159. data/app/views/components/pageflow/admin/members_tab.rb +6 -4
  160. data/app/views/components/pageflow/admin/revisions_tab.rb +16 -4
  161. data/app/views/components/pageflow/admin/user_accounts_tab.rb +8 -2
  162. data/app/views/components/pageflow/admin/user_entries_tab.rb +6 -2
  163. data/app/views/components/pageflow/admin/users_tab.rb +9 -5
  164. data/app/views/layouts/pageflow/application.html.erb +2 -1
  165. data/app/views/pageflow/admin/users/_quota_exhausted.html.erb +1 -0
  166. data/app/views/pageflow/admin/users/_quota_state.html.erb +7 -0
  167. data/app/views/pageflow/config/_editor_seeds.json.jbuilder +2 -0
  168. data/app/views/pageflow/editor/entries/_entry.json.jbuilder +1 -0
  169. data/app/views/pageflow/editor/entries/seed.json.erb +3 -1
  170. data/app/views/pageflow/editor/image_files/_image_file.json.jbuilder +1 -1
  171. data/app/views/pageflow/editor/themings/_theming.json.jbuilder +0 -7
  172. data/app/views/pageflow/editor/widgets/_widget.json.jbuilder +1 -1
  173. data/app/views/pageflow/entries/_entry.html.erb +5 -5
  174. data/app/views/pageflow/entries/edit.html.erb +1 -1
  175. data/app/views/pageflow/entries/show.html.erb +1 -1
  176. data/app/views/pageflow/entry_json_seed/_entry.json.jbuilder +1 -0
  177. data/app/views/pageflow/themes/_theme.json.jbuilder +13 -0
  178. data/config/initializers/admin_resource_tabs.rb +19 -6
  179. data/config/initializers/features.rb +1 -0
  180. data/config/locales/de.yml +26 -3
  181. data/config/locales/en.yml +26 -3
  182. data/db/migrate/20170201074328_add_configuration_to_widgets.rb +5 -0
  183. data/db/migrate/20170222124848_update_video_file_output_presences.rb +1 -1
  184. data/db/migrate/20170315130000_add_theme_name_to_revisions.rb +12 -0
  185. data/db/migrate/20170912165050_reset_copied_snapshot_type.rb +24 -0
  186. data/lib/generators/pageflow/routes/routes_generator.rb +11 -1
  187. data/lib/generators/pageflow/seeds/seeds_generator.rb +5 -0
  188. data/lib/generators/pageflow/seeds/templates/seeds.rb +5 -3
  189. data/lib/generators/pageflow/theme/templates/preview.png +0 -0
  190. data/lib/generators/pageflow/theme/templates/preview_thumbnail.png +0 -0
  191. data/lib/generators/pageflow/theme/theme_generator.rb +3 -0
  192. data/lib/pageflow/ability_mixin.rb +27 -6
  193. data/lib/pageflow/active_admin_can_can_fix.rb +34 -0
  194. data/lib/pageflow/configuration/permissions.rb +27 -0
  195. data/lib/pageflow/configuration.rb +28 -0
  196. data/lib/pageflow/engine.rb +25 -19
  197. data/lib/pageflow/images/palette.png +0 -0
  198. data/lib/pageflow/seeds.rb +1 -1
  199. data/lib/pageflow/theme.rb +8 -0
  200. data/lib/pageflow/version.rb +1 -1
  201. data/lib/pageflow/widget_type.rb +13 -0
  202. data/lib/pageflow/zencoder_video_output_definition.rb +16 -16
  203. data/lib/tasks/pageflow_tasks.rake +14 -0
  204. data/spec/factories/entries.rb +4 -0
  205. data/spec/factories/revisions.rb +10 -0
  206. data/spec/factories/users.rb +6 -0
  207. data/spec/factories/video_files.rb +4 -0
  208. data/vendor/assets/javascripts/audio5.min.js +3 -0
  209. metadata +78 -15
  210. data/app/assets/javascripts/pageflow/editor/models/mixins/widget_subject.js +0 -37
  211. data/app/assets/javascripts/pageflow/editor/utils/reload_stylesheet.js +0 -9
  212. data/app/assets/stylesheets/pageflow/text_variants.scss +0 -24
  213. data/app/views/admin/accounts/_widgets_inline_help.html.erb +0 -5
  214. data/app/views/admin/memberships/_entity_account_input.html.erb +0 -5
  215. data/app/views/admin/memberships/_entity_entry_input.html.erb +0 -5
  216. data/app/views/admin/users/_quota_exhausted.html.erb +0 -1
  217. data/app/views/components/pageflow/admin/add_membership_button_if_needed.rb +0 -62
@@ -27,6 +27,13 @@ $loading-spinner-background-color: #3b5159 !default;
27
27
  /// - `"none"`: Nothing
28
28
  $loading-spinner-background: "glow" !default;
29
29
 
30
+ /// Background size to apply to background image:
31
+ ///
32
+ /// - `"auto"`: Do not apply background size (default).
33
+ /// - `"logo"`: Apply same size as for logo image. Allows using
34
+ /// background image as an animated layer of the logo.
35
+ $loading-spinner-background-size: "auto" !default;
36
+
30
37
  /// Radial gradient color.
31
38
  $loading-spinner-glow-color: rgba(117, 149, 160, 0.8) !default;
32
39
 
@@ -57,6 +64,10 @@ $loading-spinner-animate-background: true !default;
57
64
  } @else if $loading-spinner-background == "custom" {
58
65
  content: "";
59
66
  background-image: image-url("pageflow/themes/#{$theme-name}/loading_spinner/background.png");
67
+
68
+ @if $loading-spinner-background-size == "logo" {
69
+ background-size: $loading-spinner-logo-width $loading-spinner-logo-height;
70
+ }
60
71
  }
61
72
 
62
73
  @if $loading-spinner-animate-background {
@@ -0,0 +1,27 @@
1
+ /// Alignment of the logo in desktop layout. In phone layout, logos
2
+ /// are always displayed left aligned.
3
+ ///
4
+ /// - `"left"`: Left align logo.
5
+ ///
6
+ /// - `"right"`: Right align logo in desktop layout.
7
+ $logo-alignment: "left" !default;
8
+
9
+ // Left position relative to page when logo is left aligned.
10
+ $logo-left: 8% !default;
11
+
12
+ // Right position relative to page when logo is right aligned.
13
+ $logo-right: 14% !default;
14
+
15
+ @mixin logo-alignment {
16
+ @include desktop {
17
+ @if $logo-alignment == "left" {
18
+ left: $logo-left;
19
+ } @else {
20
+ right: $logo-right;
21
+ }
22
+ }
23
+
24
+ @include phone {
25
+ left: $logo-left;
26
+ }
27
+ }
@@ -1,3 +1,11 @@
1
+ @import "../alignment";
2
+
3
+ // Opacity of the logo
4
+ $logo-background-image-variant-opacity: null !default;
5
+
6
+ /// Opacity of the logo on the first page
7
+ $logo-background-image-variant-first-page-opacity: null !default;
8
+
1
9
  @mixin logo-variant-background-image(
2
10
  $first-page-only,
3
11
  $top,
@@ -14,7 +22,6 @@
14
22
  .content_and_background .scroller > div:after {
15
23
  content: "";
16
24
  position: absolute;
17
- left: 8%;
18
25
  top: $top;
19
26
  z-index: 200;
20
27
  min-width: $min-width;
@@ -24,9 +31,10 @@
24
31
  background-image: image-url("pageflow/themes/#{$theme-name}/logo_header.png");
25
32
  background-repeat: no-repeat;
26
33
  background-size: contain;
27
- background-position: left top;
34
+ background-position: #{$logo-alignment} top;
28
35
 
29
36
  @include mobile {
37
+ background-position: left top;
30
38
  padding-top: 1%;
31
39
  height: $mobile-height;
32
40
  }
@@ -34,10 +42,20 @@
34
42
  @include phone {
35
43
  top: $phone-top;
36
44
  }
45
+
46
+ @include logo-alignment;
37
47
  }
38
48
 
39
49
  &.invert .content_and_background .scroller > div:after {
40
50
  background-image: image-url("pageflow/themes/#{$theme-name}/logo_header_invert.png");
41
51
  }
42
52
  }
53
+
54
+ .page .scroller > div:after {
55
+ opacity: $logo-background-image-variant-opacity;
56
+ }
57
+
58
+ .page:first-child .scroller > div:after {
59
+ opacity: $logo-background-image-variant-first-page-opacity;
60
+ }
43
61
  }
@@ -1,3 +1,5 @@
1
+ @import "../alignment";
2
+
1
3
  /// Fade in logo when scroller is near top
2
4
  ///
3
5
  /// - `"first-page"`: only on first page
@@ -25,7 +27,6 @@ $logo-watermark-variant-fade-in-with-header: false !default;
25
27
  width: $width;
26
28
  height: $height;
27
29
  top: $top;
28
- left: 8%;
29
30
  z-index: 1;
30
31
 
31
32
  pointer-events: none;
@@ -38,6 +39,8 @@ $logo-watermark-variant-fade-in-with-header: false !default;
38
39
  top: 21px;
39
40
  }
40
41
 
42
+ @include logo-alignment;
43
+
41
44
  .js & {
42
45
  display: block;
43
46
  }
@@ -0,0 +1,113 @@
1
+ /// Max width for tagline and subtitle and content text.
2
+ $page-content-max-width: 500px !default;
3
+
4
+ /// Max width for header title when text is positioned on the
5
+ /// left. For right positioned text the max width has to match the max
6
+ /// width of tagline and subtitle to ensure the title is left aligned
7
+ /// with those elements.
8
+ $page-header-title-max-width: 700px !default;
9
+
10
+ /// Maximal width for right positioned headlines and content text.
11
+ $page-content-position-right-max-width: 500px !default;
12
+
13
+ /// Min width the header title is supposed to have in a split layout
14
+ /// (i.e. when the page has two columns and some kind of embed is
15
+ /// displayed on the right) with text positioned on the left.
16
+ $page-header-title-min-width-for-split-layout: 525px !default;
17
+
18
+ /// Relative width of tagline, subtitle and content text
19
+ $page-content-width: 60% !default;
20
+
21
+ .page {
22
+ h1,
23
+ h2 .subtitle,
24
+ h2 .tagline,
25
+ h3,
26
+ p {
27
+ max-width: $page-content-max-width;
28
+ width: $page-content-width;
29
+
30
+ @include mobile {
31
+ width: 100%;
32
+ }
33
+ }
34
+
35
+ h2 .title {
36
+ max-width: $page-header-title-max-width;
37
+ width: 100%;
38
+ }
39
+
40
+ // see pageflow/page.scss
41
+ $page-padding-left: 8%;
42
+ $page-padding-right: 14%;
43
+ $page-content-wrapper-width: 100% - $page-padding-left - $page-padding-right;
44
+
45
+ // On pages that support split layout (i.e. some kind of
46
+ // embed can be displayed on the right), we have to shorten the page
47
+ // content so that it is contained inside the left column.
48
+ //
49
+ // Embeds use up to 55% of the page width. So we want to ensure that
50
+ // the sum of the content's width and left margin stays below 45% of
51
+ // the page width:
52
+ //
53
+ // $page-content-width-relative-to-page + $page-padding-left = 45%
54
+ // $page-content-width-relative-to-wrapper * $page-content-wrapper-width
55
+ // + $page-padding-left = 45%
56
+ //
57
+ // Subtract 1% to keep a bit of space between text and embed.
58
+ $page-content-split-layout-width: floor((44% - $page-padding-left)
59
+ / ($page-content-wrapper-width / 100%));
60
+
61
+ // When the pixel width of the title is given by
62
+ //
63
+ // $title-width-in-px = $page-width-in-px
64
+ // * ($page-content-wrapper-width / 100%)
65
+ // * ($page-content-split-layout-width / 100%),
66
+ //
67
+ // the title has at least the given min width if the page has width:
68
+ $page-min-width-for-split-layout: $page-header-title-min-width-for-split-layout
69
+ / ($page-content-split-layout-width / 100%)
70
+ / ($page-content-wrapper-width / 100%);
71
+
72
+ @media screen and (min-width: $page-min-width-for-split-layout) {
73
+ &-with_split_layout {
74
+ h2 .subtitle,
75
+ h2 .title,
76
+ h2 .tagline,
77
+ h3,
78
+ p {
79
+ width: $page-content-split-layout-width;
80
+ }
81
+ }
82
+ }
83
+
84
+ &.text_position_right {
85
+ .contentText > * {
86
+ margin-left: auto;
87
+ }
88
+
89
+ h1,
90
+ h2 .subtitle,
91
+ h2 .title,
92
+ h2 .tagline,
93
+ h3,
94
+ p {
95
+ margin-left: auto;
96
+ max-width: $page-content-position-right-max-width;
97
+ width: 60%;
98
+
99
+ @include mobile {
100
+ width: 100%;
101
+ }
102
+ }
103
+
104
+ .page_header {
105
+ margin-left: auto;
106
+ width: 100%;
107
+
108
+ @include mobile {
109
+ width: 100%;
110
+ }
111
+ }
112
+ }
113
+ }
@@ -100,6 +100,7 @@ $page-content-text-font-size: 1.2em !default;
100
100
  $page-content-text-line-height: 1.5em !default;
101
101
 
102
102
  @import "./page/anchors";
103
+ @import "./page/line_lengths";
103
104
 
104
105
  .page {
105
106
  @include typography(
@@ -24,7 +24,21 @@ module Pageflow
24
24
  private
25
25
 
26
26
  def widget_batch_params
27
- params.permit(widgets: [:role, :type_name]).fetch(:widgets, [])
27
+ widget_configurations = params.fetch(:widgets, []).map do |widget_params|
28
+ widget_params[:configuration].try(:permit!)
29
+ end
30
+
31
+ params
32
+ .permit(widgets: [:role, :type_name])
33
+ .fetch(:widgets, [])
34
+ .zip(widget_configurations)
35
+ .map do |(widget_params, widget_configuration)|
36
+ if widget_configuration
37
+ widget_params.merge(configuration: widget_configuration)
38
+ else
39
+ widget_params
40
+ end
41
+ end
28
42
  end
29
43
 
30
44
  def find_subject
@@ -90,7 +90,7 @@ module Pageflow
90
90
  :overview_button_enabled,
91
91
  :emphasize_chapter_beginning, :emphasize_new_pages,
92
92
  :share_url, :share_image_id, :share_image_x, :share_image_y,
93
- :locale, :author, :publisher, :keywords)
93
+ :locale, :author, :publisher, :keywords, :theme_name)
94
94
  end
95
95
 
96
96
  def entry_request_scope
@@ -18,15 +18,6 @@ module Pageflow
18
18
  I18n.t(state, scope: 'activerecord.values.pageflow/entry.publication_states')
19
19
  end
20
20
  end
21
-
22
- def eligible_accounts
23
- AccountPolicy::Scope.new(current_user, Account).entry_movable
24
- end
25
-
26
- def eligible_themings
27
- ThemingPolicy::Scope.new(current_user, Pageflow::Theming)
28
- .themings_allowed_for(resource.account)
29
- end
30
21
  end
31
22
  end
32
23
  end
@@ -1,58 +1,22 @@
1
1
  module Pageflow
2
2
  module Admin
3
3
  module MembershipsHelper
4
- def membership_entries_collection(parent, resource)
5
- if resource.new_record?
6
- if parent.is_a?(User)
7
- accounts = AccountPolicy::Scope.new(current_user, Pageflow::Account)
8
- .entry_creatable
9
- MembershipFormCollection.new(parent,
10
- resource: resource,
11
- collection_method: :entries,
12
- display_method: :title,
13
- order: 'title ASC',
14
- managed_accounts: accounts).collection_for_entries
15
- else
16
- MembershipFormCollection.new(parent,
17
- resource: resource,
18
- collection_method: :entries,
19
- display_method: :title,
20
- order: 'title ASC').pairs
21
- end
4
+ def membership_user_select(f, parent)
5
+ if f.object.persisted?
6
+ membership_disabled_select(f, :user, f.object.user, :formal_name)
7
+ elsif parent.is_a?(User)
8
+ membership_disabled_select(f, :user, parent, :formal_name)
22
9
  else
23
- [[resource.entity.title, resource.entity_id]]
10
+ parent_type = parent.class.model_name.singular_route_key
11
+ membership_select(f, :user, parent, :"potential_users_for_#{parent_type}")
24
12
  end
25
13
  end
26
14
 
27
- def membership_accounts_collection(parent, resource)
28
- if resource.new_record?
29
- if parent.is_a?(User)
30
- accounts = AccountPolicy::Scope
31
- .new(current_user, Account).member_addable.load
32
- MembershipFormCollection.new(parent,
33
- collection_method: :accounts,
34
- display_method: :name,
35
- order: 'name ASC',
36
- managed_accounts: accounts).pairs
37
- else
38
- [[parent.name, parent.id]]
39
- end
15
+ def membership_entity_select(f, parent, entity_type)
16
+ if entity_type == 'Pageflow::Entry'
17
+ membership_entry_select(f, parent)
40
18
  else
41
- [[resource.entity.name, resource.entity_id]]
42
- end
43
- end
44
-
45
- def membership_users_collection(parent, resource)
46
- if resource.new_record?
47
- accounts = AccountPolicy::Scope
48
- .new(current_user, Pageflow::Account).member_addable.load
49
- MembershipFormCollection.new(parent,
50
- collection_method: :users,
51
- display_method: :formal_name,
52
- order: 'last_name ASC, first_name ASC',
53
- managed_accounts: accounts).pairs
54
- else
55
- [[resource.user.formal_name, resource.user.id]]
19
+ membership_account_select(f, parent)
56
20
  end
57
21
  end
58
22
 
@@ -61,6 +25,7 @@ module Pageflow
61
25
  [I18n.t('pageflow.admin.users.roles.editor'), :editor],
62
26
  [I18n.t('pageflow.admin.users.roles.publisher'), :publisher],
63
27
  [I18n.t('pageflow.admin.users.roles.manager'), :manager]]
28
+
64
29
  if entity_type == 'Pageflow::Account'
65
30
  [[I18n.t('pageflow.admin.users.roles.member'), :member]] + default_options
66
31
  else
@@ -68,88 +33,43 @@ module Pageflow
68
33
  end
69
34
  end
70
35
 
71
- class MembershipFormCollection
72
- include ActionView::Helpers::FormOptionsHelper
73
- attr_reader :parent, :options
74
-
75
- def initialize(parent, options)
76
- @parent = parent
77
- @options = options
78
- end
79
-
80
- def pairs
81
- items.each_with_object([]) do |item, result|
82
- result << [display(item), item.id]
83
- end
84
- end
85
-
86
- def collection_for_entries
87
- accounts = options[:managed_accounts]
88
- .where(accounts_ids_in_parent_accounts_ids)
89
- .includes(:entries).where('pageflow_entries.id IS NOT NULL')
90
- .where(entries_ids_not_in_parent_entries_ids)
91
- .order(:name, 'pageflow_entries.title')
92
-
93
- option_groups_from_collection_for_select(accounts, :entries, :name, :id, :title)
94
- end
95
-
96
- private
36
+ private
97
37
 
98
- def items
99
- if parent.is_a?(User)
100
- if options[:collection_method] == :users
101
- [parent]
102
- else
103
- options[:managed_accounts] - items_in_parent
104
- end
105
- elsif parent.is_a?(Entry)
106
- items_in_account - items_in_parent
107
- else
108
- Set.new(options[:managed_accounts].map(&:users).flatten) - items_in_parent
109
- end
110
- end
111
-
112
- def display(item)
113
- item.send(options[:display_method])
114
- end
115
-
116
- def items_in_account
117
- if options[:collection_method] == :users
118
- parent.account.users.order(options[:order])
119
- elsif parent.is_a?(User)
120
- options[:resource].entity.send(options[:collection_method]).order(options[:order])
121
- else
122
- parent.account.send(options[:collection_method]).order(options[:order])
123
- end
124
- end
125
-
126
- def items_in_parent
127
- parent.respond_to?(options[:collection_method]) ? parent.send(options[:collection_method]) : []
38
+ def membership_entry_select(f, parent)
39
+ if f.object.persisted?
40
+ membership_disabled_select(f, :entity, f.object.entity, :title)
41
+ elsif parent.is_a?(Entry)
42
+ membership_disabled_select(f, :entity, parent, :title)
43
+ else
44
+ membership_select(f, :entry, parent, :potential_entries_for_user)
128
45
  end
46
+ end
129
47
 
130
- def accounts_ids_in_parent_accounts_ids
131
- parent_accounts_ids = parent.accounts.map(&:id)
132
- if parent_accounts_ids.any?
133
- sanitize_sql_array(['pageflow_accounts.id IN (:parent_accounts_ids)',
134
- parent_accounts_ids: parent_accounts_ids])
135
- else
136
- 'FALSE'
137
- end
48
+ def membership_account_select(f, parent)
49
+ if f.object.persisted?
50
+ membership_disabled_select(f, :entity, f.object.entity, :name)
51
+ elsif parent.is_a?(Account)
52
+ membership_disabled_select(f, :entity, parent, :name)
53
+ else
54
+ membership_select(f, :entity, parent, :potential_accounts_for_user)
138
55
  end
56
+ end
139
57
 
140
- def entries_ids_not_in_parent_entries_ids
141
- parent_entries_ids = items_in_parent.map(&:id)
142
- if parent_entries_ids.any?
143
- sanitize_sql_array(['pageflow_entries.id NOT IN (:parent_entries_ids)',
144
- parent_entries_ids: parent_entries_ids])
145
- else
146
- 'TRUE'
147
- end
148
- end
58
+ def membership_select(f, name, parent, collection_name)
59
+ f.input(name,
60
+ as: :searchable_select,
61
+ ajax: {resource: Membership,
62
+ collection_name: collection_name,
63
+ params: {parent_id: parent.id}},
64
+ include_blank: false)
65
+ end
149
66
 
150
- def sanitize_sql_array(array)
151
- ActiveRecord::Base.send(:sanitize_sql_array, array)
152
- end
67
+ def membership_disabled_select(f, name, record, text_method)
68
+ f.input(name,
69
+ as: :searchable_select,
70
+ collection: [[record.send(text_method), record.id]],
71
+ include_blank: false,
72
+ input_html: {disabled: true})
153
73
  end
154
74
  end
155
75
  end
@@ -1,6 +1,21 @@
1
1
  module Pageflow
2
2
  module Admin
3
3
  module UsersHelper
4
+ include QuotaHelper
5
+
6
+ def users_quota_state(account)
7
+ quota = Pageflow.config.quotas.get(:users, account)
8
+ data_attributes = {
9
+ account_id: account.id,
10
+ state: quota.state
11
+ }
12
+
13
+ render('pageflow/admin/users/quota_state',
14
+ account: account,
15
+ quota: quota,
16
+ data_attributes: data_attributes)
17
+ end
18
+
4
19
  def collection_for_user_roles
5
20
  User.roles_accessible_by(current_ability).index_by { |role| t(role, :scope => 'pageflow.admin.users.roles') }
6
21
  end
@@ -42,7 +42,9 @@ module Pageflow
42
42
  end
43
43
 
44
44
  def entry_theme_stylesheet_link_tag(entry)
45
- stylesheet_link_tag(entry.theming.theme.stylesheet_path, :media => 'all')
45
+ stylesheet_link_tag(entry.theme.stylesheet_path,
46
+ media: 'all',
47
+ data: {name: 'theme'})
46
48
  end
47
49
 
48
50
  def entry_stylesheet_link_tag(entry)
@@ -12,10 +12,11 @@ module Pageflow
12
12
  end
13
13
 
14
14
  def entry_theming_seed(entry)
15
+ theme = entry.theme
15
16
  {
16
- change_to_parent_page_at_storyline_boundary: entry.theming.theme.change_to_parent_page_at_storyline_boundary?,
17
- page_change_by_scrolling: entry.theming.theme.page_change_by_scrolling?,
18
- hide_text_on_swipe: entry.theming.theme.hide_text_on_swipe?
17
+ change_to_parent_page_at_storyline_boundary: theme.change_to_parent_page_at_storyline_boundary?,
18
+ page_change_by_scrolling: theme.page_change_by_scrolling?,
19
+ hide_text_on_swipe: theme.hide_text_on_swipe?
19
20
  }
20
21
  end
21
22
 
@@ -34,6 +35,11 @@ module Pageflow
34
35
  entry.pages.as_json(only: attributes)
35
36
  end
36
37
 
38
+ def entry_widgets_seed(entry)
39
+ attributes = [:type_name, :role, :configuration]
40
+ entry.resolve_widgets.as_json(only: attributes)
41
+ end
42
+
37
43
  def entry_file_ids_seed(entry)
38
44
  Pageflow.config.file_types.with_thumbnail_support.each_with_object({}) do |file_type, result|
39
45
  result[file_type.collection_name] = entry.find_files(file_type.model).map(&:id)
@@ -9,9 +9,9 @@ module Pageflow
9
9
  def public_i18n_translations(entry)
10
10
  {
11
11
  pageflow: {
12
- public: I18n.t('pageflow.public', locale: entry.locale)
12
+ public: I18n.t('pageflow.public', locale: I18n.default_locale)
13
13
  .dup
14
- .deep_merge(I18n.t('pageflow.public', locale: I18n.default_locale))
14
+ .deep_merge(I18n.t('pageflow.public', locale: entry.locale))
15
15
  }
16
16
  }
17
17
  end
@@ -1,10 +1,10 @@
1
1
  module Pageflow
2
2
  module QuotaHelper
3
3
  def quota_state_description(name, account)
4
- description = Pageflow.config.quotas.get(:users, account).state_description
4
+ description = Pageflow.config.quotas.get(name, account).state_description
5
5
 
6
6
  if description
7
- content_tag(:p, description, :class => 'quota_state')
7
+ content_tag(:p, description, class: 'quota_state_description')
8
8
  end
9
9
  end
10
10
  end
@@ -53,9 +53,10 @@ module Pageflow
53
53
 
54
54
  def social_share_entry_image_tags(entry)
55
55
  image_urls = []
56
+ image_file = ImageFile.find_by_id(entry.share_image_id)
56
57
 
57
- if entry.share_image_id.present?
58
- image_urls << ImageFile.find(entry.share_image_id).thumbnail_url(:medium)
58
+ if image_file
59
+ image_urls << image_file.thumbnail_url(:medium)
59
60
  else
60
61
  entry.pages.each do |page|
61
62
  if image_urls.size >= 4
@@ -1,9 +1,17 @@
1
1
  module Pageflow
2
2
  module ThemesHelper
3
- def themes_options_json_seed
4
- Pageflow.config.themes.each_with_object({}) do |theme, options|
3
+ include RenderJsonHelper
4
+
5
+ def themes_options_json_seed(config = Pageflow.config)
6
+ config.themes.each_with_object({}) { |theme, options|
5
7
  options[theme.name] = theme.options
6
- end.to_json.html_safe
8
+ }.to_json.html_safe
9
+ end
10
+
11
+ def theme_json_seeds(config)
12
+ render_json_partial('pageflow/themes/theme',
13
+ collection: config.themes,
14
+ as: :theme)
7
15
  end
8
16
  end
9
17
  end
@@ -1,8 +1,12 @@
1
1
  module Pageflow
2
2
  module WidgetsHelper
3
+ include RenderJsonHelper
4
+
3
5
  def render_widget_head_fragments(entry, options = {})
4
6
  fragments = entry.resolve_widgets(options).map do |widget|
5
- widget.widget_type.render_head_fragment(self, entry)
7
+ widget.widget_type.render_head_fragment_with_configuration(self,
8
+ entry,
9
+ widget.configuration)
6
10
  end
7
11
 
8
12
  safe_join(fragments)
@@ -10,7 +14,7 @@ module Pageflow
10
14
 
11
15
  def render_widgets(entry, options = {})
12
16
  fragments = entry.resolve_widgets(options).map do |widget|
13
- widget.widget_type.render(self, entry)
17
+ widget.widget_type.render_with_configuration(self, entry, widget.configuration)
14
18
  end
15
19
 
16
20
  safe_join(fragments)
@@ -33,5 +37,9 @@ module Pageflow
33
37
  end
34
38
  end.to_json.html_safe
35
39
  end
40
+
41
+ def widgets_json_seeds(entry)
42
+ render_json_seed(entry.resolve_widgets(include_placeholders: true))
43
+ end
36
44
  end
37
45
  end
@@ -0,0 +1,9 @@
1
+ module Pageflow
2
+ class PruneAutoSnapshotsJob
3
+ @queue = :prune
4
+
5
+ def self.perform(entry_id, options)
6
+ AutoSnapshotPruning.prune(Entry.find(entry_id), options.symbolize_keys)
7
+ end
8
+ end
9
+ end