Fix CSV export missing last page (#7167)

This commit is contained in:
Charles Bochet
2024-09-20 05:42:59 +02:00
committed by GitHub
parent b1889e4569
commit 7781d70bb8
5 changed files with 7 additions and 230 deletions

View File

@@ -142,10 +142,6 @@ export const useTableData = ({
});
useEffect(() => {
const MAXIMUM_REQUESTS = isDefined(totalCount)
? Math.min(maximumRequests, totalCount / pageSize)
: maximumRequests;
const fetchNextPage = async () => {
setInflight(true);
setPreviousRecordCount(records.length);
@@ -167,8 +163,8 @@ export const useTableData = ({
}
if (
pageCount >= MAXIMUM_REQUESTS ||
(isDefined(totalCount) && records.length === totalCount)
pageCount >= maximumRequests ||
(isDefined(totalCount) && records.length >= totalCount)
) {
setPageCount(0);

View File

@@ -1,43 +0,0 @@
import { FindOperator, Not } from 'typeorm';
import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface';
import { GraphqlQueryFilterFieldParser } from 'src/engine/api/graphql/graphql-query-runner/graphql-query-parsers/graphql-query-filter/graphql-query-filter-field.parser';
import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
describe('GraphqlQueryFilterFieldParser', () => {
let parser: GraphqlQueryFilterFieldParser;
let mockFieldMetadataMap: Record<string, FieldMetadataInterface>;
beforeEach(() => {
mockFieldMetadataMap = {
simpleField: {
id: '1',
name: 'simpleField',
type: FieldMetadataType.TEXT,
label: 'Simple Field',
objectMetadataId: 'obj1',
},
};
parser = new GraphqlQueryFilterFieldParser(mockFieldMetadataMap);
});
it('should parse simple field correctly', () => {
const result = parser.parse('simpleField', 'value', false);
expect(result).toEqual({ simpleField: 'value' });
});
it('should negate simple field correctly', () => {
const result = parser.parse('simpleField', 'value', true);
expect(result).toEqual({ simpleField: Not('value') });
});
it('should parse object value using operator parser', () => {
const result = parser.parse('simpleField', { like: '%value%' }, false);
expect(result).toEqual({
simpleField: new FindOperator('like', '%%value%%'),
});
});
});

View File

@@ -1,131 +0,0 @@
import {
FindOperator,
ILike,
In,
IsNull,
LessThan,
LessThanOrEqual,
Like,
MoreThan,
MoreThanOrEqual,
Not,
} from 'typeorm';
import { GraphqlQueryRunnerException } from 'src/engine/api/graphql/graphql-query-runner/errors/graphql-query-runner.exception';
import { GraphqlQueryFilterOperatorParser } from 'src/engine/api/graphql/graphql-query-runner/graphql-query-parsers/graphql-query-filter/graphql-query-filter-operator.parser';
describe('GraphqlQueryFilterOperatorParser', () => {
let parser: GraphqlQueryFilterOperatorParser;
beforeEach(() => {
parser = new GraphqlQueryFilterOperatorParser();
});
describe('parseOperator', () => {
it('should parse eq operator correctly', () => {
const result = parser.parseOperator({ eq: 'value' }, false);
expect(result).toBe('value');
});
it('should parse neq operator correctly', () => {
const result = parser.parseOperator({ neq: 'value' }, false);
expect(result).toBeInstanceOf(FindOperator);
expect(result).toEqual(Not('value'));
});
it('should parse gt operator correctly', () => {
const result = parser.parseOperator({ gt: 5 }, false);
expect(result).toBeInstanceOf(FindOperator);
expect(result).toEqual(MoreThan(5));
});
it('should parse gte operator correctly', () => {
const result = parser.parseOperator({ gte: 5 }, false);
expect(result).toBeInstanceOf(FindOperator);
expect(result).toEqual(MoreThanOrEqual(5));
});
it('should parse lt operator correctly', () => {
const result = parser.parseOperator({ lt: 5 }, false);
expect(result).toBeInstanceOf(FindOperator);
expect(result).toEqual(LessThan(5));
});
it('should parse lte operator correctly', () => {
const result = parser.parseOperator({ lte: 5 }, false);
expect(result).toBeInstanceOf(FindOperator);
expect(result).toEqual(LessThanOrEqual(5));
});
it('should parse in operator correctly', () => {
const result = parser.parseOperator({ in: [1, 2, 3] }, false);
expect(result).toBeInstanceOf(FindOperator);
expect(result).toEqual(In([1, 2, 3]));
});
it('should parse is operator with NULL correctly', () => {
const result = parser.parseOperator({ is: 'NULL' }, false);
expect(result).toBeInstanceOf(FindOperator);
expect(result).toEqual(IsNull());
});
it('should parse is operator with non-NULL value correctly', () => {
const result = parser.parseOperator({ is: 'NOT_NULL' }, false);
expect(result).toBeInstanceOf(FindOperator);
expect(result).toEqual(Not(IsNull()));
});
it('should parse like operator correctly', () => {
const result = parser.parseOperator({ like: 'test' }, false);
expect(result).toBeInstanceOf(FindOperator);
expect(result).toEqual(Like('%test%'));
});
it('should parse ilike operator correctly', () => {
const result = parser.parseOperator({ ilike: 'test' }, false);
expect(result).toBeInstanceOf(FindOperator);
expect(result).toEqual(ILike('%test%'));
});
it('should parse startsWith operator correctly', () => {
const result = parser.parseOperator({ startsWith: 'test' }, false);
expect(result).toBeInstanceOf(FindOperator);
expect(result).toEqual(ILike('test%'));
});
it('should parse endsWith operator correctly', () => {
const result = parser.parseOperator({ endsWith: 'test' }, false);
expect(result).toBeInstanceOf(FindOperator);
expect(result).toEqual(ILike('%test'));
});
it('should negate the operator when isNegated is true', () => {
const result = parser.parseOperator({ eq: 'value' }, true);
expect(result).toBeInstanceOf(FindOperator);
expect(result).toEqual(Not('value'));
});
it('should throw an exception for unsupported operator', () => {
expect(() =>
parser.parseOperator({ unsupported: 'value' }, false),
).toThrow(GraphqlQueryRunnerException);
expect(() =>
parser.parseOperator({ unsupported: 'value' }, false),
).toThrow('Operator "unsupported" is not supported');
});
});
});

View File

@@ -1,3 +1,4 @@
import { isArray } from 'class-validator';
import { ObjectLiteral, WhereExpressionBuilder } from 'typeorm';
import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface';
@@ -48,6 +49,10 @@ export class GraphqlQueryFilterFieldParser {
}
const [[operator, value]] = Object.entries(filterValue);
if (operator === 'in' && (!isArray(value) || value.length === 0)) {
return;
}
const { sql, params } = this.computeWhereConditionParts(
fieldMetadata,
operator,

View File

@@ -1,50 +0,0 @@
import { OrderByDirection } from 'src/engine/api/graphql/workspace-query-builder/interfaces/record.interface';
import { GraphqlQueryOrderFieldParser } from 'src/engine/api/graphql/graphql-query-runner/graphql-query-parsers/graphql-query-order/graphql-query-order.parser';
import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
import { FieldMetadataMap } from 'src/engine/metadata-modules/utils/generate-object-metadata-map.util';
describe('GraphqlQueryOrderFieldParser', () => {
let parser: GraphqlQueryOrderFieldParser;
const fieldMetadataMap: FieldMetadataMap = {};
beforeEach(() => {
fieldMetadataMap['name'] = {
id: 'name-id',
name: 'name',
type: FieldMetadataType.TEXT,
label: 'Name',
objectMetadataId: 'object-id',
};
fieldMetadataMap['age'] = {
id: 'age-id',
name: 'age',
type: FieldMetadataType.NUMBER,
label: 'Age',
objectMetadataId: 'object-id',
};
fieldMetadataMap['address'] = {
id: 'address-id',
name: 'address',
type: FieldMetadataType.ADDRESS,
label: 'Address',
objectMetadataId: 'object-id',
};
parser = new GraphqlQueryOrderFieldParser(fieldMetadataMap);
});
describe('parse', () => {
it('should parse simple order by fields', () => {
const orderBy = [
{ name: OrderByDirection.AscNullsFirst },
{ age: OrderByDirection.DescNullsLast },
];
const result = parser.parse(orderBy);
expect(result).toEqual({
name: { direction: 'ASC', nulls: 'FIRST' },
age: { direction: 'DESC', nulls: 'LAST' },
});
});
});
});