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