Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion src/components/ui/ResultEntryContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,15 @@ export function ResultEntryContent({
<span className="truncate whitespace-nowrap">
{t("editor.rowsRetrieved", {
count: entry.result.rows.length,
})}{" "}
})}
{entry.result.columns.length > 0 && (
<span className="hidden @[400px]:inline text-muted">
{" · "}
{t("editor.columnsCount", {
count: entry.result.columns.length,
})}
</span>
)}{" "}
{entry.executionTime !== null && (
<span className="hidden @[400px]:inline text-muted ml-2 font-mono">
({formatDuration(entry.executionTime)})
Expand Down
8 changes: 8 additions & 0 deletions src/components/ui/StackedResultItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,14 @@ export function StackedResultItem({
)}
<span className="text-muted text-[11px] truncate whitespace-nowrap">
{t("editor.rowsRetrieved", { count: entry.result!.rows.length })}
{entry.result!.columns.length > 0 && (
<span className="hidden @[400px]:inline">
{" · "}
{t("editor.columnsCount", {
count: entry.result!.columns.length,
})}
</span>
)}
{entry.executionTime !== null && (
<span className="hidden @[400px]:inline font-mono ml-1">
({formatDuration(entry.executionTime)})
Expand Down
2 changes: 2 additions & 0 deletions src/i18n/locales/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -1355,6 +1355,8 @@
"newRow": "Neue Zeile",
"editing": "Bearbeitung: {{table}}",
"rowsRetrieved": "{{count}} Zeilen abgerufen",
"columnsCount_one": "{{count}} Spalte",
"columnsCount_other": "{{count}} Spalten",
"queryExecuted": "Abfrage erfolgreich ausgeführt",
"rowsAffected": "{{count}} Zeilen betroffen",
"autoPaginated": "Automatisch paginiert",
Expand Down
2 changes: 2 additions & 0 deletions src/i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1385,6 +1385,8 @@
"newRow": "New Row",
"editing": "Editing: {{table}}",
"rowsRetrieved": "{{count}} rows retrieved",
"columnsCount_one": "{{count}} column",
"columnsCount_other": "{{count}} columns",
"queryExecuted": "Query executed successfully",
"rowsAffected": "{{count}} rows affected",
"autoPaginated": "Auto paginated",
Expand Down
2 changes: 2 additions & 0 deletions src/i18n/locales/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -1384,6 +1384,8 @@
"newRow": "Nueva Fila",
"editing": "Editando: {{table}}",
"rowsRetrieved": "{{count}} filas obtenidas",
"columnsCount_one": "{{count}} columna",
"columnsCount_other": "{{count}} columnas",
"queryExecuted": "Consulta ejecutada correctamente",
"rowsAffected": "{{count}} filas afectadas",
"autoPaginated": "Paginación automática",
Expand Down
2 changes: 2 additions & 0 deletions src/i18n/locales/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -1377,6 +1377,8 @@
"newRow": "Nouvelle ligne",
"editing": "Modification : {{table}}",
"rowsRetrieved": "{{count}} lignes récupérées",
"columnsCount_one": "{{count}} colonne",
"columnsCount_other": "{{count}} colonnes",
"queryExecuted": "Requête exécutée avec succès",
"rowsAffected": "{{count}} lignes affectées",
"autoPaginated": "Pagination automatique",
Expand Down
2 changes: 2 additions & 0 deletions src/i18n/locales/it.json
Original file line number Diff line number Diff line change
Expand Up @@ -1376,6 +1376,8 @@
"newRow": "Nuova riga",
"editing": "Modifica: {{table}}",
"rowsRetrieved": "{{count}} righe recuperate",
"columnsCount_one": "{{count}} colonna",
"columnsCount_other": "{{count}} colonne",
"queryExecuted": "Query eseguita con successo",
"rowsAffected": "{{count}} righe interessate",
"autoPaginated": "Impaginazione automatica",
Expand Down
2 changes: 2 additions & 0 deletions src/i18n/locales/ja.json
Original file line number Diff line number Diff line change
Expand Up @@ -1367,6 +1367,8 @@
"newRow": "新規行",
"editing": "編集中: {{table}}",
"rowsRetrieved": "{{count}} 行を取得しました",
"columnsCount_one": "{{count}} 列",
"columnsCount_other": "{{count}} 列",
"queryExecuted": "クエリが正常に実行されました",
"rowsAffected": "{{count}} 行に影響",
"autoPaginated": "自動ページング",
Expand Down
2 changes: 2 additions & 0 deletions src/i18n/locales/ko.json
Original file line number Diff line number Diff line change
Expand Up @@ -1312,6 +1312,8 @@
"newRow": "새 행",
"editing": "편집 중: {{table}}",
"rowsRetrieved": "{{count}}개 행 조회됨",
"columnsCount_one": "열 {{count}}개",
"columnsCount_other": "열 {{count}}개",
"queryExecuted": "쿼리가 성공적으로 실행되었습니다",
"rowsAffected": "{{count}}개 행 영향받음",
"autoPaginated": "자동 페이지네이션됨",
Expand Down
2 changes: 2 additions & 0 deletions src/i18n/locales/pt-BR.json
Original file line number Diff line number Diff line change
Expand Up @@ -1354,6 +1354,8 @@
"newRow": "Nova Linha",
"editing": "Editando: {{table}}",
"rowsRetrieved": "{{count}} linhas obtidas",
"columnsCount_one": "{{count}} coluna",
"columnsCount_other": "{{count}} colunas",
"queryExecuted": "Consulta executada com sucesso",
"rowsAffected": "{{count}} linhas afetadas",
"autoPaginated": "Paginado automaticamente",
Expand Down
4 changes: 4 additions & 0 deletions src/i18n/locales/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -1355,6 +1355,10 @@
"newRow": "Новая строка",
"editing": "Редактирование: {{table}}",
"rowsRetrieved": "Строк: {{count}}",
"columnsCount_one": "{{count}} столбец",
"columnsCount_few": "{{count}} столбца",
"columnsCount_many": "{{count}} столбцов",
"columnsCount_other": "{{count}} столбца",
"queryExecuted": "Запрос выполнен успешно",
"rowsAffected": "затронуто строк: {{count}}",
"autoPaginated": "Автопостраничный вывод",
Expand Down
2 changes: 2 additions & 0 deletions src/i18n/locales/tl.json
Original file line number Diff line number Diff line change
Expand Up @@ -1368,6 +1368,8 @@
"newRow": "Bagong Row",
"editing": "Ine-edit: {{table}}",
"rowsRetrieved": "{{count}} row ang nakuha",
"columnsCount_one": "{{count}} column",
"columnsCount_other": "{{count}} column",
"queryExecuted": "Matagumpay na naisakatuparan ang query",
"rowsAffected": "{{count}} row ang naapektuhan",
"autoPaginated": "Auto paginated",
Expand Down
2 changes: 2 additions & 0 deletions src/i18n/locales/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -1330,6 +1330,8 @@
"newRow": "新建行",
"editing": "编辑中:{{table}}",
"rowsRetrieved": "已检索 {{count}} 行",
"columnsCount_one": "{{count}} 列",
"columnsCount_other": "{{count}} 列",
"queryExecuted": "查询执行成功",
"rowsAffected": "{{count}} 行受影响",
"autoPaginated": "自动分页",
Expand Down
10 changes: 9 additions & 1 deletion src/pages/Editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5265,7 +5265,15 @@ export const Editor = ({ commandScopeId }: EditorProps) => {
<span className="truncate whitespace-nowrap">
{t("editor.rowsRetrieved", {
count: activeTab.result.rows.length,
})}{" "}
})}
{activeTab.result.columns.length > 0 && (
<span className="hidden @[400px]:inline text-muted">
{" · "}
{t("editor.columnsCount", {
count: activeTab.result.columns.length,
})}
</span>
)}{" "}
{activeTab.executionTime !== null && (
<span className="hidden @[400px]:inline text-muted ml-2 font-mono">
({formatDuration(activeTab.executionTime)})
Expand Down
86 changes: 86 additions & 0 deletions tests/components/ui/ResultStatusColumnCount.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { describe, it, expect, vi } from "vitest";
import { render, screen } from "@testing-library/react";
import { ResultEntryContent } from "../../../src/components/ui/ResultEntryContent";
import { StackedResultItem } from "../../../src/components/ui/StackedResultItem";
import type { QueryResult, QueryResultEntry } from "../../../src/types/editor";

// The shared mock returns the bare key; these tests need the count it was given.
vi.mock("react-i18next", () => ({
useTranslation: () => ({
t: (key: string, options?: { count?: number }) =>
options?.count === undefined ? key : `${key}:${options.count}`,
i18n: { language: "en", changeLanguage: vi.fn() },
}),
initReactI18next: { type: "3rdParty", init: vi.fn() },
}));

vi.mock("../../../src/components/ui/DataGrid", () => ({
DataGrid: () => <div data-testid="data-grid" />,
}));

vi.mock("../../../src/components/ui/ErrorDisplay", () => ({
ErrorDisplay: ({ error }: { error: string }) => <div>{error}</div>,
}));

function makeEntry(result: QueryResult): QueryResultEntry {
return {
id: "tab1-result-0",
queryIndex: 0,
query: "SELECT * FROM users",
result,
error: "",
executionTime: 12,
isLoading: false,
page: 1,
activeTable: null,
pkColumns: null,
};
}

const wide: QueryResult = {
columns: ["id", "name", "email"],
rows: [[1, "Ada", "ada@example.com"]],
affected_rows: 0,
};

const noColumns: QueryResult = { columns: [], rows: [], affected_rows: 3 };

const gridProps = {
connectionId: "c1",
copyFormat: "csv" as const,
csvDelimiter: ",",
csvIncludeHeaders: true,
onPageChange: vi.fn(),
};

describe("result status bar column count", () => {
it("shows the number of columns next to the row count in a result entry", () => {
render(<ResultEntryContent {...gridProps} entry={makeEntry(wide)} />);
expect(screen.getByText(/editor\.rowsRetrieved:1/)).toBeInTheDocument();
expect(screen.getByText(/editor\.columnsCount:3/)).toBeInTheDocument();
});

it("shows the number of columns in the header of a stacked result", () => {
render(
<StackedResultItem
{...gridProps}
entry={makeEntry(wide)}
collapsed={false}
aiEnabled={false}
aiRenaming={false}
onToggleCollapse={vi.fn()}
onCopyAllRows={vi.fn()}
onRename={vi.fn()}
onRerun={vi.fn()}
onAiRename={vi.fn()}
onClose={vi.fn()}
/>,
);
expect(screen.getByText(/editor\.columnsCount:3/)).toBeInTheDocument();
});

it("leaves a statement without a result set unchanged", () => {
render(<ResultEntryContent {...gridProps} entry={makeEntry(noColumns)} />);
expect(screen.queryByText(/editor\.columnsCount/)).not.toBeInTheDocument();
});
});