Add product status badge to product form header (#35460)
* Add product status badge * Update status method to return keys * Add tests around product status * Add styling to badge * Add changelog entry * Change product status keys to enum * Add enum return type to product status function * Fix up lint errors * Convert indentation to tabs
This commit is contained in:
parent
2297787a4f
commit
7bff5cbb6b
|
@ -0,0 +1,17 @@
|
|||
.woocommerce-product-status {
|
||||
margin-left: $gap-smaller;
|
||||
padding-top: 1px;
|
||||
padding-bottom: 1px;
|
||||
color: $gray-700;
|
||||
border-color: $gray-700;
|
||||
|
||||
&.is-instock {
|
||||
color: #00a32a;
|
||||
border-color: #00a32a;
|
||||
}
|
||||
|
||||
&.is-outofstock {
|
||||
color: #cc1818;
|
||||
border-color: #cc1818;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import classnames from 'classnames';
|
||||
import { Pill } from '@woocommerce/components';
|
||||
import { PRODUCTS_STORE_NAME, WCDataSelector } from '@woocommerce/data';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { useSelect } from '@wordpress/data';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import {
|
||||
getProductStatus,
|
||||
PRODUCT_STATUS_LABELS,
|
||||
} from './utils/get-product-status';
|
||||
import './product-status-badge.scss';
|
||||
|
||||
export const ProductStatusBadge: React.FC = () => {
|
||||
const { productId } = useParams();
|
||||
const product = useSelect( ( select: WCDataSelector ) => {
|
||||
return productId
|
||||
? select( PRODUCTS_STORE_NAME ).getProduct(
|
||||
parseInt( productId, 10 ),
|
||||
undefined
|
||||
)
|
||||
: undefined;
|
||||
} );
|
||||
|
||||
const status = getProductStatus( product );
|
||||
|
||||
return (
|
||||
<Pill
|
||||
className={ classnames(
|
||||
'woocommerce-product-status',
|
||||
`is-${ status }`
|
||||
) }
|
||||
>
|
||||
{ PRODUCT_STATUS_LABELS[ status ] }
|
||||
</Pill>
|
||||
);
|
||||
};
|
|
@ -15,6 +15,7 @@ import { useSelect } from '@wordpress/data';
|
|||
* Internal dependencies
|
||||
*/
|
||||
import { getProductTitle } from './utils/get-product-title';
|
||||
import { ProductStatusBadge } from './product-status-badge';
|
||||
import { WooHeaderPageTitle } from '~/header/utils';
|
||||
|
||||
export const ProductTitle: React.FC = () => {
|
||||
|
@ -35,5 +36,10 @@ export const ProductTitle: React.FC = () => {
|
|||
|
||||
const title = getProductTitle( values.name, values.type, persistedName );
|
||||
|
||||
return <WooHeaderPageTitle>{ title }</WooHeaderPageTitle>;
|
||||
return (
|
||||
<WooHeaderPageTitle>
|
||||
{ title }
|
||||
<ProductStatusBadge />
|
||||
</WooHeaderPageTitle>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { PartialProduct } from '@woocommerce/data';
|
||||
|
||||
/**
|
||||
* Labels for product statuses.
|
||||
*/
|
||||
export enum PRODUCT_STATUS_KEYS {
|
||||
unsaved = 'unsaved',
|
||||
draft = 'draft',
|
||||
instock = 'instock',
|
||||
outofstock = 'outofstock',
|
||||
}
|
||||
|
||||
/**
|
||||
* Labels for product statuses.
|
||||
*/
|
||||
export const PRODUCT_STATUS_LABELS = {
|
||||
[ PRODUCT_STATUS_KEYS.unsaved ]: __( 'Unsaved', 'woocommerce' ),
|
||||
[ PRODUCT_STATUS_KEYS.draft ]: __( 'Draft', 'woocommerce' ),
|
||||
[ PRODUCT_STATUS_KEYS.instock ]: __( 'In stock', 'woocommerce' ),
|
||||
[ PRODUCT_STATUS_KEYS.outofstock ]: __( 'Out of stock', 'woocommerce' ),
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the product status for use in the header.
|
||||
*
|
||||
* @param product Product instance.
|
||||
* @return {PRODUCT_STATUS_KEYS} Product staus key.
|
||||
*/
|
||||
export const getProductStatus = (
|
||||
product: PartialProduct | undefined
|
||||
): PRODUCT_STATUS_KEYS => {
|
||||
if ( ! product ) {
|
||||
return PRODUCT_STATUS_KEYS.unsaved;
|
||||
}
|
||||
|
||||
if ( product.status === 'draft' ) {
|
||||
return PRODUCT_STATUS_KEYS.draft;
|
||||
}
|
||||
|
||||
if ( product.stock_status === 'instock' ) {
|
||||
return PRODUCT_STATUS_KEYS.instock;
|
||||
}
|
||||
|
||||
return PRODUCT_STATUS_KEYS.outofstock;
|
||||
};
|
|
@ -0,0 +1,38 @@
|
|||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { getProductStatus } from '../get-product-status';
|
||||
|
||||
describe( 'getProductStatus', () => {
|
||||
it( 'should return unsaved when no product exists', () => {
|
||||
const status = getProductStatus( undefined );
|
||||
expect( status ).toBe( 'unsaved' );
|
||||
} );
|
||||
|
||||
it( 'should return draft when the status is set to draft', () => {
|
||||
const status = getProductStatus( {
|
||||
id: 123,
|
||||
status: 'draft',
|
||||
stock_status: 'instock',
|
||||
} );
|
||||
expect( status ).toBe( 'draft' );
|
||||
} );
|
||||
|
||||
it( 'should return draft when the status is set to draft', () => {
|
||||
const status = getProductStatus( {
|
||||
id: 123,
|
||||
status: 'publish',
|
||||
stock_status: 'instock',
|
||||
} );
|
||||
expect( status ).toBe( 'instock' );
|
||||
} );
|
||||
|
||||
it( 'should return draft when the status is set to draft', () => {
|
||||
const status = getProductStatus( {
|
||||
id: 123,
|
||||
status: 'publish',
|
||||
stock_status: 'outofstock',
|
||||
} );
|
||||
expect( status ).toBe( 'outofstock' );
|
||||
} );
|
||||
} );
|
|
@ -0,0 +1,4 @@
|
|||
Significance: minor
|
||||
Type: add
|
||||
|
||||
Add product state badge to product form header
|
Loading…
Reference in New Issue