katalyst-koi 5.10.0 → 5.11.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.
Files changed (28) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/stylesheets/koi/blocks/page-header.css +4 -0
  3. data/app/assets/stylesheets/koi/blocks/prose.css +36 -9
  4. data/app/assets/stylesheets/koi/blocks/tables/table.css +49 -3
  5. data/app/assets/stylesheets/koi/forms/file-upload.css +20 -0
  6. data/app/assets/stylesheets/koi/global/global-styles.css +5 -5
  7. data/app/assets/stylesheets/koi/global/variables.css +3 -0
  8. data/app/models/background_job.rb +10 -5
  9. data/app/models/recurring_task.rb +5 -7
  10. data/app/views/admin/admin_roles/index.html.erb +1 -1
  11. data/app/views/admin/admin_users/archived.html.erb +1 -1
  12. data/app/views/admin/admin_users/index.html.erb +1 -1
  13. data/app/views/admin/background_jobs/blocked.html.erb +4 -1
  14. data/app/views/admin/background_jobs/completed.html.erb +4 -1
  15. data/app/views/admin/background_jobs/failed.html.erb +5 -2
  16. data/app/views/admin/background_jobs/in_progress.html.erb +4 -1
  17. data/app/views/admin/background_jobs/index.html.erb +4 -1
  18. data/app/views/admin/background_jobs/scheduled.html.erb +4 -1
  19. data/app/views/admin/feature_flags/index.html.erb +5 -2
  20. data/app/views/admin/recurring_tasks/index.html.erb +4 -1
  21. data/app/views/admin/recurring_tasks/show.html.erb +4 -1
  22. data/app/views/admin/well_knowns/index.html.erb +2 -2
  23. data/app/views/katalyst/navigation/menus/index.html.erb +1 -1
  24. data/app/views/layouts/koi/application.html.erb +3 -1
  25. data/lib/generators/koi/admin_controller/templates/controller_spec.rb.tt +1 -1
  26. data/lib/generators/koi/admin_views/templates/archived.html.erb.tt +1 -1
  27. data/lib/generators/koi/admin_views/templates/index.html.erb.tt +1 -1
  28. metadata +1 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 319724f0fb3d95cdb522b2255aff29edd723b82d30a719b772e47ffcae3e4c98
4
- data.tar.gz: fd2421bb764b29caf26567b5b41df493fb77083c6bff490db7b4c01eff1f08ad
3
+ metadata.gz: e72eb3c398c2692e5b4ee0a87c77c1d85399fa5a71602588876966814be1f694
4
+ data.tar.gz: 256b06cb43feea3ade848d16db55e8e375fecccb6a292286ac5751b966c16ba3
5
5
  SHA512:
6
- metadata.gz: d558ecb83c1aaa9503a689c56af22c7000a0fb5ad9230f59ec8c8db02ed98e2f1883452893fbd556600cebee65e131913f63f728b8819dddd02d6b4f79b8474b
7
- data.tar.gz: 2e1b7ad2aef1522792bf15f767b1500e6abfd8c718070c094b2fda2be93dce2ad0d5928f19214f401786f6848cdb482752e4c84c162799a8667c14a0b4b626ec
6
+ metadata.gz: e89c84958cfaaa097b9aaca8111b908b51dbf2632f9159bcd13f7b11eb045da70439cf7e5fba3b81c0fb077634db27552ab57fdb0e064d9b2f6a0ec10c76fd6a
7
+ data.tar.gz: 586601311014a48f8129562e8a37801ef82c9457a3e9fc836e8e7b148c725d0a4fc6c9d2351541948a3f015d5e5e3ca80e8939dc7c2bb0e3e1ccaf7bb3319c17
@@ -2,6 +2,10 @@
2
2
  background: var(--color-tint);
3
3
  color: var(--color-dark);
4
4
 
5
+ h1 {
6
+ font-size: var(--size-step-5);
7
+ }
8
+
5
9
  > .wrapper {
6
10
  padding-block: var(--gutter);
7
11
  }
@@ -1,29 +1,52 @@
1
1
  .prose {
2
- --flow-space: var(--space-l);
2
+ --flow-space: var(--space-m);
3
3
  }
4
4
 
5
5
  .prose :is(h1, h2, h3) {
6
6
  overflow-wrap: anywhere;
7
7
  hyphens: auto;
8
+ min-width: var(--prose-width);
9
+
10
+ /* key line */
11
+ box-shadow: inset 0 -2px 0 currentColor;
12
+ padding-block-end: var(--space-3xs-2xs);
13
+ }
14
+
15
+ .prose :is(h1, h2, h3) + table {
16
+ border-top: none;
17
+ }
18
+
19
+ .prose .repel:has(> :is(h1, h2, h3)) {
20
+ /* replace h1 keyline */
21
+ box-shadow: inset 0 -2px 0 currentColor;
22
+ padding-block-end: var(--space-3xs-2xs);
23
+
24
+ :is(h1, h2, h3) {
25
+ box-shadow: unset;
26
+ min-width: unset;
27
+ padding-block-end: unset;
28
+ }
8
29
  }
9
30
 
10
31
  .prose :is(p, li, dl, figcaption, blockquote) {
11
- max-width: 60ch;
32
+ max-width: var(--measure);
12
33
  text-wrap: pretty;
13
34
  }
14
35
 
15
- .prose :is(h1, h2, h3, h4) + *:not([class]) {
36
+ /* Set space between headings and their content */
37
+ .prose :is(h1, h2, h3, h4, h5, h6) + *:not([class]) {
16
38
  --flow-space: var(--space-m);
17
39
  }
18
40
 
19
- /* Add more space on and around figures and tables */
20
- .prose :is(figure, table),
21
- .prose :is(figure, table) + * {
22
- --flow-space: var(--space-2xl);
41
+ /* Set space between sections */
42
+ .prose * + :is(h1, h2, h3, h4, h5, h6):not([class]),
43
+ .prose * + :has(> :is(h1, h2, h3, h4, h5, h6):first-child:not([class])) {
44
+ --flow-space: var(--space-xl);
23
45
  }
24
46
 
25
- /* Add more space to headings on block start */
26
- .prose * + :is(h1, h2, h3, h4):not([class]) {
47
+ /* Add more space on and around figures and tables */
48
+ .prose :is(figure, table):not([class]),
49
+ .prose :is(figure, table):not([class]) + * {
27
50
  --flow-space: var(--space-xl);
28
51
  }
29
52
 
@@ -35,3 +58,7 @@
35
58
  .prose hr {
36
59
  --flow-space: var(--space-2xl);
37
60
  }
61
+
62
+ .prose table:not([class]) {
63
+ --table-min-width: var(--prose-width);
64
+ }
@@ -2,6 +2,20 @@
2
2
  --tag-color: var(--color-primary);
3
3
  --on-tag-color: white;
4
4
 
5
+ th.type-link a[href]:not(:hover) {
6
+ text-decoration: none;
7
+ }
8
+
9
+ th:first-child,
10
+ td:first-child {
11
+ padding-inline-start: 0;
12
+ }
13
+
14
+ th:last-child,
15
+ td:last-child {
16
+ padding-inline-end: 0;
17
+ }
18
+
5
19
  td.type-enum small {
6
20
  color: var(--on-tag-color);
7
21
  font-size: small;
@@ -34,7 +48,10 @@
34
48
  cursor: pointer;
35
49
  margin-block-end: 0;
36
50
  min-height: 1.5rem;
37
- transform: translateY(1px);
51
+ transform: translateY(0.2ch);
52
+ margin-inline-start: calc(
53
+ -1 * var(--space-s) + 2 * var(--stroke-input-width)
54
+ );
38
55
 
39
56
  &::before,
40
57
  &::after {
@@ -61,9 +78,9 @@
61
78
  }
62
79
  }
63
80
 
64
- tbody [data-cell-type="selection"] {
81
+ thead [data-cell-type="selection"] {
65
82
  label {
66
- transform: translateY(3px);
83
+ transform: translateY(0.4ch);
67
84
  }
68
85
  }
69
86
 
@@ -90,6 +107,35 @@
90
107
  }
91
108
  }
92
109
 
110
+ .katalyst--summary-table {
111
+ --table-min-width: var(--prose-width);
112
+
113
+ border-block-start: var(--stroke);
114
+
115
+ th {
116
+ padding-inline-start: unset;
117
+ padding-inline-end: var(--space-s);
118
+ }
119
+ }
120
+
121
+ @container (width < 60ch) {
122
+ .katalyst--summary-table {
123
+ th,
124
+ td {
125
+ padding-inline: unset;
126
+ }
127
+
128
+ th {
129
+ box-shadow: none;
130
+ padding-block-end: 0;
131
+ }
132
+
133
+ td {
134
+ padding-block-start: var(--space-2xs);
135
+ }
136
+ }
137
+ }
138
+
93
139
  .tables--selection--form {
94
140
  p {
95
141
  margin-bottom: var(--space-2xs);
@@ -27,6 +27,7 @@
27
27
  display: block;
28
28
  position: relative;
29
29
  z-index: 0;
30
+ container: govuk-file-upload / inline-size;
30
31
  border: var(--stroke-input);
31
32
  border-radius: var(--input-radius);
32
33
  padding: var(--space-xs-s);
@@ -121,6 +122,7 @@
121
122
 
122
123
  .preview {
123
124
  grid-area: preview;
125
+ align-self: center;
124
126
  max-width: 4rem;
125
127
  aspect-ratio: 1/1;
126
128
  object-fit: cover;
@@ -138,6 +140,7 @@
138
140
 
139
141
  .filename {
140
142
  font-weight: var(--font-bold);
143
+ word-break: break-all;
141
144
  }
142
145
 
143
146
  .size {
@@ -200,6 +203,23 @@
200
203
  }
201
204
  }
202
205
 
206
+ /* Too narrow for a third column: the actions move to their own row. */
207
+ @container govuk-file-upload (width < 20rem) {
208
+ .govuk-attachment {
209
+ grid-template-areas:
210
+ "preview caption"
211
+ "actions actions";
212
+ grid-template-columns: auto 1fr;
213
+
214
+ .actions {
215
+ flex-direction: row;
216
+ justify-content: flex-end;
217
+ flex-wrap: wrap;
218
+ gap: var(--space-2xs);
219
+ }
220
+ }
221
+ }
222
+
203
223
  /* With JavaScript running the button is the figure's only interactive
204
224
  control; the select still carries the submitted value but leaves the
205
225
  display, tab order, and accessibility tree. */
@@ -27,22 +27,22 @@ main {
27
27
  }
28
28
 
29
29
  h1 {
30
- font-size: var(--size-step-5);
30
+ font-size: var(--size-step-4);
31
31
  max-width: 20ch;
32
32
  }
33
33
 
34
34
  h2 {
35
- font-size: var(--size-step-4);
35
+ font-size: var(--size-step-3);
36
36
  max-width: 35ch;
37
37
  }
38
38
 
39
39
  h3 {
40
- font-size: var(--size-step-3);
40
+ font-size: var(--size-step-2);
41
41
  max-width: 35ch;
42
42
  }
43
43
 
44
44
  :is(h4, h5, h6) {
45
- font-size: var(--size-step-2);
45
+ font-size: var(--size-step-1);
46
46
  }
47
47
 
48
48
  small {
@@ -193,7 +193,7 @@ figcaption {
193
193
 
194
194
  table {
195
195
  border-collapse: collapse;
196
- width: 100%;
196
+ min-width: var(--table-min-width, 100%);
197
197
  }
198
198
 
199
199
  th {
@@ -18,6 +18,9 @@
18
18
 
19
19
  :root {
20
20
  --gutter: var(--space-m-l);
21
+ --measure: 60ch;
22
+ --wrapper-max-width: 85rem;
23
+ --prose-width: min(57rem, 100cqi); /* 2/3rds of wrapper */
21
24
  --transition-base: 250ms ease;
22
25
  --transition-movement: 200ms linear;
23
26
  --transition-fade: 300ms ease;
@@ -5,10 +5,11 @@ class BackgroundJob
5
5
 
6
6
  module Scopes
7
7
  def admin_search(query)
8
- where(
9
- "solid_queue_jobs.class_name LIKE :query OR solid_queue_jobs.queue_name LIKE :query",
10
- query: "%#{query}%",
11
- )
8
+ pattern = "%#{SolidQueue::Job.sanitize_sql_like(query)}%"
9
+ table = SolidQueue::Job.arel_table
10
+ class_name_matches = table[:class_name].matches(pattern)
11
+ queue_name_matches = table[:queue_name].matches(pattern)
12
+ where(class_name_matches.or(queue_name_matches))
12
13
  end
13
14
  end
14
15
 
@@ -42,7 +43,7 @@ class BackgroundJob
42
43
 
43
44
  # Serialized as an ISO8601 string in the payload; parse so views can format it.
44
45
  def enqueued_at
45
- job.arguments["enqueued_at"]&.then { |value| Time.iso8601(value) }
46
+ job.arguments["enqueued_at"]&.then { |value| Time.zone.iso8601(value) }
46
47
  end
47
48
 
48
49
  # The arguments the job was enqueued with, from the serialized payload.
@@ -76,6 +77,10 @@ class BackgroundJob
76
77
  "#{failure.exception_class}: #{failure.message}"
77
78
  end
78
79
 
80
+ def failure_class
81
+ failed_execution.exception_class
82
+ end
83
+
79
84
  def state
80
85
  if finished?
81
86
  :finished
@@ -5,13 +5,11 @@ class RecurringTask
5
5
 
6
6
  module Scopes
7
7
  def admin_search(query)
8
- where(
9
- <<~SQL.squish,
10
- solid_queue_recurring_tasks.key LIKE :query
11
- OR solid_queue_recurring_tasks.class_name LIKE :query
12
- SQL
13
- query: "%#{query}%",
14
- )
8
+ pattern = "%#{SolidQueue::RecurringTask.sanitize_sql_like(query)}%"
9
+ table = SolidQueue::RecurringTask.arel_table
10
+ key_matches = table[:key].matches(pattern)
11
+ class_name_matches = table[:class_name].matches(pattern)
12
+ where(key_matches.or(class_name_matches))
15
13
  end
16
14
  end
17
15
 
@@ -7,7 +7,7 @@
7
7
  <%= table_query_with(collection:) %>
8
8
 
9
9
  <%= table_with(collection:) do |row| %>
10
- <% row.link(:slug, url: :admin_admin_role_path) %>
10
+ <% row.link(:slug, heading: true, url: :admin_admin_role_path) %>
11
11
  <% row.date(:created_at, label: "Materialized") %>
12
12
  <% row.datetime(:last_authenticated_at, label: "Last authenticated") %>
13
13
  <% row.boolean(:orphaned?, label: "Orphaned") %>
@@ -15,7 +15,7 @@
15
15
 
16
16
  <%= table_with(collection:) do |row| %>
17
17
  <% row.select %>
18
- <% row.link :name, url: :admin_admin_user_path %>
18
+ <% row.link(:name, heading: true, url: :admin_admin_user_path) %>
19
19
  <% row.text :email %>
20
20
  <% end %>
21
21
 
@@ -17,7 +17,7 @@
17
17
 
18
18
  <%= table_with(collection:) do |row| %>
19
19
  <% row.select %>
20
- <% row.link(:name, url: :admin_admin_user_path) %>
20
+ <% row.link(:name, heading: true, url: :admin_admin_user_path) %>
21
21
  <% row.text(:email) %>
22
22
  <% row.enum(:password_login, label: "Password") %>
23
23
  <% row.boolean(:credentials, label: "Passkey") do |cell| %>
@@ -9,7 +9,10 @@
9
9
  <%= table_query_with(collection:) %>
10
10
 
11
11
  <%= table_with(collection:) do |row, job| %>
12
- <% row.link(:class_name, url: ->(record) { admin_background_job_path(record.active_job_id) }, label: "Job") %>
12
+ <% row.link(:class_name,
13
+ label: "Job",
14
+ heading: true,
15
+ url: ->(record) { admin_background_job_path(record.active_job_id) }) %>
13
16
  <% row.text(:queue_name, label: "Queue") %>
14
17
  <% row.datetime(:scheduled_at, label: "Scheduled") %>
15
18
  <% end %>
@@ -9,7 +9,10 @@
9
9
  <%= table_query_with(collection:) %>
10
10
 
11
11
  <%= table_with(collection:) do |row, job| %>
12
- <% row.link(:class_name, url: ->(record) { admin_background_job_path(record.active_job_id) }, label: "Job") %>
12
+ <% row.link(:class_name,
13
+ label: "Job",
14
+ heading: true,
15
+ url: ->(record) { admin_background_job_path(record.active_job_id) }) %>
13
16
  <% row.text(:queue_name, label: "Queue") %>
14
17
  <% row.datetime(:finished_at, label: "Finished") %>
15
18
  <% end %>
@@ -15,11 +15,14 @@
15
15
 
16
16
  <%= table_with(collection:) do |row, job| %>
17
17
  <% row.select %>
18
- <% row.link(:class_name, url: ->(record) { admin_background_job_path(record.active_job_id) }, label: "Job") %>
18
+ <% row.link(:class_name,
19
+ label: "Job",
20
+ heading: true,
21
+ url: ->(record) { admin_background_job_path(record.active_job_id) }) %>
19
22
  <% row.text(:queue_name, label: "Queue") %>
20
23
  <% row.datetime(:updated_at, label: "Last failed") %>
21
24
  <% row.text(:error, label: "Error") do %>
22
- <%= BackgroundJob.new(job).failure_reason %>
25
+ <%= BackgroundJob.new(job).failure_class %>
23
26
  <% end %>
24
27
  <% end %>
25
28
 
@@ -9,7 +9,10 @@
9
9
  <%= table_query_with(collection:) %>
10
10
 
11
11
  <%= table_with(collection:) do |row, job| %>
12
- <% row.link(:class_name, url: ->(record) { admin_background_job_path(record.active_job_id) }, label: "Job") %>
12
+ <% row.link(:class_name,
13
+ label: "Job",
14
+ heading: true,
15
+ url: ->(record) { admin_background_job_path(record.active_job_id) }) %>
13
16
  <% row.text(:queue_name, label: "Queue") %>
14
17
  <% row.datetime(:scheduled_at, label: "Scheduled") %>
15
18
  <% end %>
@@ -14,7 +14,10 @@
14
14
 
15
15
  <%= table_with(collection:) do |row, job| %>
16
16
  <% row.select %>
17
- <% row.link(:class_name, url: ->(record) { admin_background_job_path(record.active_job_id) }, label: "Job") %>
17
+ <% row.link(:class_name,
18
+ label: "Job",
19
+ heading: true,
20
+ url: ->(record) { admin_background_job_path(record.active_job_id) }) %>
18
21
  <% row.text(:queue_name, label: "Queue") %>
19
22
  <% row.datetime(:scheduled_at, label: "Scheduled") %>
20
23
  <% end %>
@@ -9,7 +9,10 @@
9
9
  <%= table_query_with(collection:) %>
10
10
 
11
11
  <%= table_with(collection:) do |row, job| %>
12
- <% row.link(:class_name, url: ->(record) { admin_background_job_path(record.active_job_id) }, label: "Job") %>
12
+ <% row.link(:class_name,
13
+ label: "Job",
14
+ heading: true,
15
+ url: ->(record) { admin_background_job_path(record.active_job_id) }) %>
13
16
  <% row.text(:queue_name, label: "Queue") %>
14
17
  <% row.datetime(:scheduled_at, label: "Scheduled") %>
15
18
  <% end %>
@@ -8,7 +8,10 @@
8
8
  <% end %>
9
9
  <% end %>
10
10
 
11
- <%= table_with(collection:) do |row, feature_flag| %>
12
- <% row.link(:key, url: ->(record) { admin_feature_flag_path(record) }, label: "Name") %>
11
+ <%= table_with(collection:) do |row| %>
12
+ <% row.link(:key,
13
+ label: "Name",
14
+ heading: true,
15
+ url: ->(record) { admin_feature_flag_path(record) }) %>
13
16
  <% row.text(:state, label: "Status") { |cell| cell.value.to_s.humanize } %>
14
17
  <% end %>
@@ -12,7 +12,10 @@
12
12
  <%= table_query_with(collection:) %>
13
13
 
14
14
  <%= table_with(collection:) do |row| %>
15
- <% row.link(:key, url: ->(record) { admin_recurring_task_path(record.key) }, label: "Job name") %>
15
+ <% row.link(:key,
16
+ label: "Job name",
17
+ heading: true,
18
+ url: ->(record) { admin_recurring_task_path(record.key) }) %>
16
19
  <% row.text(:schedule, label: "Schedule") %>
17
20
  <% row.datetime(:last_enqueued_time, label: "Last enqueued") %>
18
21
  <% end %>
@@ -23,7 +23,10 @@
23
23
  <h2>Jobs</h2>
24
24
 
25
25
  <%= table_with(collection: jobs) do |row| %>
26
- <% row.link(:job_id, url: ->(record) { admin_background_job_path(record.active_job_id) }, label: "Job") %>
26
+ <% row.link(:job_id,
27
+ label: "Job",
28
+ heading: true,
29
+ url: ->(record) { admin_background_job_path(record.active_job_id) }) %>
27
30
  <% row.datetime(:enqueued_at) %>
28
31
  <% row.datetime(:finished_at) %>
29
32
  <% row.number(:duration) %>
@@ -10,8 +10,8 @@
10
10
 
11
11
  <%= table_query_with(collection:) %>
12
12
 
13
- <%= table_with(collection:) do |row, well_known| %>
14
- <% row.link :name %>
13
+ <%= table_with(collection:) do |row| %>
14
+ <% row.link(:name, heading: true) %>
15
15
  <% row.text :purpose %>
16
16
  <% end %>
17
17
 
@@ -7,6 +7,6 @@
7
7
  <% end %>
8
8
 
9
9
  <%= table_with(collection:) do |row, menu| %>
10
- <%= row.link :title, url: (katalyst_navigation.menu_path(menu) if menu) %>
10
+ <%= row.link(:title, heading: true, url: (katalyst_navigation.menu_path(menu) if menu)) %>
11
11
  <%= row.text :slug %>
12
12
  <% end %>
@@ -60,8 +60,10 @@
60
60
  <%= yield(:roadblock) %>
61
61
  </div>
62
62
  </main>
63
+ <% elsif content_for?(:main) %>
64
+ <%= yield(:main) %>
63
65
  <% else %>
64
- <main class="flow wrapper">
66
+ <main class="flow prose wrapper">
65
67
  <% unless flash.empty? %>
66
68
  <!-- flash -->
67
69
  <%= render("layouts/koi/flash") %>
@@ -25,7 +25,7 @@ RSpec.describe <%= controller_class_name %>Controller do
25
25
 
26
26
  action
27
27
 
28
- expect(response.parsed_body.css("tbody td a").pluck(:href))
28
+ expect(response.parsed_body.css("tbody th a").pluck(:href))
29
29
  .to eq([second, first].map { |<%= singular_name %>| <%= admin_show_helper %> })
30
30
  end
31
31
  <%- end -%>
@@ -20,7 +20,7 @@
20
20
  <%% row.select %>
21
21
  <%- index_attributes.each_with_index do |attribute, index| -%>
22
22
  <%- if index.zero? -%>
23
- <%% row.link :<%= attribute.name %> %>
23
+ <%% row.link(:<%= attribute.name %>, heading: true) %>
24
24
  <%- else -%>
25
25
  <%= index_attribute_for attribute %>
26
26
  <%- end -%>
@@ -32,7 +32,7 @@
32
32
  <%- end -%>
33
33
  <%- index_attributes.each_with_index do |attribute, index| -%>
34
34
  <%- if index.zero? -%>
35
- <%% row.link :<%= attribute.name %> %>
35
+ <%% row.link(:<%= attribute.name %>, heading: true) %>
36
36
  <%- else -%>
37
37
  <%= index_attribute_for attribute %>
38
38
  <%- end -%>
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: katalyst-koi
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.10.0
4
+ version: 5.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Katalyst Interactive