Add Activity Panel Outbound Link Component (https://github.com/woocommerce/woocommerce-admin/pull/213)
* Activity Panel Outbound Link * Address PR Feedback: Pass through additional props on ActivityOutboundLink, add comment for activity panel wrapping padding, fix README naming, and use $gap $gutter trick for outbound link padding.
This commit is contained in:
parent
6abcbbdc87
commit
22028283ef
|
@ -6,7 +6,7 @@ Use `Gravatar` to display a user's Gravatar.
|
||||||
## How to use:
|
## How to use:
|
||||||
|
|
||||||
```jsx
|
```jsx
|
||||||
import { Gravatar } from 'components/gravatar';
|
import Gravatar from 'components/gravatar';
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
Link
|
||||||
|
============
|
||||||
|
|
||||||
|
Use `Link` to create a link to another resource. It accepts a type to automatically create wp-admin links, wc-admin links, and external links.
|
||||||
|
|
||||||
|
## How to use:
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
import Link from 'components/link';
|
||||||
|
|
||||||
|
render: function() {
|
||||||
|
return (
|
||||||
|
<Link
|
||||||
|
href="edit.php?post_type=shop_coupon"
|
||||||
|
type="wp-admin"
|
||||||
|
>
|
||||||
|
Coupons
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Props
|
||||||
|
|
||||||
|
* `href` (required): The resource to link to.
|
||||||
|
* `type` (required): Type of link. For wp-admin and wc-admin, the correct prefix is appended. Accepts: wc-admin, wp-admin, external.
|
|
@ -13,16 +13,24 @@ import { getAdminLink } from 'lib/nav-utils';
|
||||||
|
|
||||||
class Link extends Component {
|
class Link extends Component {
|
||||||
render() {
|
render() {
|
||||||
const { children, to, wpAdmin, ...props } = this.props;
|
const { children, href, type, ...props } = this.props;
|
||||||
if ( this.context.router && ! wpAdmin ) {
|
if ( this.context.router && 'wc-admin' === type ) {
|
||||||
return (
|
return (
|
||||||
<RouterLink to={ to } { ...props }>
|
<RouterLink to={ href } { ...props }>
|
||||||
{ children }
|
{ children }
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const path = wpAdmin ? getAdminLink( to ) : getAdminLink( 'admin.php?page=wcadmin#' + to );
|
let path;
|
||||||
|
if ( 'wp-admin' === type ) {
|
||||||
|
path = getAdminLink( href );
|
||||||
|
} else if ( 'external' === type ) {
|
||||||
|
path = href;
|
||||||
|
} else {
|
||||||
|
path = getAdminLink( 'admin.php?page=wc-admin#' + href );
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<a href={ path } { ...props }>
|
<a href={ path } { ...props }>
|
||||||
{ children }
|
{ children }
|
||||||
|
@ -32,12 +40,12 @@ class Link extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
Link.propTypes = {
|
Link.propTypes = {
|
||||||
to: PropTypes.string,
|
href: PropTypes.string.isRequired,
|
||||||
wpAdmin: PropTypes.bool,
|
type: PropTypes.oneOf( [ 'wp-admin', 'wc-admin', 'external' ] ).isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
Link.defaultProps = {
|
Link.defaultProps = {
|
||||||
wpAdmin: false,
|
type: 'wc-admin',
|
||||||
};
|
};
|
||||||
|
|
||||||
Link.contextTypes = {
|
Link.contextTypes = {
|
||||||
|
|
|
@ -6,7 +6,7 @@ A component designed for use in the activity panel. It returns a title and can o
|
||||||
## How to use:
|
## How to use:
|
||||||
|
|
||||||
```jsx
|
```jsx
|
||||||
import ActivityHeader from 'components/activity-header';
|
import ActivityHeader from 'layout/activity-panel/activity-header';
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
ActivityOutboundLink
|
||||||
|
============
|
||||||
|
|
||||||
|
`ActivityOutboundLink` creates a styled link for use in the Activity Panel.
|
||||||
|
|
||||||
|
## How to use:
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
import ActivityOutboundLink from 'layout/activity-panel/activity-outbound-link';
|
||||||
|
|
||||||
|
render: function() {
|
||||||
|
return (
|
||||||
|
<ActivityOutboundLink
|
||||||
|
href="edit.php?post_type=shop_coupon"
|
||||||
|
type="wp-admin"
|
||||||
|
>
|
||||||
|
Coupons
|
||||||
|
</ActivityOutboundLink>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Props
|
||||||
|
|
||||||
|
* `href` (required): The resource to link to.
|
||||||
|
* `type` (required): Type of link. For wp-admin and wc-admin, the correct prefix is appended. Accepts: wc-admin, wp-admin, external.
|
|
@ -0,0 +1,37 @@
|
||||||
|
/** @format */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import classnames from 'classnames';
|
||||||
|
import Gridicon from 'gridicons';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import './style.scss';
|
||||||
|
import Link from 'components/link';
|
||||||
|
|
||||||
|
const ActivityOutboundLink = props => {
|
||||||
|
const { href, type, className, children, ...restOfProps } = props;
|
||||||
|
const classes = classnames( 'woocommerce-layout__activity-panel-outbound-link', className );
|
||||||
|
return (
|
||||||
|
<Link href={ href } type={ type } className={ classes } { ...restOfProps }>
|
||||||
|
{ children }
|
||||||
|
<Gridicon icon="arrow-right" />
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
ActivityOutboundLink.propTypes = {
|
||||||
|
href: PropTypes.string.isRequired,
|
||||||
|
type: PropTypes.oneOf( [ 'wp-admin', 'wc-admin', 'external' ] ).isRequired,
|
||||||
|
className: PropTypes.string,
|
||||||
|
};
|
||||||
|
|
||||||
|
ActivityOutboundLink.defaultProps = {
|
||||||
|
type: 'wp-admin',
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ActivityOutboundLink;
|
|
@ -0,0 +1,52 @@
|
||||||
|
/** @format */
|
||||||
|
|
||||||
|
.woocommerce-layout__activity-panel-outbound-link {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
height: 50px;
|
||||||
|
background: $core-grey-light-200;
|
||||||
|
border-bottom: 1px solid $core-grey-light-400;
|
||||||
|
padding: $gap $gutter;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 18px;
|
||||||
|
margin: 0;
|
||||||
|
color: $woocommerce;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
.gridicon {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: $white;
|
||||||
|
color: $woocommerce;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
background: $core-grey-light-100;
|
||||||
|
color: $woocommerce-darker;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
color: $woocommerce;
|
||||||
|
background: $core-grey-light-200;
|
||||||
|
box-shadow: inset 0 0 0 1px $box-shadow-blue, inset 0 0 0 2px #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus {
|
||||||
|
.gridicon {
|
||||||
|
display: initial;
|
||||||
|
color: $woocommerce;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
.gridicon {
|
||||||
|
display: initial;
|
||||||
|
color: $woocommerce-darker;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,6 +13,7 @@ import { noop } from 'lodash';
|
||||||
*/
|
*/
|
||||||
import ActivityCard from '../activity-card';
|
import ActivityCard from '../activity-card';
|
||||||
import ActivityHeader from '../activity-header';
|
import ActivityHeader from '../activity-header';
|
||||||
|
import ActivityOutboundLink from '../activity-outbound-link';
|
||||||
import { EllipsisMenu, MenuTitle, MenuItem } from 'components/ellipsis-menu';
|
import { EllipsisMenu, MenuTitle, MenuItem } from 'components/ellipsis-menu';
|
||||||
import { formatCurrency, getCurrencyFormatDecimal } from 'lib/currency';
|
import { formatCurrency, getCurrencyFormatDecimal } from 'lib/currency';
|
||||||
import { getOrderRefundTotal } from 'lib/order-values';
|
import { getOrderRefundTotal } from 'lib/order-values';
|
||||||
|
@ -47,18 +48,19 @@ function OrdersPanel( { orders } ) {
|
||||||
{ isLoading ? (
|
{ isLoading ? (
|
||||||
<p>Loading</p>
|
<p>Loading</p>
|
||||||
) : (
|
) : (
|
||||||
data.map( ( order, i ) => {
|
<Fragment>
|
||||||
// We want the billing address, but shipping can be used as a fallback.
|
{ data.map( ( order, i ) => {
|
||||||
const address = { ...order.shipping, ...order.billing };
|
// We want the billing address, but shipping can be used as a fallback.
|
||||||
const name = `${ address.first_name } ${ address.last_name }`;
|
const address = { ...order.shipping, ...order.billing };
|
||||||
const productsCount = order.line_items.reduce(
|
const name = `${ address.first_name } ${ address.last_name }`;
|
||||||
( total, line ) => total + line.quantity,
|
const productsCount = order.line_items.reduce(
|
||||||
0
|
( total, line ) => total + line.quantity,
|
||||||
);
|
0
|
||||||
|
);
|
||||||
|
|
||||||
const total = order.total;
|
const total = order.total;
|
||||||
const refundValue = getOrderRefundTotal( order );
|
const refundValue = getOrderRefundTotal( order );
|
||||||
const remainingTotal = getCurrencyFormatDecimal( order.total ) + refundValue;
|
const remainingTotal = getCurrencyFormatDecimal( order.total ) + refundValue;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ActivityCard
|
<ActivityCard
|
||||||
|
@ -93,8 +95,12 @@ function OrdersPanel( { orders } ) {
|
||||||
>
|
>
|
||||||
<OrderStatus order={ order } />
|
<OrderStatus order={ order } />
|
||||||
</ActivityCard>
|
</ActivityCard>
|
||||||
);
|
);
|
||||||
} )
|
} ) }
|
||||||
|
<ActivityOutboundLink href={ 'edit.php?post_type=shop_order' }>
|
||||||
|
{ __( 'Manage all orders' ) }
|
||||||
|
</ActivityOutboundLink>
|
||||||
|
</Fragment>
|
||||||
) }
|
) }
|
||||||
</Section>
|
</Section>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
|
|
|
@ -186,8 +186,14 @@
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
|
|
||||||
|
// Extra padding is needed at the bottom of the wrapper because of our positioning, height, and overflow rules. Otherwise, some content can get cut off.
|
||||||
|
padding-bottom: $gap-small * 6;
|
||||||
|
@include breakpoint( '782px-1100px' ) {
|
||||||
|
padding-bottom: $gap-small;
|
||||||
|
}
|
||||||
@include breakpoint( '>1100px' ) {
|
@include breakpoint( '>1100px' ) {
|
||||||
top: 112px;
|
top: 112px;
|
||||||
|
padding-bottom: $gap * 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@include breakpoint( '<782px' ) {
|
@include breakpoint( '<782px' ) {
|
||||||
|
|
|
@ -81,11 +81,11 @@ class Header extends Component {
|
||||||
<div className={ className }>
|
<div className={ className }>
|
||||||
<h1 className="woocommerce-layout__header-breadcrumbs">
|
<h1 className="woocommerce-layout__header-breadcrumbs">
|
||||||
<span>
|
<span>
|
||||||
<Link to="/">WooCommerce</Link>
|
<Link href="/">WooCommerce</Link>
|
||||||
</span>
|
</span>
|
||||||
{ _sections.map( ( section, i ) => {
|
{ _sections.map( ( section, i ) => {
|
||||||
const sectionPiece = isArray( section ) ? (
|
const sectionPiece = isArray( section ) ? (
|
||||||
<Link to={ section[ 0 ] } wpAdmin={ isEmbedded }>
|
<Link href={ section[ 0 ] } type={ isEmbedded ? 'wp-admin' : 'wc-admin' }>
|
||||||
{ section[ 1 ] }
|
{ section[ 1 ] }
|
||||||
</Link>
|
</Link>
|
||||||
) : (
|
) : (
|
||||||
|
|
|
@ -41,6 +41,8 @@ $valid-green: #4ab866;
|
||||||
$notice-yellow: #ffb900;
|
$notice-yellow: #ffb900;
|
||||||
$error-red: #d94f4f;
|
$error-red: #d94f4f;
|
||||||
$woocommerce: #95588a;
|
$woocommerce: #95588a;
|
||||||
|
$woocommerce-darker: #5b3453;
|
||||||
|
$box-shadow-blue: #5b9dd9;
|
||||||
$core-orange: #ca4a1f;
|
$core-orange: #ca4a1f;
|
||||||
|
|
||||||
$button: #f0f2f4;
|
$button: #f0f2f4;
|
||||||
|
|
Loading…
Reference in New Issue