summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoreug-vs <eug-vs@keemail.me>2021-04-17 11:33:32 +0300
committereug-vs <eug-vs@keemail.me>2021-04-17 11:33:32 +0300
commitf0e470472a16957217b091489afdab2006719294 (patch)
treedfb177a6272bf59a5f3ce3f5680f5b1b8fbce984
parent27f51e35bf732667e4e6015fb76f7fd6871e41cd (diff)
downloadcommercel-ui-f0e470472a16957217b091489afdab2006719294.tar.gz
feat: add sort to ListTable
-rw-r--r--src/components/ListTable.tsx35
-rw-r--r--src/lib/ServiceList.tsx3
2 files changed, 31 insertions, 7 deletions
diff --git a/src/components/ListTable.tsx b/src/components/ListTable.tsx
index 89a2e06..e90d2db 100644
--- a/src/components/ListTable.tsx
+++ b/src/components/ListTable.tsx
@@ -1,4 +1,4 @@
-import React from 'react';
+import React, { useState, useMemo, useCallback } from 'react';
import _ from 'lodash';
export interface Field {
@@ -10,9 +10,14 @@ export interface Field {
interface Props<T = any> {
items?: T[];
fields: Field[];
- handleRowClick?: (index: number) => void;
+ handleRowClick?: (item: T, index?: number) => void;
}
+const sortLabels = {
+ asc: '^',
+ desc: 'v',
+};
+
const getItemField = (item: any, field: Field) => {
const value = _.get(item, field.key);
return field.transform ? field.transform(value) : value;
@@ -20,20 +25,40 @@ const getItemField = (item: any, field: Field) => {
const ListTable: React.FC<Props> = ({ items = [], fields, handleRowClick = () => {} }) => {
+ const [sortBy, setSortBy] = useState<string>('');
+ const [sortOrder, setSortOrder] = useState<'asc' | 'desc'>('asc');
+
+ const sortedItems = useMemo(() => {
+ const result = _.sortBy(items, sortBy);
+ if (sortOrder === 'asc') result.reverse();
+ return result;
+ }, [items, sortBy, sortOrder]);
+
+ const handleFieldClick = useCallback((field: Field) => {
+ if (sortBy === field.key) setSortOrder(sortOrder === 'asc' ? 'desc' : 'asc');
+ else setSortOrder('desc');
+ setSortBy(field.key);
+ }, [sortBy, sortOrder]);
+
if (!items.length) return <div className="text-center p-6">No data</div>;
+
return (
<table className="table-auto w-full">
<thead>
<tr className="border-b select-none">
- {fields.map(field => <th className="pl-3 text-left bg-gray-100" key={field.label}>{field.label}</th>)}
+ {fields.map(field => (
+ <th className="pl-3 text-left bg-gray-100" key={field.label} onClick={() => handleFieldClick(field)}>
+ {field.label} {field.key === sortBy && sortLabels[sortOrder]}
+ </th>
+ ))}
</tr>
</thead>
<tbody>
- {items.map((item, index) => (
+ {sortedItems.map((item, index) => (
<tr
key={item._id}
className={`border-b hover:bg-gray-100 cursor-pointer ${index % 2 && 'bg-gray-50'}`}
- onClick={() => handleRowClick(index)}
+ onClick={() => handleRowClick(item, index)}
>
{fields.map(field => (
<td key={`${item._id} ${field.label}`} className="p-3">
diff --git a/src/lib/ServiceList.tsx b/src/lib/ServiceList.tsx
index 74ad10b..e7015ae 100644
--- a/src/lib/ServiceList.tsx
+++ b/src/lib/ServiceList.tsx
@@ -16,8 +16,7 @@ const ServiceList: React.FC = () => {
route: `/${service.route}/add${location.search}`,
}];
- const handleRowClick = (index: number) => {
- const item = data && data[index];
+ const handleRowClick = (item: any) => {
const route = service.rowLink
? service.rowLink(item)
: `/${service.route}/${item?._id}`;