The variations table should match the height of number of rows selected (#41140)
* Remove fixed height to the variations table and add per row skeletong when loading * Add changelog file * Add last variations instead of the current per page var given that there it is not accessible anymore
This commit is contained in:
parent
8486dfcdba
commit
c416b57a94
|
@ -0,0 +1,4 @@
|
|||
Significance: minor
|
||||
Type: add
|
||||
|
||||
The variations table should match the height of number of rows selected
|
|
@ -3,6 +3,7 @@
|
|||
@import "./pagination/styles.scss";
|
||||
@import "./table-empty-state/styles.scss";
|
||||
@import "./variations-filter/styles.scss";
|
||||
@import "./table-row-skeleton/styles.scss";
|
||||
|
||||
$table-row-height: calc($grid-unit * 9);
|
||||
|
||||
|
@ -39,11 +40,6 @@ $table-row-height: calc($grid-unit * 9);
|
|||
}
|
||||
}
|
||||
|
||||
&__table {
|
||||
height: $table-row-height * 5;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
&__selection {
|
||||
.components-checkbox-control__input[type="checkbox"] {
|
||||
&:not(:checked):not(:focus) {
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
export * from './table-row-skeleton';
|
|
@ -0,0 +1,51 @@
|
|||
.woocommerce-table-row-skeleton {
|
||||
@mixin skeleton {
|
||||
@include placeholder();
|
||||
background-color: $gray-200;
|
||||
border-radius: $grid-unit-05;
|
||||
width: $grid-unit-30;
|
||||
min-height: $grid-unit-30;
|
||||
}
|
||||
|
||||
display: grid;
|
||||
grid-template-columns: 44px auto 25% 25% 88px;
|
||||
padding: 0;
|
||||
min-height: 9 * $grid-unit;
|
||||
border: none;
|
||||
align-items: center;
|
||||
|
||||
&__checkbox {
|
||||
@include skeleton();
|
||||
}
|
||||
|
||||
&__attribute-option {
|
||||
@include skeleton();
|
||||
width: 9 * $grid-unit;
|
||||
}
|
||||
|
||||
&__regular-price,
|
||||
&__quantity {
|
||||
@include skeleton();
|
||||
width: $grid-unit-80;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
&__visibility-icon {
|
||||
@include skeleton();
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
&__edit-link {
|
||||
@include skeleton();
|
||||
width: $grid-unit-70;
|
||||
height: $grid-unit-40 + $grid-unit-05;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
&__menu-toggle {
|
||||
@include skeleton();
|
||||
width: $grid-unit-40 + $grid-unit-05;
|
||||
height: $grid-unit-40 + $grid-unit-05;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { createElement } from '@wordpress/element';
|
||||
|
||||
export function TableRowSkeleton() {
|
||||
return (
|
||||
<div className="woocommerce-sortable__item" aria-hidden="true">
|
||||
<div className="woocommerce-list-item woocommerce-table-row-skeleton">
|
||||
<div className="woocommerce-sortable__handle" />
|
||||
|
||||
<div className="woocommerce-product-variations__selection">
|
||||
<div className="woocommerce-table-row-skeleton__checkbox" />
|
||||
</div>
|
||||
|
||||
<div className="woocommerce-product-variations__attributes">
|
||||
{ Array( 3 )
|
||||
.fill( 0 )
|
||||
.map( ( _, index ) => (
|
||||
<div
|
||||
key={ index }
|
||||
className="woocommerce-tag woocommerce-product-variations__attribute"
|
||||
>
|
||||
<div className="woocommerce-table-row-skeleton__attribute-option" />
|
||||
</div>
|
||||
) ) }
|
||||
</div>
|
||||
|
||||
<div className="woocommerce-product-variations__price">
|
||||
<div className="woocommerce-table-row-skeleton__regular-price" />
|
||||
</div>
|
||||
|
||||
<div className="woocommerce-product-variations__quantity">
|
||||
<div className="woocommerce-table-row-skeleton__quantity" />
|
||||
</div>
|
||||
|
||||
<div className="woocommerce-product-variations__actions">
|
||||
<div className="woocommerce-table-row-skeleton__visibility-icon" />
|
||||
|
||||
<div className="woocommerce-table-row-skeleton__edit-link" />
|
||||
|
||||
<div className="woocommerce-table-row-skeleton__menu-toggle" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -41,6 +41,7 @@ import { Pagination } from './pagination';
|
|||
import { EmptyTableState } from './table-empty-state';
|
||||
import { VariationsFilter } from './variations-filter';
|
||||
import { useVariations } from './use-variations';
|
||||
import { TableRowSkeleton } from './table-row-skeleton';
|
||||
|
||||
const NOT_VISIBLE_TEXT = __( 'Not visible to customers', 'woocommerce' );
|
||||
|
||||
|
@ -302,16 +303,6 @@ export const VariationsTable = forwardRef<
|
|||
|
||||
return (
|
||||
<div className="woocommerce-product-variations" ref={ ref }>
|
||||
{ ( isLoading || isGenerating ) && (
|
||||
<div className="woocommerce-product-variations__loading">
|
||||
<Spinner />
|
||||
{ isGenerating && (
|
||||
<span>
|
||||
{ __( 'Generating variations…', 'woocommerce' ) }
|
||||
</span>
|
||||
) }
|
||||
</div>
|
||||
) }
|
||||
{ noticeText && (
|
||||
<Notice
|
||||
status={ noticeStatus }
|
||||
|
@ -405,148 +396,170 @@ export const VariationsTable = forwardRef<
|
|||
</div>
|
||||
) }
|
||||
|
||||
<Sortable className="woocommerce-product-variations__table">
|
||||
{ variations.map( ( variation ) => (
|
||||
<ListItem key={ `${ variation.id }` }>
|
||||
<div className="woocommerce-product-variations__selection">
|
||||
{ isUpdating[ variation.id ] ? (
|
||||
<Spinner />
|
||||
) : (
|
||||
<CheckboxControl
|
||||
value={ variation.id }
|
||||
checked={ isSelected( variation ) }
|
||||
onChange={ onSelect( variation ) }
|
||||
disabled={ isSelectingAll }
|
||||
/>
|
||||
) }
|
||||
</div>
|
||||
<div className="woocommerce-product-variations__attributes">
|
||||
{ variation.attributes.map( ( attribute ) => {
|
||||
const tag = (
|
||||
/* eslint-disable-next-line @typescript-eslint/ban-ts-comment */
|
||||
/* @ts-ignore Additional props are not required. */
|
||||
<Tag
|
||||
id={ attribute.id }
|
||||
className="woocommerce-product-variations__attribute"
|
||||
key={ attribute.id }
|
||||
label={ truncate( attribute.option, {
|
||||
length: PRODUCT_VARIATION_TITLE_LIMIT,
|
||||
} ) }
|
||||
screenReaderLabel={ attribute.option }
|
||||
/>
|
||||
);
|
||||
|
||||
return attribute.option.length <=
|
||||
PRODUCT_VARIATION_TITLE_LIMIT ? (
|
||||
tag
|
||||
{ isLoading || isGenerating ? (
|
||||
<div
|
||||
className="woocommerce-product-variations__table"
|
||||
aria-label={
|
||||
isGenerating
|
||||
? __( 'Generating variations…', 'woocommerce' )
|
||||
: __( 'Loading variations…', 'woocommerce' )
|
||||
}
|
||||
>
|
||||
{ Array.from( { length: variations.length || 5 } ).map(
|
||||
( _, index ) => (
|
||||
<TableRowSkeleton key={ index } />
|
||||
)
|
||||
) }
|
||||
</div>
|
||||
) : (
|
||||
<Sortable className="woocommerce-product-variations__table">
|
||||
{ variations.map( ( variation ) => (
|
||||
<ListItem key={ `${ variation.id }` }>
|
||||
<div className="woocommerce-product-variations__selection">
|
||||
{ isUpdating[ variation.id ] ? (
|
||||
<Spinner />
|
||||
) : (
|
||||
<Tooltip
|
||||
key={ attribute.id }
|
||||
text={ attribute.option }
|
||||
position="top center"
|
||||
>
|
||||
<span>{ tag }</span>
|
||||
</Tooltip>
|
||||
);
|
||||
} ) }
|
||||
</div>
|
||||
<div
|
||||
className={ classnames(
|
||||
'woocommerce-product-variations__price',
|
||||
{
|
||||
'woocommerce-product-variations__price--fade':
|
||||
variation.status === 'private',
|
||||
}
|
||||
) }
|
||||
>
|
||||
{ variation.on_sale && (
|
||||
<span className="woocommerce-product-variations__sale-price">
|
||||
{ formatAmount( variation.sale_price ) }
|
||||
</span>
|
||||
) }
|
||||
<span
|
||||
<CheckboxControl
|
||||
value={ variation.id }
|
||||
checked={ isSelected( variation ) }
|
||||
onChange={ onSelect( variation ) }
|
||||
disabled={ isSelectingAll }
|
||||
/>
|
||||
) }
|
||||
</div>
|
||||
<div className="woocommerce-product-variations__attributes">
|
||||
{ variation.attributes.map( ( attribute ) => {
|
||||
const tag = (
|
||||
/* eslint-disable-next-line @typescript-eslint/ban-ts-comment */
|
||||
/* @ts-ignore Additional props are not required. */
|
||||
<Tag
|
||||
id={ attribute.id }
|
||||
className="woocommerce-product-variations__attribute"
|
||||
key={ attribute.id }
|
||||
label={ truncate(
|
||||
attribute.option,
|
||||
{
|
||||
length: PRODUCT_VARIATION_TITLE_LIMIT,
|
||||
}
|
||||
) }
|
||||
screenReaderLabel={
|
||||
attribute.option
|
||||
}
|
||||
/>
|
||||
);
|
||||
|
||||
return attribute.option.length <=
|
||||
PRODUCT_VARIATION_TITLE_LIMIT ? (
|
||||
tag
|
||||
) : (
|
||||
<Tooltip
|
||||
key={ attribute.id }
|
||||
text={ attribute.option }
|
||||
position="top center"
|
||||
>
|
||||
<span>{ tag }</span>
|
||||
</Tooltip>
|
||||
);
|
||||
} ) }
|
||||
</div>
|
||||
<div
|
||||
className={ classnames(
|
||||
'woocommerce-product-variations__regular-price',
|
||||
'woocommerce-product-variations__price',
|
||||
{
|
||||
'woocommerce-product-variations__regular-price--on-sale':
|
||||
variation.on_sale,
|
||||
'woocommerce-product-variations__price--fade':
|
||||
variation.status === 'private',
|
||||
}
|
||||
) }
|
||||
>
|
||||
{ formatAmount( variation.regular_price ) }
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
className={ classnames(
|
||||
'woocommerce-product-variations__quantity',
|
||||
{
|
||||
'woocommerce-product-variations__quantity--fade':
|
||||
variation.status === 'private',
|
||||
}
|
||||
) }
|
||||
>
|
||||
{ variation.regular_price && (
|
||||
<>
|
||||
<span
|
||||
className={ classnames(
|
||||
'woocommerce-product-variations__status-dot',
|
||||
getProductStockStatusClass(
|
||||
variation
|
||||
)
|
||||
) }
|
||||
>
|
||||
●
|
||||
{ variation.on_sale && (
|
||||
<span className="woocommerce-product-variations__sale-price">
|
||||
{ formatAmount( variation.sale_price ) }
|
||||
</span>
|
||||
{ getProductStockStatus( variation ) }
|
||||
</>
|
||||
) }
|
||||
</div>
|
||||
<div className="woocommerce-product-variations__actions">
|
||||
{ ( variation.status === 'private' ||
|
||||
! variation.regular_price ) && (
|
||||
<Tooltip
|
||||
// @ts-expect-error className is missing in TS, should remove this when it is included.
|
||||
className="woocommerce-attribute-list-item__actions-tooltip"
|
||||
position="top center"
|
||||
text={ NOT_VISIBLE_TEXT }
|
||||
) }
|
||||
<span
|
||||
className={ classnames(
|
||||
'woocommerce-product-variations__regular-price',
|
||||
{
|
||||
'woocommerce-product-variations__regular-price--on-sale':
|
||||
variation.on_sale,
|
||||
}
|
||||
) }
|
||||
>
|
||||
<div className="woocommerce-attribute-list-item__actions-icon-wrapper">
|
||||
<HiddenIcon className="woocommerce-attribute-list-item__actions-icon-wrapper-icon" />
|
||||
</div>
|
||||
</Tooltip>
|
||||
) }
|
||||
|
||||
{ ! areSomeSelected && (
|
||||
<>
|
||||
<Button
|
||||
href={ getEditVariationLink(
|
||||
variation
|
||||
) }
|
||||
onClick={ editVariationClickHandler(
|
||||
variation
|
||||
) }
|
||||
{ formatAmount( variation.regular_price ) }
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
className={ classnames(
|
||||
'woocommerce-product-variations__quantity',
|
||||
{
|
||||
'woocommerce-product-variations__quantity--fade':
|
||||
variation.status === 'private',
|
||||
}
|
||||
) }
|
||||
>
|
||||
{ variation.regular_price && (
|
||||
<>
|
||||
<span
|
||||
className={ classnames(
|
||||
'woocommerce-product-variations__status-dot',
|
||||
getProductStockStatusClass(
|
||||
variation
|
||||
)
|
||||
) }
|
||||
>
|
||||
●
|
||||
</span>
|
||||
{ getProductStockStatus( variation ) }
|
||||
</>
|
||||
) }
|
||||
</div>
|
||||
<div className="woocommerce-product-variations__actions">
|
||||
{ ( variation.status === 'private' ||
|
||||
! variation.regular_price ) && (
|
||||
<Tooltip
|
||||
// @ts-expect-error className is missing in TS, should remove this when it is included.
|
||||
className="woocommerce-attribute-list-item__actions-tooltip"
|
||||
position="top center"
|
||||
text={ NOT_VISIBLE_TEXT }
|
||||
>
|
||||
{ __( 'Edit', 'woocommerce' ) }
|
||||
</Button>
|
||||
<div className="woocommerce-attribute-list-item__actions-icon-wrapper">
|
||||
<HiddenIcon className="woocommerce-attribute-list-item__actions-icon-wrapper-icon" />
|
||||
</div>
|
||||
</Tooltip>
|
||||
) }
|
||||
|
||||
<VariationActionsMenu
|
||||
selection={ variation }
|
||||
onChange={ ( value ) =>
|
||||
handleVariationChange( {
|
||||
id: variation.id,
|
||||
...value,
|
||||
} )
|
||||
}
|
||||
onDelete={ ( { id } ) =>
|
||||
handleDeleteVariationClick( id )
|
||||
}
|
||||
/>
|
||||
</>
|
||||
) }
|
||||
</div>
|
||||
</ListItem>
|
||||
) ) }
|
||||
</Sortable>
|
||||
{ ! areSomeSelected && (
|
||||
<>
|
||||
<Button
|
||||
href={ getEditVariationLink(
|
||||
variation
|
||||
) }
|
||||
onClick={ editVariationClickHandler(
|
||||
variation
|
||||
) }
|
||||
>
|
||||
{ __( 'Edit', 'woocommerce' ) }
|
||||
</Button>
|
||||
|
||||
<VariationActionsMenu
|
||||
selection={ variation }
|
||||
onChange={ ( value ) =>
|
||||
handleVariationChange( {
|
||||
id: variation.id,
|
||||
...value,
|
||||
} )
|
||||
}
|
||||
onDelete={ ( { id } ) =>
|
||||
handleDeleteVariationClick( id )
|
||||
}
|
||||
/>
|
||||
</>
|
||||
) }
|
||||
</div>
|
||||
</ListItem>
|
||||
) ) }
|
||||
</Sortable>
|
||||
) }
|
||||
|
||||
{ totalCount > 5 && (
|
||||
<Pagination
|
||||
|
|
Loading…
Reference in New Issue