Sidebar operations application
Static, pinned, icon-rail, and inset sidebar configurations in operational workspaces with appearance, data, uploads, notifications, recovery, and empty states.
Sidebar configurations in operation
Static, pinned, icon-rail, and inset sidebars across operational screens. Every configuration shares the mobile drawer and has its executable settings in the Code tab.
Static sidebar — populated workspace
collapsible: false keeps the default sidebar expanded without a pin button. Live appearance, summary statistics, sortable incidents, account actions, and notifications share the frame.
- Source
Gallery::Compositions::SidebarApplicationPage
Operations overview
Production workspaces, active incidents, and deployment readiness at a glance.
- Workspaces
- 18
- 16 healthy
- Deployments today
- 42
- All checks complete
- Open incidents
- 2
- Both assigned
Active incidents
Production events that still need an owner or a final verification.
Production checks finished
Release 2026.07.13 is ready to promote.
test/dummy/app/components/gallery/compositions/sidebar_application_page.rbrender NitroKit::AppShell.new(
id: "gallery-sidebar-application-populated",
layout: :sidebar,
collapsible: false,
data: {
gallery_shell_preview: "true",
gallery_application: "sidebar",
gallery_application_state: "populated"
}
) do |shell|
shell.brand { strong { "Northstar Operations" } }
shell.navigation do
render_application_navigation(
id: "gallery-sidebar-application-populated-navigation",
account_menu: false,
current: :overview,
context: "Production",
appearance_picker_id: "gallery-sidebar-application-appearance"
)
end
shell.topbar { render_account_menu(id: "gallery-sidebar-application-account", placement: :bottom_end) }
shell.main do
render_application_main do
render NitroKit::PageHeader.new(
title: "Operations overview",
description: "Production workspaces, active incidents, and deployment readiness at a glance.",
id: "gallery-sidebar-application-populated-header"
) do |header|
header.actions NitroKit::ButtonGroup.new(label: "Operations actions") do |group|
group.button("New deployment", href: "#new-deployment", variant: :primary)
group.button("Export", href: "#export")
end
end
render NitroKit::StatGrid.new(id: "gallery-sidebar-application-stats") do |stats|
stats.stat(key: :workspaces, label: "Workspaces", value: "18", detail: "16 healthy")
stats.stat(key: :deployments, label: "Deployments today", value: "42", detail: "All checks complete")
stats.stat(key: :incidents, label: "Open incidents", value: "2", detail: "Both assigned")
end
render NitroKit::DataSection.new(
title: "Active incidents",
description: "Production events that still need an owner or a final verification.",
id: "gallery-sidebar-application-incidents-section"
) do |section|
section.table NitroKit::Table.new(
sort: :started,
direction: :desc,
id: "gallery-sidebar-application-incidents",
table_aria: { label: "Active production incidents" }
) do |table|
table.caption("Active production incidents")
table.thead do
table.tr do
table.th(sort: :service, href: "?sort=service-asc")
table.th(sort: :region, href: "?sort=region-asc")
table.th(sort: :status, href: "?sort=status-asc")
table.th(sort: :started, href: "?sort=started-asc", align: :right)
end
end
table.tbody do
[
[ "Workspace synchronization", "eu-central", :waiting, "18:42" ],
[ "Audit export", "us-east", :healthy, "17:08" ],
[ "Invoice delivery", "global", :queued, "15:31" ]
].each_with_index do |(service, region, status, started), index|
table.tr do
table.th(service, scope: :row)
table.td(region)
table.td { status_badge(status, id: "gallery-sidebar-application-status-#{index + 1}") }
table.td(started, align: :right)
end
end
end
end
end
render NitroKit::Toast.new(
duration: 600_000,
label: "Operations notifications",
id: "gallery-sidebar-application-toast"
) do |toast|
toast.item(
title: "Production checks finished",
description: "Release 2026.07.13 is ready to promote.",
variant: :success
)
end
end
end
endCollapsible sidebar — empty workspace
collapsible: true, sidebar: :expanded starts pinned open. Unpin to try the rail and hover/focus peek alongside an empty state and ordinary multipart Dropzone.
- Source
Gallery::Compositions::SidebarApplicationPage
Projects
No projects yet
Create a project manually or import a small evidence bundle.
Import project evidence
This example uses ordinary multipart submission and remains useful without JavaScript.
test/dummy/app/components/gallery/compositions/sidebar_application_page.rbrender NitroKit::AppShell.new(
id: "gallery-sidebar-application-empty",
layout: :sidebar,
collapsible: true,
sidebar: :expanded,
data: {
gallery_shell_preview: "true",
gallery_application: "sidebar",
gallery_application_state: "empty",
theme: "light"
}
) do |shell|
shell.brand(icon: :star) { strong { "Northstar Projects" } }
shell.navigation do
render_application_navigation(
id: "gallery-sidebar-application-empty-navigation",
current: :projects,
context: "New workspace"
)
end
shell.main do
render_application_main do
render NitroKit::PageHeader.new(
title: "Projects",
id: "gallery-sidebar-application-empty-header"
)
render NitroKit::EmptyState.new(
title: "No projects yet",
description: "Create a project manually or import a small evidence bundle.",
id: "gallery-sidebar-application-empty-state"
) do |empty|
empty.icon NitroKit::Icon.new(:folder)
empty.action NitroKit::Button.new("Create project", href: "#create-project", variant: :primary)
end
render NitroKit::SettingsSection.new(
title: "Import project evidence",
description: "This example uses ordinary multipart submission and remains useful without JavaScript.",
id: "gallery-sidebar-application-import"
) do |section|
section.form do
form_with(
scope: :project_import,
url: "#import-project",
builder: NitroKit::FormBuilder,
id: "gallery-sidebar-application-import-form"
) do |form|
form.group do
form.dropzone(
:files,
id: "gallery-sidebar-application-dropzone",
label: "Add project files",
description: "Up to three CSV, JSON, or text files.",
direct_upload: false,
multiple: true,
accept: ".csv,.json,text/plain",
max_files: 3,
max_bytes: 2 * 1024 * 1024
)
form.submit("Import files", id: "gallery-sidebar-application-import-submit")
end
end
end
end
end
end
endCollapsed rail — failed workspace
collapsible: true, sidebar: :collapsed starts as a rail in dark mode. Peek or pin navigation while reviewing recovery guidance, partial incident details, and a native diagnostic dialog.
- Source
Gallery::Compositions::SidebarApplicationPage
Workspace synchronization incident
The last verified snapshot remains available while the regional service recovers.
| Service | Workspace synchronization |
|---|---|
| Region | eu-central |
| Owner | Not provided |
| Started at | |
| Last update | Not provided |
test/dummy/app/components/gallery/compositions/sidebar_application_page.rbrender NitroKit::AppShell.new(
id: "gallery-sidebar-application-error",
layout: :sidebar,
collapsible: true,
sidebar: :collapsed,
data: {
gallery_shell_preview: "true",
gallery_application: "sidebar",
gallery_application_state: "error",
theme: "dark"
}
) do |shell|
shell.brand(icon: :star) { strong { "Northstar Reliability" } }
shell.navigation do
render_application_navigation(
id: "gallery-sidebar-application-error-navigation",
current: :incidents,
context: "Degraded",
dense: true
)
end
shell.main do
render_application_main(size: :lg) do
render NitroKit::PageHeader.new(
title: "Workspace synchronization incident",
description: "The last verified snapshot remains available while the regional service recovers.",
id: "gallery-sidebar-application-error-header"
)
render NitroKit::Alert.new(
variant: :destructive,
id: "gallery-sidebar-application-error-alert"
) do |alert|
alert.icon NitroKit::Icon.new(:circle_x)
alert.title("Live synchronization is unavailable")
alert.description("No customer data was changed. Retry after reviewing the partial incident record below.")
end
render NitroKit::DetailsTable.new(
INCIDENT,
label: "Incident details",
id: "gallery-sidebar-application-error-details"
) do |details|
details.fields(:service, :region, :owner, :started_at, :last_update)
end
render NitroKit::Flex.new(dir: :row, gap: 2, align: :center) do
render NitroKit::Dialog.new(id: "gallery-sidebar-application-diagnostics") do |dialog|
dialog.trigger("Review diagnostics")
dialog.panel(
title: "Regional diagnostics",
description: "The service is reachable, but the replication checkpoint is 14 minutes behind."
) do
render NitroKit::Badge.new("Read only", color: :warning, size: :sm)
dialog.close_button(label: "Close diagnostics")
end
end
end
end
end
endInset sidebar — release workspace
The application-owned inset_workspace.css joins the route toolbar and scrolling content into one rounded surface, with one workspace-content gutter. This is composition, not another AppShell option.
- Source
Gallery::Compositions::SidebarApplicationPage
Release readiness
- Services
- 3
- All production regions
- Passing checks
- 18
- No blockers
- Regions
- 3
- Ready to promote
Release checklist
Verified before promoting the next deployment.
| Service | Readiness |
|---|---|
| Workspace synchronization | Ready |
| Audit export | Ready |
| Invoice delivery | Ready |
test/dummy/app/components/gallery/compositions/sidebar_application_page.rbrender NitroKit::AppShell.new(
id: "gallery-sidebar-application-inset",
layout: :sidebar,
collapsible: false,
data: {
ui: "inset-workspace",
gallery_shell_preview: "true",
gallery_application: "sidebar",
gallery_application_state: "inset"
}
) do |shell|
shell.brand { strong { "Northstar Releases" } }
shell.navigation do
render_application_navigation(
id: "gallery-sidebar-application-inset-navigation",
current: :overview,
context: "Production"
)
end
shell.topbar do
render NitroKit::Toolbar.new do |toolbar|
toolbar.leading { h1 { "Release readiness" } }
toolbar.trailing { render NitroKit::Button.new("New deployment", href: "#new-deployment", variant: :primary) }
end
end
shell.main { render_inset_release_content }
endInset sidebar — collapsible release workspace
The same inset release canvas with collapsible: true and sidebar: :expanded. Unpin to a rail, hover or focus to peek over the canvas, and pin to reserve navigation space again.
- Source
Gallery::Compositions::SidebarApplicationPage
Release readiness
- Services
- 3
- All production regions
- Passing checks
- 18
- No blockers
- Regions
- 3
- Ready to promote
Release checklist
Verified before promoting the next deployment.
| Service | Readiness |
|---|---|
| Workspace synchronization | Ready |
| Audit export | Ready |
| Invoice delivery | Ready |
test/dummy/app/components/gallery/compositions/sidebar_application_page.rbrender NitroKit::AppShell.new(
id: "gallery-sidebar-application-inset-collapsible",
layout: :sidebar,
collapsible: true,
sidebar: :expanded,
data: {
ui: "inset-workspace",
gallery_shell_preview: "true",
gallery_application: "sidebar",
gallery_application_state: "inset-collapsible"
}
) do |shell|
shell.brand(icon: :star) { strong { "Northstar" } }
shell.navigation do
render_application_navigation(
id: "gallery-sidebar-application-inset-collapsible-navigation",
current: :overview,
context: "Production"
)
end
shell.topbar do
render NitroKit::Toolbar.new do |toolbar|
toolbar.leading { h1 { "Release readiness" } }
toolbar.trailing { render NitroKit::Button.new("New deployment", href: "#new-deployment", variant: :primary) }
end
end
shell.main { render_inset_release_content }
end