Skip to content

Commit a3e6d2e

Browse files
committed
chore: small optimization
1 parent 258611c commit a3e6d2e

3 files changed

Lines changed: 126 additions & 121 deletions

File tree

src/components/browseTab/DataTable.tsx

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useMemo } from "react";
1+
import { useCallback, useMemo } from "react";
22
import { useDatabaseStore } from "@/store/useDatabaseStore";
33
import { useDatabaseWorker } from "@/providers/DatabaseWorkerProvider";
44
import { usePanelManager } from "@/providers/PanelProvider";
@@ -26,6 +26,14 @@ const DataTable = () => {
2626
const { handleQueryFilter } = useDatabaseWorker();
2727
const { handleRowClick, selectedRowObject } = usePanelManager();
2828

29+
// Memoize filter handlers to prevent recreating functions on each render
30+
const getFilterHandler = useCallback(
31+
(column: string) => (value: string) => {
32+
handleQueryFilter(column, value);
33+
},
34+
[handleQueryFilter]
35+
);
36+
2937
const emptyDataContent = useMemo(
3038
() => (
3139
<div className="flex h-full flex-col items-center justify-center gap-1">
@@ -58,15 +66,17 @@ const DataTable = () => {
5866
);
5967

6068
const memoizedFilterInput = useMemo(() => {
61-
return (columns || []).map((column) => (
69+
if (!columns) return [];
70+
71+
return columns.map((column) => (
6272
<FilterInput
6373
key={column}
6474
column={column}
6575
value={filters?.[column] || ""}
66-
onChange={handleQueryFilter}
76+
onChange={getFilterHandler(column)}
6777
/>
6878
));
69-
}, [columns, filters, handleQueryFilter]);
79+
}, [columns, filters, getFilterHandler]);
7080

7181
return useMemo(
7282
() => (
Lines changed: 109 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
import { useCallback, useEffect, useMemo, useState } from "react";
1+
import { useCallback, useEffect, useMemo } from "react";
22
import { useDatabaseWorker } from "@/providers/DatabaseWorkerProvider";
33
import { usePanelManager } from "@/providers/PanelProvider";
44
import { useDatabaseStore } from "@/store/useDatabaseStore";
5+
import { usePanelStore } from "@/store/usePanelStore";
56

67
import { Button } from "@/components/ui/button";
78
import { Input } from "@/components/ui/input";
@@ -14,143 +15,140 @@ import {
1415
SquarePenIcon,
1516
Trash2Icon
1617
} from "lucide-react";
18+
1719
const EditSection = () => {
1820
const { handleEditSubmit } = useDatabaseWorker();
1921
const { selectedRowObject, isInserting, goBackToData } = usePanelManager();
22+
const { editValues, setEditValues } = usePanelStore();
2023
const { tablesSchema, currentTable, columns } = useDatabaseStore();
2124

22-
const [editValues, setEditValues] = useState<string[]>([]);
23-
2425
// Update formValues when isInserting or selectedRow changes
2526
useEffect(() => {
2627
if (isInserting) {
27-
// When inserting, initialize with empty strings or default values
2828
setEditValues(columns?.map(() => "") || []);
2929
} else if (selectedRowObject) {
30-
// When editing, set values from the selected row
3130
setEditValues(
3231
selectedRowObject.data.map((value) => value?.toString() ?? "")
3332
);
3433
}
35-
}, [isInserting, selectedRowObject, columns]);
34+
}, [isInserting, selectedRowObject, columns, setEditValues]);
3635

3736
// Handle when user updates the edit inputs
3837
const handleEditInputChange = useCallback(
3938
(index: number, newValue: string) => {
40-
setEditValues((prev) => {
41-
const newEditValues = [...prev];
42-
newEditValues[index] = newValue;
43-
return newEditValues;
44-
});
39+
const currentEditValues = usePanelStore.getState().editValues;
40+
setEditValues(
41+
currentEditValues.map((value, i) => (i === index ? newValue : value))
42+
);
4543
},
46-
[]
44+
[setEditValues]
4745
);
4846

49-
const editSection = useMemo(
50-
() => (
51-
<section className="h-full overflow-auto">
52-
<div className="flex h-full w-full flex-col">
53-
<div className="overflow-auto">
54-
<div className="bg-primary/5 flex w-full items-center justify-between gap-1 border-b p-2 text-sm">
55-
<div className="flex items-center gap-1">
56-
{isInserting ? (
57-
<>
58-
<PlusIcon className="h-4 w-4" />
59-
<Span className="whitespace-nowrap">Inserting row</Span>
60-
</>
61-
) : (
62-
<>
63-
<SquarePenIcon className="h-4 w-4" />
64-
<Span className="whitespace-nowrap">Updating row</Span>
65-
</>
66-
)}
67-
</div>
68-
<Button
69-
size="sm"
70-
variant="outline"
71-
className="text-xs md:hidden"
72-
onClick={goBackToData}
73-
aria-label="Go back to data"
74-
>
75-
<ChevronLeftIcon className="mr-1 h-3 w-3" />
76-
Go back
77-
</Button>
78-
</div>
47+
const formItems = useMemo(() => {
48+
if (!columns || !currentTable || !tablesSchema[currentTable]) return null;
49+
50+
return columns.map((column, index) => (
51+
<div key={column}>
52+
<label
53+
htmlFor={column}
54+
className="bg-primary/5 flex items-center gap-1 rounded-sm p-2"
55+
>
56+
<ColumnIcon
57+
columnSchema={tablesSchema[currentTable]?.schema[index]}
58+
/>
59+
<Span className="text-xs font-medium capitalize">{column}</Span>
60+
</label>
61+
<Input
62+
id={column}
63+
name={column}
64+
className="border-primary/20 h-8 rounded-none text-sm text-[0.8rem]!"
65+
value={editValues[index] || ""}
66+
onChange={(e) => handleEditInputChange(index, e.target.value)}
67+
/>
68+
</div>
69+
));
70+
}, [columns, currentTable, tablesSchema, editValues, handleEditInputChange]);
7971

80-
{columns?.map((column, index) => (
81-
<div key={column}>
82-
<label
83-
htmlFor={column}
84-
className="bg-primary/5 flex items-center gap-1 rounded-sm p-2"
85-
>
86-
<ColumnIcon
87-
columnSchema={tablesSchema[currentTable!]?.schema[index]}
88-
/>
89-
<Span className="text-xs font-medium capitalize">
90-
{column}
91-
</Span>
92-
</label>
93-
<Input
94-
id={column}
95-
name={column}
96-
className="border-primary/20 h-8 rounded-none text-sm text-[0.8rem]!"
97-
value={editValues[index] || ""}
98-
onChange={(e) => handleEditInputChange(index, e.target.value)}
99-
/>
100-
</div>
101-
))}
102-
</div>
72+
const actionButtons = useMemo(
73+
() => (
74+
<div className="flex w-full">
75+
<Button
76+
size="sm"
77+
variant="outline"
78+
className="w-full text-xs"
79+
onClick={() => handleEditSubmit(isInserting ? "insert" : "update")}
80+
aria-label={isInserting ? "Insert row" : "Apply changes"}
81+
>
82+
{isInserting ? (
83+
<>
84+
<PlusIcon className="mr-1 h-3 w-3" />
85+
Insert row
86+
</>
87+
) : (
88+
<>
89+
<SquarePenIcon className="mr-1 h-3 w-3" />
90+
Apply changes
91+
</>
92+
)}
93+
</Button>
94+
{!isInserting && (
95+
<Button
96+
size="sm"
97+
variant="destructive"
98+
className="rounded-none text-xs"
99+
onClick={() => handleEditSubmit("delete")}
100+
aria-label="Delete row"
101+
>
102+
<Trash2Icon className="h-3 w-3" />
103+
</Button>
104+
)}
105+
</div>
106+
),
107+
[handleEditSubmit, isInserting]
108+
);
103109

104-
<div className="flex w-full">
105-
<Button
106-
size="sm"
107-
variant="outline"
108-
className="w-full text-xs"
109-
onClick={() =>
110-
handleEditSubmit(isInserting ? "insert" : "update", editValues)
111-
}
112-
aria-label={isInserting ? "Insert row" : "Apply changes"}
113-
>
114-
{isInserting ? (
115-
<>
116-
<PlusIcon className="mr-1 h-3 w-3" />
117-
Insert row
118-
</>
119-
) : (
120-
<>
121-
<SquarePenIcon className="mr-1 h-3 w-3" />
122-
Apply changes
123-
</>
124-
)}
125-
</Button>
126-
{!isInserting && (
127-
<Button
128-
size="sm"
129-
variant="destructive"
130-
className="rounded-none text-xs"
131-
onClick={() => handleEditSubmit("delete", editValues)}
132-
aria-label="Delete row"
133-
>
134-
<Trash2Icon className="h-3 w-3" />
135-
</Button>
136-
)}
137-
</div>
110+
const sectionHeader = useMemo(
111+
() => (
112+
<div className="bg-primary/5 flex w-full items-center justify-between gap-1 border-b p-2 text-sm">
113+
<div className="flex items-center gap-1">
114+
{isInserting ? (
115+
<>
116+
<PlusIcon className="h-4 w-4" />
117+
<Span className="whitespace-nowrap">Inserting row</Span>
118+
</>
119+
) : (
120+
<>
121+
<SquarePenIcon className="h-4 w-4" />
122+
<Span className="whitespace-nowrap">Updating row</Span>
123+
</>
124+
)}
138125
</div>
139-
</section>
126+
<Button
127+
size="sm"
128+
variant="outline"
129+
className="text-xs md:hidden"
130+
onClick={goBackToData}
131+
aria-label="Go back to data"
132+
>
133+
<ChevronLeftIcon className="mr-1 h-3 w-3" />
134+
Go back
135+
</Button>
136+
</div>
140137
),
141-
[
142-
currentTable,
143-
tablesSchema,
144-
columns,
145-
editValues,
146-
handleEditInputChange,
147-
handleEditSubmit,
148-
isInserting,
149-
goBackToData
150-
]
138+
[isInserting, goBackToData]
151139
);
152140

153-
return editSection;
141+
return (
142+
<section className="h-full overflow-auto">
143+
<div className="flex h-full w-full flex-col">
144+
<div className="overflow-auto">
145+
{sectionHeader}
146+
{formItems}
147+
</div>
148+
{actionButtons}
149+
</div>
150+
</section>
151+
);
154152
};
155153

156154
export default EditSection;

src/providers/DatabaseWorkerProvider.tsx

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,7 @@ interface DatabaseWorkerContextProps {
2424
handlePageChange: (type: "next" | "prev" | "first" | "last" | number) => void;
2525
handleExport: (exportType: "table" | "current") => void;
2626
handleQueryExecute: () => void;
27-
handleEditSubmit: (
28-
type: "insert" | "update" | "delete",
29-
editValues: string[]
30-
) => void;
27+
handleEditSubmit: (type: "insert" | "update" | "delete") => void;
3128
}
3229

3330
const DatabaseWorkerContext = createContext<
@@ -413,14 +410,14 @@ export const DatabaseWorkerProvider = ({
413410

414411
// Handle when user submits the edit form
415412
const handleEditSubmit = useCallback(
416-
(type: "insert" | "update" | "delete", editValues: string[]) => {
413+
(type: "insert" | "update" | "delete") => {
417414
setIsDataLoading(true);
418415
workerRef.current?.postMessage({
419416
action: type,
420417
payload: {
421418
table: currentTable,
422419
columns: useDatabaseStore.getState().columns,
423-
values: editValues,
420+
values: usePanelStore.getState().editValues,
424421
whereValues: selectedRowObject?.data
425422
}
426423
});

0 commit comments

Comments
 (0)