@joseaburt/mui-v5-react-table-manager
v0.1.1
Published
This package is the implementation using [Material UI V5](https://mui.com/material-ui/getting-started/installation/) for [@joseaburt/react-table-manager ](https://www.npmjs.com/package/@joseaburt/react-table-manager) core package.
Downloads
1
Readme
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.
| Prop | Required | Type | Default | Description | | ----------------- | -------- | ------------------- | ------------------- | ------------------------------------------------------------------------------------------------------------- | | name | yes | keyof T | | Name to be used in the input. | | label | yes | string | | Value to be used in the input label . | | type | yes | ColumnType | | Define the type of the column. Important for the searching filters in header. | | render | no | RenderFactory | StringRenderFactory | By factory will be provided that return an string, so if you need custom children use it. | | width | no | string | undefined | Define the with of the column | | isHidden | no | boolean | undefined | If defined when table render given column will be no render. This can change throw manager commands | | align | no | ColumnAlign | left | Define the orientation of the content of the column cell | | queryType | no | QueryType | filter | Define in with path of the url the filter are placed. Params or Filter/Query string | | queryOperation | no | FilterOperationType | equal | Define the the operation of the column query: like or ilike o equal | | isSortable | no | boolean | true | If prop no passed a table header sort controls will be render, if explicit false if given wont be render | | isQueryable | no | boolean | true | If prop no passed a table header filter controls will be render, if explicit false if given wont be render | | customQueryParser | no | QueryParser | undefined | There 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 />);