Coder Social home page Coder Social logo

sadmann7 / shadcn-table Goto Github PK

View Code? Open in Web Editor NEW
1.8K 1.8K 154.0 1.49 MB

A shadcn table component with server-side sorting, filtering, and pagination.

Home Page: https://table.sadmn.com

License: MIT License

JavaScript 1.96% TypeScript 97.26% CSS 0.77%
drizzle-orm nextjs open-source shadcn-ui tanstack-table

shadcn-table's Issues

Feature Improvements in the DataTable component

I just checked out AG Grid and it looks cool.
What if we could develop this DataTable into a Batteries Included Table which can be used by the most junior developer to the largest teams.
What other features can be implemented ?
I was thinking of some more features

  1. Sort by Multiple Columns (excel like sort options)
  2. Full text search rather than a multiple search bars for multiple search options along with support for advanced querying like Google search
    image
  3. Multiple Data Presentation formats - Text, Charts, Graphs and Plots - Can be used in
  4. Export Table as viewed by the user to Google Sheets or Microsoft Excel

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Ignored or Blocked

These are blocked by an existing closed PR and will not be recreated unless you click a checkbox below.

Detected dependencies

github-actions
.github/workflows/code-check.yml
  • actions/checkout v4
  • actions/setup-node v4
  • pnpm/action-setup v3.0.0
  • actions/cache v4
  • actions/checkout v4
  • actions/setup-node v4
  • pnpm/action-setup v3.0.0
  • actions/cache v4
  • actions/checkout v4
  • actions/setup-node v4
  • pnpm/action-setup v3.0.0
  • actions/cache v4
npm
package.json
  • @hookform/resolvers ^3.3.4
  • @radix-ui/react-checkbox ^1.0.4
  • @radix-ui/react-dialog ^1.0.5
  • @radix-ui/react-dropdown-menu ^2.0.6
  • @radix-ui/react-icons ^1.3.0
  • @radix-ui/react-label ^2.0.2
  • @radix-ui/react-popover ^1.0.7
  • @radix-ui/react-select ^2.0.0
  • @radix-ui/react-separator ^1.0.3
  • @radix-ui/react-slot ^1.0.2
  • @radix-ui/react-toggle ^1.0.3
  • @radix-ui/react-toggle-group ^1.0.4
  • @radix-ui/react-tooltip ^1.0.7
  • @t3-oss/env-nextjs ^0.10.1
  • @tanstack/react-table ^8.16.0
  • class-variance-authority ^0.7.0
  • clsx ^2.1.1
  • cmdk ^1.0.0
  • date-fns ^3.6.0
  • drizzle-orm ^0.30.10
  • geist ^1.3.0
  • nanoid ^5.0.7
  • next 14.3.0-canary.63
  • next-themes ^0.3.0
  • postgres ^3.4.4
  • react 18.3.1
  • react-day-picker ^8.10.1
  • react-dom 18.3.1
  • react-hook-form ^7.51.4
  • server-only ^0.0.1
  • sonner ^1.4.41
  • tailwind-merge ^2.3.0
  • tailwindcss-animate ^1.0.7
  • zod ^3.23.8
  • @faker-js/faker ^8.4.1
  • @ianvs/prettier-plugin-sort-imports ^4.2.1
  • @total-typescript/ts-reset ^0.5.1
  • @types/eslint ^8.56.10
  • @types/node ^20.12.11
  • @types/react ^18.3.2
  • @types/react-dom ^18.3.0
  • @typescript-eslint/eslint-plugin ^7.8.0
  • @typescript-eslint/parser ^7.8.0
  • autoprefixer ^10.4.19
  • dotenv-cli ^7.4.2
  • drizzle-kit ^0.21.1
  • eslint ^8.57.0
  • eslint-config-next ^14.2.3
  • eslint-config-prettier ^9.1.0
  • eslint-plugin-tailwindcss ^3.15.1
  • pg ^8.11.5
  • postcss ^8.4.38
  • prettier ^3.2.5
  • prettier-plugin-tailwindcss ^0.5.14
  • rimraf ^5.0.6
  • tailwindcss ^3.4.3
  • tsx ^4.10.0
  • typescript ^5.4.5
  • pnpm 8.15.8

  • Check this box to trigger a request for Renovate to run again on this repository

[bug]: Recent Date-Range fix is displaying the previous day instead of selected url date

[Bug] useDataTable: Allow schema parameter to override default createdAt sort

Describe the bug

Hello @sadmann7,

The useDataTable is currently always adding "createdAt.desc" to the URL, as it is the default sort in the use-data-table schema constant.

This is an issue, as we might need "updatedAt" or another type of time sorting, or even no time sorting at all, like sorting simply by IDs.

It seems to me that we should make the schema a mandatory parameter for the use-data-table, so users can choose whether to default to "createdAt", somthing else or nothing at all (thus using the ID as it is the default in queries.ts).

Kind regards.

How to reproduce

Link to reproduction

Additional information

No response

Sticky Header

Hi,
requesting a sticky header feature where the scrolling only happens within the tbody

Page parameter resets back to page 1

Hi, thank you very much for creating this wonderful component.. This is really helpful.

One issue i have though while using it was that the page parameter resets back to page=1 if I reload the browser while I'm in a different page (ex. page=3).
It also reset back to page=1 if I directly visit a url with parameter (ex. page=2, page=3, etc. )

Screen.Recording.2024-02-24.at.8.06.07.PM.mov

floating bar doesn't float or stay at bottom-1

Hi
I was expecting the floating bar to stay at bottom-1 position and always be visiblte on the screen.
Not only it goes all way down when in increase the pageSize, but it doesn't stay fix.

Screenshot 2024-02-26 at 12 22 22 PM

ERR_SSL_WRONG_VERSION_NUMBER

Hi all, i clone your repo and run in my local. I use mysql/mysql-server:8 and node v20.9.0. When i access to path "/", i get an exception:
⨯ Internal error: TypeError: fetch failed at Object.fetch (node:internal/deps/undici/undici:11372:11) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) Cause: [Error: 00683F3B8E7F0000:error:0A00010B:SSL routines:ssl3_get_record:wrong version number:../deps/openssl/openssl/ssl/record/ssl3_record.c:354: ] { library: 'SSL routines', reason: 'wrong version number', code: 'ERR_SSL_WRONG_VERSION_NUMBER' } ⨯ Internal error: TypeError: fetch failed at Object.fetch (node:internal/deps/undici/undici:11372:11) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) digest: "3747308182"
Anyone could help me? Thanks so much!

Selection persists when pagination and/or filters change

If I select the first item in the list, when I move to the next page the first item is still selected. I've fixed this in useDataTable in our project by simply adding this

image

Not sure if this is a good approach (notably if I increase the per-page this won't persist already selected items), and I've notice it still happens when I select filters.

[bug]: Date range isn't persisted across reloads

Describe the bug

Date range in UI isn't persisted across reloads

image

How to reproduce

  1. Go to https://table.sadmn.com/?page=1&sort=createdAt.desc&per_page=30&operator=and&from=2024-05-08&to=2024-06-03
  2. Notice the date range is not selected in the UI, although the filter is being applied correctly

Link to reproduction

https://table.sadmn.com/?page=1&sort=createdAt.desc&per_page=30&operator=and&from=2024-05-08&to=2024-06-03

Additional information

No response

[feat]: filter boolean

Feature description

Could you add a boolean filter ?

Many thanks in advance :)

Additional Context

Actually we can filter by search text, by selectable options, there is no simple boolean filter.

Before submitting

  • I've made research efforts and searched the documentation
  • I've searched for existing issues and PRs

[feat]: Determine per_page on container/viewport on load

Feature description

I'd like to have as many rows in the table as possible to fill the container/viewport on load (i.e. no need on resize). At the moment it is set by a select dropdown.

Additional Context

Additional details here...

Before submitting

  • I've made research efforts and searched the documentation
  • I've searched for existing issues and PRs

All filters are not always being reset

I noticed in the demo when you select a filter and also use the Title search/filter, once you click on reset; the filter value is not fully reset and still is preset in the URL. Here's a quick screencast top to show you what I am running into.

CleanShot.2023-10-03.at.15.34.17.mp4

By the way, thank you so much @kavinvalli & @sadmann7 for creating this. I found it while watching your livecode247 channel on youtube. It has been very helpful and exactly what I have been looking for. 🙏🏻

[feat]: export to csv

Feature description

Add the ability to export data to csv

Additional Context

Additional details here...

Before submitting

  • I've made research efforts and searched the documentation
  • I've searched for existing issues and PRs

Page size is not working?

Hello! First of all great contribution to OSS on how to use shadcn with server side pagination, not an easy task.

I was testing the implementation and it seems that when setting different page size from initial (p.e.: 20) is not working?

Thanks a lot

EDIT: I've been testing a little bit more and I found that if you set it on the URL it works, but when changing on the popover don't. Also I have checked that, for example if you are on the second page and then you change the page size from 20 to 10, it does not reload and instead it goes to the 3rd page.

sonner vs. shadcn toast?

shadcn already has a toast component. So why do we use sonner? Seems to be adding an extra dependency

[feat]: Relations / references

Feature description

I have a table with userId field, but it is not helpful to display it as is, instead It would be nice to have the ability to easily add columns from the referenced table (user.name):

export const users = pgTable("users", {
  id: serial("id").primaryKey(),
  createdAt: timestamp("created_at").defaultNow().notNull(),
  updatedAt: timestamp("updated_at").default(sql`current_timestamp`),
})

export const tasks = pgTable("tasks", {
  id: varchar("id", { length: 30 })
    .$defaultFn(() => generateId())
    .primaryKey(),
  // ...
  userId: integer("user_id").notNull().references(() => users.id),
  createdAt: timestamp("created_at").defaultNow().notNull(),
  updatedAt: timestamp("updated_at").default(sql`current_timestamp`),
})

export const tasksRelations = relations(tasks, ({ one }) => ({
  user: one(users, {
    fields: [tasks.userId],
    references: [users.id],
  }),
}));

p.s. I've tried it myself, it did work, but it's very hacky and also type for DataTableFilterField.value had to be changed to string, because the id of my column was user_name as a result of referencing

Additional Context

Also, maybe we can utilize dynamic query building for better types and more reusability:
https://orm.drizzle.team/docs/dynamic-query-building

Before submitting

  • I've made research efforts and searched the documentation
  • I've searched for existing issues and PRs

[bug]: enableHiding and enableSorting not correctly reflected inside data-table-column-header

Describe the bug

If inside the xxx-table-column we add enableSorting:true and enableHiding:false to a column definition, the column header keep showing hide option in the dropdown menu.

We can do the following to reflect enableHide:false :

{column.getCanHide() ? (
   <>
      <DropdownMenuSeparator />
       <DropdownMenuItem
          aria-label="Hide column"
          onClick={() => column.toggleVisibility(false)}
       >
          <EyeNoneIcon
             className="mr-2 size-3.5 text-muted-foreground/70"
             aria-hidden="true"
          />
          Hide
       </DropdownMenuItem>
     </>
) : null}

also :
If enableHiding: true but enableSorting:false we loose the sorting dropdown containing the quick access to the hide option.

I propose the following :

  if (!column.getCanSort()  && !column.getCanHide()) {
    return <div className={cn(className)}>{title}</div>
  }
  
  return (
    <div className={cn("flex items-center space-x-2", className)}>
      <DropdownMenu>
        <DropdownMenuTrigger asChild>
          <Button
           aria-label={
              column.getCanSort() 
                ? column.getIsSorted() === "desc"
                  ? `Sorted descending. Click to sort ascending.`
                  : column.getIsSorted() === "asc"
                    ? `Sorted ascending. Click to sort descending.`
                    : `Not sorted. Click to sort ascending.`
                : undefined
            }
            variant="ghost"
            size="sm"
            className="-ml-3 h-8 data-[state=open]:bg-accent"
          >
            <span>{title}</span>
            {column.getCanSort() ? (
                column.getIsSorted() === "desc" ? (
                  <RxArrowDown className="ml-2 size-4" aria-hidden="true" />
                ) : column.getIsSorted() === "asc" ? (
                  <RxArrowUp className="ml-2 size-4" aria-hidden="true" />
                ) : (
                  <RxCaretSort className="ml-2 size-4" aria-hidden="true" />
                )
            ) : (
              <RxCaretSort className="ml-2 size-4" aria-hidden="true" />
            )}
          </Button>
        </DropdownMenuTrigger>
        <DropdownMenuContent align="start">
          {column.getCanSort() ? (
            <>
              <DropdownMenuItem
                aria-label="Sort ascending"
                onClick={() => column.toggleSorting(false)}
              >
                <ArrowUpIcon
                  className="mr-2 size-3.5 text-muted-foreground/70"
                  aria-hidden="true"
                />
                Asc
              </DropdownMenuItem>
              <DropdownMenuItem
                aria-label="Sort descending"
                onClick={() => column.toggleSorting(true)}
              >
                <ArrowDownIcon
                  className="mr-2 size-3.5 text-muted-foreground/70"
                  aria-hidden="true"
                />
                Desc
              </DropdownMenuItem>
           </>
          ) : null}
          
          {column.getCanSort() && column.getCanHide() ? (
             <DropdownMenuSeparator />
            )  : null}
          
         {column.getCanHide() ? (
            <DropdownMenuItem
              aria-label="Hide column"
              onClick={() => column.toggleVisibility(false)}
            >
              <EyeNoneIcon
                className="mr-2 size-3.5 text-muted-foreground/70"
                aria-hidden="true"
              />
              Hide
            </DropdownMenuItem>
         )  : null}
         
        </DropdownMenuContent>
      </DropdownMenu>
    </div>
  )

Note : we should maybe also add a clearSorting that would go back to the initial sorting ? this one I m not sure if it is necessary.

How to reproduce

add enableSorting: true and enableHiding: false to a column def

Link to reproduction

Additional information

No response

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.