Use react-table for rendering tables

This commit is contained in:
navaneeth 2021-04-09 10:26:17 +05:30
parent d53393b73c
commit b22386b1b0
3 changed files with 239 additions and 73 deletions

View file

@ -1,89 +1,168 @@
import React from 'react';
import React, { useMemo, useState, useEffect } from "react";
import { useTable, useFilters } from "react-table";
import { resolve, findProp } from '@/_helpers/utils';
import Skeleton from 'react-loading-skeleton';
export const Table = function Table({ id, component, onComponentClick, currentState, onEvent }) {
export function Table({ id, component, onComponentClick, currentState, onEvent }) {
const backgroundColor = component.definition.styles.backgroundColor.value;
const color = component.definition.styles.textColor.value;
const actions = component.definition.properties.actions || { value: []};
let loadingState = false;
const loadingStateProperty = component.definition.properties.loadingState;
if(loadingStateProperty && currentState) {
loadingState = resolve(loadingStateProperty.value, currentState);
}
const [filterInput, setFilterInput] = useState("");
const handleFilterChange = e => {
const value = e.target.value || undefined;
setFilter("name", value);
setFilterInput(value);
};
const backgroundColor = component.definition.styles.backgroundColor.value;
const color = component.definition.styles.textColor.value;
const columns = component.definition.properties.columns.value;
const actions = component.definition.properties.actions || { value: []};
const columnData = component.definition.properties.columns.value.map((column) => {
return { Header: column.name, accessor: column.key || column.name }
})
const loadingStateProperty = component.definition.properties.loadingState;
let loadingState = false;
if(loadingStateProperty && currentState) {
loadingState = resolve(loadingStateProperty.value, currentState);
}
console.log('currentState', currentState);
let data = []
let tableData = []
if(currentState) {
data = resolve(component.definition.properties.data.value, currentState, []);
console.log('resolved param', data);
}
function findColumnValue(row, column) {
if(column.key) {
return findProp(row, column.key);
} else {
return findProp(row, column.name);
}
tableData = resolve(component.definition.properties.data.value, currentState, []);
console.log('resolved param', tableData);
}
// Quick fix, need to remove later
data = data ? data : [];
tableData = tableData ? tableData : [];
const computedStyles = {
const columns = useMemo(
() =>
[
...columnData,
{
id: 'actions',
Header: 'Actions',
accessor: 'edit',
Cell: (cell) => {
return actions.value.map((action) =>
<button
className="btn btn-sm m-1 btn-light"
onClick={(e) => { e.stopPropagation(); onEvent('onTableActionButtonClicked', { component, data: cell.row.original, action }); }}
>
{action.buttonText}
</button>
)
}
}
],
[]
);
const data = useMemo(
() =>
tableData,
[tableData.length]
);
const computedStyles = {
backgroundColor,
color
color,
width: '700px'
}
return (
<div class="table-responsive table-bordered" style={{...computedStyles, width: '700px'}} onClick={() => onComponentClick(id, component) }>
<table
class="table table-vcenter table-nowrap">
<thead>
<tr>
{columns.map((column) => <th>{column.name}</th>)}
{actions.value.length > 0 &&
<th>Actions</th>
}
</tr>
</thead>
<tbody>
const {
getTableProps,
getTableBodyProps,
headerGroups,
rows,
prepareRow,
setFilter
} = useTable( {
columns,
data
},
useFilters,
);
{data.map((row =>
<tr onClick={(e) => { e.stopPropagation(); onEvent('onRowClicked', { component, data: row }); }}>
{columns.map((column) => <td>{findColumnValue(row, column)}</td>)}
{actions.value.length > 0 &&
<td>
{actions.value.map((action) => (
<button
class="btn btn-sm m-1 btn-light"
onClick={(e) => { e.stopPropagation(); onEvent('onTableActionButtonClicked', { component, data: row, action }); }}
>
{action.buttonText}
</button>
))}
</td>
}
</tr>
))}
</tbody>
{/* <div className="table-footer p-2">
Records 1-10 of 242
</div> */}
</table>
{loadingState &&
return (
<div class="card" style={{width: '702px'}} onClick={() => onComponentClick(id, component) }>
<div class="card-body border-bottom py-3">
<div class="d-flex">
<div class="text-muted">
Show
<div class="mx-2 d-inline-block">
<input type="text" class="form-control form-control-sm" value="8" size="3" aria-label="Invoices count"/>
</div>
entries
</div>
<div class="ms-auto text-muted">
Search:
<div class="ms-2 d-inline-block">
<input
className="form-control form-control-sm"
value={filterInput}
onChange={handleFilterChange}
placeholder={"Search name"}
/>
</div>
</div>
</div>
</div>
<div class="table-responsive">
<table {...getTableProps()} class="table table-vcenter table-nowrap table-bordered" style={computedStyles}>
<thead>
{headerGroups.map(headerGroup => (
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map(column => (
<th {...column.getHeaderProps()}>{column.render("Header")}</th>
))}
</tr>
))}
</thead>
<tbody {...getTableBodyProps()}>
{rows.map((row, i) => {
prepareRow(row);
return (
<tr {...row.getRowProps()} onClick={(e) => { e.stopPropagation(); onEvent('onRowClicked', { component, data: row.original }); }}>
{row.cells.map(cell => {
return <td {...cell.getCellProps()}>{cell.render("Cell")}</td>;
})}
</tr>
);
})}
</tbody>
</table>
{loadingState &&
<div style={{width: '100%'}} className="p-5">
<Skeleton count={5}/>
</div>
}
</div>
);
};
</div>
<div class="card-footer d-flex align-items-center">
<p class="m-0 text-muted">Showing <span>1</span> to <span>8</span> of <span>16</span> entries</p>
<ul class="pagination m-0 ms-auto">
<li class="page-item disabled">
<a class="page-link" href="#" tabindex="-1" aria-disabled="true">
<svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><polyline points="15 6 9 12 15 18"></polyline></svg>
prev
</a>
</li>
<li class="page-item"><a class="page-link" href="#">1</a></li>
<li class="page-item active"><a class="page-link" href="#">2</a></li>
<li class="page-item"><a class="page-link" href="#">3</a></li>
<li class="page-item"><a class="page-link" href="#">4</a></li>
<li class="page-item"><a class="page-link" href="#">5</a></li>
<li class="page-item">
<a class="page-link" href="#">
<svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><polyline points="9 6 15 12 9 18"></polyline></svg>
</a>
</li>
</ul>
</div>
</div>
);
}

View file

@ -0,0 +1,89 @@
import React from 'react';
import { resolve, findProp } from '@/_helpers/utils';
import Skeleton from 'react-loading-skeleton';
export const Table = function Table({ id, component, onComponentClick, currentState, onEvent }) {
const backgroundColor = component.definition.styles.backgroundColor.value;
const color = component.definition.styles.textColor.value;
const columns = component.definition.properties.columns.value;
const actions = component.definition.properties.actions || { value: []};
const loadingStateProperty = component.definition.properties.loadingState;
let loadingState = false;
if(loadingStateProperty && currentState) {
loadingState = resolve(loadingStateProperty.value, currentState);
}
console.log('currentState', currentState);
let data = []
if(currentState) {
data = resolve(component.definition.properties.data.value, currentState, []);
console.log('resolved param', data);
}
function findColumnValue(row, column) {
if(column.key) {
return findProp(row, column.key);
} else {
return findProp(row, column.name);
}
}
// Quick fix, need to remove later
data = data ? data : [];
const computedStyles = {
backgroundColor,
color
}
return (
<div class="table-responsive table-bordered" style={{...computedStyles, width: '700px'}} onClick={() => onComponentClick(id, component) }>
<table
class="table table-vcenter table-nowrap">
<thead>
<tr>
{columns.map((column) => <th>{column.name}</th>)}
{actions.value.length > 0 &&
<th>Actions</th>
}
</tr>
</thead>
<tbody>
{data.map((row =>
<tr onClick={(e) => { e.stopPropagation(); onEvent('onRowClicked', { component, data: row }); }}>
{columns.map((column) => <td>{findColumnValue(row, column)}</td>)}
{actions.value.length > 0 &&
<td>
{actions.value.map((action) => (
<button
class="btn btn-sm m-1 btn-light"
onClick={(e) => { e.stopPropagation(); onEvent('onTableActionButtonClicked', { component, data: row, action }); }}
>
{action.buttonText}
</button>
))}
</td>
}
</tr>
))}
</tbody>
{/* <div className="table-footer p-2">
Records 1-10 of 242
</div> */}
</table>
{loadingState &&
<div style={{width: '100%'}} className="p-5">
<Skeleton count={5}/>
</div>
}
</div>
);
};

View file

@ -51,7 +51,6 @@ export const componentTypes = [
'onRowClicked'
],
styles: {
backgroundColor: { type: 'color'},
textColor: { type: 'color'}
},
definition: {
@ -73,7 +72,6 @@ export const componentTypes = [
}
},
styles: {
backgroundColor: { value: '' },
textColor: { value: '' }
}
}