studio-engine 0.82.0 → 0.83.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 +92 -0
- data/README.md +3 -0
- data/app/assets/javascripts/studio/leaflet.js +42 -0
- data/app/assets/stylesheets/studio/leaflet.css +693 -0
- data/app/controllers/concerns/studio/link_preview_bots.rb +45 -2
- data/app/controllers/studio/bookings_controller.rb +22 -0
- data/app/controllers/studio/site_identities_controller.rb +15 -3
- data/app/helpers/studio/link_preview_helper.rb +54 -6
- data/app/helpers/studio/site_footer_helper.rb +180 -0
- data/app/models/studio/site_identity.rb +39 -3
- data/app/views/layouts/studio/_link_preview_tags.html.erb +12 -1
- data/app/views/studio/booking/_assets.html.erb +162 -0
- data/app/views/studio/booking/_frame.html.erb +41 -0
- data/app/views/studio/booking/_popup.html.erb +34 -0
- data/app/views/studio/bookings/show.html.erb +20 -0
- data/app/views/studio/site_footer/_assets.html.erb +209 -0
- data/app/views/studio/site_footer/_footer.html.erb +99 -0
- data/app/views/studio/site_footer/_link.html.erb +14 -0
- data/app/views/studio/site_footer/_map.html.erb +22 -0
- data/app/views/studio/site_footer/_social_icon.html.erb +23 -0
- data/app/views/style/_site_footer.html.erb +79 -0
- data/app/views/style/_tricks.html.erb +3 -0
- data/lib/generators/studio/site_identity/site_identity_generator.rb +6 -2
- data/lib/studio/booking.rb +47 -0
- data/lib/studio/engine.rb +2 -0
- data/lib/studio/link_preview.rb +91 -0
- data/lib/studio/site_footer.rb +294 -0
- data/lib/studio/version.rb +1 -1
- data/lib/studio.rb +105 -0
- metadata +18 -2
data/lib/studio.rb
CHANGED
|
@@ -13,6 +13,8 @@ require "studio/js_literal"
|
|
|
13
13
|
require "studio/js_identifier"
|
|
14
14
|
require "studio/partial_block"
|
|
15
15
|
require "studio/sidebar_sections"
|
|
16
|
+
require "studio/site_footer"
|
|
17
|
+
require "studio/booking"
|
|
16
18
|
require "studio/navbar_links"
|
|
17
19
|
require "studio/navbar_identity"
|
|
18
20
|
require "studio/profile_sections"
|
|
@@ -516,6 +518,17 @@ module Studio
|
|
|
516
518
|
# trusted as given.
|
|
517
519
|
mattr_accessor :link_preview_fallback_image, default: "/og.png"
|
|
518
520
|
|
|
521
|
+
# The app's CANONICAL base URL for previews, e.g. "https://cyvasse.xyz". When
|
|
522
|
+
# set, og:url is this base plus the page's path (no query string), and every
|
|
523
|
+
# relative preview image is made absolute on it — so a share through a
|
|
524
|
+
# herokuapp.com host or a ?utm_ link does not split one page into many URLs in
|
|
525
|
+
# an unfurler's share counts. nil (the default) uses the request's base URL,
|
|
526
|
+
# and og:url is the URL as requested. Set it in production only, or a local
|
|
527
|
+
# page's card points at production:
|
|
528
|
+
#
|
|
529
|
+
# config.link_preview_base_url = "https://cyvasse.xyz" if Rails.env.production?
|
|
530
|
+
mattr_accessor :link_preview_base_url, default: nil
|
|
531
|
+
|
|
519
532
|
# THE SITE IDENTITY'S DRAFTED DEFAULTS — this app's title and description as
|
|
520
533
|
# written in code, under whatever the operator saves at /admin/link_preview.
|
|
521
534
|
# The standing convention is that an agent drafts these when it sets an app up
|
|
@@ -547,6 +560,80 @@ module Studio
|
|
|
547
560
|
# config.draw_public_user_routes = true
|
|
548
561
|
mattr_accessor :draw_public_user_routes, default: false
|
|
549
562
|
|
|
563
|
+
# ---- Site footer and booking (Studio::SiteFooter, Studio::Booking) -------
|
|
564
|
+
#
|
|
565
|
+
# The public site's footer: brand and social profiles, link columns, an
|
|
566
|
+
# optional Location band with a live map, and a legal line. And the booking
|
|
567
|
+
# primitives: Google Calendar's appointment page inline, in a popup, and on a
|
|
568
|
+
# page. See docs/SITE_FOOTER.md.
|
|
569
|
+
|
|
570
|
+
# The footer's facts: a Hash, or a callable receiving the view. nil (the
|
|
571
|
+
# default) means this app has no footer, and `studio_site_footer` renders
|
|
572
|
+
# nothing, so a layout can call it before the app declares one. Every key is
|
|
573
|
+
# optional; shape and rules: lib/studio/site_footer.rb.
|
|
574
|
+
#
|
|
575
|
+
# config.site_footer = ->(view) {
|
|
576
|
+
# { tagline: "Everything, by example",
|
|
577
|
+
# address: { street: "123 Example St", city_line: "Washington, DC 20024",
|
|
578
|
+
# lat: 38.8894, lng: -77.0352 },
|
|
579
|
+
# columns: [ [ "Company", [ [ "Home", view.root_path ], [ "Career", nil ] ] ] ],
|
|
580
|
+
# legal: [ [ "Privacy Policy", view.privacy_path ] ] }
|
|
581
|
+
# }
|
|
582
|
+
mattr_reader :site_footer, default: nil
|
|
583
|
+
|
|
584
|
+
def self.site_footer=(declared)
|
|
585
|
+
SiteFooter.validate!(declared)
|
|
586
|
+
@@site_footer = declared
|
|
587
|
+
end
|
|
588
|
+
|
|
589
|
+
# Controllers whose pages keep the footer for a SIGNED-IN viewer, by
|
|
590
|
+
# controller name ("landing") or path ("admin/reports"). A visitor gets the
|
|
591
|
+
# footer on every page; a signed-in viewer gets it only here, because every
|
|
592
|
+
# other signed-in page is a working surface (a board, a queue, an editor) and
|
|
593
|
+
# stays full height. The engine's own booking page is always included.
|
|
594
|
+
#
|
|
595
|
+
# config.site_footer_controllers = %w[landing packages contact_submissions]
|
|
596
|
+
mattr_accessor :site_footer_controllers, default: []
|
|
597
|
+
|
|
598
|
+
# THE WHOLE RULE for where the footer shows, as one callable receiving the
|
|
599
|
+
# view. The default is the rule above: every page for a visitor, the listed
|
|
600
|
+
# controllers for a signed-in viewer. That default shows the footer on ANY page
|
|
601
|
+
# a signed-out visitor can reach, an app page included, so an app with public
|
|
602
|
+
# working pages narrows it here. Compose with the default rather than
|
|
603
|
+
# restating it:
|
|
604
|
+
#
|
|
605
|
+
# config.site_footer_visible = ->(view) {
|
|
606
|
+
# Studio::SiteFooter.default_visible?(view) && !view.controller_path.start_with?("games/")
|
|
607
|
+
# }
|
|
608
|
+
mattr_reader :site_footer_visible, default: ->(view) { Studio::SiteFooter.default_visible?(view) }
|
|
609
|
+
|
|
610
|
+
def self.site_footer_visible=(rule)
|
|
611
|
+
SiteFooter.validate_visible!(rule)
|
|
612
|
+
@@site_footer_visible = rule
|
|
613
|
+
end
|
|
614
|
+
|
|
615
|
+
# The app's Google Calendar appointment schedule: the public link Google gives
|
|
616
|
+
# you to share, WITHOUT `?gv=true` (the frame and the popup add it). nil (the
|
|
617
|
+
# default) means no booking: `studio_booking_frame` and `studio_booking_popup`
|
|
618
|
+
# render nothing and no link opens a popup.
|
|
619
|
+
#
|
|
620
|
+
# config.booking_url = "https://calendar.google.com/calendar/appointments/schedules/EXAMPLE-SCHEDULE-ID"
|
|
621
|
+
mattr_reader :booking_url, default: nil
|
|
622
|
+
|
|
623
|
+
def self.booking_url=(url)
|
|
624
|
+
Booking.validate!(url)
|
|
625
|
+
@@booking_url = url.to_s.strip.empty? ? nil : Booking.page_url(url)
|
|
626
|
+
end
|
|
627
|
+
|
|
628
|
+
# Draw the booking page, GET /schedule (Studio::BookingsController, route
|
|
629
|
+
# helper studio_booking_path). OFF by default, like every route surface a
|
|
630
|
+
# consumer might already own: mcritchie-studio draws its own /schedule today,
|
|
631
|
+
# and its adoption turns this on as it deletes that route. With the flag on and
|
|
632
|
+
# no booking_url the page answers 404.
|
|
633
|
+
#
|
|
634
|
+
# config.draw_booking_routes = true
|
|
635
|
+
mattr_accessor :draw_booking_routes, default: false
|
|
636
|
+
|
|
550
637
|
# THE APP'S IDENTITY COPY, resolved: { title:, description:, image_url: }.
|
|
551
638
|
# The operator's saved value (Studio::SiteIdentity, edited at
|
|
552
639
|
# /admin/link_preview) wins, then the drafted Studio.site_title /
|
|
@@ -1046,6 +1133,18 @@ module Studio
|
|
|
1046
1133
|
SidebarSections.resolve(sidebar_sections, view)
|
|
1047
1134
|
end
|
|
1048
1135
|
|
|
1136
|
+
# The site footer's facts resolved for a view (lib/studio/site_footer.rb), or
|
|
1137
|
+
# nil when the app declared none. The name defaults to the site identity's
|
|
1138
|
+
# title and the logo to the navbar logo, so an app that has set those up says
|
|
1139
|
+
# them once.
|
|
1140
|
+
def self.site_footer_for(view)
|
|
1141
|
+
return nil if site_footer.nil?
|
|
1142
|
+
|
|
1143
|
+
booking_path = draw_booking_routes && view.respond_to?(:studio_booking_path) ? view.studio_booking_path : nil
|
|
1144
|
+
SiteFooter.resolve(site_footer, view,
|
|
1145
|
+
name: site_identity[:title], logo: logo_for("Footer Logo"), booking_path: booking_path)
|
|
1146
|
+
end
|
|
1147
|
+
|
|
1049
1148
|
# Navbar links resolved for a view context (lib/studio/navbar_links.rb).
|
|
1050
1149
|
def self.navbar_links_for(view)
|
|
1051
1150
|
NavbarLinks.resolve(navbar_links, view)
|
|
@@ -1250,6 +1349,12 @@ module Studio
|
|
|
1250
1349
|
format: false, constraints: { username: %r{[^/]+} }
|
|
1251
1350
|
end
|
|
1252
1351
|
|
|
1352
|
+
# The booking page (/schedule): Google Calendar's appointment page inline,
|
|
1353
|
+
# with the site footer. OPT-IN — see Studio.draw_booking_routes.
|
|
1354
|
+
if Studio.draw_booking_routes
|
|
1355
|
+
get "schedule", to: "studio/bookings#show", as: :studio_booking
|
|
1356
|
+
end
|
|
1357
|
+
|
|
1253
1358
|
# The living style guide. Canonical at /admin/style (StyleController#index);
|
|
1254
1359
|
# /admin/design_system redirects here but KEEPS its admin_design_system_path
|
|
1255
1360
|
# helper so a shipped host sidebar link on the old helper still resolves.
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: studio-engine
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.83.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Alex McRitchie
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-10-01 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rails
|
|
@@ -309,10 +309,12 @@ files:
|
|
|
309
309
|
- app/assets/images/state-flags/wy.svg
|
|
310
310
|
- app/assets/javascripts/studio/alpine.js
|
|
311
311
|
- app/assets/javascripts/studio/canvas_confetti.js
|
|
312
|
+
- app/assets/javascripts/studio/leaflet.js
|
|
312
313
|
- app/assets/javascripts/studio/session.js
|
|
313
314
|
- app/assets/javascripts/studio/sortable.js
|
|
314
315
|
- app/assets/javascripts/studio/sticky_table_header.js
|
|
315
316
|
- app/assets/javascripts/studio/studio_confetti.js
|
|
317
|
+
- app/assets/stylesheets/studio/leaflet.css
|
|
316
318
|
- app/assets/stylesheets/studio/sticky_table_header.css
|
|
317
319
|
- app/assets/tailwind/studio_engine/engine-motion.css
|
|
318
320
|
- app/assets/tailwind/studio_engine/engine.css
|
|
@@ -334,6 +336,7 @@ files:
|
|
|
334
336
|
- app/controllers/schema_controller.rb
|
|
335
337
|
- app/controllers/sessions_controller.rb
|
|
336
338
|
- app/controllers/solana_sessions_controller.rb
|
|
339
|
+
- app/controllers/studio/bookings_controller.rb
|
|
337
340
|
- app/controllers/studio/email_images_controller.rb
|
|
338
341
|
- app/controllers/studio/emails_controller.rb
|
|
339
342
|
- app/controllers/studio/geo_settings_controller.rb
|
|
@@ -355,6 +358,7 @@ files:
|
|
|
355
358
|
- app/helpers/studio/geo_helper.rb
|
|
356
359
|
- app/helpers/studio/link_preview_helper.rb
|
|
357
360
|
- app/helpers/studio/public_user_helper.rb
|
|
361
|
+
- app/helpers/studio/site_footer_helper.rb
|
|
358
362
|
- app/helpers/studio_email_delivery_helper.rb
|
|
359
363
|
- app/helpers/studio_navbar_helper.rb
|
|
360
364
|
- app/helpers/studio_sidebar_helper.rb
|
|
@@ -445,6 +449,10 @@ files:
|
|
|
445
449
|
- app/views/studio/board/_board.html.erb
|
|
446
450
|
- app/views/studio/board/_card_shell.html.erb
|
|
447
451
|
- app/views/studio/board/_column.html.erb
|
|
452
|
+
- app/views/studio/booking/_assets.html.erb
|
|
453
|
+
- app/views/studio/booking/_frame.html.erb
|
|
454
|
+
- app/views/studio/booking/_popup.html.erb
|
|
455
|
+
- app/views/studio/bookings/show.html.erb
|
|
448
456
|
- app/views/studio/email_images/index.html.erb
|
|
449
457
|
- app/views/studio/emails/_banner_editor.html.erb
|
|
450
458
|
- app/views/studio/emails/_banner_preview.html.erb
|
|
@@ -529,10 +537,16 @@ files:
|
|
|
529
537
|
- app/views/studio/profiles/show.html.erb
|
|
530
538
|
- app/views/studio/public_users/not_found.html.erb
|
|
531
539
|
- app/views/studio/public_users/show.html.erb
|
|
540
|
+
- app/views/studio/site_footer/_assets.html.erb
|
|
541
|
+
- app/views/studio/site_footer/_footer.html.erb
|
|
542
|
+
- app/views/studio/site_footer/_link.html.erb
|
|
543
|
+
- app/views/studio/site_footer/_map.html.erb
|
|
544
|
+
- app/views/studio/site_footer/_social_icon.html.erb
|
|
532
545
|
- app/views/studio/site_identities/edit.html.erb
|
|
533
546
|
- app/views/style/_host.html.erb
|
|
534
547
|
- app/views/style/_modal_specimen.html.erb
|
|
535
548
|
- app/views/style/_modals.html.erb
|
|
549
|
+
- app/views/style/_site_footer.html.erb
|
|
536
550
|
- app/views/style/_specimen.html.erb
|
|
537
551
|
- app/views/style/_tasks.html.erb
|
|
538
552
|
- app/views/style/_theme.html.erb
|
|
@@ -573,6 +587,7 @@ files:
|
|
|
573
587
|
- lib/generators/studio/site_identity/site_identity_generator.rb
|
|
574
588
|
- lib/studio-engine.rb
|
|
575
589
|
- lib/studio.rb
|
|
590
|
+
- lib/studio/booking.rb
|
|
576
591
|
- lib/studio/cable.rb
|
|
577
592
|
- lib/studio/color_scale.rb
|
|
578
593
|
- lib/studio/email.rb
|
|
@@ -605,6 +620,7 @@ files:
|
|
|
605
620
|
- lib/studio/session_fingerprint.rb
|
|
606
621
|
- lib/studio/session_state.rb
|
|
607
622
|
- lib/studio/sidebar_sections.rb
|
|
623
|
+
- lib/studio/site_footer.rb
|
|
608
624
|
- lib/studio/theme_resolver.rb
|
|
609
625
|
- lib/studio/ui_primitives.rb
|
|
610
626
|
- lib/studio/username_generator.rb
|