* 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:
Justin Shreve 2018-07-17 14:51:56 -04:00 committed by GitHub
parent 6abcbbdc87
commit 22028283ef
11 changed files with 187 additions and 24 deletions

View File

@ -6,7 +6,7 @@ Use `Gravatar` to display a user's Gravatar.
## How to use:
```jsx
import { Gravatar } from 'components/gravatar';
import Gravatar from 'components/gravatar';
render: function() {
return (

View File

@ -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.

View File

@ -13,16 +13,24 @@ import { getAdminLink } from 'lib/nav-utils';
class Link extends Component {
render() {
const { children, to, wpAdmin, ...props } = this.props;
if ( this.context.router && ! wpAdmin ) {
const { children, href, type, ...props } = this.props;
if ( this.context.router && 'wc-admin' === type ) {
return (
<RouterLink to={ to } { ...props }>
<RouterLink to={ href } { ...props }>
{ children }
</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 (
<a href={ path } { ...props }>
{ children }
@ -32,12 +40,12 @@ class Link extends Component {
}
Link.propTypes = {
to: PropTypes.string,
wpAdmin: PropTypes.bool,
href: PropTypes.string.isRequired,
type: PropTypes.oneOf( [ 'wp-admin', 'wc-admin', 'external' ] ).isRequired,
};
Link.defaultProps = {
wpAdmin: false,
type: 'wc-admin',
};
Link.contextTypes = {

View File

@ -6,7 +6,7 @@ A component designed for use in the activity panel. It returns a title and can o
## How to use:
```jsx
import ActivityHeader from 'components/activity-header';
import ActivityHeader from 'layout/activity-panel/activity-header';
render: function() {
return (

View File

@ -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.

View File

@ -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;

View File

@ -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;
}
}
}

View File

@ -13,6 +13,7 @@ import { noop } from 'lodash';
*/
import ActivityCard from '../activity-card';
import ActivityHeader from '../activity-header';
import ActivityOutboundLink from '../activity-outbound-link';
import { EllipsisMenu, MenuTitle, MenuItem } from 'components/ellipsis-menu';
import { formatCurrency, getCurrencyFormatDecimal } from 'lib/currency';
import { getOrderRefundTotal } from 'lib/order-values';
@ -47,18 +48,19 @@ function OrdersPanel( { orders } ) {
{ isLoading ? (
<p>Loading</p>
) : (
data.map( ( order, i ) => {
// We want the billing address, but shipping can be used as a fallback.
const address = { ...order.shipping, ...order.billing };
const name = `${ address.first_name } ${ address.last_name }`;
const productsCount = order.line_items.reduce(
( total, line ) => total + line.quantity,
0
);
<Fragment>
{ data.map( ( order, i ) => {
// We want the billing address, but shipping can be used as a fallback.
const address = { ...order.shipping, ...order.billing };
const name = `${ address.first_name } ${ address.last_name }`;
const productsCount = order.line_items.reduce(
( total, line ) => total + line.quantity,
0
);
const total = order.total;
const refundValue = getOrderRefundTotal( order );
const remainingTotal = getCurrencyFormatDecimal( order.total ) + refundValue;
const total = order.total;
const refundValue = getOrderRefundTotal( order );
const remainingTotal = getCurrencyFormatDecimal( order.total ) + refundValue;
return (
<ActivityCard
@ -93,8 +95,12 @@ function OrdersPanel( { orders } ) {
>
<OrderStatus order={ order } />
</ActivityCard>
);
} )
);
} ) }
<ActivityOutboundLink href={ 'edit.php?post_type=shop_order' }>
{ __( 'Manage all orders' ) }
</ActivityOutboundLink>
</Fragment>
) }
</Section>
</Fragment>

View File

@ -186,8 +186,14 @@
overflow-x: hidden;
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' ) {
top: 112px;
padding-bottom: $gap * 2;
}
@include breakpoint( '<782px' ) {

View File

@ -81,11 +81,11 @@ class Header extends Component {
<div className={ className }>
<h1 className="woocommerce-layout__header-breadcrumbs">
<span>
<Link to="/">WooCommerce</Link>
<Link href="/">WooCommerce</Link>
</span>
{ _sections.map( ( section, i ) => {
const sectionPiece = isArray( section ) ? (
<Link to={ section[ 0 ] } wpAdmin={ isEmbedded }>
<Link href={ section[ 0 ] } type={ isEmbedded ? 'wp-admin' : 'wc-admin' }>
{ section[ 1 ] }
</Link>
) : (

View File

@ -41,6 +41,8 @@ $valid-green: #4ab866;
$notice-yellow: #ffb900;
$error-red: #d94f4f;
$woocommerce: #95588a;
$woocommerce-darker: #5b3453;
$box-shadow-blue: #5b9dd9;
$core-orange: #ca4a1f;
$button: #f0f2f4;