Skip to content

Commit 7f735ad

Browse files
committed
displayFormat is an empty object for non-date field types
1 parent 50c1cf5 commit 7f735ad

File tree

5 files changed

+76
-35
lines changed

5 files changed

+76
-35
lines changed

packages/dataviews/src/dataform-controls/date.tsx

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -258,11 +258,17 @@ function CalendarDateControl< Item >( {
258258
hideLabelFromVision,
259259
validity,
260260
}: DataFormControlProps< Item > ) {
261-
const { id, label, setValue, getValue, isValid } = field;
261+
const { id, type, label, setValue, getValue, isValid, displayFormat } =
262+
field;
262263
const [ selectedPresetId, setSelectedPresetId ] = useState< string | null >(
263264
null
264265
);
265266

267+
let weekStartsOn;
268+
if ( type === 'date' ) {
269+
weekStartsOn = weekStartsOnToNumber( displayFormat.weekStartsOn );
270+
}
271+
266272
const fieldValue = getValue( { item: data } );
267273
const value = typeof fieldValue === 'string' ? fieldValue : undefined;
268274
const [ calendarMonth, setCalendarMonth ] = useState< Date >( () => {
@@ -396,9 +402,7 @@ function CalendarDateControl< Item >( {
396402
month={ calendarMonth }
397403
onMonthChange={ setCalendarMonth }
398404
timeZone={ timezoneString || undefined }
399-
weekStartsOn={ weekStartsOnToNumber(
400-
field.displayFormat.weekStartsOn
401-
) }
405+
weekStartsOn={ weekStartsOn }
402406
/>
403407
</VStack>
404408
</BaseControl>
@@ -413,7 +417,7 @@ function CalendarDateRangeControl< Item >( {
413417
hideLabelFromVision,
414418
validity,
415419
}: DataFormControlProps< Item > ) {
416-
const { id, label, getValue, setValue } = field;
420+
const { id, type, label, getValue, setValue, displayFormat } = field;
417421
let value: DateRange;
418422
const fieldValue = getValue( { item: data } );
419423
if (
@@ -424,6 +428,11 @@ function CalendarDateRangeControl< Item >( {
424428
value = fieldValue as DateRange;
425429
}
426430

431+
let weekStartsOn;
432+
if ( type === 'date' ) {
433+
weekStartsOn = weekStartsOnToNumber( displayFormat.weekStartsOn );
434+
}
435+
427436
const onChangeCallback = useCallback(
428437
( newValue: DateRange ) => {
429438
onChange(
@@ -611,9 +620,7 @@ function CalendarDateRangeControl< Item >( {
611620
month={ calendarMonth }
612621
onMonthChange={ setCalendarMonth }
613622
timeZone={ timezone.string || undefined }
614-
weekStartsOn={ weekStartsOnToNumber(
615-
field.displayFormat.weekStartsOn
616-
) }
623+
weekStartsOn={ weekStartsOn }
617624
/>
618625
</VStack>
619626
</BaseControl>

packages/dataviews/src/field-types/date.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,15 @@ export default {
4848
return '';
4949
}
5050

51+
// Not all fields have displayFormat, but date fields do.
52+
//
53+
// At runtime, this method will never be called for non-date fields.
54+
// However, the type system does not know this, so we need to check it.
55+
// There's an opportunity here to improve the type system.
56+
if ( field.type !== 'date' ) {
57+
return '';
58+
}
59+
5160
return dateI18n( field.displayFormat.date, value );
5261
},
5362
enableSorting: true,

packages/dataviews/src/test/normalize-fields.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,7 @@ describe( 'normalizeFields: default getValue', () => {
374374
);
375375
} );
376376

377-
it( 'always adds displayFormat.date and displayFormat.weekStartsOn for all field types', () => {
377+
it( 'adds empty displayFormat for non-date field types', () => {
378378
const fields: Field< {} >[] = [
379379
{
380380
id: 'title',
@@ -386,14 +386,8 @@ describe( 'normalizeFields: default getValue', () => {
386386
},
387387
];
388388
const normalizedFields = normalizeFields( fields );
389-
expect( normalizedFields[ 0 ].displayFormat.date ).toBeDefined();
390-
expect( normalizedFields[ 1 ].displayFormat.date ).toBeDefined();
391-
expect(
392-
normalizedFields[ 0 ].displayFormat.weekStartsOn
393-
).toBeDefined();
394-
expect(
395-
normalizedFields[ 1 ].displayFormat.weekStartsOn
396-
).toBeDefined();
389+
expect( normalizedFields[ 0 ].displayFormat ).toEqual( {} );
390+
expect( normalizedFields[ 1 ].displayFormat ).toEqual( {} );
397391
} );
398392
} );
399393
} );

packages/dataviews/src/types/field-api.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ type DisplayFormatDate = {
335335
| 'saturday';
336336
};
337337

338-
export type NormalizedField< Item > = Omit< Field< Item >, 'Edit' > & {
338+
type NormalizedFieldBase< Item > = Omit< Field< Item >, 'Edit' > & {
339339
label: string;
340340
header: string | ReactElement;
341341
getValue: ( args: { item: Item } ) => any;
@@ -349,9 +349,22 @@ export type NormalizedField< Item > = Omit< Field< Item >, 'Edit' > & {
349349
enableSorting: boolean;
350350
filterBy: NormalizedFilterByConfig | false;
351351
readOnly: boolean;
352+
};
353+
354+
export type NormalizedFieldDate< Item > = NormalizedFieldBase< Item > & {
355+
type: 'date';
352356
displayFormat: Required< DisplayFormatDate >;
353357
};
354358

359+
export type NormalizedFieldGeneric< Item > = NormalizedFieldBase< Item > & {
360+
type?: Exclude< FieldType, 'date' >;
361+
displayFormat: {};
362+
};
363+
364+
export type NormalizedField< Item > =
365+
| NormalizedFieldDate< Item >
366+
| NormalizedFieldGeneric< Item >;
367+
355368
/**
356369
* A collection of dataview fields for a data type.
357370
*/

packages/dataviews/src/utils/normalize-fields.ts

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,15 @@ export default function normalizeFields< Item >(
188188

189189
const filterBy = getFilterBy( field, fieldTypeDefinition );
190190

191-
return {
192-
...field,
191+
// TypeScript is unable to figure out that we're returning the proper types
192+
// (either NormalizedFieldDate or NormalizedFieldGeneric)
193+
// when the type is part of the object spread below.
194+
//
195+
// Hence, why we remove it and add back it later.
196+
const { type, ...fieldWithoutType } = field;
197+
198+
const baseField = {
199+
...fieldWithoutType,
193200
label: field.label || field.id,
194201
header: field.header || field.label || field.id,
195202
getValue,
@@ -206,21 +213,32 @@ export default function normalizeFields< Item >(
206213
true,
207214
filterBy,
208215
readOnly: field.readOnly ?? fieldTypeDefinition.readOnly ?? false,
209-
displayFormat: {
210-
date:
211-
field.type === 'date' &&
212-
field.displayFormat?.date !== undefined &&
213-
typeof field.displayFormat.date === 'string'
214-
? field.displayFormat.date
215-
: getSettings().formats.date,
216-
weekStartsOn:
217-
field.type === 'date' &&
218-
field.displayFormat?.weekStartsOn !== undefined
219-
? field.displayFormat.weekStartsOn
220-
: numberToWeekStartsOn(
221-
getSettings().l10n.startOfWeek
222-
),
223-
},
216+
};
217+
218+
if ( field.type === 'date' ) {
219+
return {
220+
...baseField,
221+
type: 'date' as const,
222+
displayFormat: {
223+
date:
224+
field.displayFormat?.date !== undefined &&
225+
typeof field.displayFormat.date === 'string'
226+
? field.displayFormat.date
227+
: getSettings().formats.date,
228+
weekStartsOn:
229+
field.displayFormat?.weekStartsOn !== undefined
230+
? field.displayFormat.weekStartsOn
231+
: numberToWeekStartsOn(
232+
getSettings().l10n.startOfWeek
233+
),
234+
},
235+
};
236+
}
237+
238+
return {
239+
...baseField,
240+
type: field.type,
241+
displayFormat: {},
224242
};
225243
} );
226244
}

0 commit comments

Comments
 (0)