Skip to content

Commit

Permalink
[studio] fix table rows indexes #1485 (#1487)
Browse files Browse the repository at this point in the history
studio - fix db table row key
  • Loading branch information
janavlachova authored Jan 14, 2025
1 parent db325c1 commit 79ccd80
Show file tree
Hide file tree
Showing 10 changed files with 172 additions and 32 deletions.
17 changes: 17 additions & 0 deletions agdb_studio/src/components/base/table/AgdbTableHeader.spec.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,30 @@
import { shallowMount } from "@vue/test-utils";
import AgdbTableHeader from "./AgdbTableHeader.vue";
import { describe, it, expect } from "vitest";
import { INJECT_KEY_TABLE_NAME } from "@/composables/table/constants";
import { TABLE_NAME } from "@/tests/tableMocks";

describe("TableHeader", () => {
it("should render", () => {
const wrapper = shallowMount(AgdbTableHeader, {
props: {
tableKey: "table",
},
global: {
provide: {
[INJECT_KEY_TABLE_NAME]: { value: TABLE_NAME },
},
},
});
expect(wrapper.exists()).toBe(true);
});
it("should handle if tableKey is undefined", () => {
const wrapper = shallowMount(AgdbTableHeader, {
global: {
provide: {
[INJECT_KEY_TABLE_NAME]: undefined,
},
},
});
expect(wrapper.exists()).toBe(true);
});
Expand Down
58 changes: 58 additions & 0 deletions agdb_studio/src/components/base/table/AgdbTableRow.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ describe("TableRow", () => {
global: {
provide: {
[INJECT_KEY_COLUMNS]: { value: columnsMap },
[INJECT_KEY_TABLE_NAME]: { value: TABLE_NAME },
},
},
});
Expand Down Expand Up @@ -70,4 +71,61 @@ describe("TableRow", () => {
await wrapper.vm.$nextTick();
expect(wrapper.find(".expanded-row").exists()).toBe(true);
});

it("should not render expand button if rowDetailsComponent is not set", () => {
addTable({
name: "table_without_row_details",
columns: tableConfig,
});
const wrapper = mount(AgdbTableRow, {
props: {
columns: columnsMap,
row: {
role: "admin",
owner: "admin",
db: "app3",
db_type: "file",
size: 50,
backup: 0,
},
},
global: {
provide: {
[INJECT_KEY_COLUMNS]: { value: columnsMap },
[INJECT_KEY_TABLE_NAME]: {
value: "table_without_row_details",
},
},
stubs: {
transitions: false,
},
},
});
expect(wrapper.find(".expand-row").exists()).toBe(false);
});
it("should handle if tableKey is undefined", () => {
const wrapper = mount(AgdbTableRow, {
props: {
columns: columnsMap,
row: {
role: "admin",
owner: "admin",
db: "app3",
db_type: "file",
size: 50,
backup: 0,
},
},
global: {
provide: {
[INJECT_KEY_COLUMNS]: { value: columnsMap },
[INJECT_KEY_TABLE_NAME]: undefined,
},
stubs: {
transitions: false,
},
},
});
expect(wrapper.find(".expand-row").exists()).toBe(false);
});
});
56 changes: 49 additions & 7 deletions agdb_studio/src/components/db/DbTable.spec.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,56 @@
import { shallowMount } from "@vue/test-utils";
import DbTable from "./DbTable.vue";
import { describe, it, expect } from "vitest";
import { describe, it, expect, vi } from "vitest";

const { databases, getDbName } = vi.hoisted(() => {
return {
databases: {
value: [
{
owner: "test_owner",
db: "test_db",
db_type: "memory",
role: "admin",
size: 2656,
backup: 0,
},
{
owner: "test_owner2",
db: "test_db2",
db_type: "memory",
role: "admin",
size: 2656,
backup: 0,
},
],
},

getDbName: vi.fn().mockImplementation((db) => {
return `${db.owner}/${db.db}`;
}),
};
});

vi.mock("@/composables/db/dbStore", () => {
return {
useDbStore: () => {
return {
databases,
getDbName,
};
},
};
});

describe("DbTable", () => {
it("should render", () => {
const wrapper = shallowMount(DbTable, {
props: {
tableKey: "table",
},
});
it("should create table and render databases", () => {
const wrapper = shallowMount(DbTable);
expect(wrapper.exists()).toBe(true);
});

it("should render message when no databases", () => {
databases.value = [];
const wrapper = shallowMount(DbTable);
expect(wrapper.text()).toContain("No databases found");
});
});
4 changes: 3 additions & 1 deletion agdb_studio/src/components/db/DbTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,16 @@ import { setTableData } from "@/composables/table/tableData";
import { watchEffect } from "vue";
import { dbColumns } from "@/composables/db/dbConfig";
const { databases } = useDbStore();
const { databases, getDbName } = useDbStore();
const TABLE_KEY = Symbol("databases");
addTable({
name: TABLE_KEY,
columns: dbColumns,
rowDetailsComponent: "DbDetails",
uniqueKey: (row) =>
getDbName({ owner: row.owner.toString(), db: row.db.toString() }),
});
watchEffect(() => {
Expand Down
1 change: 0 additions & 1 deletion agdb_studio/src/composables/db/dbConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ const dbActions: Action[] = [
label: "Backup",
action: ({ params }: DbActionProps) =>
client.value?.db_backup(params).then(() => {
console.log("Backup created", params);
addNotification({
type: "success",
title: "Backup created",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,6 @@ const testNotifications: AddNotificationProps[] = [
{ type: "warning", title: "Warning without message" },
];

// const testAddNotification = () => {
// testNotifications.forEach((notification) => {
// addNotification(notification);
// });
// };
// testAddNotification();

describe("notificationStore", () => {
beforeEach(() => {
vi.useFakeTimers();
Expand Down
3 changes: 3 additions & 0 deletions agdb_studio/src/composables/table/tableConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ type AddTableProps<T extends TRow> = {
name: Symbol | string;
columns: Column<T>[];
rowDetailsComponent?: AsyncComponent;
uniqueKey?: string | ((row: T) => string);
};

const addTable = ({
name,
columns,
rowDetailsComponent,
uniqueKey,
}: AddTableProps<TRow>): void => {
const columnMap = new Map<string, Column<TRow>>();
columns.forEach((column) => {
Expand All @@ -25,6 +27,7 @@ const addTable = ({
columns: columnMap,
data: new Map(),
rowDetailsComponent,
uniqueKey,
});
};

Expand Down
37 changes: 27 additions & 10 deletions agdb_studio/src/composables/table/tableData.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,15 @@ import {
import { TABLE_NAME, tableConfig, tableData } from "@/tests/tableMocks";
import { addFilter, getTableFilter, setSort } from "./tableFilter";
import { describe, beforeEach, it, expect } from "vitest";
import type { TRow } from "./types";

describe("tableData", () => {
addTable({ name: TABLE_NAME, columns: tableConfig });
addTable({
name: TABLE_NAME,
columns: tableConfig,
uniqueKey: (row: TRow) =>
`${row.owner.toString()}/${row.db.toString()}`,
});

beforeEach(() => {
const table = getTable(TABLE_NAME);
Expand All @@ -38,13 +44,24 @@ describe("tableData", () => {
});
setTableData("table_without_unique_key", tableData);
const table = getTable("table_without_unique_key");
expect([...(table?.data?.keys() ?? [])]).toStrictEqual([
"0",
"1",
"2",
"3",
"4",
expect(table?.data?.size).toBe(5);
});
it("should set table data with custom string unique key", () => {
addTable({
name: "table_with_string_unique_key",
columns: [
{ key: "key", title: "Key" },
{ key: "value", title: "Value" },
],
uniqueKey: "key",
});
setTableData("table_with_string_unique_key", [
{ key: "key1", value: "value1" },
{ key: "key2", value: "value2" },
{ key: "key3", value: "value3" },
]);
const table = getTable("table_with_string_unique_key");
expect(table?.data?.size).toBe(3);
});
});

Expand All @@ -69,11 +86,11 @@ describe("tableData", () => {
it("should remove row", () => {
const table = getTable(TABLE_NAME);
setTableData(TABLE_NAME, tableData);
expect(table?.data?.get("1")).toBeDefined();
expect(table?.data?.get("user/app1")).toBeDefined();
expect(table?.data?.size).toBe(5);
removeRow(TABLE_NAME, "1");
removeRow(TABLE_NAME, "user/app1");
expect(table?.data?.size).toBe(4);
expect(table?.data?.get("1")).toBeUndefined();
expect(table?.data?.get("user/app1")).toBeUndefined();
});
});

Expand Down
20 changes: 14 additions & 6 deletions agdb_studio/src/composables/table/tableData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,17 @@ import type { TRow } from "./types";
import { getTable } from "./tableConfig";
import { getTableFilter } from "./tableFilter";

const getRowKey = <T extends TRow>(
row: T,
uniqueKey?: string | ((row: T) => string),
): string => {
const rowKey =
typeof uniqueKey === "string"
? String(row[uniqueKey])
: uniqueKey?.(row);
return rowKey ?? (Date.now() + Math.random()).toString();
};

const setTableData = <T extends TRow>(
tableName: Symbol | string,
data: T[],
Expand All @@ -16,18 +27,15 @@ const setTableData = <T extends TRow>(
table.columns.forEach((column) => {
rowData[column.key] = data[rowIndex][column.key];
});
const rowKey = rowIndex;

table.data.set(rowKey, rowData);
table.data.set(getRowKey(rowData, table.uniqueKey), rowData);
}
};

const addRow = <T extends TRow>(tableName: Symbol | string, row: T): void => {
const table = getTable<T>(tableName);
const rowKey = table?.data?.size.toString();
if (!rowKey) {
return;
}

const rowKey = getRowKey(row, table?.uniqueKey);

table?.data?.set(rowKey, row);
};
Expand Down
1 change: 1 addition & 0 deletions agdb_studio/src/composables/table/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ export type Table<T extends TRow> = {
columns: Map<string, Column<T>>;
data?: Map<string, T>;
rowDetailsComponent?: AsyncComponent;
uniqueKey?: string | ((row: T) => string);
};

0 comments on commit 79ccd80

Please sign in to comment.