Components: Export reusable components to a separate file + global (https://github.com/woocommerce/woocommerce-admin/pull/297)
* Importing all components from a root components file * Update Ratings component to avoid circular dependencies, fix tests * Export components on `wc.components`, use this for importing * Move react-dates initialize to the components file * Push query changes to history Fixes an issues where native a links do not update the query in `history` * Update test config for new @woocommerce/components path * Update chart components import * Merge simple/complex & alphabetize by first exported name * Add a readme with info about how to call these components
This commit is contained in:
parent
11524e19e1
commit
dec97d178e
|
@ -9,7 +9,7 @@ import { Component, Fragment } from '@wordpress/element';
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
import Header from 'layout/header';
|
import Header from 'layout/header';
|
||||||
import { SummaryList, SummaryNumber } from 'components/summary';
|
import { SummaryList, SummaryNumber } from '@woocommerce/components';
|
||||||
|
|
||||||
export default class extends Component {
|
export default class extends Component {
|
||||||
render() {
|
render() {
|
||||||
|
|
|
@ -13,10 +13,9 @@ import { partial } from 'lodash';
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
import Card from 'components/card';
|
import { Card, ReportFilters } from '@woocommerce/components';
|
||||||
import { filters, filterPaths, advancedFilterConfig } from './constants';
|
import { filters, filterPaths, advancedFilterConfig } from './constants';
|
||||||
import Header from 'layout/header/index';
|
import Header from 'layout/header/index';
|
||||||
import { ReportFilters } from 'components/filters';
|
|
||||||
import './style.scss';
|
import './style.scss';
|
||||||
|
|
||||||
class OrdersReport extends Component {
|
class OrdersReport extends Component {
|
||||||
|
|
|
@ -10,7 +10,7 @@ import { Component, Fragment } from '@wordpress/element';
|
||||||
*/
|
*/
|
||||||
import { filterPaths, filters } from './constants';
|
import { filterPaths, filters } from './constants';
|
||||||
import Header from 'layout/header';
|
import Header from 'layout/header';
|
||||||
import { ReportFilters } from 'components/filters';
|
import { ReportFilters } from '@woocommerce/components';
|
||||||
import './style.scss';
|
import './style.scss';
|
||||||
|
|
||||||
export default class extends Component {
|
export default class extends Component {
|
||||||
|
|
|
@ -11,15 +11,18 @@ import PropTypes from 'prop-types';
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
import Card from 'components/card';
|
import {
|
||||||
import Chart from 'components/chart';
|
Card,
|
||||||
|
Chart,
|
||||||
|
ReportFilters,
|
||||||
|
SummaryList,
|
||||||
|
SummaryNumber,
|
||||||
|
TableCard,
|
||||||
|
} from '@woocommerce/components';
|
||||||
import { formatCurrency, getCurrencyFormatDecimal } from 'lib/currency';
|
import { formatCurrency, getCurrencyFormatDecimal } from 'lib/currency';
|
||||||
import { getAdminLink, updateQueryString } from 'lib/nav-utils';
|
import { getAdminLink, updateQueryString } from 'lib/nav-utils';
|
||||||
import { getReportData } from 'lib/swagger';
|
import { getReportData } from 'lib/swagger';
|
||||||
import Header from 'layout/header';
|
import Header from 'layout/header';
|
||||||
import { ReportFilters } from 'components/filters';
|
|
||||||
import { SummaryList, SummaryNumber } from 'components/summary';
|
|
||||||
import { TableCard } from 'components/table';
|
|
||||||
|
|
||||||
// Mock data until we fetch from an API
|
// Mock data until we fetch from an API
|
||||||
import rawData from './mock-data';
|
import rawData from './mock-data';
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
Components
|
||||||
|
==========
|
||||||
|
|
||||||
|
This folder contains the WooCommerce-created components. These are exported onto a global, `wc.components`, for general use.
|
||||||
|
|
||||||
|
## How to use:
|
||||||
|
|
||||||
|
For any files not imported into `components/index.js` (`analytics/*`, `layout/*`, `dashboard/*`, etc), we can use `import { Card, etc … } from @woocommerce/components`.
|
||||||
|
|
||||||
|
For any `component/*` files, we should import from component-specific paths, not from `component/index.js`, to prevent circular dependencies. See `components/card/index.js` for an example.
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
import { Card, Link } from '@woocommerce/components';
|
||||||
|
|
||||||
|
render: function() {
|
||||||
|
return (
|
||||||
|
<Card title="Card demo">
|
||||||
|
Card content with an <Link href="/">example link.</Link>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## For external development
|
||||||
|
|
||||||
|
External developers will need to enqueue the components library, `wc-components`, and then can access them from the global.
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
const { Card, Link } = wc.components;
|
||||||
|
|
||||||
|
render: function() {
|
||||||
|
return (
|
||||||
|
<Card title="Card demo">
|
||||||
|
Card content with an <Link href="/">example link.</Link>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
|
@ -10,7 +10,7 @@ import PropTypes from 'prop-types';
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
import './style.scss';
|
import './style.scss';
|
||||||
import { EllipsisMenu } from '../ellipsis-menu';
|
import { EllipsisMenu } from 'components/ellipsis-menu';
|
||||||
import { H, Section } from 'layout/section';
|
import { H, Section } from 'layout/section';
|
||||||
|
|
||||||
class Card extends Component {
|
class Card extends Component {
|
||||||
|
|
|
@ -9,7 +9,7 @@ import { Component, Fragment } from '@wordpress/element';
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
import Card from 'components/card';
|
import Card from 'components/card';
|
||||||
import Chart from 'components/chart';
|
import Chart from './index';
|
||||||
import dummyOrders from './test/fixtures/dummy';
|
import dummyOrders from './test/fixtures/dummy';
|
||||||
|
|
||||||
class WidgetCharts extends Component {
|
class WidgetCharts extends Component {
|
||||||
|
|
|
@ -14,7 +14,6 @@ import classnames from 'classnames';
|
||||||
import ComparePeriods from './compare-periods';
|
import ComparePeriods from './compare-periods';
|
||||||
import { DateRange } from 'components/calendar';
|
import { DateRange } from 'components/calendar';
|
||||||
import { H, Section } from 'layout/section';
|
import { H, Section } from 'layout/section';
|
||||||
import Link from 'components/link';
|
|
||||||
import PresetPeriods from './preset-periods';
|
import PresetPeriods from './preset-periods';
|
||||||
|
|
||||||
const isMobileViewport = () => window.innerWidth < 782;
|
const isMobileViewport = () => window.innerWidth < 782;
|
||||||
|
@ -45,7 +44,7 @@ class DatePickerContent extends Component {
|
||||||
before,
|
before,
|
||||||
onUpdate,
|
onUpdate,
|
||||||
onClose,
|
onClose,
|
||||||
getUpdatePath,
|
onSelect,
|
||||||
isValidSelection,
|
isValidSelection,
|
||||||
resetCustomValues,
|
resetCustomValues,
|
||||||
focusedInput,
|
focusedInput,
|
||||||
|
@ -127,13 +126,13 @@ class DatePickerContent extends Component {
|
||||||
</Button>
|
</Button>
|
||||||
) }
|
) }
|
||||||
{ isValidSelection( selectedTab ) ? (
|
{ isValidSelection( selectedTab ) ? (
|
||||||
<Link
|
<Button
|
||||||
className="woocommerce-filters-date__button components-button is-button is-primary"
|
className="woocommerce-filters-date__button"
|
||||||
href={ getUpdatePath( selectedTab ) }
|
onClick={ onSelect( selectedTab, onClose ) }
|
||||||
onClick={ onClose }
|
isPrimary
|
||||||
>
|
>
|
||||||
{ __( 'Update', 'wc-admin' ) }
|
{ __( 'Update', 'wc-admin' ) }
|
||||||
</Link>
|
</Button>
|
||||||
) : (
|
) : (
|
||||||
<Button className="woocommerce-filters-date__button" isPrimary disabled>
|
<Button className="woocommerce-filters-date__button" isPrimary disabled>
|
||||||
{ __( 'Update', 'wc-admin' ) }
|
{ __( 'Update', 'wc-admin' ) }
|
||||||
|
@ -155,7 +154,7 @@ DatePickerContent.propTypes = {
|
||||||
compare: PropTypes.string.isRequired,
|
compare: PropTypes.string.isRequired,
|
||||||
onUpdate: PropTypes.func.isRequired,
|
onUpdate: PropTypes.func.isRequired,
|
||||||
onClose: PropTypes.func.isRequired,
|
onClose: PropTypes.func.isRequired,
|
||||||
getUpdatePath: PropTypes.func.isRequired,
|
onSelect: PropTypes.func.isRequired,
|
||||||
resetCustomValues: PropTypes.func.isRequired,
|
resetCustomValues: PropTypes.func.isRequired,
|
||||||
focusedInput: PropTypes.string,
|
focusedInput: PropTypes.string,
|
||||||
afterText: PropTypes.string,
|
afterText: PropTypes.string,
|
||||||
|
|
|
@ -12,7 +12,7 @@ import { Dropdown } from '@wordpress/components';
|
||||||
import DatePickerContent from './content';
|
import DatePickerContent from './content';
|
||||||
import DropdownButton from 'components/dropdown-button';
|
import DropdownButton from 'components/dropdown-button';
|
||||||
import { getCurrentDates, getDateParamsFromQuery, isoDateFormat } from 'lib/date';
|
import { getCurrentDates, getDateParamsFromQuery, isoDateFormat } from 'lib/date';
|
||||||
import { getNewPath, getQuery } from 'lib/nav-utils';
|
import { getQuery, updateQueryString } from 'lib/nav-utils';
|
||||||
import './style.scss';
|
import './style.scss';
|
||||||
|
|
||||||
const shortDateFormat = __( 'MM/DD/YYYY', 'wc-admin' );
|
const shortDateFormat = __( 'MM/DD/YYYY', 'wc-admin' );
|
||||||
|
@ -23,7 +23,7 @@ class DatePicker extends Component {
|
||||||
this.state = this.getResetState();
|
this.state = this.getResetState();
|
||||||
|
|
||||||
this.update = this.update.bind( this );
|
this.update = this.update.bind( this );
|
||||||
this.getUpdatePath = this.getUpdatePath.bind( this );
|
this.onSelect = this.onSelect.bind( this );
|
||||||
this.isValidSelection = this.isValidSelection.bind( this );
|
this.isValidSelection = this.isValidSelection.bind( this );
|
||||||
this.resetCustomValues = this.resetCustomValues.bind( this );
|
this.resetCustomValues = this.resetCustomValues.bind( this );
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,8 @@ class DatePicker extends Component {
|
||||||
this.setState( update );
|
this.setState( update );
|
||||||
}
|
}
|
||||||
|
|
||||||
getUpdatePath( selectedTab ) {
|
onSelect( selectedTab, onClose ) {
|
||||||
|
return event => {
|
||||||
const { period, compare, after, before } = this.state;
|
const { period, compare, after, before } = this.state;
|
||||||
const data = {
|
const data = {
|
||||||
period: 'custom' === selectedTab ? 'custom' : period,
|
period: 'custom' === selectedTab ? 'custom' : period,
|
||||||
|
@ -57,7 +58,9 @@ class DatePicker extends Component {
|
||||||
data.after = after ? after.format( isoDateFormat ) : '';
|
data.after = after ? after.format( isoDateFormat ) : '';
|
||||||
data.before = before ? before.format( isoDateFormat ) : '';
|
data.before = before ? before.format( isoDateFormat ) : '';
|
||||||
}
|
}
|
||||||
return getNewPath( data );
|
updateQueryString( data );
|
||||||
|
onClose( event );
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
getButtonLabel() {
|
getButtonLabel() {
|
||||||
|
@ -122,7 +125,7 @@ class DatePicker extends Component {
|
||||||
before={ before }
|
before={ before }
|
||||||
onUpdate={ this.update }
|
onUpdate={ this.update }
|
||||||
onClose={ onClose }
|
onClose={ onClose }
|
||||||
getUpdatePath={ this.getUpdatePath }
|
onSelect={ this.onSelect }
|
||||||
isValidSelection={ this.isValidSelection }
|
isValidSelection={ this.isValidSelection }
|
||||||
resetCustomValues={ this.resetCustomValues }
|
resetCustomValues={ this.resetCustomValues }
|
||||||
focusedInput={ focusedInput }
|
focusedInput={ focusedInput }
|
||||||
|
|
|
@ -14,8 +14,7 @@ import PropTypes from 'prop-types';
|
||||||
*/
|
*/
|
||||||
import AnimationSlider from 'components/animation-slider';
|
import AnimationSlider from 'components/animation-slider';
|
||||||
import DropdownButton from 'components/dropdown-button';
|
import DropdownButton from 'components/dropdown-button';
|
||||||
import { getNewPath, getQuery } from 'lib/nav-utils';
|
import { getQuery, updateQueryString } from 'lib/nav-utils';
|
||||||
import Link from 'components/link';
|
|
||||||
import './style.scss';
|
import './style.scss';
|
||||||
|
|
||||||
export const DEFAULT_FILTER = 'all';
|
export const DEFAULT_FILTER = 'all';
|
||||||
|
@ -30,7 +29,6 @@ class FilterPicker extends Component {
|
||||||
animate: null,
|
animate: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.getSelectionPath = this.getSelectionPath.bind( this );
|
|
||||||
this.getSelectedFilter = this.getSelectedFilter.bind( this );
|
this.getSelectedFilter = this.getSelectedFilter.bind( this );
|
||||||
this.selectSubFilters = this.selectSubFilters.bind( this );
|
this.selectSubFilters = this.selectSubFilters.bind( this );
|
||||||
this.getVisibleFilters = this.getVisibleFilters.bind( this );
|
this.getVisibleFilters = this.getVisibleFilters.bind( this );
|
||||||
|
@ -42,10 +40,6 @@ class FilterPicker extends Component {
|
||||||
return query.filter || DEFAULT_FILTER;
|
return query.filter || DEFAULT_FILTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
getSelectionPath( filter ) {
|
|
||||||
return getNewPath( { filter: filter.value } );
|
|
||||||
}
|
|
||||||
|
|
||||||
getSelectedFilter() {
|
getSelectedFilter() {
|
||||||
const { filters, filterPaths } = this.props;
|
const { filters, filterPaths } = this.props;
|
||||||
const value = this.getFilterValue();
|
const value = this.getFilterValue();
|
||||||
|
@ -111,14 +105,15 @@ class FilterPicker extends Component {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const onClick = event => {
|
||||||
|
onClose( event );
|
||||||
|
updateQueryString( { filter: filter.value } );
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Link
|
<Button className="woocommerce-filters-filter__button" onClick={ onClick }>
|
||||||
className="woocommerce-filters-filter__button components-button"
|
|
||||||
href={ this.getSelectionPath( filter ) }
|
|
||||||
onClick={ onClose }
|
|
||||||
>
|
|
||||||
{ filter.label }
|
{ filter.label }
|
||||||
</Link>
|
</Button>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
/** @format */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* External Dependencies
|
||||||
|
*/
|
||||||
|
// Turn on react-dates classes/styles, see https://github.com/airbnb/react-dates#initialize
|
||||||
|
import 'react-dates/initialize';
|
||||||
|
|
||||||
|
export { AdvancedFilters, DatePicker, FilterPicker, ReportFilters } from './filters';
|
||||||
|
export { default as AnimationSlider } from './animation-slider';
|
||||||
|
export { default as Card } from './card';
|
||||||
|
export { default as Chart } from './chart';
|
||||||
|
export { default as Count } from './count';
|
||||||
|
export { DateRange } from './calendar';
|
||||||
|
export { default as DropdownButton } from './dropdown-button';
|
||||||
|
export { EllipsisMenu, MenuItem, MenuTitle } from './ellipsis-menu';
|
||||||
|
export { default as Flag } from './flag';
|
||||||
|
export { default as Gravatar } from './gravatar';
|
||||||
|
export { default as Link } from './link';
|
||||||
|
export { default as OrderStatus } from './order-status';
|
||||||
|
export { default as Pagination } from './pagination';
|
||||||
|
export { default as ProductImage } from './product-image';
|
||||||
|
export { default as ProductRating } from './rating/product';
|
||||||
|
export { default as Rating } from './rating';
|
||||||
|
export { default as ReviewRating } from './rating/review';
|
||||||
|
export { default as SegmentedSelection } from './segmented-selection';
|
||||||
|
export { default as SplitButton } from './split-button';
|
||||||
|
export { SummaryList, SummaryNumber } from './summary';
|
||||||
|
export { TableCard, Table, TableSummary } from './table';
|
||||||
|
export { default as useFilters } from './higher-order/use-filters';
|
|
@ -64,6 +64,4 @@ Rating.defaultProps = {
|
||||||
size: 18,
|
size: 18,
|
||||||
};
|
};
|
||||||
|
|
||||||
export { Rating };
|
export default Rating;
|
||||||
export { default as ProductRating } from './product';
|
|
||||||
export { default as ReviewRating } from './review';
|
|
||||||
|
|
|
@ -3,21 +3,17 @@
|
||||||
/**
|
/**
|
||||||
* External dependencies
|
* External dependencies
|
||||||
*/
|
*/
|
||||||
import { Component } from '@wordpress/element';
|
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
import { Rating } from './index';
|
import Rating from './index';
|
||||||
|
|
||||||
class ProductRating extends Component {
|
const ProductRating = ( { product, ...props } ) => {
|
||||||
render() {
|
|
||||||
const { product, restOfProps } = this.props;
|
|
||||||
const rating = ( product && product.average_rating ) || 0;
|
const rating = ( product && product.average_rating ) || 0;
|
||||||
return <Rating rating={ rating } { ...restOfProps } />;
|
return <Rating rating={ rating } { ...props } />;
|
||||||
}
|
};
|
||||||
}
|
|
||||||
|
|
||||||
ProductRating.propTypes = {
|
ProductRating.propTypes = {
|
||||||
product: PropTypes.object.isRequired,
|
product: PropTypes.object.isRequired,
|
||||||
|
|
|
@ -3,21 +3,17 @@
|
||||||
/**
|
/**
|
||||||
* External dependencies
|
* External dependencies
|
||||||
*/
|
*/
|
||||||
import { Component } from '@wordpress/element';
|
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
import { Rating } from './index';
|
import Rating from './index';
|
||||||
|
|
||||||
class ReviewRating extends Component {
|
const ReviewRating = ( { review, ...props } ) => {
|
||||||
render() {
|
|
||||||
const { review, restOfProps } = this.props;
|
|
||||||
const rating = ( review && review.rating ) || 0;
|
const rating = ( review && review.rating ) || 0;
|
||||||
return <Rating rating={ rating } { ...restOfProps } />;
|
return <Rating rating={ rating } { ...props } />;
|
||||||
}
|
};
|
||||||
}
|
|
||||||
|
|
||||||
ReviewRating.propTypes = {
|
ReviewRating.propTypes = {
|
||||||
review: PropTypes.object.isRequired,
|
review: PropTypes.object.isRequired,
|
||||||
|
|
|
@ -7,7 +7,9 @@ import { shallow } from 'enzyme';
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
import { ReviewRating, ProductRating, Rating } from '../';
|
import Rating from '../';
|
||||||
|
import ProductRating from '../product';
|
||||||
|
import ReviewRating from '../review';
|
||||||
|
|
||||||
describe( 'Rating', () => {
|
describe( 'Rating', () => {
|
||||||
test( 'should render the passed rating prop', () => {
|
test( 'should render the passed rating prop', () => {
|
||||||
|
@ -28,28 +30,22 @@ describe( 'Rating', () => {
|
||||||
|
|
||||||
describe( 'ReviewRating', () => {
|
describe( 'ReviewRating', () => {
|
||||||
test( 'should render rating based on review object', () => {
|
test( 'should render rating based on review object', () => {
|
||||||
const rating = shallow(
|
const review = {
|
||||||
<ReviewRating
|
|
||||||
review={ {
|
|
||||||
review: 'Nice T-shirt!',
|
review: 'Nice T-shirt!',
|
||||||
rating: 1.5,
|
rating: 1.5,
|
||||||
} }
|
};
|
||||||
/>
|
const rating = shallow( <ReviewRating review={ review } /> );
|
||||||
);
|
|
||||||
expect( rating ).toMatchSnapshot();
|
expect( rating ).toMatchSnapshot();
|
||||||
} );
|
} );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
describe( 'ProductRating', () => {
|
describe( 'ProductRating', () => {
|
||||||
test( 'should render rating based on product object', () => {
|
test( 'should render rating based on product object', () => {
|
||||||
const rating = shallow(
|
const product = {
|
||||||
<ProductRating
|
|
||||||
product={ {
|
|
||||||
name: 'Test Product',
|
name: 'Test Product',
|
||||||
average_rating: 2.5,
|
average_rating: 2.5,
|
||||||
} }
|
};
|
||||||
/>
|
const rating = shallow( <ProductRating product={ product } /> );
|
||||||
);
|
|
||||||
expect( rating ).toMatchSnapshot();
|
expect( rating ).toMatchSnapshot();
|
||||||
} );
|
} );
|
||||||
} );
|
} );
|
||||||
|
|
|
@ -9,11 +9,11 @@ import { Component, Fragment } from '@wordpress/element';
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
import './style.scss';
|
import './style.scss';
|
||||||
|
import { Card } from '@woocommerce/components';
|
||||||
|
import ChartExample from 'components/chart/example';
|
||||||
import Header from 'layout/header';
|
import Header from 'layout/header';
|
||||||
import StorePerformance from './store-performance';
|
import StorePerformance from './store-performance';
|
||||||
import TopSellingProducts from './top-selling-products';
|
import TopSellingProducts from './top-selling-products';
|
||||||
import Chart from 'components/chart/example';
|
|
||||||
import Card from 'components/card';
|
|
||||||
|
|
||||||
export default class Dashboard extends Component {
|
export default class Dashboard extends Component {
|
||||||
render() {
|
render() {
|
||||||
|
@ -21,7 +21,7 @@ export default class Dashboard extends Component {
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<Header sections={ [ __( 'Dashboard', 'wc-admin' ) ] } />
|
<Header sections={ [ __( 'Dashboard', 'wc-admin' ) ] } />
|
||||||
<StorePerformance />
|
<StorePerformance />
|
||||||
<Chart />
|
<ChartExample />
|
||||||
<div className="woocommerce-dashboard__columns">
|
<div className="woocommerce-dashboard__columns">
|
||||||
<div>
|
<div>
|
||||||
<TopSellingProducts />
|
<TopSellingProducts />
|
||||||
|
|
|
@ -9,9 +9,14 @@ import { Component } from '@wordpress/element';
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
import Card from 'components/card';
|
import {
|
||||||
import { EllipsisMenu, MenuItem, MenuTitle } from 'components/ellipsis-menu';
|
Card,
|
||||||
import { SummaryList, SummaryNumber } from 'components/summary';
|
EllipsisMenu,
|
||||||
|
MenuItem,
|
||||||
|
MenuTitle,
|
||||||
|
SummaryList,
|
||||||
|
SummaryNumber,
|
||||||
|
} from '@woocommerce/components';
|
||||||
import './style.scss';
|
import './style.scss';
|
||||||
|
|
||||||
class StorePerformance extends Component {
|
class StorePerformance extends Component {
|
||||||
|
|
|
@ -9,11 +9,10 @@ import { map } from 'lodash';
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
import Card from 'components/card';
|
import { Card, Table } from '@woocommerce/components';
|
||||||
import { getAdminLink } from 'lib/nav-utils';
|
import { getAdminLink } from 'lib/nav-utils';
|
||||||
import { numberFormat } from 'lib/number';
|
import { numberFormat } from 'lib/number';
|
||||||
import { formatCurrency, getCurrencyFormatDecimal } from 'lib/currency';
|
import { formatCurrency, getCurrencyFormatDecimal } from 'lib/currency';
|
||||||
import { Table } from 'components/table';
|
|
||||||
import './style.scss';
|
import './style.scss';
|
||||||
|
|
||||||
// Mock data until we fetch from an API
|
// Mock data until we fetch from an API
|
||||||
|
|
|
@ -6,7 +6,6 @@ import { APIProvider } from '@wordpress/components';
|
||||||
import { pick } from 'lodash';
|
import { pick } from 'lodash';
|
||||||
import { render } from '@wordpress/element';
|
import { render } from '@wordpress/element';
|
||||||
import { Provider as SlotFillProvider } from 'react-slot-fill';
|
import { Provider as SlotFillProvider } from 'react-slot-fill';
|
||||||
import 'react-dates/initialize';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
|
|
|
@ -10,7 +10,7 @@ import { shallow } from 'enzyme';
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
import { ActivityCard } from '../';
|
import { ActivityCard } from '../';
|
||||||
import Gravatar from 'components/gravatar';
|
import { Gravatar } from '@woocommerce/components';
|
||||||
|
|
||||||
describe( 'ActivityCard', () => {
|
describe( 'ActivityCard', () => {
|
||||||
test( 'should have correct title', () => {
|
test( 'should have correct title', () => {
|
||||||
|
|
|
@ -10,7 +10,7 @@ import PropTypes from 'prop-types';
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
import './style.scss';
|
import './style.scss';
|
||||||
import { EllipsisMenu } from 'components/ellipsis-menu';
|
import { EllipsisMenu } from '@woocommerce/components';
|
||||||
import { H } from 'layout/section';
|
import { H } from 'layout/section';
|
||||||
|
|
||||||
class ActivityHeader extends Component {
|
class ActivityHeader extends Component {
|
||||||
|
|
|
@ -11,7 +11,7 @@ import Gridicon from 'gridicons';
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
import './style.scss';
|
import './style.scss';
|
||||||
import Link from 'components/link';
|
import { Link } from '@woocommerce/components';
|
||||||
|
|
||||||
const ActivityOutboundLink = props => {
|
const ActivityOutboundLink = props => {
|
||||||
const { href, type, className, children, ...restOfProps } = props;
|
const { href, type, className, children, ...restOfProps } = props;
|
||||||
|
|
|
@ -14,12 +14,16 @@ 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 ActivityOutboundLink from '../activity-outbound-link';
|
||||||
import { EllipsisMenu, MenuTitle, MenuItem } from 'components/ellipsis-menu';
|
import {
|
||||||
|
EllipsisMenu,
|
||||||
|
Gravatar,
|
||||||
|
Flag,
|
||||||
|
MenuTitle,
|
||||||
|
MenuItem,
|
||||||
|
OrderStatus,
|
||||||
|
} from '@woocommerce/components';
|
||||||
import { formatCurrency, getCurrencyFormatDecimal } from 'lib/currency';
|
import { formatCurrency, getCurrencyFormatDecimal } from 'lib/currency';
|
||||||
import { getOrderRefundTotal } from 'lib/order-values';
|
import { getOrderRefundTotal } from 'lib/order-values';
|
||||||
import Gravatar from 'components/gravatar';
|
|
||||||
import Flag from 'components/flag';
|
|
||||||
import OrderStatus from 'components/order-status';
|
|
||||||
import { Section } from 'layout/section';
|
import { Section } from 'layout/section';
|
||||||
|
|
||||||
function OrdersPanel( { orders } ) {
|
function OrdersPanel( { orders } ) {
|
||||||
|
|
|
@ -13,12 +13,8 @@ import { noop } from 'lodash';
|
||||||
*/
|
*/
|
||||||
import { ActivityCard, ActivityCardPlaceholder } from '../activity-card';
|
import { ActivityCard, ActivityCardPlaceholder } from '../activity-card';
|
||||||
import ActivityHeader from '../activity-header';
|
import ActivityHeader from '../activity-header';
|
||||||
import Gravatar from 'components/gravatar';
|
import { Gravatar, Link, ProductImage, ReviewRating, SplitButton } from '@woocommerce/components';
|
||||||
import Link from 'components/link';
|
|
||||||
import ProductImage from 'components/product-image';
|
|
||||||
import { ReviewRating } from 'components/rating';
|
|
||||||
import { Section } from 'layout/section';
|
import { Section } from 'layout/section';
|
||||||
import SplitButton from 'components/split-button';
|
|
||||||
|
|
||||||
// TODO Pull proper data from the API
|
// TODO Pull proper data from the API
|
||||||
const demoReviews = [
|
const demoReviews = [
|
||||||
|
|
|
@ -8,7 +8,6 @@ import classnames from 'classnames';
|
||||||
import { decodeEntities } from '@wordpress/html-entities';
|
import { decodeEntities } from '@wordpress/html-entities';
|
||||||
import { Fill } from 'react-slot-fill';
|
import { Fill } from 'react-slot-fill';
|
||||||
import { isArray } from 'lodash';
|
import { isArray } from 'lodash';
|
||||||
import Link from 'components/link';
|
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import ReactDom from 'react-dom';
|
import ReactDom from 'react-dom';
|
||||||
|
|
||||||
|
@ -17,6 +16,7 @@ import ReactDom from 'react-dom';
|
||||||
*/
|
*/
|
||||||
import './style.scss';
|
import './style.scss';
|
||||||
import ActivityPanel from '../activity-panel';
|
import ActivityPanel from '../activity-panel';
|
||||||
|
import { Link } from '@woocommerce/components';
|
||||||
|
|
||||||
class Header extends Component {
|
class Header extends Component {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
|
|
@ -1,4 +1,10 @@
|
||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* Register javascript & css files.
|
||||||
|
*
|
||||||
|
* @package WC_Admin
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers the JS & CSS for the admin and admin embed
|
* Registers the JS & CSS for the admin and admin embed
|
||||||
*/
|
*/
|
||||||
|
@ -14,10 +20,25 @@ function wc_admin_register_script() {
|
||||||
$css_entry = 'dist/css/index.css';
|
$css_entry = 'dist/css/index.css';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wp_register_script(
|
||||||
|
'wc-components',
|
||||||
|
wc_admin_url( 'dist/components.js' ),
|
||||||
|
[ 'wp-components', 'wp-data', 'wp-element', 'wp-hooks', 'wp-i18n', 'wp-keycodes' ],
|
||||||
|
filemtime( wc_admin_dir_path( 'dist/components.js' ) ),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
wp_register_style(
|
||||||
|
'wc-components',
|
||||||
|
wc_admin_url( 'dist/css/components.css' ),
|
||||||
|
[ 'wp-edit-blocks' ],
|
||||||
|
filemtime( wc_admin_dir_path( 'dist/css/components.css' ) )
|
||||||
|
);
|
||||||
|
|
||||||
wp_register_script(
|
wp_register_script(
|
||||||
WC_ADMIN_APP,
|
WC_ADMIN_APP,
|
||||||
wc_admin_url( $js_entry ),
|
wc_admin_url( $js_entry ),
|
||||||
[ 'wp-blocks', 'wp-components', 'wp-date', 'wp-element', 'wp-hooks', 'wp-html-entities', 'wp-i18n', 'wp-keycodes' ],
|
[ 'wc-components', 'wp-date', 'wp-html-entities', 'wp-keycodes' ],
|
||||||
filemtime( wc_admin_dir_path( $js_entry ) ),
|
filemtime( wc_admin_dir_path( $js_entry ) ),
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
@ -25,18 +46,18 @@ function wc_admin_register_script() {
|
||||||
wp_register_style(
|
wp_register_style(
|
||||||
WC_ADMIN_APP,
|
WC_ADMIN_APP,
|
||||||
wc_admin_url( $css_entry ),
|
wc_admin_url( $css_entry ),
|
||||||
[ 'wp-edit-blocks' ],
|
[ 'wc-components' ],
|
||||||
filemtime( wc_admin_dir_path( $css_entry ) )
|
filemtime( wc_admin_dir_path( $css_entry ) )
|
||||||
);
|
);
|
||||||
|
|
||||||
// Set up the text domain and translations
|
// Set up the text domain and translations.
|
||||||
$locale_data = gutenberg_get_jed_locale_data( 'wc-admin' );
|
$locale_data = gutenberg_get_jed_locale_data( 'wc-admin' );
|
||||||
$content = 'wp.i18n.setLocaleData( ' . json_encode( $locale_data ) . ', "wc-admin" );';
|
$content = 'wp.i18n.setLocaleData( ' . json_encode( $locale_data ) . ', "wc-admin" );';
|
||||||
wp_add_inline_script( WC_ADMIN_APP, $content, 'before' );
|
wp_add_inline_script( 'wc-components', $content, 'before' );
|
||||||
|
|
||||||
wp_enqueue_script( 'wp-api' );
|
wp_enqueue_script( 'wp-api' );
|
||||||
|
|
||||||
// Settings and variables can be passed here for access in the app
|
// Settings and variables can be passed here for access in the app.
|
||||||
$settings = array(
|
$settings = array(
|
||||||
'adminUrl' => admin_url(),
|
'adminUrl' => admin_url(),
|
||||||
'wcAssetUrl' => plugins_url( 'assets/', WC_PLUGIN_FILE ),
|
'wcAssetUrl' => plugins_url( 'assets/', WC_PLUGIN_FILE ),
|
||||||
|
@ -51,12 +72,12 @@ function wc_admin_register_script() {
|
||||||
);
|
);
|
||||||
|
|
||||||
wp_add_inline_script(
|
wp_add_inline_script(
|
||||||
WC_ADMIN_APP,
|
'wc-components',
|
||||||
'var wcSettings = '. json_encode( $settings ) . ';',
|
'var wcSettings = ' . json_encode( $settings ) . ';',
|
||||||
'before'
|
'before'
|
||||||
);
|
);
|
||||||
|
|
||||||
// Resets lodash to wp-admin's version of lodash
|
// Resets lodash to wp-admin's version of lodash.
|
||||||
wp_add_inline_script(
|
wp_add_inline_script(
|
||||||
WC_ADMIN_APP,
|
WC_ADMIN_APP,
|
||||||
'_.noConflict();',
|
'_.noConflict();',
|
||||||
|
|
|
@ -8,7 +8,8 @@
|
||||||
],
|
],
|
||||||
"moduleDirectories": ["node_modules", "<rootDir>/client"],
|
"moduleDirectories": ["node_modules", "<rootDir>/client"],
|
||||||
"moduleNameMapper": {
|
"moduleNameMapper": {
|
||||||
"tinymce": "<rootDir>/tests/js/mocks/tinymce"
|
"tinymce": "<rootDir>/tests/js/mocks/tinymce",
|
||||||
|
"@woocommerce/components": "<rootDir>/client/components"
|
||||||
},
|
},
|
||||||
"setupFiles": [
|
"setupFiles": [
|
||||||
"<rootDir>/node_modules/@wordpress/jest-preset-default/scripts/setup-globals.js",
|
"<rootDir>/node_modules/@wordpress/jest-preset-default/scripts/setup-globals.js",
|
||||||
|
|
|
@ -14,6 +14,8 @@ global.wp = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
global.wc = {};
|
||||||
|
|
||||||
Object.defineProperty( global.wp, 'element', {
|
Object.defineProperty( global.wp, 'element', {
|
||||||
get: () => require( '@wordpress/element' ),
|
get: () => require( '@wordpress/element' ),
|
||||||
} );
|
} );
|
||||||
|
@ -22,6 +24,10 @@ Object.defineProperty( global.wp, 'date', {
|
||||||
get: () => require( '@wordpress/date' ),
|
get: () => require( '@wordpress/date' ),
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
Object.defineProperty( global.wc, 'components', {
|
||||||
|
get: () => require( '@woocommerce/components' ),
|
||||||
|
} );
|
||||||
|
|
||||||
global.wcSettings = {
|
global.wcSettings = {
|
||||||
adminUrl: 'https://vagrant.local/wp/wp-admin/',
|
adminUrl: 'https://vagrant.local/wp/wp-admin/',
|
||||||
locale: 'en-US',
|
locale: 'en-US',
|
||||||
|
|
|
@ -9,6 +9,7 @@ const ExtractTextPlugin = require( 'extract-text-webpack-plugin' );
|
||||||
const NODE_ENV = process.env.NODE_ENV || 'development';
|
const NODE_ENV = process.env.NODE_ENV || 'development';
|
||||||
|
|
||||||
const externals = {
|
const externals = {
|
||||||
|
'@woocommerce/components': { this: [ 'wc', 'components' ] },
|
||||||
'@wordpress/blocks': { this: [ 'wp', 'blocks' ] },
|
'@wordpress/blocks': { this: [ 'wp', 'blocks' ] },
|
||||||
'@wordpress/components': { this: [ 'wp', 'components' ] },
|
'@wordpress/components': { this: [ 'wp', 'components' ] },
|
||||||
'@wordpress/compose': { this: [ 'wp', 'compose' ] },
|
'@wordpress/compose': { this: [ 'wp', 'compose' ] },
|
||||||
|
@ -31,6 +32,7 @@ const webpackConfig = {
|
||||||
mode: NODE_ENV,
|
mode: NODE_ENV,
|
||||||
entry: {
|
entry: {
|
||||||
index: './client/index.js',
|
index: './client/index.js',
|
||||||
|
components: './client/components/index.js',
|
||||||
embedded: './client/embedded.js',
|
embedded: './client/embedded.js',
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
|
@ -85,9 +87,7 @@ const webpackConfig = {
|
||||||
'gutenberg-components': path.resolve( __dirname, 'node_modules/@wordpress/components/src' ),
|
'gutenberg-components': path.resolve( __dirname, 'node_modules/@wordpress/components/src' ),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [ new ExtractTextPlugin( 'css/[name].css' ) ],
|
||||||
new ExtractTextPlugin( 'css/[name].css' ),
|
|
||||||
],
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if ( webpackConfig.mode !== 'production' ) {
|
if ( webpackConfig.mode !== 'production' ) {
|
||||||
|
|
Loading…
Reference in New Issue