// Detalhe de um serviço: cabeçalho com ações (deploy, stop, reload) e as abas
// General (fonte), Connection, Domains, Environment, Deployments, Logs e
// Advanced.
component {
resources {
link(rel = import, href = "service/logs.gvb", as = ServiceLogsTab)
link(rel = import, href = "service/general.gvb", as = ServiceGeneralTab)
link(rel = import, href = "service/connection.gvb", as = ServiceConnectionTab)
link(rel = import, href = "service/environment.gvb", as = ServiceEnvironmentTab)
link(rel = import, href = "service/domains.gvb", as = ServiceDomainsTab)
link(rel = import, href = "service/migrar.gvb", as = ServiceMigrarTab)
link(rel = import, href = "service/databases.gvb", as = ServiceDatabasesTab)
link(rel = import, href = "service/deployments.gvb", as = ServiceDeploymentsTab)
link(rel = import, href = "service/healthcheck.gvb", as = ServiceHealthcheckTab)
link(rel = import, href = "service/advanced.gvb", as = ServiceAdvancedTab)
style """
/* Cabeçalho + ações */
.svc_head { width: fill; align-y: start; }
.svc_title_row { width: fill; spacing: 14; align-y: center; }
.svc_title { width: fill; }
/* Sub-linha de status (badge + timer) logo abaixo do nome. */
.svc_substatus { spacing: 10; align-y: center; }
.tabs_scroll { width: fill; }
.tabs_main { width: shrink; spacing: 4; }
.svc_actions { spacing: 10; align-y: center; }
.btn_blue { color: var(--blue); padding: 11 22; border-radius: 5 }
/* Corpo: conteúdo da aba + painel lateral */
.svc_body { width: fill; height: fill; spacing: 20; }
.svc_main { width: fill; height: fill; spacing: 16; }
.svc_aside { width: 360; height: fill; spacing: 16; }
.svc_err { size: 13; color: var(--error); }
/* Connection (pares chave/valor) */
.kv_key { width: fill; size: 13; color: var(--muted); }
.kv_val { size: 16; bold: true; color: var(--text); }
.select { width: fill; padding: 12 14; background: var(--raised); border-radius: 4; border-width: 1; border-color: #30363D; color: var(--text-2); }
/* Deployments (lista + build log) */
.col_dep_id { width: 130; }
.col_dep_start { width: fill; }
.dep_image { size: 11; color: var(--faint); padding: 2 0 0 0; }
.dep_wrap { width: fill; height: fill; spacing: 8; }
.dep_list_scroll { width: fill; height: 240; }
.dep_actions { spacing: 8; align-y: center; }
.dep_logs_btn { color: var(--border); padding: 5 12; border-radius: 3 }
.dep_del_btn { color: var(--danger); padding: 5 12; border-radius: 3 }
.label_cap_fill { width: fill; size: 11; bold: true; color: var(--faint); }
/* Logs (aba Logs = launcher da janela isolada; painel usado só p/ layout) */
.log_panel { width: fill; height: fill; background: var(--surface); border-radius: 6; border-width: 1; border-color: var(--border); padding: 14 16; spacing: 8; }
.log_body { width: fill; spacing: 2; }
.log_line { width: fill; spacing: 12; }
.log_time { width: 76; size: 11; color: var(--faint); }
.log_text { width: fill; size: 12; color: #9DA7B3; }
/* Painel lateral */
.aside_panel { width: fill; background: var(--surface); border-radius: 6; border-width: 1; border-color: var(--border); padding: 18; spacing: 8; }
.aside_panel_fill { width: fill; height: fill; background: var(--surface); border-radius: 6; border-width: 1; border-color: var(--border); padding: 14 16; spacing: 8; }
/* Responsivo: estreita o painel lateral e aperta o corpo (glacier-ui 0.9.0+). */
@media (max-width: 900) {
.svc_aside { width: 240; }
.svc_body { spacing: 12; }
}
@media (max-width: 560) {
.svc_aside { width: 170; }
}
"""
}
column(class = content) {
// ── Header: nome + estado + ações ──────────────────────────────────
row(class = svc_head) {
column(class = header_titles) {
row(class = svc_title_row) {
button(
class = btn_ghost,
on_click = open_project:@svc_project_id,
text = "‹ @svc_project",
)
text(class = "title svc_title", content = "@svc_name")
}
row(class = svc_substatus) {
rp-badge(color = @svc_status_color, label = @svc_status_label)
row(class = badge, if = @svc_deploy_running, equals = true) {
text(class = state_dot, color = #58A6FF, content = "⏱")
text(
class = badge_lbl,
color = #58A6FF,
content = "@svc_deploy_elapsed",
)
}
}
text(
if = @svc_action_msg,
not_equals = "",
class = muted,
color = @svc_action_color,
content = "@svc_action_msg",
)
row(class = "svc_actions svc_actions_compact") {
button(
class = btn_primary,
on_click = svc_deploy,
text = "▶",
tooltip = Deploy,
)
button(
class = btn_blue,
on_click = svc_reload,
text = "⟳",
tooltip = Reload,
)
button(
class = btn_blue,
on_click = svc_rebuild,
text = "⚙",
tooltip = Rebuild,
)
button(
class = btn_danger,
on_click = svc_stop,
text = "■",
tooltip = Stop,
)
}
}
row(class = "svc_actions svc_actions_full") {
button(class = btn_primary, on_click = svc_deploy, text = Deploy)
button(class = btn_blue, on_click = svc_reload, text = Reload)
button(class = btn_blue, on_click = svc_rebuild, text = Rebuild)
button(class = btn_danger, on_click = svc_stop, text = Stop)
}
}
// ── Abas ───────────────────────────────────────────────────────────
scroll(class = tabs_scroll, direction = horizontal) {
row(class = tabs_main) {
TabButton(
label = General,
current = @tab,
target = general,
action = tab:general,
)
TabButton(
label = Connection,
current = @tab,
target = connection,
action = tab:connection,
)
TabButton(
label = Environment,
current = @tab,
target = environment,
action = tab:environment,
)
TabButton(
label = Domains,
current = @tab,
target = domains,
action = tab:domains,
)
TabButton(
label = Deployments,
current = @tab,
target = deployments,
action = tab:deployments,
)
if @svc_shared == "true" {
TabButton(
label = Databases,
current = @tab,
target = databases,
action = tab:databases,
)
}
if @svc_can_migrate == "true" {
TabButton(
label = Migrar,
current = @tab,
target = migrar,
action = tab:migrar,
)
}
TabButton(
label = Healthcheck,
current = @tab,
target = healthcheck,
action = tab:healthcheck,
)
TabButton(
label = Logs,
current = @tab,
target = logs,
action = tab:logs,
)
TabButton(
label = Advanced,
current = @tab,
target = advanced,
action = tab:advanced,
)
}
}
hr
// ── Corpo: conteúdo da aba + painel lateral ────────────────────────
row(class = svc_body) {
column(class = svc_main) {
text(
if = @svc_error,
not_equals = "",
class = svc_err,
content = "@svc_error",
)
ServiceGeneralTab(if = @tab, equals = general)
ServiceConnectionTab(if = @tab, equals = connection)
ServiceEnvironmentTab(if = @tab, equals = environment)
ServiceDomainsTab(if = @tab, equals = domains)
ServiceMigrarTab(if = @tab, equals = migrar)
ServiceDatabasesTab(if = @tab, equals = databases)
ServiceDeploymentsTab(if = @tab, equals = deployments)
ServiceHealthcheckTab(if = @tab, equals = healthcheck)
ServiceLogsTab(if = @tab, equals = logs)
ServiceAdvancedTab(if = @tab, equals = advanced)
}
column(class = svc_aside) {
column(class = aside_panel) {
text(class = label_cap, content = "STATUS")
rp-badge(color = @svc_status_color, label = @svc_status_label)
text(class = label_cap, content = "UPTIME")
text(class = kv_val, content = "@daemon_uptime")
text(class = label_cap, content = "SERVICES")
text(class = kv_val, content = "@services_label")
}
column(class = aside_panel_fill) {
text(class = label_cap, content = "LOGS")
text(
class = muted,
content = "Runtime e build logs abrem em janelas próprias (isoladas).",
)
row(class = env_add) {
button(
class = tab,
on_click = open_logs_window,
text = "Logs de runtime",
)
}
}
}
}
}
}