import React, { useMemo, useState, useEffect } from 'react'; import { useTable, useFilters, useSortBy, useGlobalFilter, useAsyncDebounce, usePagination, useBlockLayout, useResizeColumns } from 'react-table'; import { resolveReferences } from '@/_helpers/utils'; import Skeleton from 'react-loading-skeleton'; import SelectSearch, { fuzzySearch } from 'react-select-search'; import { useExportData } from 'react-table-plugins'; import Papa from 'papaparse'; import { Pagination } from './Pagination'; import { CustomSelect } from './CustomSelect'; import { Tags } from './Tags'; import { Radio } from './Radio'; import { Toggle } from './Toggle' var _ = require('lodash'); export function Table({ id, width, height, component, onComponentClick, currentState = { components: {} }, onEvent, paramUpdated, changeCanDrag, onComponentOptionChanged, onComponentOptionsChanged, darkMode }) { const color = component.definition.styles.textColor.value; const actions = component.definition.properties.actions || { value: [] }; const serverSidePaginationProperty = component.definition.properties.serverSidePagination; const serverSidePagination = serverSidePaginationProperty ? serverSidePaginationProperty.value : false; const serverSideSearchProperty = component.definition.properties.serverSideSearch; const serverSideSearch = serverSideSearchProperty ? serverSideSearchProperty.value : false; const displaySearchBoxProperty = component.definition.properties.displaySearchBox; const displaySearchBox = displaySearchBoxProperty ? displaySearchBoxProperty.value : true; const [loadingState, setLoadingState] = useState(false); useEffect(() => { const loadingStateProperty = component.definition.properties.loadingState; if (loadingStateProperty && currentState) { const newState = resolveReferences(loadingStateProperty.value, currentState, false); setLoadingState(newState); } }, [currentState]); const [componentState, setcomponentState] = useState(currentState.components[component.component] || {}); useEffect(() => { setcomponentState(currentState.components[component.name] || {}); }, [currentState.components[component.name]]); const [isFiltersVisible, setFiltersVisibility] = useState(false); const [filters, setFilters] = useState([]); function showFilters() { setFiltersVisibility(true); } function hideFilters() { setFiltersVisibility(false); } function filterColumnChanged(index, value) { const newFilters = filters; newFilters[index].id = value; setFilters(newFilters); setAllFilters(newFilters.filter((filter) => filter.id !== '')); } function filterOperationChanged(index, value) { const newFilters = filters; newFilters[index].value = { ...newFilters[index].value, operation: value }; setFilters(newFilters); setAllFilters(newFilters.filter((filter) => filter.id !== '')); } function filterValueChanged(index, value) { const newFilters = filters; newFilters[index].value = { ...newFilters[index].value, value: value }; setFilters(newFilters); setAllFilters(newFilters.filter((filter) => filter.id !== '')); } function addFilter() { setFilters([...filters, { id: '', value: { operation: 'contains', value: '' } }]); } function removeFilter(index) { let newFilters = filters; newFilters.splice(index, 1); setFilters(newFilters); setAllFilters(newFilters); } function clearFilters() { setFilters([]); setAllFilters([]); } const defaultColumn = React.useMemo( () => ({ minWidth: 60, width: 268 }), [] ); const columnSizes = component.definition.properties.columnSizes || {}; function handleCellValueChange(index, key, value, rowData) { const changeSet = componentState.changeSet; const dataUpdates = componentState.dataUpdates || []; let obj = changeSet ? changeSet[index] || {} : {}; obj = _.set(obj, key, value); let newChangeset = { ...changeSet, [index]: { ...obj } }; obj = _.set(rowData, key, value); let newDataUpdates = { ...dataUpdates, [index]: { ...obj } }; onComponentOptionsChanged(component, [ ['dataUpdates', newDataUpdates], ['changeSet', newChangeset] ]); } function getExportFileBlob({ columns, data }) { const headerNames = columns.map((col) => col.exportValue); const csvString = Papa.unparse({ fields: headerNames, data }); return new Blob([csvString], { type: 'text/csv' }); } function onPageIndexChanged(page) { onComponentOptionChanged(component, 'pageIndex', page).then(() => { onEvent('onPageChanged', { component, data: {} }); }); } function handleChangesSaved() { Object.keys(changeSet).forEach((key) => { tableData[key] = { ..._.merge(tableData[key], changeSet[key]) }; }); onComponentOptionChanged(component, 'changeSet', {}); onComponentOptionChanged(component, 'dataUpdates', []); } function handleChangesDiscarded() { onComponentOptionChanged(component, 'changeSet', {}); onComponentOptionChanged(component, 'dataUpdates', []); } function customFilter(rows, columnIds, filterValue) { try { if (filterValue.operation === 'equals') { return rows.filter((row) => row.values[columnIds[0]] === filterValue.value); } if (filterValue.operation === 'matches') { return rows.filter((row) => row.values[columnIds[0]].toString().toLowerCase().includes(filterValue.value.toLowerCase())); } if (filterValue.operation === 'gt') { return rows.filter((row) => row.values[columnIds[0]] > filterValue.value); } if (filterValue.operation === 'lt') { return rows.filter((row) => row.values[columnIds[0]] < filterValue.value); } if (filterValue.operation === 'gte') { return rows.filter((row) => row.values[columnIds[0]] >= filterValue.value); } if (filterValue.operation === 'lte') { return rows.filter((row) => row.values[columnIds[0]] <= filterValue.value); } let value = filterValue.value; if (typeof value === 'string') { value = value.toLowerCase(); } return rows.filter((row) => { let rowValue = row.values[columnIds[0]]; if (typeof rowValue === 'string') { rowValue = rowValue.toLowerCase(); } return rowValue.includes(value); }); } catch { return rows; } } const changeSet = componentState ? componentState.changeSet : {}; const columnData = component.definition.properties.columns.value.map((column) => { const columnSize = columnSizes[column.id] || columnSizes[column.name]; const columnType = column.columnType; const columnOptions = {}; if (columnType === 'dropdown' || columnType === 'multiselect' || columnType === 'badge' || columnType === 'badges' || columnType === 'radio') { const values = resolveReferences(column.values, currentState) || []; const labels = resolveReferences(column.labels, currentState, []) || []; if (typeof labels === 'object') { columnOptions.selectOptions = labels.map((label, index) => { return { name: label, value: values[index] }; }); } } const width = columnSize || defaultColumn.width; return { id: column.id, Header: column.name, accessor: column.key || column.name, filter: customFilter, width: width, Cell: function (cell) { const rowChangeSet = changeSet ? changeSet[cell.row.index] : null; const cellValue = rowChangeSet ? rowChangeSet[column.name] || cell.value : cell.value; if (columnType === undefined || columnType === 'default') { return {cellValue}; } if (columnType === 'string') { if (column.isEditable) { return ( { if (e.key === 'Enter') { handleCellValueChange(cell.row.index, column.key || column.name, e.target.value, cell.row.original); } }} onBlur={(e) => { handleCellValueChange(cell.row.index, column.key || column.name, e.target.value, cell.row.original); }} className="form-control-plaintext form-control-plaintext-sm" defaultValue={cellValue} /> ); } return {cellValue}; } if (columnType === 'text') { return ; } if (columnType === 'dropdown') { return (
| {column.render('Header')} | ))}
|---|
| {cell.render('Cell')} | ; })}