Skip to content

Commit

Permalink
feat: create table and redirect to table page
Browse files Browse the repository at this point in the history
  • Loading branch information
nichenqin committed Dec 2, 2022
1 parent 4b83393 commit 2d4cbd6
Show file tree
Hide file tree
Showing 23 changed files with 137 additions and 122 deletions.
24 changes: 1 addition & 23 deletions apps/web/app/App.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,3 @@
'use client'

import { AppShell, Header } from '@egodb/ui'
import { EGOTable } from '@egodb/table-ui'
import { CreateTableFormDrawer } from '../components/create-table-form'
import { TableNavList } from '../components/tables-list-nav/table-list-nav'

export default function App() {
return (
<>
<AppShell
padding="md"
navbar={<TableNavList />}
header={
<Header height={60} p="xs">
{/* Header content */}
</Header>
}
>
<EGOTable />
</AppShell>
<CreateTableFormDrawer />
</>
)
return <>{null}</>
}
12 changes: 11 additions & 1 deletion apps/web/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
'use client'
import { Aside, Box } from '@egodb/ui'
import { CreateTableFormDrawer } from '../components/create-table-form'
import { TableNavList } from '../components/tables-list-nav/table-list-nav'
import RootStyleRegistry from './emotion'
import Trpc from './trpc'

Expand All @@ -7,7 +11,13 @@ export default function RootLayout({ children }: { children: React.ReactNode })
<head />
<body>
<RootStyleRegistry>
<Trpc>{children}</Trpc>
<Trpc>
<Box display="flex">
<TableNavList />
<Aside>{children}</Aside>
</Box>
<CreateTableFormDrawer />
</Trpc>
</RootStyleRegistry>
</body>
</html>
Expand Down
29 changes: 29 additions & 0 deletions apps/web/app/table/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
'use client'

import { Alert, Container, IconAlertCircle } from '@egodb/ui'
import { trpc } from '../../../trpc'
import Table from './table'

export default function Page({ params: { id } }: { params: { id: string } }) {
const getTable = trpc.table.get.useQuery({ id })

if (getTable.isLoading) {
return 'loading'
}

if (getTable.isError) {
return (
<Container>
<Alert icon={<IconAlertCircle size={16} />} title="Oops! Get Table Error!" mt="lg" color="red">
{getTable.error.message}
</Alert>
</Container>
)
}

if (!getTable.data) {
return 'none'
}

return <Table table={getTable.data} />
}
18 changes: 18 additions & 0 deletions apps/web/app/table/[id]/table.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
'use client'

import type { IGetTableOutput } from '@egodb/core'
import { EGOTable } from '@egodb/table-ui'
import { Box, Title } from '@egodb/ui'

interface IProps {
table: NonNullable<IGetTableOutput>
}

export default function Table({ table }: IProps) {
return (
<Box>
<Title>{table.name}</Title>
<EGOTable table={table} />
</Box>
)
}
5 changes: 4 additions & 1 deletion apps/web/components/create-table-form/create-table-form.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Alert, Button, Divider, Group, IconAlertCircle, Text, Space, TextInput } from '@egodb/ui'
import { useRouter } from 'next/navigation'
import { trpc } from '../../trpc'
import { CreateTableAddColumnButton } from './create-table-add-field-button'
import { useCreateTableFormContext } from './create-table-form-context'
Expand All @@ -12,11 +13,13 @@ interface IProps {
export const CreateTableForm: React.FC<IProps> = ({ onCancel, onSuccess }) => {
const form = useCreateTableFormContext()
const utils = trpc.useContext()
const router = useRouter()

const createTable = trpc.table.create.useMutation({
onSuccess: () => {
onSuccess: (data) => {
reset()
utils.table.list.refetch()
router.push(`table/${data.id}`)
onSuccess?.()
},
})
Expand Down
6 changes: 3 additions & 3 deletions apps/web/components/tables-list-nav/table-list-nav.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Navbar, Box, Skeleton, NavLink, Center, Button, IconPlus } from '@egodb/ui'
import { Navbar, Box, Skeleton, NavLink, Center, Button, IconPlus, ScrollArea } from '@egodb/ui'
import { useAtom } from 'jotai'
import { trpc } from '../../trpc'
import { createTableFormDrawerOpened } from '../create-table-form/drawer-opened.atom'
Expand All @@ -8,8 +8,8 @@ export const TableNavList: React.FC = () => {
const getTables = trpc.table.list.useQuery({})

return (
<Navbar width={{ base: 250 }} p="xl">
<Navbar.Section grow>
<Navbar w={300} p="xl">
<Navbar.Section grow component={ScrollArea}>
<Box>
{getTables.isLoading && (
<>
Expand Down
1 change: 1 addition & 0 deletions packages/core/column/column.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export const createColumnSchema = z.discriminatedUnion('type', [createTextColumn
export type ICreateColumnSchema = z.infer<typeof createColumnSchema>

export const queryColumnSchema = z.discriminatedUnion('type', [textColumnQuerySchema, numberColumnQuerySchema])
export type IQueryColumnSchema = z.infer<typeof queryColumnSchema>
export const queryColumnsSchema = z.array(queryColumnSchema)
export type IQueryColumnsSchema = z.infer<typeof queryColumnsSchema>

Expand Down
2 changes: 1 addition & 1 deletion packages/core/column/value-objects/column-name.vo.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ValueObject } from '@egodb/domain'
import * as z from 'zod'

export const columnNameSchema = z.string().min(2).max(20)
export const columnNameSchema = z.string().trim().min(2).max(20)

export class ColumnName extends ValueObject<string> {
private constructor(value: string) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,7 @@ export class CreateTableCommandHandler implements ICreateTableCommandHandler {
async execute(command: CreateTableCommand): Promise<ICreateTableOutput> {
const table = Table.create(command)
await this.repo.insert(table)

return { id: table.id.value }
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import * as z from 'zod'
import { tableIdSchema } from '../../value-objects'

export const createTableCommandOutput = z.void()
export const createTableCommandOutput = z.object({
id: tableIdSchema,
})
4 changes: 2 additions & 2 deletions packages/core/queries/get-table/get-table.query.handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ export class GetTableQueryHandler implements IQueryHandler<GetTableQuery, IGetTa
constructor(protected readonly rm: ITableQueryModel) {}

async execute(query: GetTableQuery): Promise<IGetTableOutput> {
const table = (await this.rm.findOneById(query.id)).unwrap()
const table = (await this.rm.findOneById(query.id)).into(undefined)

return { id: table.id, name: table.name, columns: table.columns }
return table && { id: table.id, name: table.name, columns: table.columns }
}
}
12 changes: 7 additions & 5 deletions packages/core/queries/get-table/get-table.query.output.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import * as z from 'zod'
import { queryColumnsSchema } from '../../column'

export const getTableQueryOutput = z.object({
id: z.string(),
name: z.string(),
columns: queryColumnsSchema,
})
export const getTableQueryOutput = z
.object({
id: z.string(),
name: z.string(),
columns: queryColumnsSchema,
})
.optional()
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import * as z from 'zod'
import { getTableQueryOutput } from '../get-table/get-table.query.output'

export const getTablesQueryOutput = z.array(getTableQueryOutput)
export const getTablesQueryOutput = z.array(getTableQueryOutput.unwrap())
4 changes: 3 additions & 1 deletion packages/core/specifications/table-id.specifaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { CompositeSpecification } from '@egodb/domain'
import type { Result } from 'oxide.ts'
import { Ok } from 'oxide.ts'
import type { Table } from '../table'
import type { TableId } from '../value-objects'
import { TableId } from '../value-objects'
import type { ITableSpecVisitor } from './interface'

export class WithTableId extends CompositeSpecification {
Expand All @@ -24,3 +24,5 @@ export class WithTableId extends CompositeSpecification {
return Ok(undefined)
}
}

export const WithTableIdS = (id: string) => new WithTableId(TableId.from(id))
2 changes: 1 addition & 1 deletion packages/core/value-objects/table-name.vo.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ValueObject } from '@egodb/domain'
import * as z from 'zod'

export const tableNameSchema = z.string().min(2).max(20)
export const tableNameSchema = z.string().trim().min(2).max(20)

export class TableName extends ValueObject<string> {
private constructor(name: string) {
Expand Down
91 changes: 15 additions & 76 deletions packages/table-ui/index.tsx
Original file line number Diff line number Diff line change
@@ -1,81 +1,20 @@
import type { IGetTableOutput } from '@egodb/core'
import { Table } from '@egodb/ui'
import { createColumnHelper, flexRender, getCoreRowModel, useReactTable } from '@tanstack/react-table'
import { useReducer, useState } from 'react'
import { useReducer } from 'react'

type Person = {
firstName: string
lastName: string
age: number
visits: number
status: string
progress: number
interface IProps {
table: NonNullable<IGetTableOutput>
}

const defaultData: Person[] = [
{
firstName: 'tanner',
lastName: 'linsley',
age: 24,
visits: 100,
status: 'In Relationship',
progress: 50,
},
{
firstName: 'tandy',
lastName: 'miller',
age: 40,
visits: 40,
status: 'Single',
progress: 80,
},
{
firstName: 'joe',
lastName: 'dirte',
age: 45,
visits: 20,
status: 'Complicated',
progress: 10,
},
]

const columnHelper = createColumnHelper<Person>()

const columns = [
columnHelper.accessor('firstName', {
cell: (info) => info.getValue(),
footer: (info) => info.column.id,
}),
columnHelper.accessor((row) => row.lastName, {
id: 'lastName',
cell: (info) => <i>{info.getValue()}</i>,
header: () => <span>Last Name</span>,
footer: (info) => info.column.id,
}),
columnHelper.accessor('age', {
header: () => 'Age',
cell: (info) => info.renderValue(),
footer: (info) => info.column.id,
}),
columnHelper.accessor('visits', {
header: () => <span>Visits</span>,
footer: (info) => info.column.id,
}),
columnHelper.accessor('status', {
header: 'Status',
footer: (info) => info.column.id,
}),
columnHelper.accessor('progress', {
header: 'Profile Progress',
footer: (info) => info.column.id,
}),
]

export const EGOTable = () => {
const [data] = useState(() => [...defaultData])
export const EGOTable: React.FC<IProps> = ({ table }) => {
const rerender = useReducer(() => ({}), {})[1]
// TODO: helper types should infered by type
const columnHelper = createColumnHelper<Record<string, string | number>>()
const columns = table.columns.map((c) => columnHelper.accessor(c.name, { id: c.id }))

const table = useReactTable({
data,
const rt = useReactTable({
data: [],
columns,
getCoreRowModel: getCoreRowModel(),
})
Expand All @@ -84,7 +23,7 @@ export const EGOTable = () => {
<div className="p-2">
<Table striped highlightOnHover>
<thead>
{table.getHeaderGroups().map((headerGroup) => (
{rt.getHeaderGroups().map((headerGroup) => (
<tr key={headerGroup.id}>
{headerGroup.headers.map((header) => (
<th key={header.id}>
Expand All @@ -94,8 +33,8 @@ export const EGOTable = () => {
</tr>
))}
</thead>
<tbody>
{table.getRowModel().rows.map((row) => (
{/* <tbody>
{rt.getRowModel().rows.map((row) => (
<tr key={row.id}>
{row.getVisibleCells().map((cell) => (
<td key={cell.id}>{flexRender(cell.column.columnDef.cell, cell.getContext())}</td>
Expand All @@ -104,7 +43,7 @@ export const EGOTable = () => {
))}
</tbody>
<tfoot>
{table.getFooterGroups().map((footerGroup) => (
{rt.getFooterGroups().map((footerGroup) => (
<tr key={footerGroup.id}>
{footerGroup.headers.map((header) => (
<th key={header.id}>
Expand All @@ -113,7 +52,7 @@ export const EGOTable = () => {
))}
</tr>
))}
</tfoot>
</tfoot> */}
</Table>
<div className="h-4" />
<button onClick={() => rerender()} className="border p-2">
Expand Down
1 change: 1 addition & 0 deletions packages/table-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"types": "./index.tsx",
"dependencies": {
"@egodb/ui": "workspace:^0.0.0",
"@egodb/core": "workspace:^0.0.0",
"@tanstack/react-table": "^8.7.0"
},
"devDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/AppShell.tsx
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export { AppShell, Navbar, Header, Aside, Footer } from '@mantine/core'
export { AppShell, Navbar, Header, Aside, Footer, ScrollArea } from '@mantine/core'
2 changes: 1 addition & 1 deletion packages/ui/Layout.tsx
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export { Center, Group, Flex, Box, Space } from '@mantine/core'
export { Center, Group, Flex, Box, Space, Container } from '@mantine/core'
2 changes: 1 addition & 1 deletion packages/ui/Typography.tsx
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export { Text } from '@mantine/core'
export { Text, Title } from '@mantine/core'
2 changes: 2 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 2d4cbd6

Please sign in to comment.