woocommerce/plugins/woocommerce-admin/client/layout/controller.js

214 lines
6.2 KiB
JavaScript
Raw Normal View History

/** @format */
/**
* External dependencies
*/
import { Component, createElement } from '@wordpress/element';
2019-06-13 19:58:21 +00:00
import { parse, stringify } from 'qs';
import { find, isEqual, last } from 'lodash';
import { applyFilters } from '@wordpress/hooks';
import { __ } from '@wordpress/i18n';
/**
* WooCommerce dependencies
*/
2019-06-13 19:58:21 +00:00
import { getNewPath, getPersistedQuery, getHistory } from '@woocommerce/navigation';
/**
* Internal dependencies
*/
import AnalyticsReport, { getReports } from 'analytics/report';
Add settings page with excluded order statuses (https://github.com/woocommerce/woocommerce-admin/pull/1364) * Add settings page routes * Add control options for excluded statuses * Add control options for excluded statuses * Add excluded order statuses to rest api * Add wc settings to wc-api * Add wc settings to wc-api * Split and validate multiselect values in settings controller * Add wcAdminSettings to wcSettings global * Set initial excluded statuses from serverside wcSettings data * Add extensible filter for wcSettings global * Split arrays into comma separated strings in wc-api * Extract setting as separate component * Extra settings to config file * Add checkboxGroup option as input type * Separate status types into default and custom groups * Add setting option styling * Add responsive styling for settings * Fix wpClosedMenu and wpOpenMenu for settings page * Add support for resetting to default values * Only show checkbox group if options are available * Add proptypes to Setting component * Add extensible filter to analytics settings * Add readme for settings config and extensibility * Hook up excluded status settings to reports * Pass object to settings API instead of comma delimited string * Fix inpuType -> inputType typo * Remove hasError from constructor * Bump settings API to v4 * Use interpolateComponents instead of dangerously setting html * Use empty array in initial excldued statuses setting value if none is retrieved * Remove double check for refunded status in default order statuses * Update settings wc-api to use namespace * Add aria=labelledby to checkbox group
2019-01-31 01:04:11 +00:00
import AnalyticsSettings from 'analytics/settings';
import Dashboard from 'dashboard';
import DevDocs from 'devdocs';
const TIME_EXCLUDED_SCREENS_FILTER = 'woocommerce_admin_time_excluded_screens';
export const PAGES_FILTER = 'woocommerce_admin_pages_list';
export const getPages = () => {
const pages = [];
if ( window.wcAdminFeatures.devdocs ) {
pages.push( {
container: DevDocs,
path: '/devdocs',
breadcrumbs: [ 'Documentation' ],
wpOpenMenu: 'toplevel_page_woocommerce',
} );
pages.push( {
container: DevDocs,
path: '/devdocs/:component',
breadcrumbs: ( { match } ) => [ [ '/devdocs', 'Documentation' ], match.params.component ],
wpOpenMenu: 'toplevel_page_woocommerce',
} );
}
if ( window.wcAdminFeatures[ 'analytics-dashboard' ] ) {
pages.push( {
container: Dashboard,
path: '/',
breadcrumbs: [ __( 'Dashboard', 'woocommerce-admin' ) ],
wpOpenMenu: 'toplevel_page_woocommerce',
} );
}
if ( window.wcAdminFeatures.analytics ) {
pages.push( {
Add settings page with excluded order statuses (https://github.com/woocommerce/woocommerce-admin/pull/1364) * Add settings page routes * Add control options for excluded statuses * Add control options for excluded statuses * Add excluded order statuses to rest api * Add wc settings to wc-api * Add wc settings to wc-api * Split and validate multiselect values in settings controller * Add wcAdminSettings to wcSettings global * Set initial excluded statuses from serverside wcSettings data * Add extensible filter for wcSettings global * Split arrays into comma separated strings in wc-api * Extract setting as separate component * Extra settings to config file * Add checkboxGroup option as input type * Separate status types into default and custom groups * Add setting option styling * Add responsive styling for settings * Fix wpClosedMenu and wpOpenMenu for settings page * Add support for resetting to default values * Only show checkbox group if options are available * Add proptypes to Setting component * Add extensible filter to analytics settings * Add readme for settings config and extensibility * Hook up excluded status settings to reports * Pass object to settings API instead of comma delimited string * Fix inpuType -> inputType typo * Remove hasError from constructor * Bump settings API to v4 * Use interpolateComponents instead of dangerously setting html * Use empty array in initial excldued statuses setting value if none is retrieved * Remove double check for refunded status in default order statuses * Update settings wc-api to use namespace * Add aria=labelledby to checkbox group
2019-01-31 01:04:11 +00:00
container: AnalyticsSettings,
path: '/analytics/settings',
breadcrumbs: [
[ '/analytics/revenue', __( 'Analytics', 'woocommerce-admin' ) ],
__( 'Settings', 'woocommerce-admin' ),
],
2019-07-01 00:33:52 +00:00
wpOpenMenu: 'toplevel_page_wc-admin-path--analytics-revenue',
} );
pages.push( {
container: AnalyticsReport,
path: '/analytics/:report',
breadcrumbs: ( { match } ) => {
const report = find( getReports(), { report: match.params.report } );
if ( ! report ) {
return [];
}
return [ [ '/analytics/revenue', __( 'Analytics', 'woocommerce-admin' ) ], report.title ];
},
2019-07-01 00:33:52 +00:00
wpOpenMenu: 'toplevel_page_wc-admin-path--analytics-revenue',
} );
}
return applyFilters( PAGES_FILTER, pages );
};
export class Controller extends Component {
componentDidMount() {
window.document.documentElement.scrollTop = 0;
}
componentDidUpdate( prevProps ) {
const prevQuery = this.getQuery( prevProps.location.search );
const prevBaseQuery = this.getBaseQuery( prevProps.location.search );
const baseQuery = this.getBaseQuery( this.props.location.search );
if ( prevQuery.page > 1 && ! isEqual( prevBaseQuery, baseQuery ) ) {
getHistory().replace( getNewPath( { page: 1 } ) );
}
if ( prevProps.match.url !== this.props.match.url ) {
window.document.documentElement.scrollTop = 0;
}
}
getQuery( searchString ) {
if ( ! searchString ) {
return {};
}
const search = searchString.substring( 1 );
return parse( search );
}
getBaseQuery( searchString ) {
const query = this.getQuery( searchString );
delete query.page;
return query;
}
render() {
2019-06-13 19:58:21 +00:00
const { page, match, location } = this.props;
const { url, params } = match;
const query = this.getBaseQuery( location.search );
window.wpNavMenuUrlUpdate( page, query );
2019-06-13 19:58:21 +00:00
window.wpNavMenuClassChange( page, url );
return createElement( page.container, { params, path: url, pathMatch: page.path, query } );
}
}
/**
* Update an anchor's link in sidebar to include persisted queries. Leave excluded screens
* as is.
*
* @param {HTMLElement} item - Sidebar anchor link.
2019-06-13 19:58:21 +00:00
* @param {object} nextQuery - A query object to be added to updated hrefs.
* @param {Array} excludedScreens - wc-admin screens to avoid updating.
*/
export function updateLinkHref( item, nextQuery, excludedScreens ) {
2019-06-13 19:58:21 +00:00
const isWCAdmin = /admin.php\?page=wc-admin/.test( item.href );
if ( isWCAdmin ) {
const search = last( item.href.split( '?' ) );
const query = parse( search );
const path = query.path || 'dashboard';
const screen = path.replace( '/analytics', '' ).replace( '/', '' );
const isExcludedScreen = excludedScreens.includes( screen );
const href =
'admin.php?' + stringify( Object.assign( query, isExcludedScreen ? {} : nextQuery ) );
// Replace the href so you can see the url on hover.
item.href = href;
item.onclick = e => {
e.preventDefault();
getHistory().push( href );
};
}
}
2019-06-13 19:58:21 +00:00
// Update's wc-admin links in wp-admin menu
window.wpNavMenuUrlUpdate = function( page, query ) {
const excludedScreens = applyFilters( TIME_EXCLUDED_SCREENS_FILTER, [
'devdocs',
'stock',
'settings',
'customers',
] );
2019-06-13 19:58:21 +00:00
const nextQuery = getPersistedQuery( query );
Array.from( document.querySelectorAll( '#adminmenu a' ) ).forEach( item =>
updateLinkHref( item, nextQuery, excludedScreens )
);
};
// When the route changes, we need to update wp-admin's menu with the correct section & current link
2019-06-13 19:58:21 +00:00
window.wpNavMenuClassChange = function( page, url ) {
Array.from( document.getElementsByClassName( 'current' ) ).forEach( function( item ) {
item.classList.remove( 'current' );
} );
const submenu = Array.from( document.querySelectorAll( '.wp-has-current-submenu' ) );
submenu.forEach( function( element ) {
element.classList.remove( 'wp-has-current-submenu' );
element.classList.remove( 'wp-menu-open' );
element.classList.remove( 'selected' );
element.classList.add( 'wp-not-current-submenu' );
element.classList.add( 'menu-top' );
} );
2019-06-13 19:58:21 +00:00
const pageUrl =
'/' === url
? 'admin.php?page=wc-admin'
: 'admin.php?page=wc-admin&path=' + encodeURIComponent( url );
const currentItemsSelector =
2019-06-13 19:58:21 +00:00
url === '/'
? `li > a[href$="${ pageUrl }"], li > a[href*="${ pageUrl }?"]`
: `li > a[href*="${ pageUrl }"]`;
const currentItems = document.querySelectorAll( currentItemsSelector );
Array.from( currentItems ).forEach( function( item ) {
item.parentElement.classList.add( 'current' );
} );
if ( page.wpOpenMenu ) {
const currentMenu = document.querySelector( '#' + page.wpOpenMenu );
currentMenu.classList.remove( 'wp-not-current-submenu' );
currentMenu.classList.add( 'wp-has-current-submenu' );
currentMenu.classList.add( 'wp-menu-open' );
currentMenu.classList.add( 'current' );
}
const wpWrap = document.querySelector( '#wpwrap' );
wpWrap.classList.remove( 'wp-responsive-open' );
};