Skip to content

Commit

Permalink
DataViews: Refactor the edit function to be based on discrete controls (
Browse files Browse the repository at this point in the history
#64404)

Co-authored-by: youknowriad <[email protected]>
Co-authored-by: oandregal <[email protected]>
Co-authored-by: ntsekouras <[email protected]>
  • Loading branch information
4 people authored and getdave committed Aug 14, 2024
1 parent 2e909fd commit b59d797
Show file tree
Hide file tree
Showing 11 changed files with 201 additions and 218 deletions.
37 changes: 37 additions & 0 deletions packages/dataviews/src/dataform-controls/datetime.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* WordPress dependencies
*/
import { BaseControl, TimePicker } from '@wordpress/components';
import { useCallback } from '@wordpress/element';

/**
* Internal dependencies
*/
import type { DataFormControlProps } from '../types';

export default function DateTime< Item >( {
data,
field,
onChange,
}: DataFormControlProps< Item > ) {
const { id, label } = field;
const value = field.getValue( { item: data } );

const onChangeControl = useCallback(
( newValue: string | null ) => onChange( { [ id ]: newValue } ),
[ id, onChange ]
);

return (
<fieldset>
<BaseControl.VisualLabel as="legend">
{ label }
</BaseControl.VisualLabel>
<TimePicker
currentTime={ value }
onChange={ onChangeControl }
hideLabelFromVision
/>
</fieldset>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,23 @@ import type {
DataFormControlProps,
Field,
FieldTypeDefinition,
} from '../../types';
} from '../types';
import datetime from './datetime';
import integer from './integer';
import radio from './radio';
import select from './select';
import text from './text';

interface FormControls {
[ key: string ]: ComponentType< DataFormControlProps< any > >;
}

const FORM_CONTROLS: FormControls = {
datetime,
integer,
radio,
select,
text,
};

export function getControl< Item >(
Expand All @@ -29,18 +37,25 @@ export function getControl< Item >(
return field.Edit;
}

let control;
if ( typeof field.Edit === 'string' ) {
control = getControlByType( field.Edit );
return getControlByType( field.Edit );
}

return control || fieldTypeDefinition.Edit;
if ( field.elements ) {
return getControlByType( 'select' );
}

if ( typeof fieldTypeDefinition.Edit === 'string' ) {
return getControlByType( fieldTypeDefinition.Edit );
}

return fieldTypeDefinition.Edit;
}

export function getControlByType( type: string ) {
if ( Object.keys( FORM_CONTROLS ).includes( type ) ) {
return FORM_CONTROLS[ type ];
}

return null;
throw 'Control ' + type + ' not found';
}
38 changes: 38 additions & 0 deletions packages/dataviews/src/dataform-controls/integer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* WordPress dependencies
*/
import { __experimentalNumberControl as NumberControl } from '@wordpress/components';
import { useCallback } from '@wordpress/element';

/**
* Internal dependencies
*/
import type { DataFormControlProps } from '../types';

export default function Integer< Item >( {
data,
field,
onChange,
hideLabelFromVision,
}: DataFormControlProps< Item > ) {
const { id, label, description } = field;
const value = field.getValue( { item: data } ) ?? '';
const onChangeControl = useCallback(
( newValue: string | undefined ) =>
onChange( {
[ id ]: Number( newValue ),
} ),
[ id, onChange ]
);

return (
<NumberControl
label={ label }
help={ description }
value={ value }
onChange={ onChangeControl }
__next40pxDefaultSize
hideLabelFromVision={ hideLabelFromVision }
/>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import { useCallback } from '@wordpress/element';
/**
* Internal dependencies
*/
import type { DataFormControlProps } from '../../types';
import type { DataFormControlProps } from '../types';

export default function Edit< Item >( {
export default function Radio< Item >( {
data,
field,
onChange,
Expand All @@ -20,10 +20,9 @@ export default function Edit< Item >( {

const onChangeControl = useCallback(
( newValue: string ) =>
onChange( ( prevItem: Item ) => ( {
...prevItem,
onChange( {
[ id ]: newValue,
} ) ),
} ),
[ id, onChange ]
);

Expand Down
52 changes: 52 additions & 0 deletions packages/dataviews/src/dataform-controls/select.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/**
* WordPress dependencies
*/
import { SelectControl } from '@wordpress/components';
import { useCallback } from '@wordpress/element';
import { __ } from '@wordpress/i18n';

/**
* Internal dependencies
*/
import type { DataFormControlProps } from '../types';

export default function Select< Item >( {
data,
field,
onChange,
hideLabelFromVision,
}: DataFormControlProps< Item > ) {
const { id, label } = field;
const value = field.getValue( { item: data } ) ?? '';
const onChangeControl = useCallback(
( newValue: any ) =>
onChange( {
[ id ]: newValue,
} ),
[ id, onChange ]
);

const elements = [
/*
* Value can be undefined when:
*
* - the field is not required
* - in bulk editing
*
*/
{ label: __( 'Select item' ), value: '' },
...( field?.elements ?? [] ),
];

return (
<SelectControl
label={ label }
value={ value }
options={ elements }
onChange={ onChangeControl }
__next40pxDefaultSize
__nextHasNoMarginBottom
hideLabelFromVision={ hideLabelFromVision }
/>
);
}
40 changes: 40 additions & 0 deletions packages/dataviews/src/dataform-controls/text.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* WordPress dependencies
*/
import { TextControl } from '@wordpress/components';
import { useCallback } from '@wordpress/element';

/**
* Internal dependencies
*/
import type { DataFormControlProps } from '../types';

export default function Text< Item >( {
data,
field,
onChange,
hideLabelFromVision,
}: DataFormControlProps< Item > ) {
const { id, label, placeholder } = field;
const value = field.getValue( { item: data } );

const onChangeControl = useCallback(
( newValue: string ) =>
onChange( {
[ id ]: newValue,
} ),
[ id, onChange ]
);

return (
<TextControl
label={ label }
placeholder={ placeholder }
value={ value ?? '' }
onChange={ onChangeControl }
__next40pxDefaultSize
__nextHasNoMarginBottom
hideLabelFromVision={ hideLabelFromVision }
/>
);
}
67 changes: 2 additions & 65 deletions packages/dataviews/src/field-types/datetime.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,7 @@
/**
* WordPress dependencies
*/
import { BaseControl, TimePicker, SelectControl } from '@wordpress/components';
import { useCallback } from '@wordpress/element';
import { __ } from '@wordpress/i18n';

/**
* Internal dependencies
*/
import type {
SortDirection,
ValidationContext,
DataFormControlProps,
} from '../types';
import type { SortDirection, ValidationContext } from '../types';

function sort( a: any, b: any, direction: SortDirection ) {
const timeA = new Date( a ).getTime();
Expand All @@ -32,60 +21,8 @@ function isValid( value: any, context?: ValidationContext ) {
return true;
}

function Edit< Item >( {
data,
field,
onChange,
}: DataFormControlProps< Item > ) {
const { id, label } = field;
const value = field.getValue( { item: data } );

const onChangeControl = useCallback(
( newValue: string | null ) => onChange( { [ id ]: newValue } ),
[ id, onChange ]
);

if ( field.elements ) {
const elements = [
/*
* Value can be undefined when:
*
* - the field is not required
* - in bulk editing
*
*/
{ label: __( 'Select item' ), value: '' },
...field.elements,
];

return (
<SelectControl
label={ label }
value={ value }
options={ elements }
onChange={ onChangeControl }
__next40pxDefaultSize
__nextHasNoMarginBottom
/>
);
}

return (
<fieldset>
<BaseControl.VisualLabel as="legend">
{ label }
</BaseControl.VisualLabel>
<TimePicker
currentTime={ value }
onChange={ onChangeControl }
hideLabelFromVision
/>
</fieldset>
);
}

export default {
sort,
isValid,
Edit,
Edit: 'datetime',
};
Loading

0 comments on commit b59d797

Please sign in to comment.