feat(connectors): checks card and account list polish (#15893)

This commit is contained in:
Raunak Bhagat authored and GitHub committed 2026-10-12 18:07:25 +00:00
1 parent d29aaa8a61
commit 29f8c837d0
13 files changed
+47 -54

No files matched your search

+3 -3
View File
@@ -26,9 +26,9 @@ statuses are a subset of `StatusVariants`:
| Status | Icon | `heavy` background |
| --------- | ------------------- | ------------------- |
| `default` | `text-03` | — (never heavy) |
| `success` | `status-success-05` | `status-success-01` |
| `warning` | `theme-amber-05` | `theme-amber-01` |
| `error` | `status-error-05` | `status-error-01` |
| `success` | `status-success-05` | `status-success-00` |
| `warning` | `theme-amber-05` | `status-warning-00` |
| `error` | `status-error-05` | `status-error-00` |
A `light` line has no background. Use `heavy` for the lines that need action,
such as a failure that blocks. The variant sets colours only; pass the icon
+3 -3
View File
@@ -23,11 +23,11 @@
}
.opal-log[data-opal-log-weight="heavy"][data-opal-log-status="success"] {
@apply bg-status-success-01;
@apply bg-status-success-00;
}
.opal-log[data-opal-log-weight="heavy"][data-opal-log-status="warning"] {
@apply bg-theme-amber-01;
@apply bg-status-warning-00;
}
.opal-log[data-opal-log-weight="heavy"][data-opal-log-status="error"] {
@apply bg-status-error-01;
@apply bg-status-error-00;
}
+2 -4
View File
@@ -9040,9 +9040,6 @@
"required": {
"label": "مطلوب"
},
"running": {
"label": "جارٍ تشغيل الفحوصات…"
},
"empty": {
"label": "لم يتم تشغيل أي فحوصات بعد."
},
@@ -9066,7 +9063,8 @@
"requiredFailed": "{count, plural, one {فشل فحص مطلوب واحد} other {فشل # فحوصات مطلوبة}}",
"state": {
"completed": "اكتملت عمليات التحقق.",
"inProgress": "عمليات التحقق قيد التنفيذ…"
"inProgress": "عمليات التحقق قيد التنفيذ...",
"waiting": "بانتظار إعدادات الموصل..."
}
}
},
+2 -4
View File
@@ -9040,9 +9040,6 @@
"required": {
"label": "Erforderlich"
},
"running": {
"label": "Prüfungen laufen…"
},
"empty": {
"label": "Es wurden noch keine Prüfungen ausgeführt."
},
@@ -9066,7 +9063,8 @@
"requiredFailed": "{count, plural, one {# erforderliche Prüfung fehlgeschlagen} other {# erforderliche Prüfungen fehlgeschlagen}}",
"state": {
"completed": "Prüfungen abgeschlossen.",
"inProgress": "Prüfungen laufen…"
"inProgress": "Prüfungen laufen...",
"waiting": "Warten auf Connector-Einstellungen..."
}
}
},
+2 -4
View File
@@ -9040,9 +9040,6 @@
"required": {
"label": "Required"
},
"running": {
"label": "Running checks…"
},
"empty": {
"label": "No checks have run yet."
},
@@ -9066,7 +9063,8 @@
"requiredFailed": "{count, plural, one {# required check failed} other {# required checks failed}}",
"state": {
"completed": "Checks completed.",
"inProgress": "Checks in progress…"
"inProgress": "Checks in progress...",
"waiting": "Waiting for connector settings..."
}
}
},
+2 -4
View File
@@ -9040,9 +9040,6 @@
"required": {
"label": "Obligatoria"
},
"running": {
"label": "Ejecutando comprobaciones…"
},
"empty": {
"label": "Aún no se han ejecutado comprobaciones."
},
@@ -9066,7 +9063,8 @@
"requiredFailed": "{count, plural, one {# comprobación obligatoria fallida} other {# comprobaciones obligatorias fallidas}}",
"state": {
"completed": "Comprobaciones completadas.",
"inProgress": "Comprobaciones en curso…"
"inProgress": "Comprobaciones en curso...",
"waiting": "Esperando la configuración del conector..."
}
}
},
+2 -4
View File
@@ -9040,9 +9040,6 @@
"required": {
"label": "Obligatoire"
},
"running": {
"label": "Vérifications en cours…"
},
"empty": {
"label": "Aucune vérification n'a encore été exécutée."
},
@@ -9066,7 +9063,8 @@
"requiredFailed": "{count, plural, one {# vérification obligatoire en échec} other {# vérifications obligatoires en échec}}",
"state": {
"completed": "Vérifications terminées.",
"inProgress": "Vérifications en cours…"
"inProgress": "Vérifications en cours...",
"waiting": "En attente des paramètres du connecteur..."
}
}
},
+2 -4
View File
@@ -9040,9 +9040,6 @@
"required": {
"label": "必須"
},
"running": {
"label": "チェックを実行中…"
},
"empty": {
"label": "まだチェックは実行されていません。"
},
@@ -9066,7 +9063,8 @@
"requiredFailed": "{count, plural, one {必須チェック # 件が失敗} other {必須チェック # 件が失敗}}",
"state": {
"completed": "チェックが完了しました。",
"inProgress": "チェックを実行中…"
"inProgress": "チェックを実行中...",
"waiting": "コネクタ設定を待機中..."
}
}
},
+2 -4
View File
@@ -9040,9 +9040,6 @@
"required": {
"label": "필수"
},
"running": {
"label": "검사 실행 중…"
},
"empty": {
"label": "아직 실행된 검사가 없습니다."
},
@@ -9066,7 +9063,8 @@
"requiredFailed": "{count, plural, one {필수 검사 #개 실패} other {필수 검사 #개 실패}}",
"state": {
"completed": "검사가 완료되었습니다.",
"inProgress": "검사 진행 중…"
"inProgress": "검사 진행 중...",
"waiting": "커넥터 설정을 기다리는 중..."
}
}
},
+2 -4
View File
@@ -9040,9 +9040,6 @@
"required": {
"label": "Obrigatória"
},
"running": {
"label": "Executando verificações…"
},
"empty": {
"label": "Nenhuma verificação foi executada ainda."
},
@@ -9066,7 +9063,8 @@
"requiredFailed": "{count, plural, one {# verificação obrigatória falhou} other {# verificações obrigatórias falharam}}",
"state": {
"completed": "Verificações concluídas.",
"inProgress": "Verificações em andamento…"
"inProgress": "Verificações em andamento...",
"waiting": "Aguardando as configurações do conector..."
}
}
},
+2 -4
View File
@@ -9040,9 +9040,6 @@
"required": {
"label": "必需"
},
"running": {
"label": "正在运行检查…"
},
"empty": {
"label": "尚未运行任何检查。"
},
@@ -9066,7 +9063,8 @@
"requiredFailed": "{count, plural, one {# 项必需检查失败} other {# 项必需检查失败}}",
"state": {
"completed": "检查已完成。",
"inProgress": "检查进行中…"
"inProgress": "检查进行中...",
"waiting": "正在等待连接器设置..."
}
}
},
@@ -28,7 +28,6 @@ import {
SvgMinusCircle,
SvgPlay,
SvgRefreshCw,
SvgXCircle,
SvgXOctagon,
} from "@opal/icons";
import type { IconFunctionComponent, IconProps, RichStr } from "@opal/types";
@@ -84,7 +83,7 @@ const CHECK_LOGS = {
// A failed required check blocks, so `CheckLog` makes it heavy.
failed: {
variant: "error-light",
icon: SvgXCircle,
icon: SvgXOctagon,
detail: "status.failed",
font: OUTCOME_FONT,
color: "status-error-05",
@@ -312,7 +311,7 @@ function CheckCardView({
// "2 failed, 1 skipped, 5 successful". Zero counts are left out.
const summary = useMemo(() => {
if (notice) return notice;
if (!hasChecks) return isRunning ? t("running.label") : t("empty.label");
if (!hasChecks) return isRunning ? t("state.inProgress") : t("empty.label");
const parts: Array<[string, number]> = [
[t("summary.failed", { count: count("failed") }), count("failed")],
[
@@ -349,14 +348,17 @@ function CheckCardView({
title={t("title")}
suffix={progress.suffix}
// Expanded, a short state line keeps the header's height steady while
// the rows fold. A run that broke reads the same either way.
// the rows fold. A run that broke reads the same either way. Checks
// that wait for settings have not run, so the run is not complete.
description={
notice ??
(collapsed
? summary
: isRunning || inProgressCount > 0
? t("state.inProgress")
: t("state.completed"))
: expectedCount > 0
? t("state.waiting")
: t("state.completed"))
}
sizePreset="main-content"
variant="section"
@@ -466,7 +468,7 @@ function CheckCardView({
) : (
!notice && (
<Text font="main-ui-body" color="text-03">
{isRunning ? t("running.label") : t("empty.label")}
{isRunning ? t("state.inProgress") : t("empty.label")}
</Text>
)
)}
@@ -18,6 +18,7 @@ import {
toast,
} from "@opal/layouts";
import { Disabled } from "@opal/core";
import { cn } from "@opal/utils";
import { FormikField } from "@/refresh-components/form/FormikField";
import { SvgExpand, SvgFold, SvgListTree, SvgPlusCircle } from "@opal/icons";
import type {
@@ -482,21 +483,23 @@ export default function AuthenticationAccountSection({
<Section gap={6} alignItems="stretch" width="full">
{/* One list in a fixed order. Folded, each card that is not the
chosen one fades, then its height collapses, so the chosen card
moves up on its own. Each item holds its own spacing: a closed fold
takes no height, but a gap around it would stay. */}
moves up on its own. Every item but the first is spaced from the
one above inside its fold, so a closed item takes no space. */}
<div className="flex flex-col">
{credentials.map((credential) => (
{credentials.map((credential, index) => (
<Fold
key={credential.id}
open={accountsExpanded || credential.id === selectedSavedId}
keepMounted
>
<div className="pb-2">{renderSavedCard(credential)}</div>
<div className={cn(index > 0 && "pt-2")}>
{renderSavedCard(credential)}
</div>
</Fold>
))}
{canAuthorize && (
<Fold open={accountsExpanded} keepMounted>
<div className="pb-2">
<div className={cn(credentials.length > 0 && "pt-2")}>
<Section flexDirection="row" justifyContent="start" gap={1}>
<Button
disabled={isAuthorizing}
@@ -519,7 +522,13 @@ export default function AuthenticationAccountSection({
open={accountsExpanded || selectedSavedId === null}
keepMounted
>
{newAccountCard}
<div
className={cn(
(credentials.length > 0 || canAuthorize) && "pt-2"
)}
>
{newAccountCard}
</div>
</Fold>
</div>