From d444752ae8d68c79c8a8adec5a0d9a44a86d9e63 Mon Sep 17 00:00:00 2001 From: tjrmswo <93309061+tjrmswo@users.noreply.github.com> Date: Mon, 17 Feb 2025 21:27:59 +0900 Subject: [PATCH 1/3] feat: reogrganization main --- frontend/package.json | 2 + frontend/pnpm-lock.yaml | 107 +++++++++++++++ frontend/src/app/LayoutContent.tsx | 2 +- frontend/src/app/page.tsx | 17 ++- frontend/src/components/ui/checkbox.tsx | 30 +++++ frontend/src/components/ui/columns.tsx | 78 +++++++++++ frontend/src/components/ui/dataTable.tsx | 159 +++++++++++++++++++++++ frontend/src/components/ui/table.tsx | 120 +++++++++++++++++ frontend/src/constants/tableMockDatat.ts | 116 +++++++++++++++++ frontend/src/types/home.ts | 8 ++ 10 files changed, 636 insertions(+), 3 deletions(-) create mode 100644 frontend/src/components/ui/checkbox.tsx create mode 100644 frontend/src/components/ui/columns.tsx create mode 100644 frontend/src/components/ui/dataTable.tsx create mode 100644 frontend/src/components/ui/table.tsx create mode 100644 frontend/src/constants/tableMockDatat.ts create mode 100644 frontend/src/types/home.ts diff --git a/frontend/package.json b/frontend/package.json index 12a7bf4..67fb8bb 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -17,12 +17,14 @@ }, "dependencies": { "@hookform/resolvers": "^3.10.0", + "@radix-ui/react-checkbox": "^1.1.4", "@radix-ui/react-dialog": "^1.1.5", "@radix-ui/react-dropdown-menu": "^2.1.5", "@radix-ui/react-label": "^2.1.1", "@radix-ui/react-separator": "^1.1.1", "@radix-ui/react-slot": "^1.1.1", "@radix-ui/react-tooltip": "^1.1.7", + "@tanstack/react-table": "^8.21.2", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "lucide-react": "^0.471.0", diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index 05856f8..79c7da4 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -11,6 +11,9 @@ importers: '@hookform/resolvers': specifier: ^3.10.0 version: 3.10.0(react-hook-form@7.54.2(react@19.0.0)) + '@radix-ui/react-checkbox': + specifier: ^1.1.4 + version: 1.1.4(@types/react-dom@19.0.2(@types/react@19.0.4))(@types/react@19.0.4)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) '@radix-ui/react-dialog': specifier: ^1.1.5 version: 1.1.5(@types/react-dom@19.0.2(@types/react@19.0.4))(@types/react@19.0.4)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) @@ -29,6 +32,9 @@ importers: '@radix-ui/react-tooltip': specifier: ^1.1.7 version: 1.1.7(@types/react-dom@19.0.2(@types/react@19.0.4))(@types/react@19.0.4)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + '@tanstack/react-table': + specifier: ^8.21.2 + version: 8.21.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) class-variance-authority: specifier: ^0.7.1 version: 0.7.1 @@ -409,6 +415,19 @@ packages: '@types/react-dom': optional: true + '@radix-ui/react-checkbox@1.1.4': + resolution: {integrity: sha512-wP0CPAHq+P5I4INKe3hJrIa1WoNqqrejzW+zoU0rOvo1b9gDEJJFl2rYfO1PYJUQCc2H1WZxIJmyv9BS8i5fLw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-collection@1.1.1': resolution: {integrity: sha512-LwT3pSho9Dljg+wY2KN2mrrh6y3qELfftINERIzBUO9e0N+t0oMTyn3k9iv+ZqgrwGkRnLpNJrsMv9BZlt2yuA==} peerDependencies: @@ -597,6 +616,19 @@ packages: '@types/react-dom': optional: true + '@radix-ui/react-primitive@2.0.2': + resolution: {integrity: sha512-Ec/0d38EIuvDF+GZjcMU/Ze6MxntVJYO/fRlCPhCaVUyPY9WTalHJw54tp9sXeJo3tlShWpy41vQRgLRGOuz+w==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-roving-focus@1.1.1': resolution: {integrity: sha512-QE1RoxPGJ/Nm8Qmk0PxP8ojmoaS67i0s7hVssS7KuI2FQoc/uzVlZsqKfQvxPE6D8hICCPHJ4D88zNhT3OOmkw==} peerDependencies: @@ -632,6 +664,15 @@ packages: '@types/react': optional: true + '@radix-ui/react-slot@1.1.2': + resolution: {integrity: sha512-YAKxaiGsSQJ38VzKH86/BPRC4rh+b1Jpa+JneA5LRE7skmLPNAyeG8kPJj/oo4STLvlrs8vkf/iYyc3A5stYCQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@radix-ui/react-tooltip@1.1.7': resolution: {integrity: sha512-ss0s80BC0+g0+Zc53MvilcnTYSOi4mSuFWBPYPuTOFGjx+pUU+ZrmamMNwS56t8MTFlniA5ocjd4jYm/CdhbOg==} peerDependencies: @@ -681,6 +722,15 @@ packages: '@types/react': optional: true + '@radix-ui/react-use-previous@1.1.0': + resolution: {integrity: sha512-Z/e78qg2YFnnXcW88A4JmTtm4ADckLno6F7OXotmkQfeuCVaKuYzqAATPhVzl3delXE7CxIV8shofPn3jPc5Og==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@radix-ui/react-use-rect@1.1.0': resolution: {integrity: sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==} peerDependencies: @@ -727,6 +777,17 @@ packages: '@swc/helpers@0.5.15': resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} + '@tanstack/react-table@8.21.2': + resolution: {integrity: sha512-11tNlEDTdIhMJba2RBH+ecJ9l1zgS2kjmexDPAraulc8jeNA4xocSNeyzextT0XJyASil4XsCYlJmf5jEWAtYg==} + engines: {node: '>=12'} + peerDependencies: + react: '>=16.8' + react-dom: '>=16.8' + + '@tanstack/table-core@8.21.2': + resolution: {integrity: sha512-uvXk/U4cBiFMxt+p9/G7yUWI/UbHYbyghLCjlpWZ3mLeIZiUBSKcUnw9UnKkdRz7Z/N4UBuFLWQdJCjUe7HjvA==} + engines: {node: '>=12'} + '@types/estree@1.0.6': resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} @@ -2625,6 +2686,22 @@ snapshots: '@types/react': 19.0.4 '@types/react-dom': 19.0.2(@types/react@19.0.4) + '@radix-ui/react-checkbox@1.1.4(@types/react-dom@19.0.2(@types/react@19.0.4))(@types/react@19.0.4)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + dependencies: + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.4)(react@19.0.0) + '@radix-ui/react-context': 1.1.1(@types/react@19.0.4)(react@19.0.0) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@19.0.2(@types/react@19.0.4))(@types/react@19.0.4)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.2(@types/react@19.0.4))(@types/react@19.0.4)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.0.4)(react@19.0.0) + '@radix-ui/react-use-previous': 1.1.0(@types/react@19.0.4)(react@19.0.0) + '@radix-ui/react-use-size': 1.1.0(@types/react@19.0.4)(react@19.0.0) + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) + optionalDependencies: + '@types/react': 19.0.4 + '@types/react-dom': 19.0.2(@types/react@19.0.4) + '@radix-ui/react-collection@1.1.1(@types/react-dom@19.0.2(@types/react@19.0.4))(@types/react@19.0.4)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': dependencies: '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.4)(react@19.0.0) @@ -2811,6 +2888,15 @@ snapshots: '@types/react': 19.0.4 '@types/react-dom': 19.0.2(@types/react@19.0.4) + '@radix-ui/react-primitive@2.0.2(@types/react-dom@19.0.2(@types/react@19.0.4))(@types/react@19.0.4)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + dependencies: + '@radix-ui/react-slot': 1.1.2(@types/react@19.0.4)(react@19.0.0) + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) + optionalDependencies: + '@types/react': 19.0.4 + '@types/react-dom': 19.0.2(@types/react@19.0.4) + '@radix-ui/react-roving-focus@1.1.1(@types/react-dom@19.0.2(@types/react@19.0.4))(@types/react@19.0.4)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': dependencies: '@radix-ui/primitive': 1.1.1 @@ -2844,6 +2930,13 @@ snapshots: optionalDependencies: '@types/react': 19.0.4 + '@radix-ui/react-slot@1.1.2(@types/react@19.0.4)(react@19.0.0)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.4)(react@19.0.0) + react: 19.0.0 + optionalDependencies: + '@types/react': 19.0.4 + '@radix-ui/react-tooltip@1.1.7(@types/react-dom@19.0.2(@types/react@19.0.4))(@types/react@19.0.4)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': dependencies: '@radix-ui/primitive': 1.1.1 @@ -2890,6 +2983,12 @@ snapshots: optionalDependencies: '@types/react': 19.0.4 + '@radix-ui/react-use-previous@1.1.0(@types/react@19.0.4)(react@19.0.0)': + dependencies: + react: 19.0.0 + optionalDependencies: + '@types/react': 19.0.4 + '@radix-ui/react-use-rect@1.1.0(@types/react@19.0.4)(react@19.0.0)': dependencies: '@radix-ui/rect': 1.1.0 @@ -2925,6 +3024,14 @@ snapshots: dependencies: tslib: 2.8.1 + '@tanstack/react-table@8.21.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + dependencies: + '@tanstack/table-core': 8.21.2 + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) + + '@tanstack/table-core@8.21.2': {} + '@types/estree@1.0.6': {} '@types/json-schema@7.0.15': {} diff --git a/frontend/src/app/LayoutContent.tsx b/frontend/src/app/LayoutContent.tsx index 3d78eb8..f5d27be 100644 --- a/frontend/src/app/LayoutContent.tsx +++ b/frontend/src/app/LayoutContent.tsx @@ -53,7 +53,7 @@ export function LayoutContent({ children }: { children: React.ReactNode }) { return ( -
+
-

Light Switch

+
+
+ + + Feature Flag Management + +
+ +
); } diff --git a/frontend/src/components/ui/checkbox.tsx b/frontend/src/components/ui/checkbox.tsx new file mode 100644 index 0000000..c6fdd07 --- /dev/null +++ b/frontend/src/components/ui/checkbox.tsx @@ -0,0 +1,30 @@ +"use client" + +import * as React from "react" +import * as CheckboxPrimitive from "@radix-ui/react-checkbox" +import { Check } from "lucide-react" + +import { cn } from "@/lib/utils" + +const Checkbox = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + + + + + +)) +Checkbox.displayName = CheckboxPrimitive.Root.displayName + +export { Checkbox } diff --git a/frontend/src/components/ui/columns.tsx b/frontend/src/components/ui/columns.tsx new file mode 100644 index 0000000..939afdf --- /dev/null +++ b/frontend/src/components/ui/columns.tsx @@ -0,0 +1,78 @@ +'use client'; + +import { ColumnDef } from '@tanstack/react-table'; +import { ArrowUpDown } from 'lucide-react'; + +import { Button } from '@/components/ui/button'; +import { Checkbox } from '@/components/ui/checkbox'; +import { TableDataType } from '@/types/home'; +import React from 'react'; + +export const columns: ColumnDef[] = [ + { + id: 'select', + header: ({ table }) => ( + table.toggleAllPageRowsSelected(!!value)} + aria-label="Select all" + /> + ), + cell: ({ row }) => ( + row.toggleSelected(!!value)} + aria-label="Select row" + /> + ), + enableSorting: false, + enableHiding: false, + }, + { + accessorKey: 'Name', + header: ({ column }) => { + return ( + + ); + }, + }, + { + accessorKey: 'Type', + header: 'Type', + }, + { + accessorKey: 'Created', + header: ({ column }) => { + return ( + + ); + }, + }, + { + accessorKey: 'By', + header: 'By', + }, + { + accessorKey: 'Status', + header: 'Status', + }, + { + accessorKey: 'Default Value', + header: 'Default Value', + }, +]; diff --git a/frontend/src/components/ui/dataTable.tsx b/frontend/src/components/ui/dataTable.tsx new file mode 100644 index 0000000..b2f8758 --- /dev/null +++ b/frontend/src/components/ui/dataTable.tsx @@ -0,0 +1,159 @@ +'use client'; +import { + ColumnDef, + SortingState, + flexRender, + getCoreRowModel, + getPaginationRowModel, + useReactTable, + getSortedRowModel, + Row, + PaginationState, +} from '@tanstack/react-table'; +import { SetStateAction, useState } from 'react'; +import { Trash2 } from 'lucide-react'; + +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from '@/components/ui/table'; +import { Button } from '@/components/ui/button'; +import { TableDataType } from '@/types/home'; + +export interface DataTableProps { + columns: ColumnDef[]; + data: TData[]; +} + +export function DataTable({ + columns, + data, +}: DataTableProps) { + const [sorting, setSorting] = useState([]); + const [rowSelection, setRowSelection] = useState({}); + const [pagination, setPagination] = useState({ + pageIndex: 0, + pageSize: 9, + }); + + const table = useReactTable({ + data, + columns, + getCoreRowModel: getCoreRowModel(), + getPaginationRowModel: getPaginationRowModel(), + onRowSelectionChange: setRowSelection, + onSortingChange: setSorting, + getSortedRowModel: getSortedRowModel(), + state: { + rowSelection, + sorting, + pagination, + }, + onPaginationChange: (updater) => { + setPagination((prev) => ({ + ...prev, + ...updater, + })); + }, + }); + + const handlePreviousPage = () => { + setPagination((prev) => ({ + ...prev, + pageIndex: Math.max(prev.pageIndex - 1, 0), + })); + }; + + const handleNextPage = () => { + setPagination((prev) => ({ + ...prev, + pageIndex: prev.pageIndex + 1, + })); + }; + + return ( +
+
+ + + {table.getHeaderGroups().map((headerGroup) => ( + + {headerGroup.headers.map((header) => { + return ( + + {header.isPlaceholder + ? null + : flexRender( + header.column.columnDef.header, + header.getContext(), + )} + + ); + })} + + ))} + + + {table.getRowModel().rows?.length ? ( + table.getRowModel().rows.map((row) => ( + + {row.getVisibleCells().map((cell) => ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext(), + )} + + ))} + + )) + ) : ( + + + No results. + + + )} + +
+
+
+ {table.getFilteredSelectedRowModel().rows.length} of{' '} + {table.getFilteredRowModel().rows.length} row(s) selected +
+ + Page {pagination.pageIndex + 1} of {table.getPageCount()} + +
+ + +
+
+
+
+ ); +} diff --git a/frontend/src/components/ui/table.tsx b/frontend/src/components/ui/table.tsx new file mode 100644 index 0000000..c0df655 --- /dev/null +++ b/frontend/src/components/ui/table.tsx @@ -0,0 +1,120 @@ +import * as React from "react" + +import { cn } from "@/lib/utils" + +const Table = React.forwardRef< + HTMLTableElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+ + +)) +Table.displayName = "Table" + +const TableHeader = React.forwardRef< + HTMLTableSectionElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( + +)) +TableHeader.displayName = "TableHeader" + +const TableBody = React.forwardRef< + HTMLTableSectionElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( + +)) +TableBody.displayName = "TableBody" + +const TableFooter = React.forwardRef< + HTMLTableSectionElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( + tr]:last:border-b-0", + className + )} + {...props} + /> +)) +TableFooter.displayName = "TableFooter" + +const TableRow = React.forwardRef< + HTMLTableRowElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( + +)) +TableRow.displayName = "TableRow" + +const TableHead = React.forwardRef< + HTMLTableCellElement, + React.ThHTMLAttributes +>(({ className, ...props }, ref) => ( +
[role=checkbox]]:translate-y-[2px]", + className + )} + {...props} + /> +)) +TableHead.displayName = "TableHead" + +const TableCell = React.forwardRef< + HTMLTableCellElement, + React.TdHTMLAttributes +>(({ className, ...props }, ref) => ( + [role=checkbox]]:translate-y-[2px]", + className + )} + {...props} + /> +)) +TableCell.displayName = "TableCell" + +const TableCaption = React.forwardRef< + HTMLTableCaptionElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +TableCaption.displayName = "TableCaption" + +export { + Table, + TableHeader, + TableBody, + TableFooter, + TableHead, + TableRow, + TableCell, + TableCaption, +} diff --git a/frontend/src/constants/tableMockDatat.ts b/frontend/src/constants/tableMockDatat.ts new file mode 100644 index 0000000..429e6e1 --- /dev/null +++ b/frontend/src/constants/tableMockDatat.ts @@ -0,0 +1,116 @@ +import { TableDataType } from '@/types/home'; + +export const ExampleData: TableDataType[] = [ + { + Name: 'New Dashboard', + Type: 'Boolean', + Created: '2024-01-15', + By: 'Alice', + Status: false, + 'Default Value': false, + }, + { + Name: 'Feature Flags', + Type: 'String', + Created: '2024-02-01', + By: 'KeunJae', + Status: true, + 'Default Value': 'so', + }, + { + Name: 'Example 1', + Type: 'Number', + Created: '2024-01-28', + By: 'Elon Musk', + Status: true, + 'Default Value': 0, + }, + { + Name: 'Example 2', + Type: 'String', + Created: '2024-02-01', + By: 'KeunJae', + Status: true, + 'Default Value': 'so', + }, + { + Name: 'User Preferences', + Type: 'Boolean', + Created: '2024-03-05', + By: 'Sarah', + Status: false, + 'Default Value': true, + }, + { + Name: 'Application Mode', + Type: 'String', + Created: '2024-03-10', + By: 'Michael', + Status: true, + 'Default Value': 'production', + }, + { + Name: 'Retry Count', + Type: 'Number', + Created: '2024-03-15', + By: 'Nina', + Status: false, + 'Default Value': 3, + }, + { + Name: 'Notifications', + Type: 'Boolean', + Created: '2024-03-20', + By: 'Tom', + Status: true, + 'Default Value': true, + }, + { + Name: 'Dark Mode', + Type: 'Boolean', + Created: '2024-03-25', + By: 'Emma', + Status: false, + 'Default Value': false, + }, + { + Name: 'Max Items', + Type: 'Number', + Created: '2024-03-30', + By: 'John', + Status: true, + 'Default Value': 10, + }, + { + Name: 'User Role', + Type: 'String', + Created: '2024-04-05', + By: 'Sophia', + Status: true, + 'Default Value': 'user', + }, + { + Name: 'Enable Logging', + Type: 'Boolean', + Created: '2024-04-10', + By: 'Alice', + Status: false, + 'Default Value': true, + }, + { + Name: 'API Key', + Type: 'String', + Created: '2024-04-15', + By: 'KeunJae', + Status: true, + 'Default Value': '12345-abcde', + }, + { + Name: 'Connection Timeout', + Type: 'Number', + Created: '2024-04-20', + By: 'Elon Musk', + Status: false, + 'Default Value': 30, + }, +]; diff --git a/frontend/src/types/home.ts b/frontend/src/types/home.ts new file mode 100644 index 0000000..1910439 --- /dev/null +++ b/frontend/src/types/home.ts @@ -0,0 +1,8 @@ +export type TableDataType = { + Name: string; + Type: string; + Created: string; + By: string; + Status: boolean; + 'Default Value': boolean | string | number; +}; From 3295615caae9fb8facf8e8f553bd33b2ba67bdd2 Mon Sep 17 00:00:00 2001 From: tjrmswo <93309061+tjrmswo@users.noreply.github.com> Date: Tue, 18 Feb 2025 01:38:36 +0900 Subject: [PATCH 2/3] fix: include feedback --- frontend/src/app/page.tsx | 18 ++--- .../ui/{dataTable.tsx => TanstackTable.tsx} | 53 +++---------- frontend/src/components/ui/checkbox.tsx | 24 +++--- frontend/src/components/ui/columns.tsx | 78 ------------------- .../src/components/ui/featureFlagColumns.tsx | 28 +++++++ frontend/src/components/ui/table.tsx | 62 +++++++-------- frontend/src/constants/tableMockDatat.ts | 74 +++++++----------- frontend/src/types/home.ts | 8 -- frontend/src/types/types.ts | 7 ++ 9 files changed, 128 insertions(+), 224 deletions(-) rename frontend/src/components/ui/{dataTable.tsx => TanstackTable.tsx} (68%) delete mode 100644 frontend/src/components/ui/columns.tsx create mode 100644 frontend/src/components/ui/featureFlagColumns.tsx delete mode 100644 frontend/src/types/home.ts create mode 100644 frontend/src/types/types.ts diff --git a/frontend/src/app/page.tsx b/frontend/src/app/page.tsx index 5045b42..3b11025 100644 --- a/frontend/src/app/page.tsx +++ b/frontend/src/app/page.tsx @@ -1,20 +1,18 @@ -import { columns } from '@/components/ui/columns'; -import { DataTable } from '@/components/ui/dataTable'; -import { ExampleData } from '@/constants/tableMockDatat'; -import { TableDataType } from '@/types/home'; import { FlagIcon } from 'lucide-react'; +import { columns } from '@/components/ui/featureFlagColumns'; +import { DataTable } from '@/components/ui/TanstackTable'; +import { ExampleData } from '@/constants/tableMockDatat'; + export default function Home() { return ( -
-
+
+
- - Feature Flag Management - + Feature Flag Management
- +
); } diff --git a/frontend/src/components/ui/dataTable.tsx b/frontend/src/components/ui/TanstackTable.tsx similarity index 68% rename from frontend/src/components/ui/dataTable.tsx rename to frontend/src/components/ui/TanstackTable.tsx index b2f8758..eae08ce 100644 --- a/frontend/src/components/ui/dataTable.tsx +++ b/frontend/src/components/ui/TanstackTable.tsx @@ -1,17 +1,14 @@ 'use client'; import { ColumnDef, - SortingState, flexRender, getCoreRowModel, getPaginationRowModel, useReactTable, getSortedRowModel, - Row, PaginationState, } from '@tanstack/react-table'; -import { SetStateAction, useState } from 'react'; -import { Trash2 } from 'lucide-react'; +import { useState } from 'react'; import { Table, @@ -22,19 +19,17 @@ import { TableRow, } from '@/components/ui/table'; import { Button } from '@/components/ui/button'; -import { TableDataType } from '@/types/home'; +import { featureFlagTableType } from '@/types/types'; -export interface DataTableProps { +export interface DataTableProps { columns: ColumnDef[]; data: TData[]; } -export function DataTable({ +export function DataTable({ columns, data, }: DataTableProps) { - const [sorting, setSorting] = useState([]); - const [rowSelection, setRowSelection] = useState({}); const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 9, @@ -45,36 +40,13 @@ export function DataTable({ columns, getCoreRowModel: getCoreRowModel(), getPaginationRowModel: getPaginationRowModel(), - onRowSelectionChange: setRowSelection, - onSortingChange: setSorting, getSortedRowModel: getSortedRowModel(), state: { - rowSelection, - sorting, pagination, }, - onPaginationChange: (updater) => { - setPagination((prev) => ({ - ...prev, - ...updater, - })); - }, + onPaginationChange: setPagination, }); - const handlePreviousPage = () => { - setPagination((prev) => ({ - ...prev, - pageIndex: Math.max(prev.pageIndex - 1, 0), - })); - }; - - const handleNextPage = () => { - setPagination((prev) => ({ - ...prev, - pageIndex: prev.pageIndex + 1, - })); - }; - return (
@@ -128,17 +100,16 @@ export function DataTable({
- {table.getFilteredSelectedRowModel().rows.length} of{' '} - {table.getFilteredRowModel().rows.length} row(s) selected -
- - Page {pagination.pageIndex + 1} of {table.getPageCount()} + {`${table.getFilteredSelectedRowModel().rows.length} of ${table.getFilteredRowModel().rows.length} row(s) selected`} +
+ + {`Page ${pagination.pageIndex + 1} of ${table.getPageCount()}`} -
+
- ); - }, - }, - { - accessorKey: 'Type', - header: 'Type', - }, - { - accessorKey: 'Created', - header: ({ column }) => { - return ( - - ); - }, - }, - { - accessorKey: 'By', - header: 'By', - }, - { - accessorKey: 'Status', - header: 'Status', - }, - { - accessorKey: 'Default Value', - header: 'Default Value', - }, -]; diff --git a/frontend/src/components/ui/featureFlagColumns.tsx b/frontend/src/components/ui/featureFlagColumns.tsx new file mode 100644 index 0000000..83292bb --- /dev/null +++ b/frontend/src/components/ui/featureFlagColumns.tsx @@ -0,0 +1,28 @@ +'use client'; + +import { ColumnDef } from '@tanstack/react-table'; + +import { featureFlagTableType } from '@/types/types'; + +export const columns: ColumnDef[] = [ + { + accessorKey: 'Key', + header: 'Key', + }, + { + accessorKey: 'Type', + header: 'Type', + }, + { + accessorKey: 'Created', + header: 'Created', + }, + { + accessorKey: 'By', + header: 'By', + }, + { + accessorKey: 'ToggleButton', + header: 'ToggleButton ', + }, +]; diff --git a/frontend/src/components/ui/table.tsx b/frontend/src/components/ui/table.tsx index c0df655..d0c6422 100644 --- a/frontend/src/components/ui/table.tsx +++ b/frontend/src/components/ui/table.tsx @@ -1,6 +1,6 @@ -import * as React from "react" +import * as React from 'react'; -import { cn } from "@/lib/utils" +import { cn } from '@/lib/utils'; const Table = React.forwardRef< HTMLTableElement, @@ -9,20 +9,20 @@ const Table = React.forwardRef<
-)) -Table.displayName = "Table" +)); +Table.displayName = 'Table'; const TableHeader = React.forwardRef< HTMLTableSectionElement, React.HTMLAttributes >(({ className, ...props }, ref) => ( - -)) -TableHeader.displayName = "TableHeader" + +)); +TableHeader.displayName = 'TableHeader'; const TableBody = React.forwardRef< HTMLTableSectionElement, @@ -30,11 +30,11 @@ const TableBody = React.forwardRef< >(({ className, ...props }, ref) => ( -)) -TableBody.displayName = "TableBody" +)); +TableBody.displayName = 'TableBody'; const TableFooter = React.forwardRef< HTMLTableSectionElement, @@ -43,13 +43,13 @@ const TableFooter = React.forwardRef< tr]:last:border-b-0", - className + 'border-t bg-muted/50 font-medium [&>tr]:last:border-b-0', + className, )} {...props} /> -)) -TableFooter.displayName = "TableFooter" +)); +TableFooter.displayName = 'TableFooter'; const TableRow = React.forwardRef< HTMLTableRowElement, @@ -58,13 +58,13 @@ const TableRow = React.forwardRef< -)) -TableRow.displayName = "TableRow" +)); +TableRow.displayName = 'TableRow'; const TableHead = React.forwardRef< HTMLTableCellElement, @@ -73,13 +73,13 @@ const TableHead = React.forwardRef<
[role=checkbox]]:translate-y-[2px]", - className + 'h-10 px-2 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]', + className, )} {...props} /> -)) -TableHead.displayName = "TableHead" +)); +TableHead.displayName = 'TableHead'; const TableCell = React.forwardRef< HTMLTableCellElement, @@ -88,13 +88,13 @@ const TableCell = React.forwardRef< [role=checkbox]]:translate-y-[2px]", - className + 'p-2 align-middle [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]', + className, )} {...props} /> -)) -TableCell.displayName = "TableCell" +)); +TableCell.displayName = 'TableCell'; const TableCaption = React.forwardRef< HTMLTableCaptionElement, @@ -102,11 +102,11 @@ const TableCaption = React.forwardRef< >(({ className, ...props }, ref) => (
-)) -TableCaption.displayName = "TableCaption" +)); +TableCaption.displayName = 'TableCaption'; export { Table, @@ -117,4 +117,4 @@ export { TableRow, TableCell, TableCaption, -} +}; diff --git a/frontend/src/constants/tableMockDatat.ts b/frontend/src/constants/tableMockDatat.ts index 429e6e1..2d57130 100644 --- a/frontend/src/constants/tableMockDatat.ts +++ b/frontend/src/constants/tableMockDatat.ts @@ -1,116 +1,102 @@ -import { TableDataType } from '@/types/home'; +import { featureFlagTableType } from '@/types/types'; -export const ExampleData: TableDataType[] = [ +export const ExampleData: featureFlagTableType[] = [ { - Name: 'New Dashboard', + Key: 'New Dashboard', Type: 'Boolean', Created: '2024-01-15', By: 'Alice', - Status: false, - 'Default Value': false, + ToggleButton: false, }, { - Name: 'Feature Flags', + Key: 'Feature Flags', Type: 'String', Created: '2024-02-01', By: 'KeunJae', - Status: true, - 'Default Value': 'so', + ToggleButton: true, }, { - Name: 'Example 1', + Key: 'Example 1', Type: 'Number', Created: '2024-01-28', By: 'Elon Musk', - Status: true, - 'Default Value': 0, + ToggleButton: true, }, { - Name: 'Example 2', + Key: 'Example 2', Type: 'String', Created: '2024-02-01', By: 'KeunJae', - Status: true, - 'Default Value': 'so', + ToggleButton: true, }, { - Name: 'User Preferences', + Key: 'User Preferences', Type: 'Boolean', Created: '2024-03-05', By: 'Sarah', - Status: false, - 'Default Value': true, + ToggleButton: false, }, { - Name: 'Application Mode', + Key: 'Application Mode', Type: 'String', Created: '2024-03-10', By: 'Michael', - Status: true, - 'Default Value': 'production', + ToggleButton: true, }, { - Name: 'Retry Count', + Key: 'Retry Count', Type: 'Number', Created: '2024-03-15', By: 'Nina', - Status: false, - 'Default Value': 3, + ToggleButton: false, }, { - Name: 'Notifications', + Key: 'Notifications', Type: 'Boolean', Created: '2024-03-20', By: 'Tom', - Status: true, - 'Default Value': true, + ToggleButton: true, }, { - Name: 'Dark Mode', + Key: 'Dark Mode', Type: 'Boolean', Created: '2024-03-25', By: 'Emma', - Status: false, - 'Default Value': false, + ToggleButton: false, }, { - Name: 'Max Items', + Key: 'Max Items', Type: 'Number', Created: '2024-03-30', By: 'John', - Status: true, - 'Default Value': 10, + ToggleButton: true, }, { - Name: 'User Role', + Key: 'User Role', Type: 'String', Created: '2024-04-05', By: 'Sophia', - Status: true, - 'Default Value': 'user', + ToggleButton: true, }, { - Name: 'Enable Logging', + Key: 'Enable Logging', Type: 'Boolean', Created: '2024-04-10', By: 'Alice', - Status: false, - 'Default Value': true, + ToggleButton: false, }, { - Name: 'API Key', + Key: 'API Key', Type: 'String', Created: '2024-04-15', By: 'KeunJae', - Status: true, - 'Default Value': '12345-abcde', + ToggleButton: true, }, { - Name: 'Connection Timeout', + Key: 'Connection Timeout', Type: 'Number', Created: '2024-04-20', By: 'Elon Musk', - Status: false, - 'Default Value': 30, + ToggleButton: false, }, ]; diff --git a/frontend/src/types/home.ts b/frontend/src/types/home.ts deleted file mode 100644 index 1910439..0000000 --- a/frontend/src/types/home.ts +++ /dev/null @@ -1,8 +0,0 @@ -export type TableDataType = { - Name: string; - Type: string; - Created: string; - By: string; - Status: boolean; - 'Default Value': boolean | string | number; -}; diff --git a/frontend/src/types/types.ts b/frontend/src/types/types.ts new file mode 100644 index 0000000..2b9ece3 --- /dev/null +++ b/frontend/src/types/types.ts @@ -0,0 +1,7 @@ +export type featureFlagTableType = { + Key: string; + Type: string; + Created: string; + By: string; + ToggleButton: boolean; +}; From 620f0f6f1587fc04f657bc6713b1bc5594533c7e Mon Sep 17 00:00:00 2001 From: tjrmswo <93309061+tjrmswo@users.noreply.github.com> Date: Wed, 19 Feb 2025 23:55:25 +0900 Subject: [PATCH 3/3] fix: include feedback --- frontend/src/app/page.tsx | 6 +- .../src/components/{ui => }/TanstackTable.tsx | 10 +- .../src/components/ui/featureFlagColumns.tsx | 28 ----- frontend/src/constants/featureFlagColumns.tsx | 26 ++++ frontend/src/constants/tableMockDatat.ts | 116 +++++++++--------- frontend/src/types/types.ts | 18 ++- 6 files changed, 104 insertions(+), 100 deletions(-) rename frontend/src/components/{ui => }/TanstackTable.tsx (92%) delete mode 100644 frontend/src/components/ui/featureFlagColumns.tsx create mode 100644 frontend/src/constants/featureFlagColumns.tsx diff --git a/frontend/src/app/page.tsx b/frontend/src/app/page.tsx index 3b11025..c8d431d 100644 --- a/frontend/src/app/page.tsx +++ b/frontend/src/app/page.tsx @@ -1,7 +1,7 @@ import { FlagIcon } from 'lucide-react'; -import { columns } from '@/components/ui/featureFlagColumns'; -import { DataTable } from '@/components/ui/TanstackTable'; +import { columns } from '@/constants/featureFlagColumns'; +import { TanstackTable } from '@/components/TanstackTable'; import { ExampleData } from '@/constants/tableMockDatat'; export default function Home() { @@ -12,7 +12,7 @@ export default function Home() { Feature Flag Management - + ); } diff --git a/frontend/src/components/ui/TanstackTable.tsx b/frontend/src/components/TanstackTable.tsx similarity index 92% rename from frontend/src/components/ui/TanstackTable.tsx rename to frontend/src/components/TanstackTable.tsx index eae08ce..2c2819f 100644 --- a/frontend/src/components/ui/TanstackTable.tsx +++ b/frontend/src/components/TanstackTable.tsx @@ -19,14 +19,14 @@ import { TableRow, } from '@/components/ui/table'; import { Button } from '@/components/ui/button'; -import { featureFlagTableType } from '@/types/types'; +import { FeatureFlagTableType } from '@/types/types'; -export interface DataTableProps { +export interface DataTableProps { columns: ColumnDef[]; data: TData[]; } -export function DataTable({ +export function TanstackTable({ columns, data, }: DataTableProps) { @@ -109,7 +109,7 @@ export function DataTable({