fix: Add Transactional/Analytical database categorization tabs (#965)

* fix: Add Transactional/Analytical database categorization tabs

* fix

---------

Co-authored-by: Guy Ben-Aharon <baguy3@gmail.com>
This commit is contained in:
Jonathan Fishner
2025-11-03 12:03:25 +02:00
committed by GitHub
parent 4fd940afbb
commit 07dc4eace0

View File

@@ -1,20 +1,28 @@
import React, { useMemo, useState } from 'react';
import React, { useCallback, useMemo, useState } from 'react';
import { ToggleGroup } from '@/components/toggle/toggle-group';
import { DatabaseType } from '@/lib/domain/database-type';
import { DatabaseOption } from './database-option';
import { ExampleOption } from './example-option';
import { Button } from '@/components/button/button';
import { ChevronDown, ChevronUp } from 'lucide-react';
import {
Tabs,
TabsContent,
TabsList,
TabsTrigger,
} from '@/components/tabs/tabs';
export interface SelectDatabaseContentProps {
databaseType: DatabaseType;
setDatabaseType: React.Dispatch<React.SetStateAction<DatabaseType>>;
onContinue: () => void;
onContinue: (selectedDatabaseType: DatabaseType) => void;
}
const ROW_SIZE = 3;
const ROWS = 2;
const TOTAL_SLOTS = ROW_SIZE * ROWS;
const SUPPORTED_DB_TYPES: DatabaseType[] = [
// Transactional databases - OLTP systems optimized for frequent read/write operations
const TRANSACTIONAL_DB_TYPES: DatabaseType[] = [
DatabaseType.MYSQL,
DatabaseType.POSTGRESQL,
DatabaseType.MARIADB,
@@ -22,69 +30,87 @@ const SUPPORTED_DB_TYPES: DatabaseType[] = [
DatabaseType.SQL_SERVER,
DatabaseType.ORACLE,
DatabaseType.COCKROACHDB,
DatabaseType.CLICKHOUSE,
];
// Analytical databases - OLAP systems optimized for complex queries and analytics
const ANALYTICAL_DB_TYPES: DatabaseType[] = [DatabaseType.CLICKHOUSE];
export const SelectDatabaseContent: React.FC<SelectDatabaseContentProps> = ({
databaseType,
setDatabaseType,
onContinue,
}) => {
const [activeTab, setActiveTab] = useState<'transactional' | 'analytical'>(
'transactional'
);
const [currentRow, setCurrentRow] = useState(0);
const currentDbTypes =
activeTab === 'transactional'
? TRANSACTIONAL_DB_TYPES
: ANALYTICAL_DB_TYPES;
const currentDatabasesTypes = useMemo(
() =>
SUPPORTED_DB_TYPES.slice(
currentDbTypes.slice(
currentRow * ROW_SIZE,
currentRow * ROW_SIZE + TOTAL_SLOTS
),
[currentRow]
[currentRow, currentDbTypes]
);
const hasNextRow = useMemo(
() => (currentRow + 1) * ROW_SIZE < SUPPORTED_DB_TYPES.length,
[currentRow]
() => (currentRow + 1) * ROW_SIZE < currentDbTypes.length,
[currentRow, currentDbTypes]
);
const hasPreviousRow = useMemo(() => currentRow > 0, [currentRow]);
const toggleRow = () => {
const toggleRow = useCallback(() => {
if (currentRow === 0 && hasNextRow) {
setCurrentRow(currentRow + 1);
} else if (currentRow > 0) {
setCurrentRow(currentRow - 1);
}
};
}, [currentRow, hasNextRow]);
return (
<div className="flex flex-1 flex-col items-center justify-center gap-4">
<ToggleGroup
value={databaseType}
onValueChange={(value: DatabaseType) => {
if (!value) {
setDatabaseType(DatabaseType.GENERIC);
} else {
setDatabaseType(value);
onContinue();
}
}}
type="single"
className="grid grid-flow-row grid-cols-3 gap-6"
>
{Array.from({ length: TOTAL_SLOTS }).map((_, index) =>
currentDatabasesTypes?.[index] ? (
<DatabaseOption
key={currentDatabasesTypes[index]}
type={currentDatabasesTypes[index]}
/>
) : null
)}
const handleTabChange = useCallback((value: string) => {
setActiveTab(value as 'transactional' | 'analytical');
setCurrentRow(0); // Reset to first row when switching tabs
}, []);
<div className="col-span-3 flex flex-1 flex-col gap-1">
const renderDatabaseGrid = useCallback(
() => (
<div className="flex min-h-[280px] flex-col md:min-h-[370px]">
<ToggleGroup
value={databaseType}
onValueChange={(value: DatabaseType) => {
if (!value) {
setDatabaseType(DatabaseType.GENERIC);
} else {
setDatabaseType(value);
onContinue(value);
}
}}
type="single"
className="grid grid-flow-row grid-cols-3 content-start gap-4"
>
{Array.from({ length: TOTAL_SLOTS }).map((_, index) =>
currentDatabasesTypes?.[index] ? (
<DatabaseOption
key={currentDatabasesTypes[index]}
type={currentDatabasesTypes[index]}
/>
) : null
)}
</ToggleGroup>
<div className="mt-auto flex flex-col gap-1 pt-4">
{hasNextRow || hasPreviousRow ? (
<Button
variant="ghost"
onClick={toggleRow}
className="col-span-3 h-8"
className="h-8"
>
{currentRow === 0 ? (
<div className="flex h-8 w-full cursor-pointer flex-row items-center justify-center gap-2 py-3 text-center md:h-12">
@@ -105,7 +131,55 @@ export const SelectDatabaseContent: React.FC<SelectDatabaseContentProps> = ({
) : null}
<ExampleOption />
</div>
</ToggleGroup>
</div>
),
[
databaseType,
currentDatabasesTypes,
hasNextRow,
hasPreviousRow,
onContinue,
setDatabaseType,
toggleRow,
currentRow,
]
);
return (
<div className="flex flex-1 flex-col items-center gap-2">
<Tabs
defaultValue="transactional"
value={activeTab}
onValueChange={handleTabChange}
className="w-auto"
>
<TabsList className="mb-2 grid size-auto grid-cols-2 gap-1 rounded-xl border bg-background p-1">
<TabsTrigger
value="transactional"
className="gap-1.5 rounded-lg px-3 py-1 text-sm font-medium transition-all data-[state=active]:bg-sky-600 data-[state=active]:text-white data-[state=inactive]:text-muted-foreground data-[state=active]:shadow-sm data-[state=inactive]:hover:bg-muted/50 data-[state=inactive]:hover:text-foreground dark:data-[state=active]:bg-sky-500"
>
Transactional
</TabsTrigger>
<TabsTrigger
value="analytical"
className="gap-1.5 rounded-lg px-3 py-1 text-sm font-medium transition-all data-[state=active]:bg-sky-600 data-[state=active]:text-white data-[state=inactive]:text-muted-foreground data-[state=active]:shadow-sm data-[state=inactive]:hover:bg-muted/50 data-[state=inactive]:hover:text-foreground dark:data-[state=active]:bg-sky-500"
>
Analytical
</TabsTrigger>
</TabsList>
<TabsContent
value="transactional"
className="mt-0 focus-visible:ring-0 focus-visible:ring-offset-0"
>
{renderDatabaseGrid()}
</TabsContent>
<TabsContent
value="analytical"
className="mt-0 focus-visible:ring-0 focus-visible:ring-offset-0"
>
{renderDatabaseGrid()}
</TabsContent>
</Tabs>
</div>
);
};