Files
G4F/StaticHelper/source/working_file.md

4.4 KiB

components/useTableFilters.tsx

// добавьте новую функцию для экспорта CSV
export function useTableFilters(schema: FieldInfo[]| null, initialData: unknown[] | null) {
  const [filters, setFilters] = useState<FiltersState>({})
  const [visibleColumns, setVisibleColumns] = useState<VisibilityState>({})

  // Инициализация видимости колонок
  useMemo(() => {
    if (!schema){
      return;
    }

    const initialVisibility: VisibilityState = {}
    schema.forEach(field => {
      initialVisibility[field.name] = true
    })
    setVisibleColumns(initialVisibility)
  }, [schema])

  // Обновление фильтров
  const handleFilterChange = useCallback((name: string, filterPart: unknown) => {
    setFilters(prev => ({
      ...prev,
      [name]: {
        ...prev[name],
        ...filterPart
      }
    }))
  }, [])

  // Переключатель видимости колонки
  const handleColumnToggle = useCallback((name: string) => {
    setVisibleColumns(prev => ({
      ...prev,
      [name]: !prev[name]
    }))
  }, [])

  // Функция экспорта данных в CSV
  const handleExportCSV = useCallback(() => {
    if (!initialData || !schema || initialData.length === 0) {
      alert('Нет данных для экспорта')
      return
    }

    const visibleFields = schema.filter(field => visibleColumns[field.name])
    const header = visibleFields.map(field => `"${field.title.replace(/"/g, '""')}"`).join(';')

    const rows = initialData
      .filter(item => schema.every(field => {
        const value = item[field.name]
        const filter = filters[field.name]
        if (!filter) return true

        if (field.type === 'string') {
          if (filter.searchText) {
            if (typeof value !== 'string') return false
            if (!value.toLowerCase().includes(filter.searchText.toLowerCase())) return false
          }
          if (filter.exactMatch && filter.searchText) {
            return value.toLowerCase() === filter.searchText.toLowerCase()
          }
          if (filter.empty !== undefined) {
            const isEmpty = value === '' || value === null || value === undefined
            if (filter.empty && !isEmpty) return false
            if (filter.notEmpty && isEmpty) return false
          }
        } else if (field.format === 'date') {
          const dateValue = new Date(value as string).getTime()
          if (filter.fromDate) {
            const fromTime = new Date(filter.fromDate).getTime()
            if (dateValue < fromTime) return false
          }
          if (filter.toDate) {
            const toTime = new Date(filter.toDate).getTime()
            if (dateValue > toTime) return false
          }
        } else if (field.type === 'number') {
          const numValue = Number(value)
          if (filter.gte !== undefined && numValue < filter.gte) return false
          if (filter.lte !== undefined && numValue > filter.lte) return false
        }
        return true
      }))
    .map(item => {
      const row = visibleFields.map(field => {
        const val = item[field.name]
        // Обработка null/undefined
        const strVal = val !== undefined && val !== null ? String(val) : ''
        // Экранирование кавычек
        return `"${strVal.replace(/"/g, '""')}"`

      })
      return row.join(';')
    })

    const csvContent = [header, ...rows].join('\n')
    // Создаем ссылку для скачивания
    const blob = new Blob([csvContent], { type: 'text/csv' })
    const url = URL.createObjectURL(blob)
    const link = document.createElement('a')
    link.href = url
    link.download = 'export.csv'
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
    URL.revokeObjectURL(url)
  }, [initialData, schema, filters, visibleColumns])

  return {
    filters,
    setFilters,
    visibleColumns,
    setVisibleColumns,
    handleFilterChange,
    handleColumnToggle,
    filteredData,
    handleExportCSV // добавьте сюда
  }
}

Ваш файл, где вызывается handleExport (примеры использования)

const {
  filters,
  handleFilterChange,
  visibleColumns,
  handleColumnToggle,
  filteredData,
  handleExportCSV  // новая функция
} = useTableFilters(schema, dataPage.items)

const handleExport = async () => {
  handleExportCSV()
}