1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# frozen_string_literal: true
require "phlex"
module RankKing
module Views
module Sources
# The Text source's fields on the new-list form.
class TextFields < Phlex::HTML
def view_template
label(class: "field") do
plain "Items"
textarea(name: "items", rows: 6, required: true)
small { "One per line, at least two." }
end
end
end
# A typed item is its name.
class TextItem < Phlex::HTML
def initialize(item:)
@item = item
end
def view_template = plain(@item.name)
end
# The Text source's sync dialog: every item's name, editable in place,
# and a box for new ones. It fills a <dialog> as Gloss lays one out:
# header, body, footer, so the form is the body and the footer's
# Save reaches it by id.
class Text < Phlex::HTML
def initialize(list:, csrf:)
@list = list
@csrf = csrf
end
def view_template
action = "/lists/#{@list.id}/sync"
header { "Edit items" }
form(id: "sync-form", method: "post", action:) do
input(type: "hidden", name: "_csrf", value: @csrf.call(action))
p { "Clear a name to remove that item." }
@list.items_dataset.order(:id).each do |item|
input(type: "text", name: "items[#{item.id}]", value: item.name, aria_label: "Item name")
end
label(class: "field") do
plain "Add items"
textarea(name: "new_items", rows: 3)
small { "One per line." }
end
end
footer do
button(type: "button", commandfor: "sync-dialog", command: "close") { "Cancel" }
button(type: "submit", form: "sync-form", data_variant: "primary") { "Save" }
end
end
end
end
end
end