janela 0.8.0 → 0.10.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 (41) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +25 -0
  3. data/README.md +41 -2
  4. data/UPGRADING.md +75 -0
  5. data/app/assets/javascripts/janela/chart_controller.js +29 -3
  6. data/app/assets/javascripts/janela/frame_controller.js +15 -0
  7. data/app/assets/stylesheets/janela.css +16 -8
  8. data/app/controllers/janela/application_controller.rb +7 -0
  9. data/app/controllers/janela/panes_controller.rb +22 -7
  10. data/app/controllers/janela/queries_controller.rb +2 -1
  11. data/app/helpers/janela/frames_helper.rb +26 -7
  12. data/app/models/janela/frame.rb +49 -0
  13. data/app/models/janela/pane.rb +67 -4
  14. data/app/models/janela/query.rb +10 -2
  15. data/app/views/janela/frames/_content.html.erb +26 -0
  16. data/app/views/janela/frames/_frame.html.erb +9 -1
  17. data/app/views/janela/frames/_pane.html.erb +2 -2
  18. data/app/views/janela/panes/_content_form.html.erb +33 -0
  19. data/app/views/janela/panes/_row.html.erb +1 -1
  20. data/app/views/janela/panes/edit.html.erb +5 -1
  21. data/app/views/janela/panes/new.html.erb +6 -1
  22. data/app/views/janela/queries/_query.html.erb +15 -11
  23. data/config/locales/en.yml +5 -0
  24. data/db/migrate/20260924000001_add_content_to_janela_panes.rb +16 -0
  25. data/db/migrate/20260924000002_add_key_to_janela_frames.rb +10 -0
  26. data/db/migrate/20260928000001_add_default_filter_to_janela_frames.rb +10 -0
  27. data/docs/composing.md +288 -0
  28. data/docs/decisions/038-a-ratio-is-a-measure-of-its-own.md +194 -0
  29. data/docs/decisions/039-a-pane-can-hold-words-and-only-code-writes-markup.md +168 -0
  30. data/docs/decisions/040-a-host-can-fix-a-frames-filter.md +145 -0
  31. data/docs/decisions/041-a-host-finds-its-frame-by-owner-and-key.md +112 -0
  32. data/docs/decisions/042-a-charts-title-is-a-figcaption.md +174 -0
  33. data/docs/decisions/043-a-frames-default-filter-names-the-model-it-narrows.md +163 -0
  34. data/docs/decisions/INDEX.md +19 -12
  35. data/docs/multi-tenancy.md +22 -0
  36. data/docs/naming.md +7 -0
  37. data/docs/roadmap.md +129 -8
  38. data/docs/theming.md +18 -16
  39. data/lib/janela/definition.rb +8 -0
  40. data/lib/janela/version.rb +1 -1
  41. metadata +20 -18
data/docs/theming.md CHANGED
@@ -31,7 +31,7 @@ Three, and setting them moves everything that depends on them.
31
31
  | --- | --- | --- |
32
32
  | `--janela-space` | `0.25rem` | The base unit of the whole spacing scale. Every gap and padding is a multiple of it. |
33
33
  | `--janela-line` | `rgba(128, 128, 128, 0.3)` | Rules between rows, borders on cards and fields. |
34
- | `--janela-accent` | `rgb(54, 162, 235)` | A selected value, a hovered card. |
34
+ | `--janela-accent` | `rgb(54, 162, 235)` | A selected value, a hovered card, a chart's bars (#62). |
35
35
 
36
36
  ```css
37
37
  :root {
@@ -64,22 +64,27 @@ the names a theme spends most of its time on.
64
64
 
65
65
  | Class | On | Rendered when |
66
66
  | --- | --- | --- |
67
- | `janela-pane` | `<table>`, `<p>` or `<canvas>` | every pane, whatever the renderer |
67
+ | `janela-pane` | `<table>`, `<p>`, `<figure>` or `<div>` | every pane, whatever the renderer |
68
68
  | `janela-value` | `<p>` | a single value pane |
69
69
  | `janela-value-label` | `<span>` | its caption |
70
70
  | `janela-value-number` | `<strong>` | the number itself |
71
- | `janela-chart` | `<canvas>` | a bar or line pane |
71
+ | `janela-chart` | `<canvas>` | a bar or line pane, inside its `<figure>` |
72
+ | `janela-chart-title` | `<figcaption>` | its caption (ADR 042) |
72
73
  | `janela-empty` | `<p>` | a pane whose query returned nothing |
73
74
  | `janela-error` | `<p>` | a pane that could not be read |
75
+ | `janela-content` | `<div>` | a stored pane holding words or a host partial rather than a query (ADR 039) |
76
+ | `janela-content-heading` | `<h2>` | a text pane's heading |
74
77
 
75
- A table pane also renders a `<caption>`, its accessible name, and a
76
- chart pane carries the same string as `aria-label`.
78
+ A table pane renders a `<caption>` and a chart pane a `<figcaption>`,
79
+ each its own accessible name; the chart's canvas points to its
80
+ figcaption with `aria-labelledby` rather than repeating the string in
81
+ `aria-label`, so the two cannot drift apart (ADR 042).
77
82
 
78
83
  ### Hiding a heading you already wrote
79
84
 
80
- Put `janela-own-headings` on any ancestor and a pane's caption and a
81
- single value's label are hidden from sight while staying in the
82
- accessibility tree.
85
+ Put `janela-own-headings` on any ancestor and a table's caption, a
86
+ single value's label and a chart's title are hidden from sight while
87
+ staying in the accessibility tree.
83
88
 
84
89
  ```erb
85
90
  <div class="janela-own-headings">
@@ -89,14 +94,11 @@ accessibility tree.
89
94
  ```
90
95
 
91
96
  Use it when your own markup already says what the pane is, so the text
92
- is not on screen twice. It hides rather than removes on purpose: a table
93
- with no caption has no accessible name, so a screen reader lands on a
94
- grid of numbers with nothing to say what they measure. `display: none`
95
- would do that, which is why this rule ships here rather than being left
96
- for each host to write.
97
-
98
- A chart pane needs nothing: its title is only ever an `aria-label` and
99
- was never drawn.
97
+ is not on screen twice. It hides rather than removes on purpose: a pane
98
+ with no visible caption still needs its accessible name, so a screen
99
+ reader lands on a grid of numbers with nothing to say what they
100
+ measure. `display: none` would do that, which is why this rule ships
101
+ here rather than being left for each host to write.
100
102
 
101
103
  ## What is not the contract
102
104
 
@@ -97,6 +97,14 @@ module Janela
97
97
  dimensions.values.filter_map(&:through).map(&:to_s).uniq
98
98
  end
99
99
 
100
+ # A filter the host fixed for a render (ADR 040), applied as its own
101
+ # condition before the reader's, so the reader's can only narrow inside
102
+ # it. The same bounds as any filter: declared dimensions, ADR 025's
103
+ # predicates and value limit.
104
+ def narrow(relation, conditions)
105
+ filter(relation, conditions.to_h)
106
+ end
107
+
100
108
  private
101
109
  def filter(relation, params)
102
110
  return relation if params.empty?
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Janela
4
- VERSION = "0.8.0"
4
+ VERSION = "0.10.0"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: janela
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jay Killeen
@@ -114,6 +114,7 @@ files:
114
114
  - app/models/janela/query.rb
115
115
  - app/models/janela/snapshot.rb
116
116
  - app/views/janela/frames/_card.html.erb
117
+ - app/views/janela/frames/_content.html.erb
117
118
  - app/views/janela/frames/_form.html.erb
118
119
  - app/views/janela/frames/_frame.html.erb
119
120
  - app/views/janela/frames/_pane.html.erb
@@ -121,6 +122,7 @@ files:
121
122
  - app/views/janela/frames/index.html.erb
122
123
  - app/views/janela/frames/new.html.erb
123
124
  - app/views/janela/frames/show.html.erb
125
+ - app/views/janela/panes/_content_form.html.erb
124
126
  - app/views/janela/panes/_form.html.erb
125
127
  - app/views/janela/panes/_row.html.erb
126
128
  - app/views/janela/panes/edit.html.erb
@@ -137,6 +139,10 @@ files:
137
139
  - db/migrate/20260916000001_create_janela_frames.rb
138
140
  - db/migrate/20260916000002_create_janela_panes.rb
139
141
  - db/migrate/20260921000001_add_owner_to_janela_snapshots.rb
142
+ - db/migrate/20260924000001_add_content_to_janela_panes.rb
143
+ - db/migrate/20260924000002_add_key_to_janela_frames.rb
144
+ - db/migrate/20260928000001_add_default_filter_to_janela_frames.rb
145
+ - docs/composing.md
140
146
  - docs/decisions/001-built-to-be-forked.md
141
147
  - docs/decisions/002-measures-and-dimensions-over-ransack.md
142
148
  - docs/decisions/003-cross-filtering-with-turbo-frames.md
@@ -174,6 +180,12 @@ files:
174
180
  - docs/decisions/035-a-check-does-what-janela-does-or-says-what-it-saw.md
175
181
  - docs/decisions/036-janela-publishes-what-a-theme-may-target.md
176
182
  - docs/decisions/037-what-1-0-means.md
183
+ - docs/decisions/038-a-ratio-is-a-measure-of-its-own.md
184
+ - docs/decisions/039-a-pane-can-hold-words-and-only-code-writes-markup.md
185
+ - docs/decisions/040-a-host-can-fix-a-frames-filter.md
186
+ - docs/decisions/041-a-host-finds-its-frame-by-owner-and-key.md
187
+ - docs/decisions/042-a-charts-title-is-a-figcaption.md
188
+ - docs/decisions/043-a-frames-default-filter-names-the-model-it-narrows.md
177
189
  - docs/decisions/INDEX.md
178
190
  - docs/multi-tenancy.md
179
191
  - docs/naming.md
@@ -199,24 +211,14 @@ metadata:
199
211
  bug_tracker_uri: https://github.com/retail-tasker/janela/issues
200
212
  rubygems_mfa_required: 'true'
201
213
  post_install_message: |
202
- Janela 0.8.0 raises where it used to do nothing. One thing to act on,
203
- and one to read.
214
+ Janela 0.10.0: a migration if you use stored frames. Nobody else
215
+ has anything to do.
204
216
 
205
- 1. If you set Janela.parent_controller anywhere but an initializer, it
206
- now raises instead of being ignored in silence. config.to_prepare
207
- and config.after_initialize are both too late, and the README's own
208
- layout recipe is a to_prepare block. Until now your dashboards kept
209
- inheriting whatever was named first, so your authentication and
210
- policy_scope were not the ones you wrote (ADR 035).
211
-
212
- 2. bin/rails janela:doctor reports findings it could not reach before,
213
- including a Pundit host with no policy for Janela::Frame or
214
- Janela::Snapshot, which used to pass the doctor and raise on every
215
- request. Expect things that were always true and never printed.
216
-
217
- Also: the class names on Janela's own pages are no longer public API.
218
- They are scoped under janela-page and may change in any release. What
219
- your own markup contains is unchanged and is listed in docs/theming.md.
217
+ A frame can now carry its own permanent filter as data, not only
218
+ the per-record one you pass in code (ADR 043):
219
+ bin/rails janela:install:migrations && bin/rails db:migrate
220
+ janela_frames gains default_model and default_where, both nil on
221
+ every existing frame. Nothing changes unless you set them.
220
222
 
221
223
  Steps: UPGRADING.md in this gem, or
222
224
  https://github.com/retail-tasker/janela/blob/main/UPGRADING.md