Skip to content

Commit 9b1d2d1

Browse files
authored
Merge pull request #2504 from tf/fragments
Fragments
2 parents be946bd + 756b6cb commit 9b1d2d1

82 files changed

Lines changed: 4924 additions & 298 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎app/assets/stylesheets/pageflow/editor/files_explorer.scss‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@
171171
border-left-color: var(--ui-on-surface-color-lightest);
172172
border-top-left-radius: 0;
173173
border-bottom-left-radius: 0;
174-
background-color: #{mix(#06202a, #fff, 3%)};
174+
background-color: var(--ui-secondary-surface-color);
175175
overflow: auto;
176176
}
177177

‎app/assets/stylesheets/pageflow/ui/properties.scss‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
--ui-font-size: 13px;
1616

1717
--ui-surface-color: #fff;
18+
--ui-secondary-surface-color: #{mix(#06202a, #fff, 3%)};
1819
--ui-backdrop-color: rgba(6, 32, 42, 0.6);
1920

2021
--ui-on-surface-color: hsl(197, 26%, 23%);
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
class AddFragmentLibraryToEntries < ActiveRecord::Migration[7.1]
2+
def change
3+
add_column :pageflow_entries, :fragment_library, :string
4+
end
5+
end
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
module PageflowScrolled
2+
module Editor
3+
# @api private
4+
class FragmentExtractionsController < ActionController::Base
5+
include Pageflow::EditorController
6+
7+
before_action do
8+
head :not_found unless @entry.feature_state('fragments')
9+
end
10+
11+
def create
12+
chapter = Chapter.all_for_revision(@entry.draft).find(params[:chapter_id])
13+
library = FragmentLibrary.shared_for_account(@entry.account)
14+
15+
authorize!(:update, library)
16+
library.extract_fragment_from(entry: @entry, chapter:, title: params[:title])
17+
18+
head :created
19+
rescue ActiveRecord::RecordNotFound
20+
head :not_found
21+
end
22+
end
23+
end
24+
end
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
module PageflowScrolled
2+
module Editor
3+
# @api private
4+
class FragmentInsertionsController < ActionController::Base
5+
include Pageflow::EditorController
6+
7+
before_action do
8+
head :not_found unless @entry.feature_state('fragments')
9+
end
10+
11+
def create
12+
chapter = Chapter.all_for_revision(@entry.draft).find(params[:chapter_id])
13+
14+
@sections = authorized_scope(:read, FragmentLibrary)
15+
.find(fragment_params[:entry_id])
16+
.copy_fragment_to(fragment_perma_id: fragment_params[:chapter_perma_id],
17+
entry: @entry,
18+
chapter:)
19+
20+
render :create, status: :created
21+
rescue ActiveRecord::RecordNotFound
22+
head :not_found
23+
end
24+
25+
private
26+
27+
def fragment_params
28+
params.require(:fragment).permit(:entry_id, :chapter_perma_id)
29+
end
30+
end
31+
end
32+
end
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
module PageflowScrolled
2+
module Editor
3+
# @api private
4+
class FragmentLibrariesController < ActionController::Base
5+
include Pageflow::EditorController
6+
7+
helper Pageflow::FilesHelper
8+
9+
before_action do
10+
head :not_found unless @entry.feature_state('fragments')
11+
end
12+
13+
def index
14+
@libraries = authorized_scope(:read, FragmentLibrary.where(account: @entry.account))
15+
end
16+
end
17+
end
18+
end

‎entry_types/scrolled/app/helpers/pageflow_scrolled/editor/seed_html_helper.rb‎

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,27 +14,47 @@ module SeedHtmlHelper
1414
include WebpackPublicPathHelper
1515

1616
def scrolled_editor_iframe_seed_html_script_tag(entry)
17-
html = render(template: 'pageflow_scrolled/entries/show',
18-
locals: {
19-
entry:,
20-
entry_mode: :editor,
21-
skip_ssr: true,
22-
skip_structured_data: true,
23-
skip_feed_link_tags: true,
24-
skip_hreflang_link_tags: true,
25-
seed_options: {
26-
skip_collections: true,
27-
include_unused_additional_seed_data: true,
28-
include_unused_file_reference_locations: true,
29-
include_theme_translations: true,
30-
load_inline_editing: true
31-
}
32-
})
17+
seed_html_script_tag(entry, template: 'iframe_seed', load_inline_editing: true)
18+
end
19+
20+
def scrolled_editor_fragment_preview_seed_html_script_tag(entry)
21+
seed_html_script_tag(entry,
22+
template: 'fragment_preview_seed',
23+
accept_collection_resets: true)
24+
end
25+
26+
private
3327

28+
def seed_html_script_tag(entry, template:, **seed_options)
3429
content_tag(:script,
35-
html.gsub('</', '<\/').html_safe,
30+
seed_html(entry, **seed_options).gsub('</', '<\/').html_safe,
3631
type: 'text/html',
37-
data: {template: 'iframe_seed'})
32+
data: {template:})
33+
end
34+
35+
def seed_html(entry, **seed_options)
36+
separate_view.render(template: 'pageflow_scrolled/entries/show',
37+
locals: {
38+
entry:,
39+
entry_mode: :editor,
40+
skip_ssr: true,
41+
skip_structured_data: true,
42+
skip_feed_link_tags: true,
43+
skip_hreflang_link_tags: true,
44+
seed_options: {
45+
skip_collections: true,
46+
include_unused_additional_seed_data: true,
47+
include_unused_file_reference_locations: true,
48+
include_theme_translations: true,
49+
**seed_options
50+
}
51+
})
52+
end
53+
54+
# Shakapacker allows a single pack tag per view and collects the
55+
# packs of all documents rendered by it.
56+
def separate_view
57+
self.class.new(lookup_context, assigns, controller).extend(SeedHtmlHelper)
3858
end
3959
end
4060
end
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
module PageflowScrolled
2+
# @api private
3+
class FragmentLibrary
4+
attr_reader :entry, :account
5+
6+
delegate :id, to: :entry
7+
8+
def self.all
9+
Query.new(Pageflow::Entry.where(fragment_library: 'shared'))
10+
end
11+
12+
def self.where(...)
13+
all.where(...)
14+
end
15+
16+
def self.shared_for_account(account)
17+
entry = Pageflow::Entry
18+
.where(account:, type_name: 'scrolled', fragment_library: 'shared')
19+
.order(:id)
20+
.first
21+
22+
new(entry && Pageflow::DraftEntry.new(entry), account:)
23+
end
24+
25+
def initialize(entry, account: entry.account)
26+
@entry = entry
27+
@account = account
28+
end
29+
30+
def persisted?
31+
entry.present?
32+
end
33+
34+
def title
35+
entry.entry_title
36+
end
37+
38+
def storylines
39+
Storyline.all_for_revision(entry.draft)
40+
end
41+
42+
def chapters
43+
Chapter.all_for_revision(entry.draft)
44+
end
45+
46+
def sections
47+
Section.all_for_revision(entry.draft)
48+
end
49+
50+
def content_elements
51+
ContentElement.all_for_revision(entry.draft)
52+
end
53+
54+
def copy_fragment_to(fragment_perma_id:, entry:, chapter:)
55+
SectionsCopy
56+
.new(source_entry: self.entry, destination_entry: entry)
57+
.perform(chapters.find_by!(perma_id: fragment_perma_id).sections, chapter:)
58+
end
59+
60+
def extract_fragment_from(entry:, chapter:, title: nil)
61+
ActiveRecord::Base.transaction do
62+
@entry ||= create_entry(locale: entry.locale)
63+
64+
SectionsCopy
65+
.new(source_entry: entry, destination_entry: self.entry)
66+
.perform(chapter.sections, chapter: create_fragment_chapter(chapter, title))
67+
end
68+
end
69+
70+
private
71+
72+
def create_entry(locale:)
73+
Pageflow::DraftEntry.new(
74+
Pageflow::Entry.create!(
75+
account:,
76+
site: account.default_site,
77+
type_name: 'scrolled',
78+
fragment_library: 'shared',
79+
title: I18n.t('pageflow_scrolled.fragment_library.title',
80+
account_name: account.name,
81+
locale: locale == 'de' ? :de : :en)
82+
)
83+
)
84+
end
85+
86+
def create_fragment_chapter(chapter, title)
87+
storyline = storylines.detect { |candidate| candidate.configuration['main'] }
88+
89+
storyline.chapters.create!(position: (storyline.chapters.maximum(:position) || -1) + 1,
90+
configuration: fragment_configuration(chapter, title))
91+
end
92+
93+
def fragment_configuration(chapter, title)
94+
title = title.presence&.strip
95+
title ? chapter.configuration.merge('title' => title) : chapter.configuration
96+
end
97+
98+
# @api private
99+
class Query
100+
include Enumerable
101+
102+
def initialize(entries)
103+
@entries = entries
104+
end
105+
106+
def model
107+
FragmentLibrary
108+
end
109+
110+
def all
111+
self
112+
end
113+
114+
def none
115+
Query.new(@entries.none)
116+
end
117+
118+
def where(...)
119+
Query.new(@entries.where(...))
120+
end
121+
122+
def merge(entries)
123+
Query.new(@entries.merge(entries))
124+
end
125+
126+
def find(id)
127+
library(@entries.find(id))
128+
end
129+
130+
def each(&)
131+
@entries.order(:id).map { |entry| library(entry) }.each(&)
132+
end
133+
134+
private
135+
136+
def library(entry)
137+
FragmentLibrary.new(Pageflow::DraftEntry.new(entry))
138+
end
139+
end
140+
end
141+
end
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
module PageflowScrolled
2+
# @api private
3+
class FragmentLibraryPolicy
4+
# @api private
5+
class Scope
6+
def initialize(user, scope)
7+
@user = user
8+
@scope = scope
9+
end
10+
11+
def read
12+
return @scope if @user.admin?
13+
14+
@scope.merge(
15+
Pageflow::EntryRoleQuery::Scope.new(@user, Pageflow::Entry).with_role_at_least(:previewer)
16+
)
17+
end
18+
end
19+
20+
def initialize(user, library)
21+
@user = user
22+
@library = library
23+
end
24+
25+
def read?
26+
@user.admin? || entry_role_query.has_at_least_role?(:previewer)
27+
end
28+
29+
def update?
30+
return true if @user.admin?
31+
32+
if @library.persisted?
33+
entry_role_query.has_at_least_role?(:editor)
34+
else
35+
Pageflow::AccountRoleQuery.new(@user, @library.account).has_at_least_role?(:editor)
36+
end
37+
end
38+
39+
private
40+
41+
def entry_role_query
42+
Pageflow::EntryRoleQuery.new(@user, @library.entry)
43+
end
44+
end
45+
end
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
<%= scrolled_editor_iframe_seed_html_script_tag(entry) %>
2+
<%= scrolled_editor_fragment_preview_seed_html_script_tag(entry) %>

0 commit comments

Comments
 (0)