studio-engine 0.22.0 → 0.24.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 +103 -0
- data/README.md +22 -0
- data/app/assets/javascripts/studio/sortable.js +11 -0
- data/app/assets/tailwind/studio_engine/engine.css +59 -0
- data/app/controllers/concerns/studio/board/reorderable.rb +97 -0
- data/app/controllers/concerns/studio/error_handling.rb +34 -6
- data/app/models/concerns/studio/board/rankable.rb +84 -0
- data/app/views/components/_badge.html.erb +4 -2
- data/app/views/layouts/studio/_head.html.erb +10 -2
- data/app/views/layouts/studio/_smooth_load.html.erb +15 -0
- data/app/views/studio/_board_assets.html.erb +341 -0
- data/app/views/studio/board/_board.html.erb +151 -0
- data/app/views/studio/board/_card_shell.html.erb +47 -0
- data/app/views/studio/board/_column.html.erb +80 -0
- data/app/views/style/_tasks.html.erb +82 -11
- data/app/views/style/board/_demo_card.html.erb +22 -0
- data/lib/studio/engine.rb +1 -0
- data/lib/studio/version.rb +1 -1
- data/lib/studio.rb +14 -0
- metadata +12 -6
|
@@ -1,13 +1,52 @@
|
|
|
1
1
|
<%# Tasks section of the living style guide (admin/style).
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
/
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
The shared board primitive, LIVE. Phase D lifted the columns / cards / drag +
|
|
4
|
+
optimistic move / reorder that the three near-identical McRitchie Studio boards
|
|
5
|
+
(tasks / news / content) each hand-rolled into one engine primitive
|
|
6
|
+
(studio/board/_board + the window.studioBoard factory + vendored SortableJS).
|
|
7
|
+
The first block below renders that real primitive with `demo: true` — you can
|
|
8
|
+
DRAG a card between columns and the move animates + toasts, but nothing POSTs.
|
|
9
|
+
The blocks under it stay a static reference: the stage-* badge palette
|
|
10
|
+
(components/_badge) that is the pipeline spine, and the standard-vs-custom
|
|
11
|
+
split of what a board inherits vs sets. %>
|
|
9
12
|
<%
|
|
10
|
-
#
|
|
13
|
+
# LIVE specimen — the real studio/board/_board primitive, demo mode. Plain Hash
|
|
14
|
+
# records (the style guide has no models); each card id becomes id="card-<id>".
|
|
15
|
+
# Each demo card carries its current `zone` (the column it sits in) — in a real
|
|
16
|
+
# board the record knows its own stage; here the Hash does.
|
|
17
|
+
live_board_columns = [
|
|
18
|
+
{ key: "designed", label: "Designed", badge_class: "stage-fresh",
|
|
19
|
+
cards: [
|
|
20
|
+
{ id: "engine-board-primitive", zone: "designed", title: "Engine board primitive", repo: "studio-engine", who: "SH" },
|
|
21
|
+
{ id: "coinflow-buy-rail", zone: "designed", title: "Coinflow buy rail", repo: "turf-monster", who: "JA" }
|
|
22
|
+
] },
|
|
23
|
+
{ key: "building", label: "Building", badge_class: "stage-shaping",
|
|
24
|
+
cards: [{ id: "navbar-rpc-preload", zone: "building", title: "Navbar RPC preload", repo: "turf-monster", who: "CA" }] },
|
|
25
|
+
{ key: "submitted", label: "Submitted", badge_class: "stage-structured",
|
|
26
|
+
cards: [{ id: "magic-link-ttl-bump", zone: "submitted", title: "Magic-link TTL bump", repo: "studio-engine", who: "SH" }] },
|
|
27
|
+
{ key: "shipped", label: "Shipped", badge_class: "stage-shipped",
|
|
28
|
+
cards: [{ id: "ses-email-backend", zone: "shipped", title: "SES email backend", repo: "mcritchie", who: "ST" }] }
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
# Copy-paste-for-an-agent usage. Built by array-join, NOT a heredoc: a heredoc as
|
|
32
|
+
# the last expression of an ERB scriptlet trips Erubi, and literal ERB tags in the
|
|
33
|
+
# body would close the tag. Plain render() calls read clearly for an agent.
|
|
34
|
+
board_usage_snippet = [
|
|
35
|
+
"# once at layout level (a <script> in the board template never runs):",
|
|
36
|
+
'render "studio/board_assets"',
|
|
37
|
+
"",
|
|
38
|
+
"# then the board itself:",
|
|
39
|
+
'render "studio/board/board",',
|
|
40
|
+
" columns: @columns, # [{ key:, label:, cards:, badge_class: }]",
|
|
41
|
+
' card_partial: "tasks/task_card",',
|
|
42
|
+
" reorder_url: tasks_reorder_path, # POST { slugs: [...], zone: }",
|
|
43
|
+
' move_url: "/tasks/:id.json", # PATCH { task: { stage: } }',
|
|
44
|
+
' move_param: { resource: "task", attr: "stage" },',
|
|
45
|
+
' live_channel: "deployments"'
|
|
46
|
+
].join("\n")
|
|
47
|
+
|
|
48
|
+
# The static reference palette below (unchanged): each column maps to a stage-*
|
|
49
|
+
# badge scheme.
|
|
11
50
|
board_columns = [
|
|
12
51
|
{ key: "stage-fresh", label: "Fresh", count: 2 },
|
|
13
52
|
{ key: "stage-shaping", label: "Shaping", count: 1 },
|
|
@@ -32,13 +71,45 @@
|
|
|
32
71
|
<h2 class="text-2xl font-bold text-heading">Tasks</h2>
|
|
33
72
|
<p class="text-muted text-sm max-w-2xl">
|
|
34
73
|
The shared board primitive that every board builds from — columns, cards, the
|
|
35
|
-
<code class="font-mono text-2xs">stage-*</code> badge palette, and the drag /
|
|
36
|
-
McRitchie Studio's <code class="font-mono text-2xs">/deployments</code> board is
|
|
37
|
-
|
|
74
|
+
<code class="font-mono text-2xs">stage-*</code> badge palette, and the drag / optimistic
|
|
75
|
+
move + reorder. McRitchie Studio's <code class="font-mono text-2xs">/deployments</code> board is
|
|
76
|
+
the top-of-line; the specimen below is the <strong>real</strong>
|
|
77
|
+
<code class="font-mono text-2xs">studio/board/board</code> primitive in
|
|
78
|
+
<code class="font-mono text-2xs">demo: true</code> mode — drag a card, no save.
|
|
38
79
|
</p>
|
|
39
80
|
</div>
|
|
40
81
|
|
|
41
|
-
<%# ---- The
|
|
82
|
+
<%# ---- The LIVE primitive (demo mode) --------------------------------- %>
|
|
83
|
+
<%# Render the factory once (a <script> in the board template would never run), then
|
|
84
|
+
the board. demo: true → drag animates + toasts locally, nothing POSTs. %>
|
|
85
|
+
<%= render "studio/board_assets" %>
|
|
86
|
+
<div class="space-y-3">
|
|
87
|
+
<div class="flex items-center gap-2">
|
|
88
|
+
<span class="badge" style="color: var(--color-success); border-color: var(--color-success)">Live</span>
|
|
89
|
+
<p class="label-upper"><code class="font-mono text-2xs">studio/board/board</code> · demo — drag a card between columns</p>
|
|
90
|
+
</div>
|
|
91
|
+
<%= render "studio/board/board",
|
|
92
|
+
demo: true,
|
|
93
|
+
columns: live_board_columns,
|
|
94
|
+
card_partial: "style/board/demo_card",
|
|
95
|
+
card_as: :card,
|
|
96
|
+
reorder_url: "#",
|
|
97
|
+
move_url: "#",
|
|
98
|
+
move_param: { resource: "task", attr: "stage" },
|
|
99
|
+
group: "studio-board-demo",
|
|
100
|
+
empty_label: "Drop tasks here" %>
|
|
101
|
+
<div class="relative" x-data="{ copied: false }">
|
|
102
|
+
<pre class="bg-inset text-body text-2xs rounded-lg px-3 py-2 pr-16 overflow-x-auto"><code x-ref="boardUsage"><%= board_usage_snippet %></code></pre>
|
|
103
|
+
<button type="button"
|
|
104
|
+
class="btn btn-neutral btn-sm absolute top-2 right-2"
|
|
105
|
+
aria-label="Copy usage snippet"
|
|
106
|
+
@click="navigator.clipboard?.writeText($refs.boardUsage.innerText); copied = true; setTimeout(() => copied = false, 1200)">
|
|
107
|
+
<span x-text="copied ? 'Copied' : 'Copy'">Copy</span>
|
|
108
|
+
</button>
|
|
109
|
+
</div>
|
|
110
|
+
</div>
|
|
111
|
+
|
|
112
|
+
<%# ---- The static reference sketch ------------------------------------- %>
|
|
42
113
|
<div class="fade-edge-x overflow-x-auto pb-2">
|
|
43
114
|
<div class="flex gap-4 min-w-max">
|
|
44
115
|
<% board_columns.each do |col| %>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<%# locals: (card:, id_attr: "slug", zone_attr: "stage") %>
|
|
2
|
+
<%#
|
|
3
|
+
A demo board card for the /admin/style Board specimen. Renders THROUGH the engine
|
|
4
|
+
card-shell chrome (studio/board/_card_shell) so the specimen exercises the real
|
|
5
|
+
identity contract (id="card-<id>", class .kanban-card, data-<id_attr>/<zone_attr>),
|
|
6
|
+
not a bespoke stand-in. `card` is a plain Hash — the specimen has no models. The
|
|
7
|
+
id_attr / zone_attr flow through from the board so the same partial demonstrates
|
|
8
|
+
the primitive under both the default and a custom attribute naming.
|
|
9
|
+
%>
|
|
10
|
+
<%= render layout: "studio/board/card_shell",
|
|
11
|
+
locals: { id: card[:id], zone: card[:zone], id_attr: id_attr, zone_attr: zone_attr,
|
|
12
|
+
class: "card p-3 space-y-2 cursor-grab active:cursor-grabbing" } do %>
|
|
13
|
+
<div class="flex items-start gap-2">
|
|
14
|
+
<span class="text-muted select-none leading-none" aria-hidden="true">⠿</span>
|
|
15
|
+
<p class="text-sm font-semibold text-heading leading-snug flex-1"><%= card[:title] %></p>
|
|
16
|
+
</div>
|
|
17
|
+
<div class="flex items-center justify-between gap-2">
|
|
18
|
+
<%= render "components/badge", text: card[:repo], scheme: "neutral" %>
|
|
19
|
+
<span class="inline-flex h-6 w-6 items-center justify-center rounded-full text-2xs font-bold text-white shrink-0"
|
|
20
|
+
style="background: var(--color-cta)"><%= card[:who] %></span>
|
|
21
|
+
</div>
|
|
22
|
+
<% end %>
|
data/lib/studio/engine.rb
CHANGED
data/lib/studio/version.rb
CHANGED
data/lib/studio.rb
CHANGED
|
@@ -25,6 +25,20 @@ module Studio
|
|
|
25
25
|
mattr_accessor :theme_logos, default: []
|
|
26
26
|
mattr_accessor :sticky_table_headers, default: false
|
|
27
27
|
|
|
28
|
+
# ---- Smooth-load convention ---------------------------------------------
|
|
29
|
+
# Opt-in per app: renders the view-transition + no-preview metas so Turbo 8
|
|
30
|
+
# page swaps materialize behind the current page and present with a view
|
|
31
|
+
# transition (layouts/studio/_smooth_load). OFF by default — an app with
|
|
32
|
+
# known multi-second pages should fix those before opting in, because
|
|
33
|
+
# no-preview holds the old page until the fresh response arrives.
|
|
34
|
+
mattr_accessor :smooth_load, default: false
|
|
35
|
+
|
|
36
|
+
# Minimum ms the nav spinner stays visible once shown (_head.html.erb).
|
|
37
|
+
# Apps wrapping multi-second operations in the spinner (e.g. Solana RPC)
|
|
38
|
+
# keep the high default to avoid flicker; smooth-load apps typically drop
|
|
39
|
+
# this to ~300 so fast loads never linger on a spinner.
|
|
40
|
+
mattr_accessor :nav_spinner_min_ms, default: 2500
|
|
41
|
+
|
|
28
42
|
# ---- Authentication ------------------------------------------------------
|
|
29
43
|
# Which sign-in methods this app offers. The shared login/signup views render
|
|
30
44
|
# a button/field per enabled method (gate with Studio.auth_method?). Order is
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: studio-engine
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.24.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Alex McRitchie
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: rails
|
|
@@ -171,6 +170,7 @@ files:
|
|
|
171
170
|
- app/assets/images/resend-favicon.png
|
|
172
171
|
- app/assets/images/ses-favicon.png
|
|
173
172
|
- app/assets/javascripts/studio/canvas_confetti.js
|
|
173
|
+
- app/assets/javascripts/studio/sortable.js
|
|
174
174
|
- app/assets/javascripts/studio/sticky_table_header.js
|
|
175
175
|
- app/assets/javascripts/studio/studio_confetti.js
|
|
176
176
|
- app/assets/stylesheets/studio/sticky_table_header.css
|
|
@@ -178,6 +178,7 @@ files:
|
|
|
178
178
|
- app/assets/tailwind/studio_engine/engine.css
|
|
179
179
|
- app/controllers/concerns/solana/session_auth.rb
|
|
180
180
|
- app/controllers/concerns/studio/admin_models.rb
|
|
181
|
+
- app/controllers/concerns/studio/board/reorderable.rb
|
|
181
182
|
- app/controllers/concerns/studio/error_handling.rb
|
|
182
183
|
- app/controllers/concerns/studio/impersonation.rb
|
|
183
184
|
- app/controllers/concerns/studio/link_consumption.rb
|
|
@@ -205,6 +206,7 @@ files:
|
|
|
205
206
|
- app/mailers/application_mailer.rb
|
|
206
207
|
- app/mailers/user_mailer.rb
|
|
207
208
|
- app/models/concerns/sluggable.rb
|
|
209
|
+
- app/models/concerns/studio/board/rankable.rb
|
|
208
210
|
- app/models/concerns/studio/broadcastable.rb
|
|
209
211
|
- app/models/current.rb
|
|
210
212
|
- app/models/error_log.rb
|
|
@@ -239,6 +241,7 @@ files:
|
|
|
239
241
|
- app/views/layouts/branded_mailer.html.erb
|
|
240
242
|
- app/views/layouts/studio/_flash.html.erb
|
|
241
243
|
- app/views/layouts/studio/_head.html.erb
|
|
244
|
+
- app/views/layouts/studio/_smooth_load.html.erb
|
|
242
245
|
- app/views/magic_links/confirm.html.erb
|
|
243
246
|
- app/views/navbar/show.html.erb
|
|
244
247
|
- app/views/registrations/new.html.erb
|
|
@@ -246,6 +249,7 @@ files:
|
|
|
246
249
|
- app/views/sessions/_sso_continue.html.erb
|
|
247
250
|
- app/views/sessions/new.html.erb
|
|
248
251
|
- app/views/studio/_age_verify_assets.html.erb
|
|
252
|
+
- app/views/studio/_board_assets.html.erb
|
|
249
253
|
- app/views/studio/_confirm_interstitial.html.erb
|
|
250
254
|
- app/views/studio/_cropper_assets.html.erb
|
|
251
255
|
- app/views/studio/_leveling_activity_assets.html.erb
|
|
@@ -259,6 +263,9 @@ files:
|
|
|
259
263
|
- app/views/studio/banners/_email_status_button.html.erb
|
|
260
264
|
- app/views/studio/banners/_environment.html.erb
|
|
261
265
|
- app/views/studio/banners/_impersonation.html.erb
|
|
266
|
+
- app/views/studio/board/_board.html.erb
|
|
267
|
+
- app/views/studio/board/_card_shell.html.erb
|
|
268
|
+
- app/views/studio/board/_column.html.erb
|
|
262
269
|
- app/views/studio/email_images/index.html.erb
|
|
263
270
|
- app/views/studio/links/confirm.html.erb
|
|
264
271
|
- app/views/studio/local_emails/index.html.erb
|
|
@@ -299,6 +306,7 @@ files:
|
|
|
299
306
|
- app/views/style/_tasks.html.erb
|
|
300
307
|
- app/views/style/_theme.html.erb
|
|
301
308
|
- app/views/style/_tricks.html.erb
|
|
309
|
+
- app/views/style/board/_demo_card.html.erb
|
|
302
310
|
- app/views/style/index.html.erb
|
|
303
311
|
- app/views/style/modals/_age_verify.html.erb
|
|
304
312
|
- app/views/style/modals/_auth.html.erb
|
|
@@ -341,7 +349,6 @@ metadata:
|
|
|
341
349
|
source_code_uri: https://github.com/amcritchie/studio-engine/tree/main
|
|
342
350
|
bug_tracker_uri: https://github.com/amcritchie/studio-engine/issues
|
|
343
351
|
changelog_uri: https://github.com/amcritchie/studio-engine/blob/main/CHANGELOG.md
|
|
344
|
-
post_install_message:
|
|
345
352
|
rdoc_options: []
|
|
346
353
|
require_paths:
|
|
347
354
|
- lib
|
|
@@ -356,8 +363,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
356
363
|
- !ruby/object:Gem::Version
|
|
357
364
|
version: '0'
|
|
358
365
|
requirements: []
|
|
359
|
-
rubygems_version:
|
|
360
|
-
signing_key:
|
|
366
|
+
rubygems_version: 4.0.9
|
|
361
367
|
specification_version: 4
|
|
362
368
|
summary: Shared Rails engine providing auth, SSO, error logging, theming, and S3-backed
|
|
363
369
|
image caching
|