Closed jorge-riberi closed 5 years ago
Hi @jorge-riberi, Skeleton cells are rendered only when you are using remote data and new rows haven't been loaded yet. It is possible that you use local data with the VirtualTable. Skeleton cells are rendered in our LazyLoading demo. Could you provide an example where skeleton cells aren't rendered with LazyLoading?
Hi @LazyLahtak , thanks for the answer.
How does VirtualTable determine if the data is local or remote? What I basically did was copy the source of the infinite scroll example and adapt it to what I need. Here is the code:
// Define formatters
const CurrencyFormatter = ({ value }) => (
<div style={{display: 'flex', flexDirection: 'row'}}>
<span style={{cursor: 'inherit'}}>$</span>
<span style={{cursor: 'inherit', flex: '1 1 auto', textAlign: 'right'}}>{formatNumber(value)}</span>
</div>
);
const CurrencyTypeProvider = props => ( <DataTypeProvider formatterComponent={CurrencyFormatter} {...props} />);
const DateFormatter = ({ value }) => formatDate(value);
const DateTypeProvider = props => (<DataTypeProvider formatterComponent={DateFormatter} {...props} />);
const RootComponent = ({ ...restProps }) => (<Grid.Root {...restProps} style={{width: '100%'}} />);
// Infinite scroll settings
const VIRTUAL_PAGE_SIZE = 30;
const MAX_ROWS = 50000;
const getRowId = row => row.id;
const initialState = {
rows: [],
skip: 0,
requestedSkip: 0,
take: VIRTUAL_PAGE_SIZE * 2,
totalCount: 0,
loading: false,
lastQuery: '',
};
function reducer(state, { type, payload }) {
switch (type) {
case 'UPDATE_ROWS':
return {
...state,
...payload,
loading: false,
};
case 'START_LOADING':
return {
...state,
requestedSkip: payload.requestedSkip,
take: payload.take,
};
case 'REQUEST_ERROR':
return {
...state,
loading: false,
};
case 'FETCH_INIT':
return {
...state,
loading: true,
};
case 'UPDATE_QUERY':
return {
...state,
lastQuery: payload,
};
default:
return state;
}
}
const InfScroll = props => {
const URL = props.url;
const buildQueryString = (skip, take) => ( `${URL}?offset=${skip}&limit=${take}`);
const [state, dispatch] = useReducer(reducer, initialState);
const [tableColumnExtensions] = useState([
{ columnName: 'fecha', width: 80 },
{ columnName: 'neto_total', width: 100 },
{ columnName: 'iva', width: 100 },
{ columnName: 'total', width: 100 },
]);
const cache = useMemo(() => createRowCache(VIRTUAL_PAGE_SIZE));
// Define update rows function
const updateRows = (skip, count, newTotalCount) => {
dispatch({type: 'UPDATE_ROWS', payload: {skip, take: count, rows: cache.getRows(skip, count),totalCount: newTotalCount < MAX_ROWS ? newTotalCount : MAX_ROWS}});
};
const getRemoteRows = (requestedSkip, take) => {
dispatch({ type: 'START_LOADING', payload: { requestedSkip, take } });
};
const loadData = () => {
const { requestedSkip, take, lastQuery, loading } = state;
const query = buildQueryString(requestedSkip, take);
if (query !== lastQuery && !loading) {
const cached = cache.getRows(requestedSkip, take);
if (cached.length === take) {
updateRows(requestedSkip, take);
} else {
console.log('fetch', query);
dispatch({ type: 'FETCH_INIT' });
axios.get(query, {headers:{'x-trineo-company':props.currentCompany,'x-trineo-profile':props.currentProfile}}).then(response => {
const data = response.data;
// Response with pagination
if (data.results) {
cache.setRows(requestedSkip, data.results);
updateRows(requestedSkip, take, data.count);
}
// Response without pagination
else {
cache.setRows(requestedSkip, data);
updateRows(requestedSkip, data.length, data.length);
}
}).catch(error=> {console.log(error);dispatch({ type: 'REQUEST_ERROR' })});
}
dispatch({ type: 'UPDATE_QUERY', payload: query });
}
};
useEffect(() => loadData());
const { rows, skip, totalCount, loading, pageSize } = state;
const params = props.params || {};
const actions = props.actions || [];
const currencyColumns = props.columns.filter(c => c.currency).map(c=>c.name);
const dateColumns = props.columns.filter(c => c.date).map(c=>c.name);
return (
<Grid rootComponent={RootComponent} getRowId={getRowId} columns={props.columns} rows={rows}>
<CurrencyTypeProvider for={currencyColumns} />
<DateTypeProvider for={dateColumns} />
<VirtualTableState infiniteScrolling loading={loading} totalRowCount={totalCount} pageSize={VIRTUAL_PAGE_SIZE} skip={skip} getRows={getRemoteRows}/>
<VirtualTable columnExtensions={tableColumnExtensions}/>
<TableHeaderRow />
</Grid>
)
}
/*
InfiniteScrollTable: Scrolleable table of values
Expected props
url: Url to fecth data
params: query params to filter, order or search
columns: Array of objects of type {name: <field name in json>: title: <Title of column>, currency: true|false}
actions: Array of row actions
*/
export default (props) => (
<UserContext.Consumer>
{({currentProfile, currentCompany}) => (
<InfScroll url={props.url} columns={props.columns} actions={props.actions} currentCompany={currentCompany} currentProfile={currentProfile}/>
)}
</UserContext.Consumer>
)
@LazyLahtak , this import solves the problem: import '@devexpress/dx-react-grid-bootstrap4/dist/dx-react-grid-bootstrap4.css';
@jorge-riberi, I'm happy to hear that you have fixed this issue. If you have any further questions, let us know.
This thread has been automatically locked since it is closed and there has not been any recent activity. Please open a new issue for related bugs or feature requests.
I'm using ...
Description
Dont render skeleton cells on VirtualTable and lazy loading, only blank spaces. All other behavior is correct.
Environment