mirror of
https://github.com/we-promise/sure.git
synced 2026-09-03 13:51:29 +00:00
* Add live AI checks to system health Give super admins a dedicated AI status view with bounded liveness probes for LLMs, vector stores, pgvector, and embedding endpoints. Record sanitized failures in both the system debug log and Rails logger, and document the recommended local configuration.\n\nCloses #3145 * Fix AI health CI checks * Address AI health review feedback * Correct Ollama model preload guidance * Distinguish OpenAI-compatible providers * Make Ollama startup readiness explicit * Recognize Cloudflare AI endpoints
92 lines
2.8 KiB
Ruby
92 lines
2.8 KiB
Ruby
class DS::Tabs < DesignSystemComponent
|
|
renders_one :nav, ->(classes: nil) do
|
|
DS::Tabs::Nav.new(
|
|
active_tab: active_tab,
|
|
active_btn_classes: active_btn_classes,
|
|
inactive_btn_classes: inactive_btn_classes,
|
|
btn_classes: base_btn_classes,
|
|
dom_prefix: dom_prefix,
|
|
classes: unstyled? ? classes : class_names(nav_container_classes, classes)
|
|
)
|
|
end
|
|
|
|
renders_many :panels, ->(tab_id:, &block) do
|
|
content_tag(
|
|
:div,
|
|
class: ("hidden" unless tab_id == active_tab),
|
|
role: "tabpanel",
|
|
id: panel_dom_id(tab_id),
|
|
"aria-labelledby": tab_dom_id(tab_id),
|
|
tabindex: "0",
|
|
data: { id: tab_id, DS__tabs_target: "panel" },
|
|
&block
|
|
)
|
|
end
|
|
|
|
# Scope tab/panel DOM ids to this component instance so multiple
|
|
# `DS::Tabs` widgets on the same page (which often reuse generic
|
|
# tab ids like "all" or "overview") don't collide and break the
|
|
# `aria-controls` / `aria-labelledby` associations.
|
|
def tab_dom_id(tab_id)
|
|
"#{dom_prefix}-tab-#{tab_id}"
|
|
end
|
|
|
|
def panel_dom_id(tab_id)
|
|
"#{dom_prefix}-panel-#{tab_id}"
|
|
end
|
|
|
|
VARIANTS = {
|
|
default: {
|
|
# `tab-item-active` is a Sure token utility (white light / gray-700 dark).
|
|
# Swapping out the raw `bg-white theme-dark:bg-gray-700` removes the
|
|
# last raw-palette reference in DS::Tabs.
|
|
active_btn_classes: "tab-item-active text-primary shadow-sm",
|
|
inactive_btn_classes: "text-secondary hover:bg-surface-inset-hover",
|
|
base_btn_classes: "w-full inline-flex justify-center items-center text-sm font-medium px-2 py-1 rounded-md motion-safe:transition-colors motion-safe:duration-200",
|
|
nav_container_classes: "flex bg-surface-inset p-1 rounded-lg mb-4"
|
|
}
|
|
}
|
|
|
|
attr_reader :active_tab, :url_param_key, :session_key, :variant, :testid, :navigate_on_change
|
|
|
|
def initialize(active_tab:, url_param_key: nil, session_key: nil, navigate_on_change: false, variant: :default, active_btn_classes: "", inactive_btn_classes: "", testid: nil)
|
|
@active_tab = active_tab
|
|
@url_param_key = url_param_key
|
|
@session_key = session_key
|
|
@navigate_on_change = navigate_on_change
|
|
@variant = variant.to_sym
|
|
@active_btn_classes = active_btn_classes
|
|
@inactive_btn_classes = inactive_btn_classes
|
|
@testid = testid
|
|
end
|
|
|
|
def active_btn_classes
|
|
unstyled? ? @active_btn_classes : VARIANTS.dig(variant, :active_btn_classes)
|
|
end
|
|
|
|
def inactive_btn_classes
|
|
unstyled? ? @inactive_btn_classes : VARIANTS.dig(variant, :inactive_btn_classes)
|
|
end
|
|
|
|
private
|
|
def dom_prefix
|
|
@dom_prefix ||= "tabs-#{object_id}"
|
|
end
|
|
|
|
def unstyled?
|
|
variant == :unstyled
|
|
end
|
|
|
|
def base_btn_classes
|
|
unless unstyled?
|
|
VARIANTS.dig(variant, :base_btn_classes)
|
|
end
|
|
end
|
|
|
|
def nav_container_classes
|
|
unless unstyled?
|
|
VARIANTS.dig(variant, :nav_container_classes)
|
|
end
|
|
end
|
|
end
|