keystone_ui-pages 0.5.0 → 0.7.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.
- checksums.yaml +4 -4
- data/app/controllers/keystone_ui/pages/manage/pages_controller.rb +17 -6
- data/app/helpers/keystone_ui/pages/editor_helper.rb +1 -1
- data/app/jobs/keystone_ui/pages/pdf_job.rb +2 -2
- data/app/models/keystone_ui/pages/page.rb +12 -0
- data/app/views/keystone_ui/pages/manage/pages/index.html.erb +3 -3
- data/app/views/keystone_ui/pages/manage/pages/new.html.erb +9 -5
- data/lib/keystone_ui/pages/pdfs.rb +2 -2
- data/lib/keystone_ui/pages/version.rb +1 -1
- data/lib/keystone_ui/pages.rb +9 -5
- data/the_local/agents/keystone_ui-pages-develop.md +26 -7
- data/the_local/interface.yml +1 -0
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 52e6e9b60483ae6bcec206e22e688d5b246fb3c30bac941df3658c26c8c386db
|
|
4
|
+
data.tar.gz: ae992048e518aae337f6df23ec7a9c4ffd04f7d76e98f0a8c1a389636d99f78d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7f7dcf0832adca48663675600fa5a2d05aa5f6a6b1e4e4d8c133cf4f9c9cf7bd951fb9244e4fc1824819711733bbd1dfdc03962f239cc60479407ae9ca2754c1
|
|
7
|
+
data.tar.gz: bb06bbe0e3e0c2cc7a9876343ab7458ccec329019218c9669f266d06eb2438bff3d8b8ecc95199ff1961775718c8b4178ad5aa47c64966d19bb9843f067eaafc
|
|
@@ -8,15 +8,20 @@ module KeystoneUi
|
|
|
8
8
|
class PagesController < BaseController
|
|
9
9
|
def index
|
|
10
10
|
@archived = params[:archived].present?
|
|
11
|
+
@place = chosen_place
|
|
11
12
|
@pages = owned_pages.public_send(@archived ? :archived : :current).order(:name)
|
|
13
|
+
@pages = @pages.where(place: @place) if @place
|
|
12
14
|
@printable = Printer.chrome.present?
|
|
13
15
|
end
|
|
14
16
|
|
|
15
17
|
def new
|
|
18
|
+
@place = chosen_place
|
|
16
19
|
end
|
|
17
20
|
|
|
18
21
|
def create
|
|
19
|
-
page = Page.
|
|
22
|
+
page = Page.new(params.require(:page).permit(:name, :slug, :place).merge(owner: page_owner))
|
|
23
|
+
return render(:new, status: :unprocessable_entity) unless page.save
|
|
24
|
+
|
|
20
25
|
redirect_to manage_page_path(page)
|
|
21
26
|
end
|
|
22
27
|
|
|
@@ -33,7 +38,7 @@ module KeystoneUi
|
|
|
33
38
|
@page = owned_pages.find(params[:id])
|
|
34
39
|
return render(:edit, status: :unprocessable_entity) unless @page.update(params.require(:page).permit(:name, :slug, :place))
|
|
35
40
|
|
|
36
|
-
redirect_to manage_pages_path
|
|
41
|
+
redirect_to manage_pages_path(place: @page.place)
|
|
37
42
|
end
|
|
38
43
|
|
|
39
44
|
def publish
|
|
@@ -49,17 +54,23 @@ module KeystoneUi
|
|
|
49
54
|
end
|
|
50
55
|
|
|
51
56
|
def archive
|
|
52
|
-
owned_pages.find(params[:id])
|
|
53
|
-
|
|
57
|
+
page = owned_pages.find(params[:id])
|
|
58
|
+
page.archive
|
|
59
|
+
redirect_to manage_pages_path(place: page.place)
|
|
54
60
|
end
|
|
55
61
|
|
|
56
62
|
def restore
|
|
57
|
-
owned_pages.find(params[:id])
|
|
58
|
-
|
|
63
|
+
page = owned_pages.find(params[:id])
|
|
64
|
+
page.restore
|
|
65
|
+
redirect_to manage_pages_path(place: page.place)
|
|
59
66
|
end
|
|
60
67
|
|
|
61
68
|
private
|
|
62
69
|
|
|
70
|
+
def chosen_place
|
|
71
|
+
params[:place] if KeystoneUi::Pages.places.key?(params[:place])
|
|
72
|
+
end
|
|
73
|
+
|
|
63
74
|
def local_address?(address)
|
|
64
75
|
address.to_s.match?(%r{\A/(?![/\\])})
|
|
65
76
|
end
|
|
@@ -32,7 +32,7 @@ module KeystoneUi
|
|
|
32
32
|
redo_url: manage_page_redo_path(page),
|
|
33
33
|
undoable: page.undo_history.any?,
|
|
34
34
|
redoable: page.undone_changes.any?,
|
|
35
|
-
back_url: session.dig(:keystone_ui_pages_return_to, page.id.to_s) || manage_pages_path,
|
|
35
|
+
back_url: session.dig(:keystone_ui_pages_return_to, page.id.to_s) || manage_pages_path(place: page.place),
|
|
36
36
|
live_url: (manage_page_live_path(page) if page.live_version),
|
|
37
37
|
token: form_authenticity_token
|
|
38
38
|
}
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
module KeystoneUi
|
|
4
4
|
module Pages
|
|
5
5
|
class PdfJob < ActiveJob::Base
|
|
6
|
-
def perform(page, values)
|
|
7
|
-
KeystoneUi::Pages.pdf(page, values: values)
|
|
6
|
+
def perform(page, values, version = nil)
|
|
7
|
+
KeystoneUi::Pages.pdf(page, values: values, version: version)
|
|
8
8
|
end
|
|
9
9
|
end
|
|
10
10
|
end
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "securerandom"
|
|
3
4
|
require "keystone_ui/pages/document"
|
|
4
5
|
|
|
5
6
|
module KeystoneUi
|
|
@@ -17,6 +18,11 @@ module KeystoneUi
|
|
|
17
18
|
scope :archived, -> { where.not(archived_at: nil) }
|
|
18
19
|
scope :current, -> { where(archived_at: nil) }
|
|
19
20
|
|
|
21
|
+
before_validation(on: :create) do
|
|
22
|
+
self.name = default_name if name.blank?
|
|
23
|
+
self.slug = SecureRandom.hex(4) if slug.blank?
|
|
24
|
+
end
|
|
25
|
+
|
|
20
26
|
validates :name, :slug, presence: true
|
|
21
27
|
validates :slug, uniqueness: { scope: %i[owner_type owner_id] }
|
|
22
28
|
validates :place, inclusion: { in: -> { KeystoneUi::Pages.places.keys } }, allow_nil: true, if: -> { KeystoneUi::Pages.places.any? }
|
|
@@ -81,6 +87,12 @@ module KeystoneUi
|
|
|
81
87
|
def next_number
|
|
82
88
|
(versions.maximum(:number) || 0) + 1
|
|
83
89
|
end
|
|
90
|
+
|
|
91
|
+
def default_name
|
|
92
|
+
word = KeystoneUi::Pages.default_names.fetch(place, "Page")
|
|
93
|
+
used = Page.where(owner: owner, place: place).pluck(:name).filter_map { |taken| taken[/\A#{Regexp.escape(word)} (\d+)\z/, 1]&.to_i }
|
|
94
|
+
"#{word} #{(used.max || 0) + 1}"
|
|
95
|
+
end
|
|
84
96
|
end
|
|
85
97
|
end
|
|
86
98
|
end
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
<%= ui_page(max_width: :xl) do %>
|
|
2
|
-
<%= ui_page_header(title: @archived ? "Archived pages" : "Pages", action_url: (new_manage_page_path unless @archived), action_label: "Create") do |header| %>
|
|
3
|
-
<% header.action { ui_button(label: "Create", href: new_manage_page_path) } unless @archived %>
|
|
2
|
+
<%= ui_page_header(title: @archived ? "Archived pages" : "Pages", action_url: (new_manage_page_path(place: @place) unless @archived), action_label: "Create") do |header| %>
|
|
3
|
+
<% header.action { ui_button(label: "Create", href: new_manage_page_path(place: @place)) } unless @archived %>
|
|
4
4
|
<% end %>
|
|
5
5
|
|
|
6
6
|
<p class="mb-4 text-sm">
|
|
7
|
-
<%= @archived ? link_to("Show current pages", manage_pages_path) : link_to("Show archived", manage_pages_path(archived: 1)) %>
|
|
7
|
+
<%= @archived ? link_to("Show current pages", manage_pages_path(place: @place)) : link_to("Show archived", manage_pages_path(archived: 1, place: @place)) %>
|
|
8
8
|
</p>
|
|
9
9
|
|
|
10
10
|
<div class="ks-table overflow-x-auto">
|
|
@@ -2,15 +2,19 @@
|
|
|
2
2
|
<%= ui_page_header(title: "New page") %>
|
|
3
3
|
|
|
4
4
|
<%= ui_form(action: manage_pages_path, method: :post) do %>
|
|
5
|
+
<%= hidden_field_tag "page[place]", @place if @place %>
|
|
6
|
+
|
|
5
7
|
<label class="ks-label mb-1">Name</label>
|
|
6
8
|
<%= ui_input(name: "page[name]", placeholder: "e.g. Pricing") %>
|
|
7
9
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
+
<% unless @place %>
|
|
11
|
+
<label class="ks-label mb-1">Address</label>
|
|
12
|
+
<%= ui_input(name: "page[slug]", placeholder: "e.g. pricing") %>
|
|
10
13
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
+
<% if KeystoneUi::Pages.places.any? %>
|
|
15
|
+
<label class="ks-label mb-1">Place</label>
|
|
16
|
+
<%= ui_select(name: "page[place]", options: KeystoneUi::Pages.places.invert.to_a) %>
|
|
17
|
+
<% end %>
|
|
14
18
|
<% end %>
|
|
15
19
|
|
|
16
20
|
<%= ui_button(label: "Create", type: :submit) %>
|
|
@@ -9,8 +9,8 @@ module KeystoneUi
|
|
|
9
9
|
module Pdfs
|
|
10
10
|
module_function
|
|
11
11
|
|
|
12
|
-
def for(page, values: {})
|
|
13
|
-
version = page.versions.live.first
|
|
12
|
+
def for(page, values: {}, version: nil)
|
|
13
|
+
version = version ? page.versions.find_by(number: version) : page.versions.live.first
|
|
14
14
|
digest = Operations.digest(values.to_h.stringify_keys)
|
|
15
15
|
Pdf.find_by(version: version, values_digest: digest) || Pdf.create!(version: version, values_digest: digest,
|
|
16
16
|
file: { io: StringIO.new(Printer.pdf(PdfDocument.html(version, values: values))), filename: "#{page.slug}.pdf", content_type: "application/pdf" })
|
data/lib/keystone_ui/pages.rb
CHANGED
|
@@ -9,7 +9,7 @@ require "keystone_ui/pages/engine"
|
|
|
9
9
|
module KeystoneUi
|
|
10
10
|
module Pages
|
|
11
11
|
class << self
|
|
12
|
-
attr_writer :base_controller, :layout, :editor_layout, :pdf_stylesheet, :places, :access_exceptions
|
|
12
|
+
attr_writer :base_controller, :layout, :editor_layout, :pdf_stylesheet, :places, :access_exceptions, :default_names
|
|
13
13
|
attr_accessor :edit_check_method, :view_check_method, :values_method, :owner_method, :refusal_method, :chrome_path
|
|
14
14
|
|
|
15
15
|
def base_controller
|
|
@@ -35,15 +35,19 @@ module KeystoneUi
|
|
|
35
35
|
def access_exceptions
|
|
36
36
|
@access_exceptions || {}
|
|
37
37
|
end
|
|
38
|
+
|
|
39
|
+
def default_names
|
|
40
|
+
@default_names || {}
|
|
41
|
+
end
|
|
38
42
|
end
|
|
39
43
|
|
|
40
|
-
def self.pdf(page, values: {})
|
|
44
|
+
def self.pdf(page, values: {}, version: nil)
|
|
41
45
|
require "keystone_ui/pages/pdfs"
|
|
42
|
-
Pdfs.for(page, values: values)
|
|
46
|
+
Pdfs.for(page, values: values, version: version)
|
|
43
47
|
end
|
|
44
48
|
|
|
45
|
-
def self.prepare_pdf(page, values: {})
|
|
46
|
-
PdfJob.perform_later(page, values.to_h.stringify_keys)
|
|
49
|
+
def self.prepare_pdf(page, values: {}, version: nil)
|
|
50
|
+
PdfJob.perform_later(page, values.to_h.stringify_keys, version)
|
|
47
51
|
end
|
|
48
52
|
|
|
49
53
|
def self.catalog
|
|
@@ -51,6 +51,11 @@ inherit from the base controller, so define it there.
|
|
|
51
51
|
When it is not empty, the New page form offers them, a page with a place not
|
|
52
52
|
in it is refused, and the page list shows each page's place. The view check
|
|
53
53
|
reads it as `page.place`. Unset, pages have no place.
|
|
54
|
+
- `KeystoneUi::Pages.default_names = { "client_report" => "Report template" }`
|
|
55
|
+
— the word a page created with no name starts with, per place. The page is
|
|
56
|
+
named with the word and the next number among that owner's pages in that
|
|
57
|
+
place, so "Report template 1", then "Report template 2". A place with no word,
|
|
58
|
+
and a page with no place, use "Page".
|
|
54
59
|
- `KeystoneUi::Pages.access_exceptions = { "public_preview" => "Public preview" }`
|
|
55
60
|
— a hash of the exceptions an editor can set on a page, each stored value to
|
|
56
61
|
its label. When it is not empty, the builder's top bar has an Access exception
|
|
@@ -120,15 +125,17 @@ inherit from the base controller, so define it there.
|
|
|
120
125
|
unpublished or archived. It returns nil when the page has no version with
|
|
121
126
|
that number. A record made from a page keeps the number it was made with
|
|
122
127
|
and passes it here, so it keeps drawing the same way after later publishes.
|
|
123
|
-
- `KeystoneUi::Pages.pdf(page, values: {})` — returns a
|
|
128
|
+
- `KeystoneUi::Pages.pdf(page, values: {}, version: nil)` — returns a
|
|
124
129
|
`KeystoneUi::Pages::Pdf` record for the page's live version drawn with the
|
|
125
130
|
values given. Its `file` is an Active Storage attachment, ready to download,
|
|
126
|
-
link or email. The same
|
|
131
|
+
link or email. The same version and values return the record already
|
|
127
132
|
kept, and a newly published version or different values print a new one.
|
|
128
|
-
When nothing is kept it prints in the current request.
|
|
129
|
-
|
|
133
|
+
When nothing is kept it prints in the current request. `version:` takes a
|
|
134
|
+
published version's number and prints that version instead, live or
|
|
135
|
+
superseded, the same way `keystone_ui_page` draws it.
|
|
136
|
+
- `KeystoneUi::Pages.prepare_pdf(page, values: {}, version: nil)` — queues
|
|
130
137
|
`KeystoneUi::Pages::PdfJob`, which calls `KeystoneUi::Pages.pdf` with the same
|
|
131
|
-
page and
|
|
138
|
+
page, values and version, so the file is kept before anyone asks for it.
|
|
132
139
|
|
|
133
140
|
### The builder and the editor's screens
|
|
134
141
|
|
|
@@ -276,8 +283,8 @@ The catalog offers these Keystone UI components by default: `button`,
|
|
|
276
283
|
layout and print rules together.
|
|
277
284
|
- **Only the live version leaves the builder.** The draft is what editors
|
|
278
285
|
change. Visitors, `keystone_ui_page` and PDFs show the live version, so an
|
|
279
|
-
unpublished change shows nowhere else. `keystone_ui_page` with
|
|
280
|
-
|
|
286
|
+
unpublished change shows nowhere else. `keystone_ui_page` and PDFs with
|
|
287
|
+
`version:` show an earlier published version, never the draft.
|
|
281
288
|
- **Value names are strings.** `Values.names`, the provider's hash and the
|
|
282
289
|
`values:` passed to the helper and to PDFs all use the same names. The gem
|
|
283
290
|
turns symbol keys into strings, so either works, but the names must match.
|
|
@@ -310,6 +317,18 @@ The catalog offers these Keystone UI components by default: `button`,
|
|
|
310
317
|
from `--ks-spacing`. The page builder has no setting of its own for these:
|
|
311
318
|
a host changes them through its keystone_ui theme values. A section saved
|
|
312
319
|
without either draws as it did before.
|
|
320
|
+
- **A place's page list** at `/pages/manage/pages?place=client_report` shows
|
|
321
|
+
only that place's pages, and its Create and archived links keep the place.
|
|
322
|
+
With no place, or one the host does not name, the list shows every page. For
|
|
323
|
+
a page with a place, the redirects after saving settings, archiving and
|
|
324
|
+
restoring go to that place's list, and so does the builder's Back link unless
|
|
325
|
+
the host passed its own `return_to`.
|
|
326
|
+
- **The New page form** at `/pages/manage/pages/new` saves a blank name from
|
|
327
|
+
`default_names` and a blank slug as eight random hex characters. A host
|
|
328
|
+
linking to it with `new_manage_page_path(place: "client_report")` creates the
|
|
329
|
+
page in that place, and the form then asks for a name only. A place the host
|
|
330
|
+
does not name in the link is ignored, and one posted to create is refused
|
|
331
|
+
with the form shown again.
|
|
313
332
|
- **A page's settings** at `/pages/manage/pages/:id/edit` change its name, slug
|
|
314
333
|
and place after it is created. A slug another page of the same owner uses, or
|
|
315
334
|
a place the host does not name, is refused with a message and changes nothing.
|
data/the_local/interface.yml
CHANGED
|
@@ -11,6 +11,7 @@ develop:
|
|
|
11
11
|
- KeystoneUi::Pages.view_check_method
|
|
12
12
|
- KeystoneUi::Pages.places
|
|
13
13
|
- KeystoneUi::Pages.access_exceptions
|
|
14
|
+
- KeystoneUi::Pages.default_names
|
|
14
15
|
- KeystoneUi::Pages.values_method
|
|
15
16
|
- KeystoneUi::Pages.edit_check_method
|
|
16
17
|
- KeystoneUi::Pages.refusal_method
|