janela 0.8.0 → 0.9.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -0
- data/README.md +33 -2
- data/UPGRADING.md +48 -0
- data/app/assets/javascripts/janela/frame_controller.js +15 -0
- data/app/assets/stylesheets/janela.css +16 -8
- data/app/controllers/janela/application_controller.rb +7 -0
- data/app/controllers/janela/panes_controller.rb +22 -7
- data/app/controllers/janela/queries_controller.rb +2 -1
- data/app/helpers/janela/frames_helper.rb +26 -7
- data/app/models/janela/frame.rb +20 -0
- data/app/models/janela/pane.rb +67 -4
- data/app/models/janela/query.rb +7 -2
- data/app/views/janela/frames/_content.html.erb +26 -0
- data/app/views/janela/frames/_frame.html.erb +9 -1
- data/app/views/janela/frames/_pane.html.erb +2 -2
- data/app/views/janela/panes/_content_form.html.erb +33 -0
- data/app/views/janela/panes/_row.html.erb +1 -1
- data/app/views/janela/panes/edit.html.erb +5 -1
- data/app/views/janela/panes/new.html.erb +6 -1
- data/app/views/janela/queries/_query.html.erb +15 -11
- data/config/locales/en.yml +5 -0
- data/db/migrate/20260924000001_add_content_to_janela_panes.rb +16 -0
- data/db/migrate/20260924000002_add_key_to_janela_frames.rb +10 -0
- data/docs/composing.md +269 -0
- data/docs/decisions/038-a-ratio-is-a-measure-of-its-own.md +194 -0
- data/docs/decisions/039-a-pane-can-hold-words-and-only-code-writes-markup.md +168 -0
- data/docs/decisions/040-a-host-can-fix-a-frames-filter.md +145 -0
- data/docs/decisions/041-a-host-finds-its-frame-by-owner-and-key.md +112 -0
- data/docs/decisions/042-a-charts-title-is-a-figcaption.md +174 -0
- data/docs/decisions/INDEX.md +18 -12
- data/docs/multi-tenancy.md +22 -0
- data/docs/naming.md +7 -0
- data/docs/roadmap.md +129 -8
- data/docs/theming.md +17 -15
- data/lib/janela/definition.rb +8 -0
- data/lib/janela/version.rb +1 -1
- metadata +25 -17
data/docs/multi-tenancy.md
CHANGED
|
@@ -149,6 +149,28 @@ save failed silently. `bin/rails janela:doctor` reports this for you:
|
|
|
149
149
|
it asks your policy for a scope over frames and looks for an owner in
|
|
150
150
|
what comes back.
|
|
151
151
|
|
|
152
|
+
### A frame of your own for a page
|
|
153
|
+
|
|
154
|
+
Your code finds a frame it keeps for one of its pages by owner and key
|
|
155
|
+
(ADR 041):
|
|
156
|
+
|
|
157
|
+
```ruby
|
|
158
|
+
Janela::Frame.for(Current.account, :overview)
|
|
159
|
+
Janela::Frame.for(queue, :analytics) { |frame| frame.name = "#{queue.name} analytics" }
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
When the owner is the tenant, nothing changes in your policy. When it is
|
|
163
|
+
one of your own records, such as the queue above, the frame belongs to
|
|
164
|
+
the tenant through that record, and your scope has to say so or the
|
|
165
|
+
frame is hidden from the people it was made for:
|
|
166
|
+
|
|
167
|
+
```ruby
|
|
168
|
+
def resolve
|
|
169
|
+
scope.where(owner: Current.account)
|
|
170
|
+
.or(scope.where(owner_type: "Queue", owner_id: Current.account.queues.select(:id)))
|
|
171
|
+
end
|
|
172
|
+
```
|
|
173
|
+
|
|
152
174
|
## Snapshots
|
|
153
175
|
|
|
154
176
|
A snapshot carries the same polymorphic owner a frame does, so your
|
data/docs/naming.md
CHANGED
|
@@ -44,6 +44,13 @@ from the thing itself rather than from a list of synonyms for "chart".
|
|
|
44
44
|
| **Query** | The runtime object that calculates one pane | Not a window word, on purpose. It is an implementation detail rather than something a person arranges, so it gets the plain name for what it does. |
|
|
45
45
|
| **Grid** | How a frame is divided: `columns`, `gap`, and each pane's `span` | A window is divided into panes, and the grid is the division. Small integers that choose a class the stylesheet already defines, so nothing an analyst types reaches CSS (ADR 016). |
|
|
46
46
|
| **Vitral** | The optional stained glass theme | A stained glass window, in the same language. See ADR 023. |
|
|
47
|
+
| **Vista** | The roadmap | The view through the window. What you can see from here is also what is ahead: *outlook* and *prospect* carry the same double meaning in English, and this one carries it in Portuguese. |
|
|
48
|
+
| **Horizonte** | The roadmap's far half: wanted, not blocking a release | The horizon is the edge of what you can see. Work still in sight, as against work that is not in the picture at all. |
|
|
49
|
+
|
|
50
|
+
The last two are a step away from anatomy. A window's parts name the
|
|
51
|
+
things a host arranges; what you see through it names the things the
|
|
52
|
+
project has not built yet. Both halves come from the same object, which
|
|
53
|
+
is the point of picking an object rather than a list of synonyms.
|
|
47
54
|
|
|
48
55
|
The anatomy was argued over before it was settled. *Sash* was
|
|
49
56
|
considered for the dashboard and rejected: a sash is one layer inside a
|
data/docs/roadmap.md
CHANGED
|
@@ -2,7 +2,125 @@
|
|
|
2
2
|
Topics: roadmap, releases, scope, planning
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
-
#
|
|
5
|
+
# Vista
|
|
6
|
+
|
|
7
|
+
<p style="text-align: center;">Vista shows where Janela is heading.</p>
|
|
8
|
+
|
|
9
|
+
<svg viewBox="0 0 680 360" width="100%" role="img" aria-labelledby="vista-title vista-desc" class="vista-art" style="display: block; margin: 1.75rem 0; border-radius: 10px;">
|
|
10
|
+
<title id="vista-title">Vista</title>
|
|
11
|
+
<desc id="vista-desc">Sea and sky with a horizon across them. Eight lights burn on the near water, one for each issue in 1.0, and three sit far off at the horizon for the work still in sight past it. A low sun rises and sets on the horizon as the pointer moves up and down, and never climbs higher: the sky above is empty, because what is not coming is not in view.</desc>
|
|
12
|
+
|
|
13
|
+
<style>
|
|
14
|
+
.vista-art .v-far { transform: translate3d(calc(var(--vitral-shift-x, 0) * 13px), calc(var(--vitral-shift-y, 0) * 7px), 0); transition: transform .45s cubic-bezier(.2,.7,.3,1); }
|
|
15
|
+
.vista-art .v-mid { transform: translate3d(calc(var(--vitral-shift-x, 0) * 6px), calc(var(--vitral-shift-y, 0) * 3px), 0); transition: transform .45s cubic-bezier(.2,.7,.3,1); }
|
|
16
|
+
.vista-art .v-near { transform: translate3d(calc(var(--vitral-shift-x, 0) * -8px), calc(var(--vitral-shift-y, 0) * -4px), 0); transition: transform .45s cubic-bezier(.2,.7,.3,1); }
|
|
17
|
+
.vista-art .v-glow-a { opacity: calc(.6 - var(--vitral-shift-x, 0) * 1.2); transform: translate3d(calc(var(--vitral-shift-x, 0) * -40px), calc(var(--vitral-shift-y, 0) * 16px), 0); transition: transform .9s cubic-bezier(.2,.7,.3,1), opacity .9s ease; }
|
|
18
|
+
.vista-art .v-glow-b { opacity: calc(.6 + var(--vitral-shift-x, 0) * 1.2); transform: translate3d(calc(var(--vitral-shift-x, 0) * 44px), calc(var(--vitral-shift-y, 0) * -14px), 0); transition: transform .9s cubic-bezier(.2,.7,.3,1), opacity .9s ease; }
|
|
19
|
+
.vista-art .v-sun { transform: translate3d(calc(var(--vitral-shift-x, 0) * 10px), calc(var(--vitral-shift-y, 0) * 84px), 0); transition: transform 1.1s cubic-bezier(.2,.7,.3,1); }
|
|
20
|
+
.vista-art .v-glint { opacity: calc(.45 - var(--vitral-shift-y, 0) * .9); transform: translate3d(calc(var(--vitral-shift-x, 0) * 10px), 0, 0); transition: opacity 1.1s ease, transform 1.1s cubic-bezier(.2,.7,.3,1); }
|
|
21
|
+
@media (prefers-reduced-motion: reduce) {
|
|
22
|
+
.vista-art .v-sun, .vista-art .v-glint { transform: none; opacity: .45; }
|
|
23
|
+
.vista-art .v-far, .vista-art .v-mid, .vista-art .v-near, .vista-art .v-glow-a, .vista-art .v-glow-b { transform: none; opacity: .6; }
|
|
24
|
+
}
|
|
25
|
+
</style>
|
|
26
|
+
|
|
27
|
+
<defs>
|
|
28
|
+
<clipPath id="vFrame"><rect x="0" y="0" width="680" height="360" rx="10"/></clipPath>
|
|
29
|
+
<clipPath id="vAbove"><rect x="0" y="0" width="680" height="196"/></clipPath>
|
|
30
|
+
<radialGradient id="vSun">
|
|
31
|
+
<stop offset="0" stop-color="#FFF4D6" stop-opacity="0.95"/>
|
|
32
|
+
<stop offset="0.7" stop-color="#FFD58A" stop-opacity="0.9"/>
|
|
33
|
+
<stop offset="1" stop-color="#F7A96B" stop-opacity="0.75"/>
|
|
34
|
+
</radialGradient>
|
|
35
|
+
<radialGradient id="vSunHalo">
|
|
36
|
+
<stop offset="0" stop-color="#FFD98F" stop-opacity="0.5"/>
|
|
37
|
+
<stop offset="1" stop-color="#F7A96B" stop-opacity="0"/>
|
|
38
|
+
</radialGradient>
|
|
39
|
+
<linearGradient id="vSky" x1="0" y1="0" x2="0.22" y2="1">
|
|
40
|
+
<stop offset="0" stop-color="#5B49C9" stop-opacity="0.54"/>
|
|
41
|
+
<stop offset="0.38" stop-color="#8A6EE4" stop-opacity="0.34"/>
|
|
42
|
+
<stop offset="0.7" stop-color="#E06082" stop-opacity="0.29"/>
|
|
43
|
+
<stop offset="1" stop-color="#F0B046" stop-opacity="0.46"/>
|
|
44
|
+
</linearGradient>
|
|
45
|
+
<linearGradient id="vSea" x1="0" y1="0" x2="0.08" y2="1">
|
|
46
|
+
<stop offset="0" stop-color="#F0B046" stop-opacity="0.34"/>
|
|
47
|
+
<stop offset="0.22" stop-color="#1CA89E" stop-opacity="0.38"/>
|
|
48
|
+
<stop offset="1" stop-color="#132F5C" stop-opacity="0.78"/>
|
|
49
|
+
</linearGradient>
|
|
50
|
+
<radialGradient id="vLamp">
|
|
51
|
+
<stop offset="0" stop-color="#FFE9B8" stop-opacity="0.78"/>
|
|
52
|
+
<stop offset="1" stop-color="#FFD98F" stop-opacity="0"/>
|
|
53
|
+
</radialGradient>
|
|
54
|
+
<radialGradient id="vP1"><stop offset="0" stop-color="#367AEB" stop-opacity="0.6"/><stop offset="1" stop-color="#367AEB" stop-opacity="0"/></radialGradient>
|
|
55
|
+
<radialGradient id="vP2"><stop offset="0" stop-color="#1CA89E" stop-opacity="0.30"/><stop offset="1" stop-color="#1CA89E" stop-opacity="0"/></radialGradient>
|
|
56
|
+
<radialGradient id="vP3"><stop offset="0" stop-color="#E06082" stop-opacity="0.5"/><stop offset="1" stop-color="#E06082" stop-opacity="0"/></radialGradient>
|
|
57
|
+
</defs>
|
|
58
|
+
|
|
59
|
+
<g clip-path="url(#vFrame)">
|
|
60
|
+
<g class="v-far">
|
|
61
|
+
<rect x="-30" y="-30" width="740" height="256" fill="url(#vSky)"/>
|
|
62
|
+
<ellipse class="v-glow-a" cx="150" cy="104" rx="230" ry="132" fill="url(#vP1)"/>
|
|
63
|
+
<ellipse class="v-glow-b" cx="520" cy="140" rx="250" ry="100" fill="url(#vP3)"/>
|
|
64
|
+
</g>
|
|
65
|
+
|
|
66
|
+
<g clip-path="url(#vAbove)">
|
|
67
|
+
<g class="v-sun">
|
|
68
|
+
<circle cx="432" cy="192" r="96" fill="url(#vSunHalo)"/>
|
|
69
|
+
<circle cx="432" cy="192" r="24" fill="url(#vSun)"/>
|
|
70
|
+
</g>
|
|
71
|
+
</g>
|
|
72
|
+
<g class="v-mid">
|
|
73
|
+
<rect x="-30" y="196" width="740" height="204" fill="url(#vSea)"/>
|
|
74
|
+
<ellipse cx="580" cy="288" rx="220" ry="124" fill="url(#vP2)"/>
|
|
75
|
+
<path d="M6 200.0 h18 M46 200.0 h18 M80 200.0 h11 M145 200.0 h9 M173 200.0 h8 M204 200.0 h22 M235 200.0 h7 M266 200.0 h18 M305 200.0 h19 M339 200.0 h23 M372 200.0 h30 M424 200.0 h24 M490 200.0 h16 M519 200.0 h30 M555 200.0 h12 M581 200.0 h30 M618 200.0 h22 M650 200.0 h9" stroke="#FFF3DA" stroke-opacity="0.28" stroke-width="1" stroke-linecap="round"/>
|
|
76
|
+
<path d="M74 204.2 h12 M100 204.2 h12 M195 204.2 h28 M245 204.2 h13 M384 204.2 h10 M404 204.2 h23 M441 204.2 h31 M527 204.2 h30 M568 204.2 h12 M604 204.2 h12 M639 204.2 h23 M669 204.2 h8" stroke="#FFF3DA" stroke-opacity="0.28" stroke-width="1" stroke-linecap="round"/>
|
|
77
|
+
<path d="M127 209.4 h23 M169 209.4 h16 M278 209.4 h32 M329 209.4 h27 M398 209.4 h27 M431 209.4 h25 M477 209.4 h17 M501 209.4 h23 M548 209.4 h28 M598 209.4 h33 M650 209.4 h32" stroke="#FFF3DA" stroke-opacity="0.27" stroke-width="1" stroke-linecap="round"/>
|
|
78
|
+
<path d="M6 215.8 h32 M56 215.8 h27 M148 215.8 h38 M208 215.8 h20 M247 215.8 h22 M370 215.8 h23 M487 215.8 h35 M538 215.8 h35 M593 215.8 h15 M631 215.8 h36" stroke="#FFF3DA" stroke-opacity="0.26" stroke-width="1" stroke-linecap="round"/>
|
|
79
|
+
<path d="M6 223.7 h28 M44 223.7 h26 M96 223.7 h32 M141 223.7 h15 M169 223.7 h17 M207 223.7 h26 M258 223.7 h41 M308 223.7 h11 M326 223.7 h32 M492 223.7 h30 M543 223.7 h31" stroke="#FFF3DA" stroke-opacity="0.25" stroke-width="1" stroke-linecap="round"/>
|
|
80
|
+
<path d="M56 233.5 h23 M99 233.5 h33 M149 233.5 h39 M197 233.5 h44 M252 233.5 h27 M308 233.5 h24 M361 233.5 h39 M477 233.5 h40 M542 233.5 h18 M591 233.5 h46 M664 233.5 h22" stroke="#FFF3DA" stroke-opacity="0.24" stroke-width="1" stroke-linecap="round"/>
|
|
81
|
+
<path d="M52 245.5 h34 M107 245.5 h13 M246 245.5 h33 M309 245.5 h40 M494 245.5 h38 M562 245.5 h35 M615 245.5 h46" stroke="#FFF3DA" stroke-opacity="0.22" stroke-width="1" stroke-linecap="round"/>
|
|
82
|
+
<path d="M6 260.4 h52 M147 260.4 h37 M193 260.4 h58 M271 260.4 h50 M414 260.4 h33 M482 260.4 h26 M521 260.4 h33 M589 260.4 h35 M639 260.4 h42" stroke="#FFF3DA" stroke-opacity="0.20" stroke-width="1" stroke-linecap="round"/>
|
|
83
|
+
<path d="M79 278.8 h28 M126 278.8 h34 M310 278.8 h39 M432 278.8 h49 M507 278.8 h60 M605 278.8 h28 M669 278.8 h63" stroke="#FFF3DA" stroke-opacity="0.17" stroke-width="1" stroke-linecap="round"/>
|
|
84
|
+
<path d="M296 301.6 h69 M404 301.6 h26 M521 301.6 h73 M610 301.6 h49" stroke="#FFF3DA" stroke-opacity="0.14" stroke-width="1" stroke-linecap="round"/>
|
|
85
|
+
<path d="M156 329.6 h58 M314 329.6 h91 M422 329.6 h26 M479 329.6 h75 M587 329.6 h58" stroke="#FFF3DA" stroke-opacity="0.09" stroke-width="1" stroke-linecap="round"/>
|
|
86
|
+
<circle cx="186" cy="202" r="8" fill="url(#vLamp)" opacity="0.2"/>
|
|
87
|
+
<circle cx="186" cy="202" r="1.7" fill="#FFF3DC" opacity="0.55"/>
|
|
88
|
+
<circle cx="322" cy="201" r="8" fill="url(#vLamp)" opacity="0.2"/>
|
|
89
|
+
<circle cx="322" cy="201" r="1.5" fill="#FFF3DC" opacity="0.55"/>
|
|
90
|
+
<circle cx="540" cy="202.5" r="8" fill="url(#vLamp)" opacity="0.2"/>
|
|
91
|
+
<circle cx="540" cy="202.5" r="1.6" fill="#FFF3DC" opacity="0.55"/>
|
|
92
|
+
</g>
|
|
93
|
+
|
|
94
|
+
<g class="v-glint" stroke="#FFE2A6" stroke-linecap="round">
|
|
95
|
+
<path d="M404 201 h56" stroke-width="2" stroke-opacity="0.7"/>
|
|
96
|
+
<path d="M412 207 h40" stroke-width="1.6" stroke-opacity="0.55"/>
|
|
97
|
+
<path d="M418 214 h28" stroke-width="1.4" stroke-opacity="0.42"/>
|
|
98
|
+
<path d="M423 223 h18" stroke-width="1.2" stroke-opacity="0.3"/>
|
|
99
|
+
<path d="M427 234 h10" stroke-width="1" stroke-opacity="0.2"/>
|
|
100
|
+
</g>
|
|
101
|
+
<g class="v-near">
|
|
102
|
+
<circle cx="74" cy="330" r="22" fill="url(#vLamp)" opacity="0.4"/>
|
|
103
|
+
<circle cx="74" cy="330" r="4.3" fill="#FFF6E2" opacity="0.88"/>
|
|
104
|
+
<circle cx="154" cy="302" r="20" fill="url(#vLamp)" opacity="0.4"/>
|
|
105
|
+
<circle cx="154" cy="302" r="4.0" fill="#FFF6E2" opacity="0.88"/>
|
|
106
|
+
<circle cx="238" cy="340" r="21" fill="url(#vLamp)" opacity="0.4"/>
|
|
107
|
+
<circle cx="238" cy="340" r="4.2" fill="#FFF6E2" opacity="0.88"/>
|
|
108
|
+
<circle cx="312" cy="283" r="18" fill="url(#vLamp)" opacity="0.4"/>
|
|
109
|
+
<circle cx="312" cy="283" r="3.6" fill="#FFF6E2" opacity="0.88"/>
|
|
110
|
+
<circle cx="392" cy="314" r="19" fill="url(#vLamp)" opacity="0.4"/>
|
|
111
|
+
<circle cx="392" cy="314" r="3.8" fill="#FFF6E2" opacity="0.88"/>
|
|
112
|
+
<circle cx="470" cy="268" r="16" fill="url(#vLamp)" opacity="0.4"/>
|
|
113
|
+
<circle cx="470" cy="268" r="3.3" fill="#FFF6E2" opacity="0.88"/>
|
|
114
|
+
<circle cx="552" cy="294" r="18" fill="url(#vLamp)" opacity="0.4"/>
|
|
115
|
+
<circle cx="552" cy="294" r="3.5" fill="#FFF6E2" opacity="0.88"/>
|
|
116
|
+
<circle cx="630" cy="256" r="16" fill="url(#vLamp)" opacity="0.4"/>
|
|
117
|
+
<circle cx="630" cy="256" r="3.1" fill="#FFF6E2" opacity="0.88"/>
|
|
118
|
+
</g>
|
|
119
|
+
|
|
120
|
+
<path d="M0 196 H680" stroke="#FFF1D2" stroke-opacity="0.72" stroke-width="1.5" fill="none"/>
|
|
121
|
+
<text x="664" y="218" text-anchor="end" font-size="10" letter-spacing="0.13em" fill="#FFF4DE" opacity="0.6">HORIZONTE</text>
|
|
122
|
+
</g>
|
|
123
|
+
</svg>
|
|
6
124
|
|
|
7
125
|
Janela is alpha. It works, it is tested against a real Rails application
|
|
8
126
|
in a real browser, and its public surface has changed in three of the
|
|
@@ -39,6 +157,8 @@ A check nobody can prove is working is a check nobody should rely on.
|
|
|
39
157
|
|
|
40
158
|
## In 1.0
|
|
41
159
|
|
|
160
|
+
The eight lights burning in the near ground.
|
|
161
|
+
|
|
42
162
|
| Issue | What |
|
|
43
163
|
| --- | --- |
|
|
44
164
|
| [#24](https://github.com/retail-tasker/janela/issues/24) | A chart's height and aspect ratio are the host's to set |
|
|
@@ -53,10 +173,10 @@ A check nobody can prove is working is a check nobody should rely on.
|
|
|
53
173
|
Progress is tracked on the
|
|
54
174
|
[1.0 milestone](https://github.com/retail-tasker/janela/milestone/2).
|
|
55
175
|
|
|
56
|
-
##
|
|
176
|
+
## Horizonte
|
|
57
177
|
|
|
58
|
-
|
|
59
|
-
refusal.
|
|
178
|
+
The three lights far off at the horizon. Wanted, not blocking a stable
|
|
179
|
+
release, and being on this list is not a refusal.
|
|
60
180
|
|
|
61
181
|
- **Drill-down on time panes** ([#18](https://github.com/retail-tasker/janela/issues/18)).
|
|
62
182
|
Clicking a month could filter every other pane to it, or narrow that
|
|
@@ -70,10 +190,11 @@ refusal.
|
|
|
70
190
|
|
|
71
191
|
## Not coming
|
|
72
192
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
193
|
+
The sky above the horizon is empty, and that is the honest part of the
|
|
194
|
+
picture. Janela is meant to be small enough that forking it and adding
|
|
195
|
+
your own piece is a normal way to use it. These are the things you would
|
|
196
|
+
be adding yourself, and each is left out because something you already
|
|
197
|
+
run does it better.
|
|
77
198
|
|
|
78
199
|
Natural-language query. A separate data warehouse. A row-level-security
|
|
79
200
|
subsystem, because your application already has Pundit or CanCanCan and
|
data/docs/theming.md
CHANGED
|
@@ -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 `<
|
|
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
|
|
76
|
-
|
|
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
|
|
81
|
-
single value's label are hidden from sight while
|
|
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
|
|
93
|
-
with no caption
|
|
94
|
-
grid of numbers with nothing to say what they
|
|
95
|
-
would do that, which is why this rule ships
|
|
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
|
|
data/lib/janela/definition.rb
CHANGED
|
@@ -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?
|
data/lib/janela/version.rb
CHANGED
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.
|
|
4
|
+
version: 0.9.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,9 @@ 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
|
+
- docs/composing.md
|
|
140
145
|
- docs/decisions/001-built-to-be-forked.md
|
|
141
146
|
- docs/decisions/002-measures-and-dimensions-over-ransack.md
|
|
142
147
|
- docs/decisions/003-cross-filtering-with-turbo-frames.md
|
|
@@ -174,6 +179,11 @@ files:
|
|
|
174
179
|
- docs/decisions/035-a-check-does-what-janela-does-or-says-what-it-saw.md
|
|
175
180
|
- docs/decisions/036-janela-publishes-what-a-theme-may-target.md
|
|
176
181
|
- docs/decisions/037-what-1-0-means.md
|
|
182
|
+
- docs/decisions/038-a-ratio-is-a-measure-of-its-own.md
|
|
183
|
+
- docs/decisions/039-a-pane-can-hold-words-and-only-code-writes-markup.md
|
|
184
|
+
- docs/decisions/040-a-host-can-fix-a-frames-filter.md
|
|
185
|
+
- docs/decisions/041-a-host-finds-its-frame-by-owner-and-key.md
|
|
186
|
+
- docs/decisions/042-a-charts-title-is-a-figcaption.md
|
|
177
187
|
- docs/decisions/INDEX.md
|
|
178
188
|
- docs/multi-tenancy.md
|
|
179
189
|
- docs/naming.md
|
|
@@ -199,24 +209,22 @@ metadata:
|
|
|
199
209
|
bug_tracker_uri: https://github.com/retail-tasker/janela/issues
|
|
200
210
|
rubygems_mfa_required: 'true'
|
|
201
211
|
post_install_message: |
|
|
202
|
-
Janela 0.
|
|
203
|
-
|
|
212
|
+
Janela 0.9.0: a migration if you use stored frames, and a markup
|
|
213
|
+
check if you wrote CSS or JavaScript against a chart pane.
|
|
204
214
|
|
|
205
|
-
1. If you
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
215
|
+
1. If you use stored frames, take two migrations together:
|
|
216
|
+
bin/rails janela:install:migrations && bin/rails db:migrate
|
|
217
|
+
A pane can now hold words or a host partial instead of a query
|
|
218
|
+
(ADR 039), and Janela::Frame.for(owner, key) finds a frame kept
|
|
219
|
+
for one of your pages without a column of your own (ADR 041).
|
|
220
|
+
Existing frames and panes are unaffected either way.
|
|
211
221
|
|
|
212
|
-
2.
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
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.
|
|
222
|
+
2. A chart pane's title is now a visible <figcaption> inside a
|
|
223
|
+
<figure> wrapping the canvas, not only the canvas's aria-label
|
|
224
|
+
(ADR 042). janela-pane moved from the <canvas> to the <figure>;
|
|
225
|
+
janela-chart stayed on the canvas. If you selected
|
|
226
|
+
.janela-pane.janela-chart as one element, or read a chart's
|
|
227
|
+
title from aria-label, both need updating.
|
|
220
228
|
|
|
221
229
|
Steps: UPGRADING.md in this gem, or
|
|
222
230
|
https://github.com/retail-tasker/janela/blob/main/UPGRADING.md
|