katalyst-koi 4.5.0.beta.2 → 4.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -5,46 +5,208 @@ module Koi
5
5
  # Custom header row component, in order to override the default header cell component
6
6
  # for number columns, we add a class to the header cell to allow for custom styling
7
7
  class HeaderRowComponent < Katalyst::Tables::HeaderRowComponent
8
- def boolean(attribute, **attributes, &block)
9
- header_cell(attribute, **attributes, &block)
8
+ # Renders a boolean column header
9
+ # @param method [Symbol] the method to call on the record to get the value
10
+ # @param attributes [Hash] additional arguments are applied as html attributes to the th element
11
+ # @option attributes [String] :label (nil) The label options to display in the header
12
+ # @option attributes [Hash] :link ({}) The link options for the sorting link
13
+ # @option attributes [String] :width (:xs) The width of the column, can be +:xs+, +:s+, +:m+, +:l+ or nil
14
+ #
15
+ # @example Render a boolean column header
16
+ # <% row.boolean :active %> # => <th>Active</th>
17
+ #
18
+ # @example Render a boolean column header with a custom label
19
+ # <% row.boolean :active, label: "Published" %> # => <th>Published</th>
20
+ #
21
+ # @example Render a boolean column header with medium width
22
+ # <% row.boolean :active, width: :m %>
23
+ # # => <th class="width-s">Active</th>
24
+ #
25
+ # @see Koi::Tables::BodyRowComponent#boolean
26
+ def boolean(method, **attributes, &block)
27
+ header_cell(method, component: Header::BooleanComponent, **attributes, &block)
10
28
  end
11
29
 
12
- def date(attribute, **attributes, &block)
13
- header_cell(attribute, **attributes, &block)
30
+ # Renders a date column header
31
+ # @param method [Symbol] the method to call on the record to get the value
32
+ # @param attributes [Hash] additional arguments are applied as html attributes to the th element
33
+ # @option attributes [String] :label (nil) The label options to display in the header
34
+ # @option attributes [Hash] :link ({}) The link options for the sorting link
35
+ # @option attributes [String] :width (:s) The width of the column, can be +:xs+, +:s+, +:m+, +:l+ or nil
36
+ #
37
+ # @example Render a date column header
38
+ # <% row.date :published_on %> # => <th>Published on</th>
39
+ #
40
+ # @example Render a date column header with a custom label
41
+ # <% row.date :published_on, label: "Date" %> # => <th>Date</th>
42
+ #
43
+ # @example Render a date column header with small width
44
+ # <% row.date :published_on, width: :s %>
45
+ # # => <th class="width-s">Published on</th>
46
+ #
47
+ # @see Koi::Tables::BodyRowComponent#date
48
+ def date(method, **attributes, &block)
49
+ header_cell(method, component: Header::DateComponent, **attributes, &block)
14
50
  end
15
51
 
16
- def datetime(attribute, **attributes, &block)
17
- header_cell(attribute, **attributes, &block)
52
+ # Renders a datetime column header
53
+ # @param method [Symbol] the method to call on the record to get the value
54
+ # @param attributes [Hash] additional arguments are applied as html attributes to the th element
55
+ # @option attributes [String] :label (nil) The label options to display in the header
56
+ # @option attributes [Hash] :link ({}) The link options for the sorting link
57
+ # @option attributes [String] :width (:m) The width of the column, can be +:xs+, +:s+, +:m+, +:l+ or nil
58
+ #
59
+ # @example Render a datetime column header
60
+ # <% row.datetime :created_at %> # => <th>Created at</th>
61
+ #
62
+ # @example Render a datetime column header with a custom label
63
+ # <% row.datetime :created_at, label: "Published at" %> # => <th>Published at</th>
64
+ #
65
+ # @example Render a datetime column header with small width
66
+ # <% row.datetime :created_at, width: :s %>
67
+ # # => <th class="width-s">Created at</th>
68
+ #
69
+ # @see Koi::Tables::BodyRowComponent#datetime
70
+ def datetime(method, **attributes, &block)
71
+ header_cell(method, component: Header::DateTimeComponent, **attributes, &block)
18
72
  end
19
73
 
20
- def number(attribute, **attributes, &block)
21
- header_cell(attribute, **attributes, component: Header::NumberComponent, &block)
74
+ # Renders a number column header
75
+ # @param method [Symbol] the method to call on the record to get the value
76
+ # @param attributes [Hash] additional arguments are applied as html attributes to the th element
77
+ # @option attributes [String] :label (nil) The label options to display in the header
78
+ # @option attributes [Hash] :link ({}) The link options for the sorting link
79
+ # @option attributes [String] :width (:xs) The width of the column, can be +:xs+, +:s+, +:m+, +:l+ or nil
80
+ #
81
+ # @example Render a number column header
82
+ # <% row.number :comment_count %> # => <th>Comments</th>
83
+ #
84
+ # @example Render a number column header with a custom label
85
+ # <% row.number :comment_count, label: "Comments" %> # => <th>Comments</th>
86
+ #
87
+ # @example Render a number column header with medium width
88
+ # <% row.number :comment_count, width: :m %>
89
+ # # => <th class="width-m">Comment Count</th>
90
+ #
91
+ # @see Koi::Tables::BodyRowComponent#number
92
+ def number(method, **attributes, &block)
93
+ header_cell(method, component: Header::NumberComponent, **attributes, &block)
22
94
  end
23
95
 
24
- def money(attribute, **attributes, &block)
25
- header_cell(attribute, **attributes, component: Header::NumberComponent, &block)
96
+ # Renders a currency column header
97
+ # @param method [Symbol] the method to call on the record to get the value
98
+ # @param attributes [Hash] additional arguments are applied as html attributes to the th element
99
+ # @option attributes [String] :label (nil) The label options to display in the header
100
+ # @option attributes [Hash] :link ({}) The link options for the sorting link
101
+ # @option attributes [String] :width (:s) The width of the column, can be +:xs+, +:s+, +:m+, +:l+ or nil
102
+ #
103
+ # @example Render a currency column header
104
+ # <% row.currency :price %> # => <th>Price</th>
105
+ #
106
+ # @example Render a currency column header with a custom label
107
+ # <% row.currency :price, label: "Amount($)" %> # => <th>Amount($)</th>
108
+ #
109
+ # @example Render a currency column header with medium width
110
+ # <% row.currency :price, width: :m %>
111
+ # # => <th class="width-m">Price</th>
112
+ #
113
+ # @see Koi::Tables::BodyRowComponent#currency
114
+ def currency(method, **attributes, &block)
115
+ header_cell(method, component: Header::CurrencyComponent, **attributes, &block)
26
116
  end
27
117
 
28
- def rich_text(attribute, **attributes, &block)
29
- header_cell(attribute, **attributes, &block)
118
+ # Renders a rich text column header
119
+ # @param method [Symbol] the method to call on the record to get the value
120
+ # @param attributes [Hash] additional arguments are applied as html attributes to the th element
121
+ # @option attributes [String] :label (nil) The label options to display in the header
122
+ # @option attributes [Hash] :link ({}) The link options for the sorting link
123
+ # @option attributes [String] :width (nil) The width of the column, can be +:xs+, +:s+, +:m+, +:l+ or nil
124
+ #
125
+ # @example Render a rich text column header
126
+ # <% row.rich_text :content %> # => <th>Content</th>
127
+ #
128
+ # @example Render a rich text column header with a custom label
129
+ # <% row.rich_text :content, label: "Post content" %> # => <th>Post content</th>
130
+ #
131
+ # @example Render a rich text column header with large width
132
+ # <% row.rich_text :content, width: :l %>
133
+ # # => <th class="width-l">Content</th>
134
+ #
135
+ # @see Koi::Tables::BodyRowComponent#rich_text
136
+ def rich_text(method, **attributes, &block)
137
+ header_cell(method, component: Header::TextComponent, **attributes, &block)
30
138
  end
31
139
 
32
- def link(attribute, **attributes, &block)
33
- header_cell(attribute, **attributes, &block)
140
+ # Renders a link column header
141
+ # @param method [Symbol] the method to call on the record to get the value
142
+ # @param attributes [Hash] additional arguments are applied as html attributes to the th element
143
+ # @option attributes [String] :label (nil) The label options to display in the header
144
+ # @option attributes [Hash] :link ({}) The link options for the sorting link
145
+ # @option attributes [String] :width (nil) The width of the column, can be +:xs+, +:s+, +:m+, +:l+ or nil
146
+ #
147
+ # @example Render a link column header
148
+ # <% row.link :link %> # => <th>Link</th>
149
+ #
150
+ # @example Render a link column header with a custom label
151
+ # <% row.link :link, label: "Post" %> # => <th>Post</th>
152
+ #
153
+ # @example Render a link column header with small width
154
+ # <% row.link :content, width: :s %>
155
+ # # => <th class="width-s">Content</th>
156
+ #
157
+ # @see Koi::Tables::BodyRowComponent#link
158
+ def link(method, **attributes, &block)
159
+ header_cell(method, component: Header::LinkComponent, **attributes, &block)
34
160
  end
35
161
 
36
- def text(attribute, **attributes, &block)
37
- header_cell(attribute, **attributes, &block)
162
+ # Renders a text column header
163
+ # @param method [Symbol] the method to call on the record to get the value
164
+ # @param attributes [Hash] additional arguments are applied as html attributes to the th element
165
+ # @option attributes [String] :label (nil) The label options to display in the header
166
+ # @option attributes [Hash] :link ({}) The link options for the sorting link
167
+ # @option attributes [String] :width (nil) The width of the column, can be +:xs+, +:s+, +:m+, +:l+ or nil
168
+ #
169
+ # @example Render a text column header
170
+ # <% row.text :content %> # => <th>Content</th>
171
+ #
172
+ # @example Render a text column header with a custom label
173
+ # <% row.text :content, label: "Description" %> # => <th>Description</th>
174
+ #
175
+ # @example Render a text column header with large width
176
+ # <% row.text :content, width: :l %>
177
+ # # => <th class="width-l">Content</th>
178
+ #
179
+ # @see Koi::Tables::BodyRowComponent#text
180
+ def text(method, **attributes, &block)
181
+ header_cell(method, component: Header::TextComponent, **attributes, &block)
38
182
  end
39
183
 
40
- def image(attribute, **attributes, &block)
41
- header_cell(attribute, **attributes, &block)
184
+ # Renders a attachment column header
185
+ # @param method [Symbol] the method to call on the record to get the value
186
+ # @param attributes [Hash] additional arguments are applied as html attributes to the th element
187
+ # @option attributes [String] :label (nil) The label options to display in the header
188
+ # @option attributes [Hash] :link ({}) The link options for the sorting link
189
+ # @option attributes [String] :width (nil) The width of the column, can be +:xs+, +:s+, +:m+, +:l+ or nil
190
+ #
191
+ # @example Render a attachment column header
192
+ # <% row.attachment :attachment %> # => <th>Attachment</th>
193
+ #
194
+ # @example Render a attachment column header with a custom label
195
+ # <% row.attachment :attachment, label: "Document" %> # => <th>Document</th>
196
+ #
197
+ # @example Render a attachment column header with small width
198
+ # <% row.attachment :attachment, width: :s %>
199
+ # # => <th class="width-s">Attachment</th>
200
+ #
201
+ # @see Koi::Tables::BodyRowComponent#attachment
202
+ def attachment(method, **attributes, &block)
203
+ header_cell(method, component: Header::AttachmentComponent, **attributes, &block)
42
204
  end
43
205
 
44
206
  private
45
207
 
46
- def header_cell(attribute, component: HeaderCellComponent, **attributes, &block)
47
- with_column(component.new(@table, attribute, link: @link_attributes, **attributes), &block)
208
+ def header_cell(method, component: HeaderCellComponent, **attributes, &block)
209
+ with_column(component.new(@table, method, link: @link_attributes, **attributes), &block)
48
210
  end
49
211
  end
50
212
  end
@@ -1,36 +1,26 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # rubocop:disable Naming/MethodName
4
3
  module Koi
5
4
  module DateHelper
6
- # @deprecated
7
- def date_format(date, format)
8
- date.strftime format.gsub(/yyyy/, "%Y")
9
- .gsub(/yy/, "%y")
10
- .gsub(/Month/, "%B")
11
- .gsub(/M/, "%b")
12
- .gsub(/mm/, "%m")
13
- .gsub(/m/, "%-m")
14
- .gsub(/Day/, "%A")
15
- .gsub(/D/, "%a")
16
- .gsub(/dd/, "%d")
17
- .gsub(/d/, "%-d")
18
- end
19
-
20
- # @deprecated
21
- def date_Month_d_yyyy(date)
22
- date.strftime "%B %-d, %Y"
23
- end
24
-
25
- # @deprecated
26
- def date_d_Month_yyyy(date)
27
- date.strftime "%-d %B %Y"
28
- end
5
+ # Returns a string representing the number of days ago or from now.
6
+ # If the date is not 'recent' returns nil.
7
+ def days_ago_in_words(value)
8
+ from_time = value.to_time
9
+ to_time = Date.current.to_time
10
+ distance_in_days = ((to_time - from_time) / (24.0 * 60.0 * 60.0)).round
29
11
 
30
- # @deprecated
31
- def date_d_M_yy(date)
32
- date.strftime "%-d %b %y"
12
+ case distance_in_days
13
+ when 0
14
+ "today"
15
+ when 1
16
+ "yesterday"
17
+ when -1
18
+ "tomorrow"
19
+ when 2..5
20
+ "#{distance_in_days} days ago"
21
+ when -5..-2
22
+ "#{distance_in_days.abs} days from now"
23
+ end
33
24
  end
34
25
  end
35
26
  end
36
- # rubocop:enable Naming/MethodName
@@ -2,7 +2,6 @@
2
2
 
3
3
  module Admin
4
4
  class <%= controller_class_name %>Controller < ApplicationController
5
-
6
5
  before_action :set_<%= singular_name %>, only: %i[show edit update destroy]
7
6
 
8
7
  def index
@@ -31,7 +30,7 @@ module Admin
31
30
  @<%= singular_name %> = ::<%= class_name %>.new(<%= singular_table_name %>_params)
32
31
 
33
32
  if @<%= singular_name %>.save
34
- redirect_to [:admin, @<%= singular_name %>]
33
+ redirect_to [:admin, @<%= singular_name %>], status: :see_other
35
34
  else
36
35
  render :new, locals: { <%= singular_name %>: @<%= singular_name %> }, status: :unprocessable_entity
37
36
  end
@@ -39,16 +38,16 @@ module Admin
39
38
 
40
39
  def update
41
40
  if @<%= singular_name %>.update(<%= singular_table_name %>_params)
42
- redirect_to action: :show
41
+ redirect_to action: :show, status: :see_other
43
42
  else
44
43
  render :edit, locals: { <%= singular_name %>: @<%= singular_name %> }, status: :unprocessable_entity
45
44
  end
46
45
  end
47
46
 
48
47
  def destroy
49
- @<%= singular_name %>.destroy
48
+ @<%= singular_name %>.destroy!
50
49
 
51
- redirect_to action: :index
50
+ redirect_to action: :index, status: :see_other
52
51
  end
53
52
 
54
53
  private
@@ -56,9 +55,9 @@ module Admin
56
55
  # Only allow a list of trusted parameters through.
57
56
  def <%= "#{singular_table_name}_params" %>
58
57
  <%- if attributes_names.empty? -%>
59
- params.fetch(:<%= singular_table_name %>, {})
58
+ params.fetch(:<%= singular_table_name %>, {})
60
59
  <%- else -%>
61
- params.require(:<%= singular_table_name %>).permit(<%= permitted_params %>)
60
+ params.require(:<%= singular_table_name %>).permit(<%= permitted_params %>)
62
61
  <%- end -%>
63
62
  end
64
63
 
@@ -23,7 +23,7 @@ RSpec.describe Admin::<%= controller_class_name %>Controller do
23
23
 
24
24
  it "paginates the collection" do
25
25
  action
26
- expect(response.body).to have_selector("tbody tr", count: 20)
26
+ expect(response.body).to have_css("tbody tr", count: 20)
27
27
  end
28
28
  end
29
29
 
@@ -37,7 +37,7 @@ RSpec.describe Admin::<%= controller_class_name %>Controller do
37
37
 
38
38
  it "finds first in second place" do
39
39
  action
40
- expect(response.body).to have_selector("tbody tr + tr td", text: "first")
40
+ expect(response.body).to have_css("tbody tr + tr td", text: "first")
41
41
  end
42
42
  end
43
43
 
@@ -51,12 +51,12 @@ RSpec.describe Admin::<%= controller_class_name %>Controller do
51
51
 
52
52
  it "finds the needle" do
53
53
  action
54
- expect(response.body).to have_selector("table td", text: "first")
54
+ expect(response.body).to have_css("table td", text: "first")
55
55
  end
56
56
 
57
57
  it "removes the chaff" do
58
58
  action
59
- expect(response.body).not_to have_selector("table td", text: "second")
59
+ expect(response.body).to have_no_css("table td", text: "second")
60
60
  end
61
61
  end
62
62
  end
@@ -38,10 +38,10 @@ module Koi
38
38
  %(<%= form.govuk_check_box_field :#{attribute.name} %>)
39
39
  when :date
40
40
  %(<%= form.govuk_date_field :#{attribute.name}, legend: { size: "s" } %>)
41
- when :text
42
- %(<%= form.govuk_rich_text_area :#{attribute.name} %>)
43
- when :rich_text
41
+ when :rich_text, :text
44
42
  %(<%= form.govuk_rich_text_area :#{attribute.name} %>)
43
+ when :attachment
44
+ %(<%= form.govuk_image_field :#{attribute.name} %>)
45
45
  else
46
46
  ""
47
47
  end
@@ -61,6 +61,8 @@ module Koi
61
61
  %(<% dl.datetime :#{attribute.name} %>)
62
62
  when :rich_text
63
63
  %(<% dl.rich_text :#{attribute.name} %>)
64
+ when :attachment
65
+ %(<% dl.attachment :#{attribute.name} %>)
64
66
  else
65
67
  %(<% dl.text :#{attribute.name} %>)
66
68
  end
@@ -79,7 +81,7 @@ module Koi
79
81
  when :rich_text
80
82
  %(<% row.rich_text :#{attribute.name} %>)
81
83
  when :attachment
82
- %(<% row.image :#{attribute.name} %>)
84
+ %(<% row.attachment :#{attribute.name} %>)
83
85
  else
84
86
  %(<% row.text :#{attribute.name} %>)
85
87
  end
data/lib/koi/config.rb CHANGED
@@ -1,11 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "active_support/configurable"
4
+ require "active_support/core_ext/numeric"
4
5
 
5
6
  module Koi
6
7
  class Config
7
8
  include ActiveSupport::Configurable
8
9
 
9
10
  config_accessor(:resource_name_candidates) { %i[title name] }
11
+
12
+ config_accessor(:image_size_limit) { 10.megabytes }
10
13
  end
11
14
  end
@@ -37,7 +37,7 @@ module Koi
37
37
  # @api internal
38
38
  # @see GOVUKDesignSystemFormBuilder::Builder#govuk_document_field
39
39
  def govuk_document_field(attribute_name, hint: {}, **kwargs, &block)
40
- max_size = hint[:max_size] || App::PERMITTED_IMAGE_SIZE
40
+ max_size = hint[:max_size] || Koi.config.image_size_limit
41
41
  super(attribute_name, hint:, **kwargs) do
42
42
  if block
43
43
  concat(yield)
@@ -50,7 +50,7 @@ module Koi
50
50
  # @api internal
51
51
  # @see GOVUKDesignSystemFormBuilder::Builder#govuk_image_field
52
52
  def govuk_image_field(attribute_name, hint: {}, **kwargs, &block)
53
- max_size = hint[:max_size] || App::PERMITTED_IMAGE_SIZE
53
+ max_size = hint[:max_size] || Koi.config.image_size_limit
54
54
  super(attribute_name, hint:, **kwargs) do
55
55
  if block
56
56
  concat(yield)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: katalyst-koi
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.5.0.beta.2
4
+ version: 4.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Katalyst Interactive
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-02-27 00:00:00.000000000 Z
11
+ date: 2024-03-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -454,9 +454,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
454
454
  version: '3.2'
455
455
  required_rubygems_version: !ruby/object:Gem::Requirement
456
456
  requirements:
457
- - - ">"
457
+ - - ">="
458
458
  - !ruby/object:Gem::Version
459
- version: 1.3.1
459
+ version: '0'
460
460
  requirements: []
461
461
  rubygems_version: 3.4.19
462
462
  signing_key: