0.1.1 • Published 9 months ago

@joseaburt/mui-v5-react-table-manager v0.1.1

Weekly downloads
-
License
MIT
Repository
-
Last release
9 months ago

react-table-manager-mui-v5

This package is the implementation using Material UI V5 for @joseaburt/react-table-manager core package.

  • Content of the documentation:
    • Installation
    • Manager Instance
    • Columns
      • Columns / Basic configs
      • Columns / Custom Render
      • Columns / Custom Query Parser
    • Getting Table Component
      • Getting Table Component / Basic Table
      • Getting Table Component / Responsive one
        • ResponsiveTableViewsBuilder
    • Getting Data / PaginableRepository
      • Contracts
      • Implementing my custom Repository
    • Full Example!!!

Installation

yarn add @mui/material @emotion/react @emotion/styled @mui/icons-material

1. Manager Instance

The brain of this module is the @joseaburt/react-table-manager and the first think we need is a fresh instance of that manager and for doing that this package provide and builder for that:

import { TableManagerBuilder } from '@joseaburt/mui-v5-react-table-manager';

const manager = TableManagerBuilder // 👈🏼 This Builder
  //
  .fromDataProvider<User>(new UserRepository())
  .addColumn({})
  .get();

Maybe you can ask how where table component come from? This is an specific topic but let see a little example. Take in mind that the following way is just one of two way, but in soon we will discuss about it.

import { TableManagerBuilder, createTable } from '@joseaburt/mui-v5-react-table-manager';

const manager = TableManagerBuilder
  //
  .fromDataProvider<User>(new UserRepository())
  .addColumn({})
  .get();

const Table = createTable(manager); // 👈🏼 Here buddy

export default function App() {
  return (
    <div className="container p-4">
      <Table />
    </div>
  );
}

2. Columns

Columns are important, so let's learn how to define them. ⚠️ The following configurations definitions are just for each column of the table.

PropRequiredTypeDefaultDescription
nameyeskeyof TName to be used in the input.
labelyesstringValue to be used in the input label .
typeyesColumnTypeDefine the type of the column. Important for the searching filters in header.
rendernoRenderFactoryStringRenderFactoryBy factory will be provided that return an string, so if you need custom children use it.
widthnostringundefinedDefine the with of the column
isHiddennobooleanundefinedIf defined when table render given column will be no render. This can change throw manager commands
alignnoColumnAlignleftDefine the orientation of the content of the column cell
queryTypenoQueryTypefilterDefine in with path of the url the filter are placed. Params or Filter/Query string
queryOperationnoFilterOperationTypeequalDefine the the operation of the column query: like or ilike o equal
isSortablenobooleantrueIf prop no passed a table header sort controls will be render, if explicit false if given wont be render
isQueryablenobooleantrueIf prop no passed a table header filter controls will be render, if explicit false if given wont be render
customQueryParsernoQueryParserundefinedThere is 3 kind of query operations: "like/ilike/equal" but maybe you required your own, so define this prop.

Let's setup a couple one for learn. For doing that we will use BankTransaction model as example.

type BankTransaction = {
  transactionId: string;
  date: Date;
  amount: number;
  description: string;
  accountFrom: string;
  accountTo: string;
  transactionType: 'deposit' | 'withdrawal' | 'transfer';
};

2.1. Columns / Basic configs

This is all you need for a simple table column. By default you get: sort, filter and render the exact value.

import { TableManagerBuilder, createTable } from '@joseaburt/mui-v5-react-table-manager';

const manager = TableManagerBuilder
  //
  .fromDataProvider<User>(new UserRepository())
  .addColumn({
    label: 'ID',
    type: 'text',
    name: 'transactionId',
  })
  .get();

export default createTable(manager);

2.2. Columns / Custom Render

This is all you need for a simple table column. By default you get: sort, filter and render the exact value.

import { TableManagerBuilder, createTable } from '@joseaburt/mui-v5-react-table-manager';

const manager = TableManagerBuilder
  //
  .fromDataProvider<User>(new UserRepository())
  .addColumn({})
  .addColumn({
    label: 'Date',
    type: 'text',
    name: 'date',
    render({ value, record }: RenderProps<User>): JSX.Element {
      // 👈🏼 Here buddy
      return (
        <MomentText variant="body2" format="short-date">
          {value}
        </MomentText>
      );
    },
  })
  .get();

export default createTable(manager);

2.3. Columns / Custom Query Parser

This is all you need for a simple table column. By default you get: sort, filter and render the exact value.

import { TableManagerBuilder, createTable } from '@joseaburt/mui-v5-react-table-manager';

function getDateRange(value: string) {
  const originalDate = moment(date);
  const gte = moment(originalDate).startOf('day').toISOString();
  const lte = moment(originalDate).endOf('day').toISOString();
  return { lte, gte };
}

const manager = TableManagerBuilder
  //
  .fromDataProvider<User>(new UserRepository())
  .addColumn({})
  .addColumn({
    label: 'Date',
    name: 'date',
    type: 'date-range',
    customQueryParser: getDateRange, // 👈🏼 Here buddy
  })
  .get();

export default createTable(manager);

And the rest are as easy as that.

3. Getting Table Component

We have two options for getting table component: one base way and one for responsive one.

3.1. Getting Table Component / Basic Table

The base table help is by using createTable this will build that table component.

import { TableManagerBuilder, createTable } from '@joseaburt/mui-v5-react-table-manager';

const manager = TableManagerBuilder
  //
  .fromDataProvider<User>(new UserRepository())
  .addColumn({})
  .get();

export default createTable(manager); // 👈🏼 Here buddy

3.2. Getting Table Component / Responsive one

This helper provides:

  • defined breakpoints for hiding columns on a given viewport width.
  • Switch to small view on given viewport width
import { TableManagerBuilder, createTable, ResponsiveTableViewsBuilder } from '@joseaburt/mui-v5-react-table-manager';

const manager = TableManagerBuilder
  //
  .fromDataProvider<BankTransaction>(new UserRepository())
  .addColumn({})
  .get();

export default ResponsiveTableViewsBuilder.new<BankTransaction>(manager)
  .addBreakpoint('(max-width: 636)', ['date']) // 👈🏼 Here buddy
  .addBreakpoint('(max-width: 519)', ['description']) // 👈🏼 Here buddy
  .registerSmallView(<div className="p-4 text-center">Small Table Not Implemented</div>) // 👈🏼 Here buddy
  .get();

3.2.1. ResponsiveTableViewsBuilder

This is a builder helper to abstract the complexity of the responsiveness of the table. This builder has two main methods:

  • addBreakpoint(cssBreakpoint: string, columnNames: (keyof T | 'action')[]): Use this method for add as many breakpoints for hiding columns base on css media query.

    export default ResponsiveTableViewsBuilder.new<BankTransaction>(manager)
      .addBreakpoint('(max-width: 636)', ['date']) // 👈🏼 Add one
      .addBreakpoint('(max-width: 519)', ['description']); // 👈🏼 And one more
      .addBreakpoint('(max-width: 519)', ['description']); // 👈🏼 More
      .addBreakpoint('(max-width: 519)', ['description']); // 👈🏼 And one more
      // Etc
  • registerSmallView(smallTableElement: JSX.Element): This is the setter method for defining small table view.

4. Getting Data / PaginableRepository

Getting data is important and as you may know we have been using new UserRepository(), so let's check how to implement one repository.

const manager = TableManagerBuilder.fromDataProvider<BankTransaction>(new UserRepository()); // 👈🏼 This Repository

The way you get and process data it is your concern and this module just offer a contract and this module depends on that contract that you have to implement and provide an implementation.

4.1. Contracts

type BackendResponse<T> = { data: T; meta: Meta };

type Meta = { page: number; total: number; pageSize: number };

interface PaginableRepository<T> {
  getAll(query: Query, signal: AbortSignal): Promise<BackendResponse<T>>;
}

4.1. Implementing my custom Repository

export class MyCustomRepository implements PaginableRepository<BankTransaction[]> {
  constructor(private endpoint: string) {}

  public async getAll(query: Query, signal: AbortSignal): Promise<BackendResponse<BankTransaction[]>> {
    const qs = this.parseQuery(query);
    const { data } = axios.get<BackendResponse<BankTransaction[]>>(`${this.endpoint}${q}`);
    return data;
  }

  public parseQuery(query: Query): string {
    // TODO implement this method
  }
}

Now you can use your impl!

5. Full Example!!!

import './index.css';
import React from 'react';
import 'react-app-polyfill/ie11';
import 'react-app-polyfill/ie11';
import ReactDOM from 'react-dom/client';
import { User } from './api/entities';
import UserRepository from './api/repository';
import EditorPreview from './components/EditorPreview';
import MoreVertIcon from '@mui/icons-material/MoreVert';
import { Avatar, Box, IconButton, Stack, Typography } from '@mui/material';
import { RenderProps, TableManagerBuilder, ResponsiveTableViewsBuilder } from '../.';

const manager = TableManagerBuilder.fromDataProvider<User>(new UserRepository())
  .addColumn({
    label: 'ID',
    name: 'id',
    type: 'text',
    width: '10%',
  })
  .addColumn({
    type: 'text',
    isSortable: true,
    isQueryable: true,
    label: 'Username',
    name: 'fullName',
    render({ value, record }: RenderProps<User>) {
      return (
        <Stack direction="row" alignItems="center" gap={1}>
          <Avatar sx={{ width: '2rem', height: '2rem' }} src={record.thumbnail} />
          <Box>
            <Typography>{record.fullName}</Typography>
            <Typography variant="caption" color="blue">
              {record.email}
            </Typography>
          </Box>
        </Stack>
      );
    },
  })
  .addColumn({
    label: 'Phone',
    name: 'phone',
    type: 'text',
  })
  .addColumn({
    label: 'Address',
    name: 'address',
    type: 'text',
  })
  .addColumn({
    label: 'Action',
    name: 'action',

    render({ value, record }: RenderProps<User>) {
      return (
        <Box>
          <IconButton>
            <MoreVertIcon />
          </IconButton>
        </Box>
      );
    },
  })
  .get();

const TableResponsive = ResponsiveTableViewsBuilder.new<User>(manager)
  .addBreakpoint('(max-width: 636)', ['date'])
  .addBreakpoint('(max-width: 519)', ['description'])
  .registerSmallView(<Box sx={{ padding: '4rem', textAlign: 'center' }}>Small Table Not Implemented</Box>)
  .get({
    debugWidth: true,
    cardProps: {
      sx: {
        border: 'none',
        borderTopRightRadius: 0,
        borderTopLeftRadius: 0,
      },
    },
  });

const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement);
root.render(<TableResponsive />);
0.1.1

9 months ago

0.1.0

9 months ago