175 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
			
		
		
	
	
			175 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
import type { DeepPartial } from "react-hook-form";
 | 
						|
import type { TableState } from "~/components/core/data-table";
 | 
						|
 | 
						|
// export function mapTableStateToPaginationQueryDSL<T>(
 | 
						|
//   state: TableState<T>
 | 
						|
// ): Record<string, string> {
 | 
						|
//   const { pagination, search, sort, filters } = state;
 | 
						|
//   const query: Record<string, string> = {};
 | 
						|
 | 
						|
//   // Pagination
 | 
						|
//   query.page = pagination.currentPage.toString();
 | 
						|
//   query.limit = pagination.pageSize.toString();
 | 
						|
 | 
						|
//   // Global search
 | 
						|
//   if (search) {
 | 
						|
//     query.search = search;
 | 
						|
//   }
 | 
						|
 | 
						|
//   // Sort (e.g., sort=createdAt:desc)
 | 
						|
//   if (sort?.key) {
 | 
						|
//     query.sortBy = `${String(sort.key)}:${sort.direction.toUpperCase()}`;
 | 
						|
//   }
 | 
						|
 | 
						|
//   // ====== FILTERS: bắt đầu với filter.<field> = $operator:value ======
 | 
						|
 | 
						|
//   // 1. select -> $in
 | 
						|
//   for (const [field, values] of Object.entries(filters.select || {})) {
 | 
						|
//     if (Array.isArray(values) && values.length > 0) {
 | 
						|
//       query[`filter.${field}`] = `$in:${values.join(",")}`;
 | 
						|
//     }
 | 
						|
//   }
 | 
						|
 | 
						|
//   // 2. text -> $cont (contains, LIKE)
 | 
						|
//   for (const [field, value] of Object.entries(filters.text || {})) {
 | 
						|
//     if (value) {
 | 
						|
//       query[`filter.${field}`] = `$ilike:${value}`;
 | 
						|
//     }
 | 
						|
//   }
 | 
						|
 | 
						|
//   // 3. dateRange -> $btw
 | 
						|
//   for (const [field, { from, to }] of Object.entries(filters.dateRange || {})) {
 | 
						|
//     if (from && to) {
 | 
						|
//       query[`filter.${field}`] = `$btw:${from.toISOString().split("T")[0]},${
 | 
						|
//         to.toISOString().split("T")[0]
 | 
						|
//       }`;
 | 
						|
//     } else if (from) {
 | 
						|
//       query[`filter.${field}`] = `$gte:${from.toISOString().split("T")[0]}`;
 | 
						|
//     } else if (to) {
 | 
						|
//       query[`filter.${field}`] = `$lte:${to.toISOString().split("T")[0]}`;
 | 
						|
//     }
 | 
						|
//   }
 | 
						|
 | 
						|
//   // 4. numberRange -> $gte / $lte / $btw
 | 
						|
//   for (const [field, { min, max }] of Object.entries(
 | 
						|
//     filters.numberRange || {}
 | 
						|
//   )) {
 | 
						|
//     if (min != null && max != null) {
 | 
						|
//       query[`filter.${field}`] = `$btw:${min},${max}`;
 | 
						|
//     } else if (min != null) {
 | 
						|
//       query[`filter.${field}`] = `$gte:${min}`;
 | 
						|
//     } else if (max != null) {
 | 
						|
//       query[`filter.${field}`] = `$lte:${max}`;
 | 
						|
//     }
 | 
						|
//   }
 | 
						|
 | 
						|
//   // 5. number -> $eq
 | 
						|
//   for (const [field, value] of Object.entries(filters.number || {})) {
 | 
						|
//     if (value != null) {
 | 
						|
//       query[`filter.${field}`] = `$eq:${value}`;
 | 
						|
//     }
 | 
						|
//   }
 | 
						|
 | 
						|
//   // 6. date -> $eq
 | 
						|
//   for (const [field, value] of Object.entries(filters.date || {})) {
 | 
						|
//     if (value) {
 | 
						|
//       query[`filter.${field}`] = `$eq:${value.toISOString().split("T")[0]}`;
 | 
						|
//     }
 | 
						|
//   }
 | 
						|
 | 
						|
//   return query;
 | 
						|
// }
 | 
						|
 | 
						|
export function mapTableStateToPaginationQueryDSL<T>(
 | 
						|
  state: DeepPartial<TableState<T>>
 | 
						|
): Record<string, string> {
 | 
						|
  const { pagination, search, sort, filters } = state || {};
 | 
						|
  const query: Record<string, string> = {};
 | 
						|
 | 
						|
  // Pagination
 | 
						|
  if (pagination?.currentPage != null) {
 | 
						|
    query.page = pagination.currentPage.toString();
 | 
						|
  }
 | 
						|
  if (pagination?.pageSize != null) {
 | 
						|
    query.limit = pagination.pageSize.toString();
 | 
						|
  }
 | 
						|
 | 
						|
  // Global search
 | 
						|
  if (search) {
 | 
						|
    query.search = search;
 | 
						|
  }
 | 
						|
 | 
						|
  // Sort
 | 
						|
  if (sort?.key && sort?.direction) {
 | 
						|
    query.sortBy = `${String(sort.key)}:${sort.direction.toUpperCase()}`;
 | 
						|
  }
 | 
						|
 | 
						|
  // === FILTERS ===
 | 
						|
  const f = filters || {};
 | 
						|
 | 
						|
  // 1. select -> $in
 | 
						|
  Object.entries(f.select || {}).forEach(([field, values]) => {
 | 
						|
    if (Array.isArray(values) && values.length > 0) {
 | 
						|
      query[`filter.${field}`] = `$in:${values.join(",")}`;
 | 
						|
    }
 | 
						|
  });
 | 
						|
 | 
						|
  // 2. text -> $ilike
 | 
						|
  Object.entries(f.text || {}).forEach(([field, value]) => {
 | 
						|
    if (value) {
 | 
						|
      query[`filter.${field}`] = `$ilike:${value}`;
 | 
						|
    }
 | 
						|
  });
 | 
						|
 | 
						|
  // 3. dateRange -> $btw, $gte, $lte
 | 
						|
  Object.entries(f.dateRange || {}).forEach(([field, range]) => {
 | 
						|
    const from = range?.from;
 | 
						|
    const to = range?.to;
 | 
						|
    if (from && to) {
 | 
						|
      query[`filter.${field}`] = `$btw:${from.toISOString().split("T")[0]},${
 | 
						|
        to.toISOString().split("T")[0]
 | 
						|
      }`;
 | 
						|
    } else if (from) {
 | 
						|
      query[`filter.${field}`] = `$gte:${from.toISOString().split("T")[0]}`;
 | 
						|
    } else if (to) {
 | 
						|
      query[`filter.${field}`] = `$lte:${to.toISOString().split("T")[0]}`;
 | 
						|
    }
 | 
						|
  });
 | 
						|
 | 
						|
  // 4. numberRange -> $btw, $gte, $lte
 | 
						|
  Object.entries(f.numberRange || {}).forEach(([field, range]) => {
 | 
						|
    const min = range?.min;
 | 
						|
    const max = range?.max;
 | 
						|
    if (min != null && max != null) {
 | 
						|
      query[`filter.${field}`] = `$btw:${min},${max}`;
 | 
						|
    } else if (min != null) {
 | 
						|
      query[`filter.${field}`] = `$gte:${min}`;
 | 
						|
    } else if (max != null) {
 | 
						|
      query[`filter.${field}`] = `$lte:${max}`;
 | 
						|
    }
 | 
						|
  });
 | 
						|
 | 
						|
  // 5. number -> $eq
 | 
						|
  Object.entries(f.number || {}).forEach(([field, value]) => {
 | 
						|
    if (value != null) {
 | 
						|
      query[`filter.${field}`] = `$eq:${value}`;
 | 
						|
    }
 | 
						|
  });
 | 
						|
 | 
						|
  // 6. date -> $eq
 | 
						|
  Object.entries(f.date || {}).forEach(([field, value]) => {
 | 
						|
    if (value) {
 | 
						|
      query[`filter.${field}`] = `$eq:${value.toISOString().split("T")[0]}`;
 | 
						|
    }
 | 
						|
  });
 | 
						|
 | 
						|
  // 7. not -> $not
 | 
						|
  Object.entries(f.not || {}).forEach(([field, value]) => {
 | 
						|
    if (value != null) {
 | 
						|
      query[`filter.${field}`] = `$not:${value}`;
 | 
						|
    }
 | 
						|
  });
 | 
						|
 | 
						|
  return query;
 | 
						|
}
 |