Skip to content

Commit

Permalink
feat: Add SideMenu #1841 (#1952)
Browse files Browse the repository at this point in the history
### What problem does this PR solve?

feat: Add SideMenu #1841

### Type of change

- [x] New Feature (non-breaking change which adds functionality)
  • Loading branch information
cike8899 authored Sep 30, 2024
1 parent 1989ed0 commit 7af04e5
Show file tree
Hide file tree
Showing 16 changed files with 837 additions and 7 deletions.
79 changes: 79 additions & 0 deletions gui/app/(dashboard)/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,82 @@ export const showDatabase = async (params: { database_name: string }) => {
console.log('🚀 ~ error:', error);
}
};

//#region table

export const listTable = async (database_name: string) => {
try {
const x = await get(
`${ApiUrl.databases}/${database_name}/${ApiUrl.tables}`
);
return x;
} catch (error) {
console.log('🚀 ~ error:', error);
}
};

export const createTable = async ({
database_name,
table_name,
create_option,
fields
}: {
database_name: string;
table_name: string;
fields: Array<{ name: string; type: string; default?: string }>;
create_option: CreateOption;
}) => {
try {
const x = await post(
`${ApiUrl.databases}/${database_name}/${ApiUrl.tables}/${table_name}`,
{
create_option,
fields
}
);
return x;
} catch (error) {
console.log('🚀 ~ error:', error);
}
};

export const dropTable = async ({
database_name,
table_name,
drop_option
}: {
database_name: string;
table_name: string;
drop_option: DropOption;
}) => {
try {
const x = await drop(
`${ApiUrl.databases}/${database_name}/${ApiUrl.tables}/${table_name}`,
{
drop_option
}
);
return x;
} catch (error) {
console.log('🚀 ~ error:', error);
}
};

export const showTable = async ({
database_name,
table_name
}: {
database_name: string;
table_name: string;
}) => {
try {
const x = await get(
`${ApiUrl.databases}/${database_name}/${ApiUrl.tables}/${table_name}`
);
return x;
} catch (error) {
console.log('🚀 ~ error:', error);
}
};

//#endregion
33 changes: 33 additions & 0 deletions gui/app/(dashboard)/database/context-menu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
'use client';

import {
ContextMenuContent,
ContextMenuItem
} from '@/components/ui/context-menu';
import { useSeDialogState } from '@/lib/hooks';
import { TableCreatingDialog } from './table-creating-dialog';
import AddIcon from '/public/add.svg';

export function InfinityContextMenuContent({
databaseName
}: {
databaseName: string;
}) {
const { showDialog, visible, hideDialog, switchVisible } = useSeDialogState();
return (
<>
<ContextMenuContent>
<ContextMenuItem>
<div className="flex justify-between w-full" onClick={showDialog}>
Add <AddIcon className="w-5 h-5"></AddIcon>
</div>
</ContextMenuItem>
</ContextMenuContent>
<TableCreatingDialog
visible={visible}
hideDialog={hideDialog}
switchVisible={switchVisible}
></TableCreatingDialog>
</>
);
}
129 changes: 127 additions & 2 deletions gui/app/(dashboard)/database/page.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,135 @@
export default async function ProductsPage({
import SideMenu, { MenuItem } from '@/components/ui/side-menu';
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow
} from '@/components/ui/table';
import { listDatabase, listTable } from '../actions';
import { InfinityContextMenuContent } from './context-menu';

const invoices = [
{
invoice: 'INV001',
paymentStatus: 'Paid',
totalAmount: '$250.00',
paymentMethod: 'Credit Card'
},
{
invoice: 'INV002',
paymentStatus: 'Pending',
totalAmount: '$150.00',
paymentMethod: 'PayPal'
},
{
invoice: 'INV003',
paymentStatus: 'Unpaid',
totalAmount: '$350.00',
paymentMethod: 'Bank Transfer'
},
{
invoice: 'INV004',
paymentStatus: 'Paid',
totalAmount: '$450.00',
paymentMethod: 'Credit Card'
},
{
invoice: 'INV005',
paymentStatus: 'Paid',
totalAmount: '$550.00',
paymentMethod: 'PayPal'
},
{
invoice: 'INV006',
paymentStatus: 'Pending',
totalAmount: '$200.00',
paymentMethod: 'Bank Transfer'
},
{
invoice: 'INV007',
paymentStatus: 'Unpaid',
totalAmount: '$300.00',
paymentMethod: 'Credit Card'
}
];

function InfinityTable() {
return (
<Table>
<TableHeader>
<TableRow>
<TableHead className="w-[100px]">Name</TableHead>
<TableHead>Type</TableHead>
<TableHead>Default</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{invoices.map((invoice) => (
<TableRow key={invoice.invoice}>
<TableCell className="font-medium">{invoice.invoice}</TableCell>
<TableCell>{invoice.paymentStatus}</TableCell>
<TableCell>{invoice.paymentMethod}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
);
}

export default async function DatabasePage({
searchParams
}: {
searchParams: { q: string; offset: string };
}) {
const search = searchParams.q ?? '';
const offset = searchParams.offset ?? 0;

return <div>database</div>;
const items: MenuItem[] = [
{
key: 'sub1',
label: 'Navigation',
children: [
{
key: 'g1',
label: 'Item 1'
},
{
key: 'g2',
label: 'Item 2'
}
]
}
];

const ret = await listDatabase();
if (ret.databases.length > 1) {
const latestDatabase = ret.databases.at(-1);
const tables = await listTable(latestDatabase);
console.log('🚀 ~ ret:', tables);
items.push({
key: latestDatabase,
label: latestDatabase,
children: tables.tables
});
}

return (
<div className="flex divide-x ">
<section className="w-40">
<SideMenu
items={items}
contextMenuContent={(key: string) => (
<InfinityContextMenuContent
databaseName={key}
></InfinityContextMenuContent>
)}
></SideMenu>
</section>
<section className="flex-1 text-center">
<InfinityTable></InfinityTable>
</section>
</div>
);
}
40 changes: 40 additions & 0 deletions gui/app/(dashboard)/database/table-creating-dialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
'use client';

import { Button } from '@/components/ui/button';
import {
Dialog,
DialogContent,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger
} from '@/components/ui/dialog';
import { IDialogProps } from '@/lib/interfaces';
import React from 'react';
import { TableCreatingForm } from './table-creating-form';

export function TableCreatingDialog({
children,
visible,
switchVisible,
hideDialog
}: React.PropsWithChildren<IDialogProps<any>>) {
return (
<Dialog open={visible} onOpenChange={switchVisible}>
<DialogTrigger asChild>{children}</DialogTrigger>
<DialogContent className="sm:max-w-[425px]">
<DialogHeader>
<DialogTitle>Create Table</DialogTitle>
</DialogHeader>
<div className="grid gap-4 py-4">
<TableCreatingForm hide={hideDialog}></TableCreatingForm>
</div>
<DialogFooter>
<Button type="submit" form="database-creating">
Save
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
}
Loading

0 comments on commit 7af04e5

Please sign in to comment.