Add routing capabilities with basic analytics page (https://github.com/woocommerce/woocommerce-admin/pull/44)

* Add routing capabilities with basic analytics page

* Pass query string to child component
This commit is contained in:
Justin Shreve 2018-05-15 11:06:15 -04:00 committed by GitHub
parent 8609346d0e
commit e5bb7e556b
9 changed files with 239 additions and 18 deletions

View File

@ -0,0 +1,21 @@
/** @format */
/**
* External dependencies
*/
import { __ } from '@wordpress/i18n';
import { Component, Fragment } from '@wordpress/element';
/**
* Internal dependencies
*/
import Header from 'components/header';
export default class extends Component {
render() {
return (
<Fragment>
<Header sections={ [ __( 'Analytics', 'woo-dash' ) ] } />
</Fragment>
);
}
}

View File

@ -0,0 +1,28 @@
/** @format */
/**
* External dependencies
*/
import { __ } from '@wordpress/i18n';
import { Component, Fragment } from '@wordpress/element';
/**
* Internal dependencies
*/
import Header from 'components/header';
import { getAdminLink } from 'lib/nav-utils';
export default class extends Component {
render() {
return (
<Fragment>
<Header
sections={ [
<a href={ getAdminLink( '/analytics' ) }>{ __( 'Analytics', 'woo-dash' ) }</a>,
__( 'Report Title', 'woo-dash' ),
] }
/>
<div>Report: { this.props.params.report }</div>
</Fragment>
);
}
}

View File

@ -9,7 +9,7 @@ import PropTypes from 'prop-types';
* Internal dependencies
*/
import './style.scss';
import { getAdminLink } from '../../lib/nav-utils';
import { getAdminLink } from 'lib/nav-utils';
// TODO Implement timeline icon
@ -20,7 +20,7 @@ const Header = ( { sections, showTimeline } ) => {
return (
<h1>
<span>
<a href={ getAdminLink( 'admin.php?page=woodash' ) }>WooCommerce</a>
<a href={ getAdminLink( '/' ) }>WooCommerce</a>
</span>
{ crumbs }
</h1>

View File

@ -2,25 +2,86 @@
/**
* External dependencies
*/
import { APIProvider } from '@wordpress/components';
import { createElement, render } from '@wordpress/element';
import { addFilter } from '@wordpress/hooks';
import { pick } from 'lodash';
import { APIProvider } from '@wordpress/components';
import { Component, createElement, render } from '@wordpress/element';
import { HashRouter as Router, Route, Switch } from 'react-router-dom';
import { parse } from 'qs';
import { pick, find } from 'lodash';
/**
* Internal dependencies
*/
import Analytics from './analytics';
import AnalyticsReport from './analytics/report';
import Dashboard from './dashboard';
render(
createElement(
APIProvider,
const getPages = () => {
const pages = [
{
...wpApiSettings,
...pick( wp.api, [ 'postTypeRestBaseMapping', 'taxonomyRestBaseMapping' ] ),
container: Dashboard,
path: '/',
wpMenu: 'toplevel_page_woodash',
},
createElement( Dashboard )
),
{
container: Analytics,
path: '/analytics',
wpMenu: 'toplevel_page_woodash--analytics',
},
{
container: AnalyticsReport,
path: '/analytics/:report',
wpMenu: 'toplevel_page_woodash--analytics',
},
];
return pages;
};
class Controller extends Component {
render() {
// Pass URL parameters (example :report -> params.report) and query string parameters
const { path, params } = this.props.match;
const search = this.props.location.search.substring( 1 );
const query = parse( search );
const page = find( getPages(), { path } );
window.wpNavMenuClassChange( page.wpMenu );
return createElement( page.container, { params, query } );
}
}
// When the route changes, we need to update wp-admin's menu with the correct section & current link
window.wpNavMenuClassChange = function( menuClass ) {
jQuery( '.current' ).each( function( i, obj ) {
jQuery( obj ).removeClass( 'current' );
} );
jQuery( '.wp-has-current-submenu' )
.removeClass( 'wp-has-current-submenu' )
.removeClass( 'wp-menu-open' )
.removeClass( 'selected' )
.addClass( 'wp-not-current-submenu menu-top' );
jQuery( 'li > a[href$="admin.php?page=woodash' + window.location.hash + '"]' )
.parent()
.addClass( 'current' );
jQuery( '#' + menuClass )
.removeClass( 'wp-not-current-submenu' )
.addClass( 'wp-has-current-submenu wp-menu-open current' );
};
render(
<APIProvider
{ ...wpApiSettings }
{ ...pick( wp.api, [ 'postTypeRestBaseMapping', 'taxonomyRestBaseMapping' ] ) }
>
<Router>
<Switch>
{ getPages().map( page => {
return <Route path={ page.path } exact component={ Controller } />;
} ) }
<Route component={ Controller } />
</Switch>
</Router>
</APIProvider>,
document.getElementById( 'root' )
);

View File

@ -6,6 +6,6 @@
* @param {String} path Relative path.
* @return {String} Full admin URL.
*/
export const getAdminLink = ( path ) => {
return wcSettings.adminUrl + path;
export const getAdminLink = path => {
return wcSettings.adminUrl + 'admin.php?page=woodash#' + path;
};

View File

@ -12,9 +12,9 @@ function woo_dash_is_admin_page() {
}
/**
* Register a new menu page for the Dashboard
* Register menu pages for the Dashboard and Analytics sections
*/
function woo_dash_register_page(){
function woo_dash_register_pages(){
// toplevel_page_woodash
add_menu_page(
__( 'Woo Dash', 'woo-dash' ),
@ -25,8 +25,29 @@ function woo_dash_register_page(){
'dashicons-cart',
6
);
// toplevel_page_wooanalytics
add_menu_page(
__( 'WooCommerce Analytics', 'woo-dash' ),
__( 'WooAnalytics', 'woo-dash' ),
'manage_options',
'woodash#/analytics',
'woo_dash_page',
'dashicons-chart-bar',
6
);
// TODO: Remove. Test report link
add_submenu_page(
'woodash#/analytics',
__( 'Report Title', 'woo-dash' ),
__( 'Report Title', 'woo-dash' ),
'manage_options',
'woodash#/analytics/test',
'woo_dash_page'
);
}
add_action( 'admin_menu', 'woo_dash_register_page' );
add_action( 'admin_menu', 'woo_dash_register_pages' );
/**
* Load the assets on the Dashboard page

View File

@ -33,7 +33,8 @@ function woo_dash_register_script() {
);
wp_add_inline_script(
WOO_DASH_APP,
'var wcSettings = '. json_encode( $settings ) . ';',
'var wcSettings = '. json_encode( $settings ) . ';' .
"jQuery( '#toplevel_page_woodash a' ).attr( 'href', 'admin.php?page=woodash#/' );",
'before'
);
}

View File

@ -5451,6 +5451,12 @@
"integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=",
"dev": true
},
"hoist-non-react-statics": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.5.0.tgz",
"integrity": "sha512-6Bl6XsDT1ntE0lHbIhr4Kp2PGcleGZ66qu5Jqk8lc0Xc/IeG6gVLmwUGs/K0Us+L8VWoKgj0uWdPMataOsm31w==",
"dev": true
},
"home-or-tmp": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz",
@ -8274,6 +8280,23 @@
"integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=",
"dev": true
},
"path-to-regexp": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz",
"integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=",
"dev": true,
"requires": {
"isarray": "0.0.1"
},
"dependencies": {
"isarray": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
"dev": true
}
}
},
"path-type": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
@ -9418,6 +9441,50 @@
"safe-buffer": "5.1.1"
}
},
"react-router-dom": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-4.2.2.tgz",
"integrity": "sha512-cHMFC1ZoLDfEaMFoKTjN7fry/oczMgRt5BKfMAkTu5zEuJvUiPp1J8d0eXSVTnBh6pxlbdqDhozunOOLtmKfPA==",
"dev": true,
"requires": {
"history": "4.7.2",
"invariant": "2.2.4",
"loose-envify": "1.3.1",
"prop-types": "15.6.1",
"react-router": "4.2.0",
"warning": "3.0.0"
},
"dependencies": {
"history": {
"version": "4.7.2",
"resolved": "https://registry.npmjs.org/history/-/history-4.7.2.tgz",
"integrity": "sha512-1zkBRWW6XweO0NBcjiphtVJVsIQ+SXF29z9DVkceeaSLVMFXHool+fdCZD4spDCfZJCILPILc3bm7Bc+HRi0nA==",
"dev": true,
"requires": {
"invariant": "2.2.4",
"loose-envify": "1.3.1",
"resolve-pathname": "2.2.0",
"value-equal": "0.4.0",
"warning": "3.0.0"
}
},
"react-router": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-4.2.0.tgz",
"integrity": "sha512-DY6pjwRhdARE4TDw7XjxjZsbx9lKmIcyZoZ+SDO7SBJ1KUeWNxT22Kara2AC7u6/c2SYEHlEDLnzBCcNhLE8Vg==",
"dev": true,
"requires": {
"history": "4.7.2",
"hoist-non-react-statics": "2.5.0",
"invariant": "2.2.4",
"loose-envify": "1.3.1",
"path-to-regexp": "1.7.0",
"prop-types": "15.6.1",
"warning": "3.0.0"
}
}
}
},
"read-chunk": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/read-chunk/-/read-chunk-2.1.0.tgz",
@ -9813,6 +9880,12 @@
"integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=",
"dev": true
},
"resolve-pathname": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-2.2.0.tgz",
"integrity": "sha512-bAFz9ld18RzJfddgrO2e/0S2O81710++chRMUxHjXOYKF6jTAMrUNZrEZ1PvV0zlhfjidm08iRPdTLPno1FuRg==",
"dev": true
},
"resolve-url": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
@ -11398,6 +11471,12 @@
"spdx-expression-parse": "3.0.0"
}
},
"value-equal": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/value-equal/-/value-equal-0.4.0.tgz",
"integrity": "sha512-x+cYdNnaA3CxvMaTX0INdTCN8m8aF2uY9BvEqmxuYp8bL09cs/kWVQPVGcA35fMktdOsP69IgU7wFj/61dJHEw==",
"dev": true
},
"vendors": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.1.tgz",
@ -11500,6 +11579,15 @@
"indexof": "0.0.1"
}
},
"warning": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz",
"integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=",
"dev": true,
"requires": {
"loose-envify": "1.3.1"
}
},
"watchpack": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz",

View File

@ -44,6 +44,7 @@
"node-sass": "^4.9.0",
"prettier": "github:automattic/calypso-prettier#c56b4251",
"prop-types": "^15.6.1",
"react-router-dom": "^4.2.2",
"readline-sync": "^1.4.9",
"sass-loader": "^7.0.1",
"style-loader": "^0.21.0",