Browse Source

support sort string in grids. (#465)

* stash

Signed-off-by: ryjiang <jiangruiyi@gmail.com>

* finish sort

Signed-off-by: ryjiang <jiangruiyi@gmail.com>

---------

Signed-off-by: ryjiang <jiangruiyi@gmail.com>
ryjiang 1 year ago
parent
commit
482b3993c1

+ 6 - 1
client/src/components/grid/TableHead.tsx

@@ -51,7 +51,12 @@ const EnhancedTableHead: FC<TableHeadType> = props => {
   } = props;
   const classes = useStyles();
   const createSortHandler = (property: string) => (event: React.MouseEvent) => {
-    handleSort && handleSort(event, property);
+    handleSort &&
+      handleSort(
+        event,
+        property,
+        colDefinitions.find(c => c.id === property)
+      );
   };
 
   return (

+ 4 - 1
client/src/components/grid/Types.ts

@@ -11,6 +11,8 @@ export type ColorType = 'default' | 'inherit' | 'primary' | 'secondary';
 
 export type SortDirection = 'asc' | 'desc';
 
+export type SortType = 'string' | 'number';
+
 /**
  * selected: selected data in table checkbox
  */
@@ -57,7 +59,7 @@ export type TableHeadType = {
   numSelected: number;
   rowCount: number;
   colDefinitions: ColDefinitionsType[];
-  handleSort?: (e: any, p: string) => void;
+  handleSort?: (e: any, p: string, col?: ColDefinitionsType) => void;
   openCheckBox?: boolean;
   disableSelect?: boolean;
 };
@@ -106,6 +108,7 @@ export type ColDefinitionsType = {
   notSort?: boolean;
   // custom sort rule property, default is row id
   sortBy?: string;
+  sortType?: 'string' | 'number';
   onClick?: (
     e: React.MouseEvent<HTMLButtonElement, MouseEvent>,
     data?: any

+ 10 - 3
client/src/hooks/Pagination.ts

@@ -1,25 +1,27 @@
 import { useMemo, useState } from 'react';
 import { stableSort, getComparator } from '../utils/Sort';
+import { ColDefinitionsType, SortType } from '../components/grid/Types';
 
 export const usePaginationHook = (list: any[]) => {
   const [currentPage, setCurrentPage] = useState(0);
   const [pageSize, setPageSize] = useState(10);
   const [orderBy, setOrderBy] = useState('');
   const [order, setOrder] = useState<'asc' | 'desc'>('asc');
+  const [sortType, setSortType] = useState<SortType>('number');
 
   const total = list.length;
   const { data, offset } = useMemo(() => {
     const offset = pageSize * currentPage;
     // only when user click sort, orderBy will have value
     const sortList = orderBy
-      ? stableSort(list, getComparator(order || 'asc', orderBy))
+      ? stableSort(list, getComparator(order || 'asc', orderBy, sortType))
       : list;
     const data = sortList.slice(offset, offset + pageSize);
     return {
       offset,
       data,
     };
-  }, [pageSize, currentPage, orderBy, list, order]);
+  }, [pageSize, currentPage, orderBy, list, order, sortType]);
 
   const handleCurrentPage = (page: number) => {
     setCurrentPage(page);
@@ -28,10 +30,15 @@ export const usePaginationHook = (list: any[]) => {
   const handlePageSize = (size: number) => {
     setPageSize(size);
   };
-  const handleGridSort = (e: any, property: string) => {
+  const handleGridSort = (
+    e: any,
+    property: string,
+    col: ColDefinitionsType = {} as ColDefinitionsType
+  ) => {
     const isAsc = orderBy === property && order === 'asc';
     setOrder(isAsc ? 'desc' : 'asc');
     setOrderBy(property);
+    setSortType(col!.sortType || 'number');
   };
 
   return {

+ 1 - 0
client/src/pages/databases/collections/Collections.tsx

@@ -340,6 +340,7 @@ const Collections = () => {
       align: 'left',
       disablePadding: true,
       sortBy: 'collection_name',
+      sortType: 'string',
       formatter({ collection_name }) {
         return (
           <Link

+ 2 - 1
client/src/pages/databases/collections/partitions/Partitions.tsx

@@ -192,9 +192,10 @@ const Partitions = () => {
   const colDefinitions: ColDefinitionsType[] = [
     {
       id: 'name',
+      sortType: 'string',
       align: 'left',
       disablePadding: true,
-      sortBy: 'collectionName',
+      sortBy: 'name',
       formatter({ name }) {
         const newName = name === '_default' ? 'Default partition' : name;
         return (

+ 2 - 0
client/src/pages/user/User.tsx

@@ -200,12 +200,14 @@ const Users = () => {
     {
       id: 'name',
       align: 'left',
+      sortType: 'string',
       disablePadding: false,
       label: userTrans('user'),
     },
     {
       id: 'role',
       align: 'left',
+      sortType: 'string',
       disablePadding: false,
       label: userTrans('role'),
     },

+ 44 - 6
client/src/utils/Sort.ts

@@ -1,8 +1,14 @@
+import { SortType } from '@/components/grid/Types';
+
 type numberObj = {
   [x: string]: number;
 };
 
-export const descendingComparator = (
+type stringObj = {
+  [x: string]: string;
+};
+
+export const descendingNumberComparator = (
   a: numberObj,
   b: numberObj,
   orderBy: string
@@ -22,15 +28,47 @@ export const descendingComparator = (
   return 0;
 };
 
-export const getComparator = (order: string, orderBy: string) => {
-  return order === 'desc'
-    ? (a: numberObj, b: numberObj) => descendingComparator(a, b, orderBy)
-    : (a: numberObj, b: numberObj) => -descendingComparator(a, b, orderBy);
+export const descendingStringComparator = (
+  a: stringObj,
+  b: stringObj,
+  orderBy: string
+) => {
+  const aValue = a[orderBy].toLowerCase(); // Convert to lowercase for case-insensitive comparison
+  const bValue = b[orderBy].toLowerCase(); // Convert to lowercase for case-insensitive comparison
+
+  if (bValue < aValue) {
+    return -1;
+  }
+  if (bValue > aValue) {
+    return 1;
+  }
+  return 0;
+};
+
+export const getComparator = (
+  order: string,
+  orderBy: string,
+  sortType: SortType = 'number'
+) => {
+  switch (sortType) {
+    case 'string':
+      return order === 'desc'
+        ? (a: stringObj, b: stringObj) =>
+            descendingStringComparator(a, b, orderBy)
+        : (a: stringObj, b: stringObj) =>
+            -descendingStringComparator(a, b, orderBy);
+    default:
+      return order === 'desc'
+        ? (a: numberObj, b: numberObj) =>
+            descendingNumberComparator(a, b, orderBy)
+        : (a: numberObj, b: numberObj) =>
+            -descendingNumberComparator(a, b, orderBy);
+  }
 };
 
 export const stableSort = (
   array: any[],
-  comparator: { (a: numberObj, b: numberObj): number }
+  comparator: ReturnType<typeof getComparator>,
 ) => {
   const stabilizedThis = array.map((el, index) => [el, index]);
   stabilizedThis.sort((a, b) => {