rustploy-gui 0.1.21

Rustploy — desktop client (glacier-ui) for the Rustploy PaaS daemon
// Card de serviço da aba "Serviços" de um projeto — o análogo do ProjectCard.
component {
  props {
    prop(name = id)
    prop(name = name)
    prop(name = port)
    prop(name = status_color)
    prop(name = status_label)
    prop(name = has_warm)
    prop(name = warm_label)
    prop(name = warm_color)
    prop(name = warm_reason)
    prop(name = cpu)
    prop(name = mem)
    prop(name = filler)
    prop(name = container_name)
    prop(name = container_id)
    prop(name = container_name_full)
    prop(name = container_id_full)
    prop(name = container_extra)
  }

  resources {
    style """
    .card__stats     { width: fill; spacing: 12; }
    .card__stat      { width: fill; spacing: 4; }
    .card__stat-num  { size: 18; bold: true; color: var(--text-2); }
    .card__container { width: fill; spacing: 6; align-y: center; }
    .card__copy      { color: var(--border); padding: 0 5; size: 11; border-radius: 3; }
    .card__actions   { width: fill; spacing: 8; }
    .card__title     { size: 16; bold: true; color: var(--text); }
    .card__port      { size: 12; color: var(--muted); }
    """
  }

  column(if = @filler, equals = 1, class = u-fill)

  column(else, class = card) {
    row(class = card__head) {
      row(class = "u-fill u-align-y-end") {
        text(class = card__title, content = "@name")
        text(class = card__port, content = ":@port")
      }

      row(class = "u-align-y-end") {
        rp-badge(if = @has_warm, equals = true, color = @warm_color, label = "◐ @warm_label")
        rp-badge(color = @status_color, label = @status_label)
      }
    }

    row(class = card__container) {
      button(
        class = card__copy,
        if = @container_name_full,
        not_equals = "",
        on_click = copy_container_name:@container_name_full,
        text = "⧉",
        tooltip = "Copiar nome",
      )

      text(class = u-muted, content = "name: @container_name")
    }

    row(class = card__container) {
      button(
        class = card__copy,
        if = @container_id_full,
        not_equals = "",
        on_click = copy_container_id:@container_id_full,
        text = "⧉",
        tooltip = "Copiar id",
      )

      text(class = u-muted, content = "id: @container_id")

      text(
        class = u-muted,
        if = @container_extra,
        not_equals = "",
        content = "extra: @container_extra",
      )
    }

    hr

    row(class = card__stats) {
      column(class = card__stat) {
        text(class = u-label-cap, content = "CPU")
        text(class = card__stat-num, content = "@cpu")
      }

      column(class = card__stat) {
        text(class = u-label-cap, content = "MEM")
        text(class = card__stat-num, content = "@mem")
      }
    }

    // Ações empilhadas: 3 botões numa linha só transbordam no tamanho mínimo
    // de janela (grade de 3 colunas).
    button(class = "card__action card__action--open", on_click = open_service:@id, disabled = @busy_open_service, text = "Abrir  ›")

    row(class = card__actions) {
      button(
        class = "card__action card__action--icon",
        on_click = service_stop_id:@id,
        disabled = @busy_service_stop_id,
        text = "■",
        tooltip = Parar,
      )

      button(
        class = "card__action card__action--icon card__action--danger",
        on_click = stop_delete_service:@id,
        disabled = @busy_stop_delete_service,
        text = "✕",
        tooltip = Remover,
      )

      button(
        class = "card__action card__action--icon",
        on_click = open_export_window:@id,
        disabled = @busy_open_export_window,
        text = "⇪",
        tooltip = "Exportar serviço (arquivo para recriá-lo em outro servidor)",
      )
    }
  }
}