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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8a26feddb5cd80b4e5a676159463899d2aa3f8956e0a9e3a2a7cfdc2a9645a61
4
- data.tar.gz: 118357d59feb0e62eeb1aa9c04a327fc59ee13683e7878023990ec0388542939
3
+ metadata.gz: 52e6e9b60483ae6bcec206e22e688d5b246fb3c30bac941df3658c26c8c386db
4
+ data.tar.gz: ae992048e518aae337f6df23ec7a9c4ffd04f7d76e98f0a8c1a389636d99f78d
5
5
  SHA512:
6
- metadata.gz: 9aee570200cb37d2bf6be9c90dec6202087b85c4cefe4a448607df0b26f274f162f5c73a85a456659404b4508541d6e6fe53da3c227877bcde74acaaa75baafe
7
- data.tar.gz: b1413f0fc7236cbfcc7769ba870726b4e79addd6d786705e1eaf5b10e6feb6f602d05a4ad5b68238b0bf67ac2a3aee9a83b24b260fa7a213d41569f3d767bc17
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.create!(params.require(:page).permit(:name, :slug, :place).merge(owner: page_owner))
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]).archive
53
- redirect_to manage_pages_path
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]).restore
58
- redirect_to manage_pages_path
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
- <label class="ks-label mb-1">Address</label>
9
- <%= ui_input(name: "page[slug]", placeholder: "e.g. pricing") %>
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
- <% if KeystoneUi::Pages.places.any? %>
12
- <label class="ks-label mb-1">Place</label>
13
- <%= ui_select(name: "page[place]", options: KeystoneUi::Pages.places.invert.to_a) %>
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" })
@@ -2,6 +2,6 @@
2
2
 
3
3
  module KeystoneUi
4
4
  module Pages
5
- VERSION = "0.5.0"
5
+ VERSION = "0.7.0"
6
6
  end
7
7
  end
@@ -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 live version and values return the record already
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
- - `KeystoneUi::Pages.prepare_pdf(page, values: {})` — queues
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 values, so the file is kept before anyone asks for it.
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 `version:`
280
- shows an earlier published version, never the draft.
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.
@@ -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
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: keystone_ui-pages
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tyler Schneider