rustploy-gui 0.1.25

Rustploy — desktop client (glacier-ui) for the Rustploy PaaS daemon
// Janela "Exportar serviço": motor Glacier próprio, aberto por open_window a partir do app principal (handlers/bundle.luau).
screen(title = "Exportar serviço — Rustploy") {
  resources {
    style """
    .dialog__check { color: var(--surface); padding: 5 10; border-radius: 4; }
    .dialog__yaml  { width: fill; height: 150; padding: 10 12; font: mono; }
    """

    script(src = "scripts/service_export_window.luau")
  }

  column(class = dialog__screen) {
    row(class = titlebar) {
      row(class = titlebar__drag, on_press = window:drag) {
        text(class = titlebar__dot, content = "●")
        text(class = titlebar__title, content = "Exportar serviço — Rustploy")
      }

      button(class = titlebar__btn, on_click = window:minimize, text = "—")
      button(class = "titlebar__btn titlebar__btn--close", on_click = window:close, text = "✕")
    }

    scrollable(class = dialog__body, direction = vertical) {
      column(class = form-panel) {
        text(class = u-label-cap, content = "EXPORTAR · @export_service")

        text(
          class = u-muted,
          content = """
            Gera um arquivo para recriar este serviço em outro servidor: abra um
            projeto de lá, Novo serviço → Importar. Só a configuração vai; os
            dados (volumes, bancos) não.
          """,
        )

        if @export_blocked != "" {
          text(class = u-error, content = "@export_blocked")
        } else {
          text(class = u-label-cap, content = "VARIÁVEIS DO SERVIÇO (@export_service_count) — TODAS VÃO")
          text(class = u-muted, content = "@export_service_vars")

          text(class = u-label-cap, content = "VARIÁVEIS DO PROJETO “@export_project” — MARQUE AS QUE O APP PRECISA")

          text(
            class = u-muted,
            content = """
              O container recebe TODAS as variáveis do projeto, e o rustploy não
              sabe quais o código lê. As marcadas por padrão são as que o serviço
              cita pelo nome (no env ou no compose); o resto é com você.
            """,
          )

          if @export_has_vars == "true" {
            row(class = dialog__actions) {
              button(
                class = "btn btn--ghost",
                on_click = export_suggested,
                disabled = @busy_export_suggested,
                text = Sugeridas,
              )
              button(class = "btn btn--ghost", on_click = export_all, disabled = @busy_export_all, text = Todas)
              button(class = "btn btn--ghost", on_click = export_none, disabled = @busy_export_none, text = Nenhuma)
              text(class = u-muted, content = "@export_picked_count marcada(s)")
            }

            column(class = kv-list) {
              template(:for-each = export_vars, var = v) {
                row(class = dialog__actions) {
                  button(
                    class = dialog__check,
                    on_click = export_toggle:@v.key,
                    disabled = @busy_export_toggle,
                    text = "@v.mark  @v.key",
                  )
                  text(class = u-muted, content = "@v.tag")
                }
              }
            }
          } else {
            text(class = u-muted, content = "O projeto não tem variáveis.")
          }

          checkbox(
            :checked = export_values,
            on_toggle = field:export_values,
            label = "Incluir os valores das variáveis",
          )

          text(
            if = @export_values,
            equals = true,
            class = u-error,
            content = """
              O arquivo vai conter segredos em texto, e o disco o grava com a
              permissão padrão: trate-o como uma senha. (Secrets do rustploy,
              “secret:NOME”, nunca são decifrados: só a referência vai.)
            """,
          )

          text(
            if = @export_values,
            equals = false,
            class = u-muted,
            content = "Sem valores: o arquivo leva só os nomes, e quem importar preenche os valores.",
          )

          row(class = dialog__actions) {
            button(
              class = "btn btn--primary",
              on_click = export_save,
              disabled = @busy_export_save,
              text = "Salvar arquivo…",
            )
            button(
              class = "btn btn--blue btn--wide",
              on_click = export_show,
              disabled = @busy_export_show,
              text = "Mostrar como texto",
            )
          }

          text(class = u-muted, if = @export_message, not_equals = "", content = "@export_message")
          text(class = u-error, if = @export_error, not_equals = "", content = "@export_error")

          if @export_yaml != "" {
            textarea(class = dialog__yaml, font = mono, :value = export_yaml)
            button(
              class = "btn btn--ghost btn--xs",
              on_click = copy_ctx:export_yaml,
              text = "Copiar texto",
            )
          }
        }
      }
    }
  }
}