Skip to content

Commit

Permalink
fix: corrected error in handling paste for European date format
Browse files Browse the repository at this point in the history
  • Loading branch information
boris-w committed May 20, 2024
1 parent 6ea342b commit 0dad34a
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import {
nullsToUndefined,
SpaceRole,
RoleType,
DateFormattingPreset,
TimeFormatting,
} from '@teable/core';
import { PrismaService } from '@teable/db-main-prisma';
import { RangeType } from '@teable/openapi';
Expand Down Expand Up @@ -363,6 +365,7 @@ describe('selectionService', () => {
const updateRecordsRo = await selectionService['fillCells']({
tableId,
tableData,
headerFields: undefined,
fields,
records,
});
Expand All @@ -386,6 +389,72 @@ describe('selectionService', () => {
],
});
});

it('date field with European and US', async () => {
const europeanField = {
id: 'europeanField',
name: 'European Field',
type: FieldType.Date,
options: {
formatting: {
date: DateFormattingPreset.European,
time: TimeFormatting.Hour24,
timeZone: 'utc',
},
},
dbFieldName: 'European Field',
cellValueType: CellValueType.DateTime,
dbFieldType: DbFieldType.DateTime,
columnMeta: {},
};
const usField = {
id: 'usField',
name: 'US Field',
type: FieldType.Date,
options: {
formatting: {
date: DateFormattingPreset.US,
time: TimeFormatting.Hour24,
timeZone: 'utc',
},
},
dbFieldName: 'US Field',
cellValueType: CellValueType.DateTime,
dbFieldType: DbFieldType.DateTime,
columnMeta: {},
};

const tableData = [['5/1/2024', '1/5/2024']];
const fields = [europeanField, usField].map(createFieldInstanceByVo);
const records = [
{
id: 'record1',
fields: {},
},
];

const updateRecordsRo = await selectionService['fillCells']({
tableId,
tableData,
headerFields: fields,
fields,
records,
});

expect(updateRecordsRo).toEqual({
fieldKeyType: FieldKeyType.Id,
typecast: true,
records: [
{
id: records[0].id,
fields: {
europeanField: '2024-01-05T00:00:00.000Z',
usField: '2024-01-05T00:00:00.000Z',
},
},
],
});
});
});

describe('expandPasteContent', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -491,11 +491,13 @@ export class SelectionService {
private async fillCells({
tableId,
tableData,
headerFields,
fields,
records,
}: {
tableId: string;
tableData: string[][];
headerFields: IFieldInstance[] | undefined;
fields: IFieldInstance[];
records: Pick<IRecord, 'id' | 'fields'>[];
}) {
Expand Down Expand Up @@ -535,6 +537,11 @@ export class SelectionService {
userSets: fieldConvertContext?.userSets,
});
break;
case FieldType.Date:
recordField[field.id] = (headerFields?.[col] || field).convertStringToCellValue(
stringValue
);
break;
default:
recordField[field.id] = field.convertStringToCellValue(stringValue);
}
Expand Down Expand Up @@ -717,6 +724,7 @@ export class SelectionService {
const updateRecordsRo = await this.fillCells({
tableId,
tableData,
headerFields: header.map(createFieldInstanceByVo),
fields: updateFields,
records: updateRecords,
});
Expand All @@ -734,6 +742,7 @@ export class SelectionService {
const updateRecordsRo = await this.fillCells({
tableId,
tableData: [],
headerFields: undefined,
fields: fieldInstances,
records,
});
Expand Down
25 changes: 25 additions & 0 deletions packages/core/src/models/field/derivate/date.field.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,31 @@ describe('DateFieldCore', () => {
expect(field.convertStringToCellValue('abc')).toBeNull();
expect(lookupField.convertStringToCellValue('2023/06/19 06:50')).toBeNull();
expect(lookupField.convertStringToCellValue('abc')).toBeNull();
// european and us date format
const europeanField = plainToInstance(DateFieldCore, {
...json,
options: {
formatting: {
date: DateFormattingPreset.European,
time: TimeFormatting.Hour24,
timeZone: DEFAULT_TIME_ZONE,
},
defaultValue: 'now',
},
});
expect(europeanField.convertStringToCellValue('5/1/2024')).toBe('2024-01-05T00:00:00.000Z');
const usField = plainToInstance(DateFieldCore, {
...json,
options: {
formatting: {
date: DateFormattingPreset.US,
time: TimeFormatting.Hour24,
timeZone: DEFAULT_TIME_ZONE,
},
defaultValue: 'now',
},
});
expect(usField.convertStringToCellValue('5/1/2024 06:50')).toBe('2024-05-01T06:50:00.000Z');
});

it('should repair invalid value', () => {
Expand Down
11 changes: 10 additions & 1 deletion packages/core/src/models/field/derivate/date.field.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import dayjs, { extend } from 'dayjs';
import customParseFormat from 'dayjs/plugin/customParseFormat';
import timezone from 'dayjs/plugin/timezone';
import utc from 'dayjs/plugin/utc';
import { z } from 'zod';
import type { FieldType, CellValueType } from '../constant';
import { FieldCore } from '../field';
Expand All @@ -10,6 +12,8 @@ import {
} from '../formatting';

extend(timezone);
extend(customParseFormat);
extend(utc);

export const dateFieldOptionsSchema = z.object({
formatting: datetimeFormattingSchema,
Expand Down Expand Up @@ -57,8 +61,13 @@ export class DateFieldCore extends FieldCore {

if (value === '' || value == null) return null;

const hasTime = /\d{1,2}:\d{2}(?::\d{2})?/.test(value);

const format =
this.options.formatting.date +
(hasTime && this.options.formatting.time ? ' ' + this.options.formatting.time : '');
try {
const formatValue = dayjs.tz(value, this.options.formatting.timeZone);
const formatValue = dayjs.tz(value, format, this.options.formatting.timeZone);
if (!formatValue.isValid()) return null;
return formatValue.toISOString();
} catch (e) {
Expand Down

0 comments on commit 0dad34a

Please sign in to comment.