Refactor: Alternative approach to implementing extendable settings from the server (https://github.com/woocommerce/woocommerce-admin/pull/2917)

* integrate with new asset data registration (php side)

- includes back-compatibility.

* update js configuration and implement settings alias

- this aliases `@woocommerce/wc-admin-settings` to the settings api exposed via blocks (either the blocks plugin or core) and all the settings provided via the server.
- Adds fallback for back-compat if `wc.wcSettings` is not available in the environment (fallsback to `wcSettings`).

* initial pass to update all wcSettings direct usage to the new api

- this is just an initial pass, more can be done in separate pulls.

* missed one spot for adding new filter implementation

* fix incorrect jest config

* Avoid unnecessary assignment and directly return.

* Remove unnecessary defaults

* Fix inline comment text case.

Co-Authored-By: Albert Juhé Lluveras <contact@albertjuhe.com>

* Remove unnecessary inline comment.

* use @todo instead of TODO

Co-Authored-By: Albert Juhé Lluveras <contact@albertjuhe.com>

* fix incorrect reference in webpack config.

* add missing import and slightly delay dependency injection for scripts

* update get-setting and set-setting callbacks

* disable lint rule for console.error on dev doc builds
This commit is contained in:
Darren Ethier 2019-09-23 17:47:08 -04:00 committed by GitHub
parent 64a3ce98f5
commit d728d38219
43 changed files with 476 additions and 175 deletions

View File

@ -300,7 +300,8 @@ export default compose(
const { getCurrentUserData } = select( 'wc-api' );
const userData = getCurrentUserData();
userPrefColumns = userData[ columnPrefsKey ];
userPrefColumns =
userData && userData[ columnPrefsKey ] ? userData[ columnPrefsKey ] : userPrefColumns;
}
if ( isRequesting || ( query.search && ! ( query[ endpoint ] && query[ endpoint ].length ) ) ) {

View File

@ -5,6 +5,7 @@
import { __, _x } from '@wordpress/i18n';
import { decodeEntities } from '@wordpress/html-entities';
import { applyFilters } from '@wordpress/hooks';
import { COUNTRIES as countries } from '@woocommerce/wc-admin-settings';
/**
* Internal dependencies
@ -116,9 +117,6 @@ export const advancedFilters = applyFilters( CUSTOMERS_REPORT_ADVANCED_FILTERS_F
component: 'Search',
type: 'countries',
getLabels: async value => {
const countries =
( wcSettings.dataEndpoints && wcSettings.dataEndpoints.countries ) || [];
const allLabels = countries.map( country => ( {
id: country.code,
label: decodeEntities( country.name ),

View File

@ -13,6 +13,7 @@ import { defaultTableDateFormat } from '@woocommerce/date';
import { formatCurrency, getCurrencyFormatDecimal } from '@woocommerce/currency';
import { Date, Link } from '@woocommerce/components';
import { numberFormat } from '@woocommerce/number';
import { COUNTRIES as countries } from '@woocommerce/wc-admin-settings';
/**
* Internal dependencies
@ -102,9 +103,7 @@ export default class CustomersReportTable extends Component {
}
getCountryName( code ) {
const countries = ( wcSettings.dataEndpoints && wcSettings.dataEndpoints.countries ) || [];
const country = countries.find( c => c.code === code );
return country ? country.name : null;
return typeof countries[ code ] !== 'undefined' ? countries[ code ] : null;
}
getRowsContent( customers ) {

View File

@ -14,6 +14,7 @@ import { find } from 'lodash';
*/
import { useFilters } from '@woocommerce/components';
import { getQuery, getSearchWords } from '@woocommerce/navigation';
import { getSetting } from '@woocommerce/wc-admin-settings';
/**
* Internal dependencies
@ -33,6 +34,7 @@ import { searchItemsByString } from 'wc-api/items/utils';
import withSelect from 'wc-api/with-select';
export const REPORTS_FILTER = 'woocommerce_admin_reports_list';
const manageStock = getSetting( 'manageStock', 'no' );
export const getReports = () => {
const reports = [
@ -71,7 +73,7 @@ export const getReports = () => {
title: __( 'Downloads', 'woocommerce-admin' ),
component: DownloadsReport,
},
'yes' === wcSettings.manageStock
'yes' === manageStock
? {
report: 'stock',
title: __( 'Stock', 'woocommerce-admin' ),

View File

@ -4,14 +4,13 @@
*/
import { __, _x } from '@wordpress/i18n';
import { applyFilters } from '@wordpress/hooks';
import { ORDER_STATUSES } from '@woocommerce/wc-admin-settings';
/**
* Internal dependencies
*/
import { getCouponLabels, getProductLabels } from 'lib/async-requests';
const { orderStatuses } = wcSettings;
const ORDERS_REPORT_CHARTS_FILTER = 'woocommerce_admin_orders_report_charts';
const ORDERS_REPORT_FILTERS_FILTER = 'woocommerce_admin_orders_report_filters';
const ORDERS_REPORT_ADVANCED_FILTERS_FILTER = 'woocommerce_admin_orders_report_advanced_filters';
@ -87,9 +86,9 @@ export const advancedFilters = applyFilters( ORDERS_REPORT_ADVANCED_FILTERS_FILT
],
input: {
component: 'SelectControl',
options: Object.keys( orderStatuses ).map( key => ( {
options: Object.keys( ORDER_STATUSES ).map( key => ( {
value: key,
label: orderStatuses[ key ],
label: ORDER_STATUSES[ key ],
} ) ),
},
},

View File

@ -13,6 +13,7 @@ import { Link } from '@woocommerce/components';
import { formatCurrency, getCurrencyFormatDecimal } from '@woocommerce/currency';
import { getNewPath, getPersistedQuery } from '@woocommerce/navigation';
import { numberFormat } from '@woocommerce/number';
import { getSetting } from '@woocommerce/wc-admin-settings';
/**
* Internal dependencies
@ -20,6 +21,9 @@ import { numberFormat } from '@woocommerce/number';
import ReportTable from 'analytics/components/report-table';
import { isLowStock } from './utils';
const manageStock = getSetting( 'manageStock', 'no' );
const stockStatuses = getSetting( 'stockStatuses', {} );
export default class VariationsReportTable extends Component {
constructor() {
super();
@ -64,13 +68,13 @@ export default class VariationsReportTable extends Component {
isSortable: true,
isNumeric: true,
},
'yes' === wcSettings.manageStock
'yes' === manageStock
? {
label: __( 'Status', 'woocommerce-admin' ),
key: 'stock_status',
}
: null,
'yes' === wcSettings.manageStock
'yes' === manageStock
? {
label: __( 'Stock', 'woocommerce-admin' ),
key: 'stock',
@ -81,7 +85,6 @@ export default class VariationsReportTable extends Component {
}
getRowsContent( data = [] ) {
const { stockStatuses } = wcSettings;
const { query } = this.props;
const persistedQuery = getPersistedQuery( query );
@ -125,7 +128,7 @@ export default class VariationsReportTable extends Component {
),
value: orders_count,
},
'yes' === wcSettings.manageStock
'yes' === manageStock
? {
display: isLowStock( stock_status, stock_quantity, low_stock_amount ) ? (
<Link href={ editPostLink } type="wp-admin">
@ -137,7 +140,7 @@ export default class VariationsReportTable extends Component {
value: stockStatuses[ stock_status ],
}
: null,
'yes' === wcSettings.manageStock
'yes' === manageStock
? {
display: stock_quantity,
value: stock_quantity,

View File

@ -14,6 +14,7 @@ import { formatCurrency, getCurrencyFormatDecimal, renderCurrency } from '@wooco
import { getNewPath, getPersistedQuery } from '@woocommerce/navigation';
import { Link, Tag } from '@woocommerce/components';
import { numberFormat } from '@woocommerce/number';
import { getSetting } from '@woocommerce/wc-admin-settings';
/**
* Internal dependencies
@ -24,6 +25,9 @@ import ReportTable from 'analytics/components/report-table';
import withSelect from 'wc-api/with-select';
import './style.scss';
const manageStock = getSetting( 'manageStock', 'no' );
const stockStatuses = getSetting( 'stockStatuses', {} );
class ProductsReportTable extends Component {
constructor() {
super();
@ -78,13 +82,13 @@ class ProductsReportTable extends Component {
key: 'variations',
isSortable: true,
},
'yes' === wcSettings.manageStock
'yes' === manageStock
? {
label: __( 'Status', 'woocommerce-admin' ),
key: 'stock_status',
}
: null,
'yes' === wcSettings.manageStock
'yes' === manageStock
? {
label: __( 'Stock', 'woocommerce-admin' ),
key: 'stock',
@ -95,7 +99,6 @@ class ProductsReportTable extends Component {
}
getRowsContent( data = [] ) {
const { stockStatuses } = wcSettings;
const { query } = this.props;
const persistedQuery = getPersistedQuery( query );
@ -194,13 +197,13 @@ class ProductsReportTable extends Component {
display: numberFormat( variations.length ),
value: variations.length,
},
'yes' === wcSettings.manageStock
'yes' === manageStock
? {
display: manage_stock ? stockStatus : __( 'N/A', 'woocommerce-admin' ),
value: manage_stock ? stockStatuses[ stock_status ] : null,
}
: null,
'yes' === wcSettings.manageStock
'yes' === manageStock
? {
display: manage_stock
? numberFormat( stock_quantity )

View File

@ -15,7 +15,6 @@ import ReportFilters from 'analytics/components/report-filters';
export default class StockReport extends Component {
render() {
const { query, path } = this.props;
return (
<Fragment>
<ReportFilters

View File

@ -11,6 +11,7 @@ import { Component } from '@wordpress/element';
import { Link } from '@woocommerce/components';
import { getNewPath, getPersistedQuery } from '@woocommerce/navigation';
import { numberFormat } from '@woocommerce/number';
import { getSetting } from '@woocommerce/wc-admin-settings';
/**
* Internal dependencies
@ -18,6 +19,8 @@ import { numberFormat } from '@woocommerce/number';
import ReportTable from 'analytics/components/report-table';
import { isLowStock } from './utils';
const stockStatuses = getSetting( 'stockStatuses', {} );
export default class StockReportTable extends Component {
constructor() {
super();
@ -58,7 +61,6 @@ export default class StockReportTable extends Component {
getRowsContent( products ) {
const { query } = this.props;
const persistedQuery = getPersistedQuery( query );
const { stockStatuses } = wcSettings;
return products.map( product => {
const {

View File

@ -5,6 +5,7 @@
import { __, sprintf } from '@wordpress/i18n';
import { applyFilters } from '@wordpress/hooks';
import interpolateComponents from 'interpolate-components';
import { getSetting, ORDER_STATUSES } from '@woocommerce/wc-admin-settings';
/**
* Internal dependencies
@ -13,7 +14,7 @@ import { DEFAULT_ACTIONABLE_STATUSES } from 'wc-api/constants';
import DefaultDate from './default-date';
const SETTINGS_FILTER = 'woocommerce_admin_analytics_settings';
const DEFAUTL_DATE_RANGE = 'period=month&compare=previous_year';
const DEFAULT_DATE_RANGE = 'period=month&compare=previous_year';
const defaultOrderStatuses = [
'completed',
@ -25,27 +26,33 @@ const defaultOrderStatuses = [
'on-hold',
];
const actionableOrderStatuses = Array.isArray(
wcSettings.wcAdminSettings.woocommerce_actionable_order_statuses
)
? wcSettings.wcAdminSettings.woocommerce_actionable_order_statuses
const {
woocommerce_actionable_order_statuses,
woocommerce_excluded_report_order_statuses,
woocommerce_default_date_range,
} = getSetting( 'wcAdminSettings', {
woocommerce_actionable_order_statuses: [],
woocommerce_excluded_report_order_statuses: [],
woocommerce_default_date_range: DEFAULT_DATE_RANGE,
} );
const actionableOrderStatuses = Array.isArray( woocommerce_actionable_order_statuses )
? woocommerce_actionable_order_statuses
: [];
const excludedOrderStatuses = Array.isArray(
wcSettings.wcAdminSettings.woocommerce_excluded_report_order_statuses
)
? wcSettings.wcAdminSettings.woocommerce_excluded_report_order_statuses
const excludedOrderStatuses = Array.isArray( woocommerce_excluded_report_order_statuses )
? woocommerce_excluded_report_order_statuses
: [];
const orderStatuses = Object.keys( wcSettings.orderStatuses )
const orderStatuses = Object.keys( ORDER_STATUSES )
.filter( status => status !== 'refunded' )
.map( key => {
return {
value: key,
label: wcSettings.orderStatuses[ key ],
label: ORDER_STATUSES[ key ],
description: sprintf(
__( 'Exclude the %s status from reports', 'woocommerce-admin' ),
wcSettings.orderStatuses[ key ]
ORDER_STATUSES[ key ]
),
};
} );
@ -112,7 +119,7 @@ export const analyticsSettings = applyFilters( SETTINGS_FILTER, [
'the default date range.',
'woocommerce-admin'
),
initialValue: wcSettings.wcAdminSettings.woocommerce_default_date_range || DEFAUTL_DATE_RANGE,
defaultValue: DEFAUTL_DATE_RANGE,
initialValue: woocommerce_default_date_range,
defaultValue: DEFAULT_DATE_RANGE,
},
] );

View File

@ -116,6 +116,9 @@ class Settings extends Component {
* @param {object} state - State
*/
persistChanges( state ) {
// @todo Should remove global state from the file. This creates
// potential hard to debug side-effects.
wcSettings.wcAdminSettings = wcSettings.wcAdminSettings || {};
analyticsSettings.forEach( setting => {
const updatedValue = state.settings[ setting.name ];
wcSettings.wcAdminSettings[ setting.name ] = updatedValue;

View File

@ -6,6 +6,7 @@ import { __ } from '@wordpress/i18n';
import { decodeEntities } from '@wordpress/html-entities';
import { SelectControl, TextControl } from 'newspack-components';
import { useMemo } from 'react';
import { COUNTRIES as countries } from '@woocommerce/wc-admin-settings';
/**
* Form validation.
@ -38,8 +39,6 @@ export function validateStoreAddress( values ) {
* @return {Object} Select options, { value: 'US:GA', label: 'United States - Georgia' }
*/
export function getCountryStateOptions() {
const countries = ( wcSettings.dataEndpoints && wcSettings.dataEndpoints.countries ) || [];
const countryStateOptions = countries.reduce( ( acc, country ) => {
if ( ! country.states.length ) {
acc.push( {

View File

@ -13,6 +13,7 @@ import { withDispatch } from '@wordpress/data';
* WooCommerce dependencies
*/
import { EllipsisMenu, MenuItem, MenuTitle, SectionHeader } from '@woocommerce/components';
import { getSetting } from '@woocommerce/wc-admin-settings';
/**
* Internal dependencies
@ -161,7 +162,7 @@ export default compose(
'wc-api'
);
const userData = getCurrentUserData();
const allLeaderboards = wcSettings.dataEndpoints.leaderboards;
const { allLeaderboards } = getSetting( 'dataEndpoints', { leaderboards: {} } );
return {
allLeaderboards,

View File

@ -14,6 +14,7 @@ import { keys, pickBy } from 'lodash';
* WooCommerce dependencies
*/
import { numberFormat } from '@woocommerce/number';
import { getSetting, CURRENCY as currency } from '@woocommerce/wc-admin-settings';
/**
* Internal dependencies
@ -23,6 +24,8 @@ import withSelect from 'wc-api/with-select';
import { recordEvent } from 'lib/tracks';
import { formatCurrency } from '@woocommerce/currency';
const wcAdminAssetUrl = getSetting( 'wcAdminAssetUrl', '' );
class BusinessDetails extends Component {
constructor() {
super();
@ -50,7 +53,7 @@ class BusinessDetails extends Component {
recordEvent( 'storeprofiler_store_business_details_continue', {
product_number: product_count,
already_selling: 'no' !== selling_venues,
currency: wcSettings.currency.code,
currency: currency.code,
revenue,
used_platform: other_platform,
install_facebook: facebook,
@ -179,7 +182,7 @@ class BusinessDetails extends Component {
{ extensionBenefits.map( benefit => (
<div className="woocommerce-profile-wizard__benefit" key={ benefit.title }>
<div className="woocommerce-profile-wizard__business-extension">
<img src={ wcSettings.wcAdminAssetUrl + benefit.icon } alt="" />
<img src={ wcAdminAssetUrl + benefit.icon } alt="" />
</div>
<div className="woocommerce-profile-wizard__benefit-content">
<H className="woocommerce-profile-wizard__benefit-title">{ benefit.title }</H>

View File

@ -9,6 +9,11 @@ import { includes, filter } from 'lodash';
import { compose } from '@wordpress/compose';
import { withDispatch } from '@wordpress/data';
/**
* WooCommerce Dependencies
*/
import { getSetting } from '@woocommerce/wc-admin-settings';
/**
* Internal dependencies
*/
@ -16,6 +21,8 @@ import { H, Card } from '@woocommerce/components';
import withSelect from 'wc-api/with-select';
import { recordEvent } from 'lib/tracks';
const onboarding = getSetting( 'onboarding', {} );
class Industry extends Component {
constructor() {
super();
@ -77,7 +84,7 @@ class Industry extends Component {
}
render() {
const { industries } = wcSettings.onboarding;
const { industries } = onboarding;
const { error } = this.state;
return (
<Fragment>

View File

@ -16,6 +16,7 @@ import { getCurrentDates, appendTimestamp, getDateParamsFromQuery } from '@wooco
import { getNewPath, getPersistedQuery } from '@woocommerce/navigation';
import { calculateDelta, formatValue } from '@woocommerce/number';
import { formatCurrency } from '@woocommerce/currency';
import { getSetting } from '@woocommerce/wc-admin-settings';
/**
* Internal dependencies
@ -33,11 +34,14 @@ import withSelect from 'wc-api/with-select';
import './style.scss';
import { recordEvent } from 'lib/tracks';
const { performanceIndicators: indicators } = getSetting( 'dataEndpoints', {
performanceIndicators: '',
} );
class StorePerformance extends Component {
renderMenu() {
const {
hiddenBlocks,
indicators,
isFirst,
isLast,
onMove,
@ -193,8 +197,6 @@ export default compose(
const datesFromQuery = getCurrentDates( query );
const endPrimary = datesFromQuery.primary.before;
const endSecondary = datesFromQuery.secondary.before;
const indicators = wcSettings.dataEndpoints.performanceIndicators;
const userIndicators = indicators.filter(
indicator => ! hiddenBlocks.includes( indicator.stat )
);

View File

@ -12,6 +12,7 @@ import { compose } from '@wordpress/compose';
*/
import { Card, List } from '@woocommerce/components';
import { updateQueryString } from '@woocommerce/navigation';
import { getSetting } from '@woocommerce/wc-admin-settings';
/**
* Internal depdencies
@ -25,6 +26,13 @@ import Tax from './tasks/tax';
import Payments from './tasks/payments';
import withSelect from 'wc-api/with-select';
const { customLogo, hasHomepage, hasProducts, shippingZonesCount } = getSetting( 'onboarding', {
customLogo: '',
hasHomePage: false,
hasProducts: false,
shippingZonesCount: 0,
} );
class TaskDashboard extends Component {
componentDidMount() {
document.body.classList.add( 'woocommerce-onboarding' );
@ -37,7 +45,6 @@ class TaskDashboard extends Component {
}
getTasks() {
const { customLogo, hasHomepage, hasProducts, shippingZonesCount } = wcSettings.onboarding;
const { profileItems, query } = this.props;
return [

View File

@ -8,7 +8,6 @@ import { Button, TextControl } from 'newspack-components';
import classnames from 'classnames';
import { Component, Fragment } from '@wordpress/element';
import { FormToggle } from '@wordpress/components';
import { get } from 'lodash';
import PropTypes from 'prop-types';
/**
@ -16,6 +15,9 @@ import PropTypes from 'prop-types';
*/
import { Flag, Form } from '@woocommerce/components';
import { getCurrencyFormatString } from '@woocommerce/currency';
import { CURRENCY } from '@woocommerce/wc-admin-settings';
const { symbol, symbolPosition } = CURRENCY;
class ShippingRates extends Component {
constructor() {
@ -81,26 +83,15 @@ class ShippingRates extends Component {
}
renderInputPrefix() {
const symbolPosition = get( wcSettings, [ 'currency', 'position' ] );
if ( 0 === symbolPosition.indexOf( 'right' ) ) {
return;
}
return (
<span className="woocommerce-shipping-rate__control-prefix">
{ get( wcSettings, [ 'currency', 'symbol' ], '$' ) }
</span>
);
return <span className="woocommerce-shipping-rate__control-prefix">{ symbol }</span>;
}
renderInputSuffix( rate ) {
const symbolPosition = get( wcSettings, [ 'currency', 'position' ] );
if ( 0 === symbolPosition.indexOf( 'right' ) ) {
return (
<span className="woocommerce-shipping-rate__control-suffix">
{ get( wcSettings, [ 'currency', 'symbol' ], '$' ) }
</span>
);
return <span className="woocommerce-shipping-rate__control-suffix">{ symbol }</span>;
}
return parseFloat( rate ) === parseFloat( 0 ) ? (

View File

@ -20,6 +20,7 @@ class Example extends Component {
try {
exampleComponent = require( `components/src/${ this.props.filePath }/docs/example` );
} catch ( e ) {
// eslint-disable-next-line no-console
console.error( e );
}

View File

@ -9,6 +9,7 @@ import { Component } from '@wordpress/element';
import Gridicon from 'gridicons';
import { IconButton, NavigableMenu } from '@wordpress/components';
import { partial, uniqueId, find } from 'lodash';
import { getSetting } from '@woocommerce/wc-admin-settings';
/**
* Internal dependencies
@ -30,6 +31,9 @@ import ReviewsPanel from './panels/reviews';
import withSelect from 'wc-api/with-select';
import WordPressNotices from './wordpress-notices';
const manageStock = getSetting( 'manageStock', 'no' );
const reviewsEnabled = getSetting( 'reviewsEnabled', 'no' );
class ActivityPanel extends Component {
constructor() {
super( ...arguments );
@ -128,7 +132,7 @@ class ActivityPanel extends Component {
icon: <Gridicon icon="pages" />,
unread: hasUnreadOrders,
},
'yes' === wcSettings.manageStock
'yes' === manageStock
? {
name: 'stock',
title: __( 'Stock', 'woocommerce-admin' ),
@ -136,7 +140,7 @@ class ActivityPanel extends Component {
unread: hasUnreadStock,
}
: null,
'yes' === wcSettings.reviewsEnabled
'yes' === reviewsEnabled
? {
name: 'reviews',
title: __( 'Reviews', 'woocommerce-admin' ),

View File

@ -9,6 +9,11 @@ import { compose } from '@wordpress/compose';
import Gridicon from 'gridicons';
import { withDispatch } from '@wordpress/data';
/**
* WooCommerce dependencies
*/
import { ADMIN_URL as adminUrl } from '@woocommerce/wc-admin-settings';
/**
* Internal dependencies
*/
@ -37,7 +42,7 @@ class InboxPanel extends Component {
const { triggerNoteAction } = this.props;
const href = event.target.href || '';
if ( href.length && ! href.startsWith( wcSettings.adminUrl ) ) {
if ( href.length && ! href.startsWith( adminUrl ) ) {
event.preventDefault();
window.open( href, '_blank' );
}

View File

@ -266,6 +266,7 @@ export default compose(
getReportItemsError,
isReportItemsRequesting,
} = select( 'wc-api' );
wcSettings.wcAdminSettings = wcSettings.wcAdminSettings || {};
const orderStatuses =
wcSettings.wcAdminSettings.woocommerce_actionable_order_statuses ||
DEFAULT_ACTIONABLE_STATUSES;

View File

@ -8,6 +8,9 @@ import { DEFAULT_ACTIONABLE_STATUSES } from 'wc-api/constants';
export function getUnreadNotes( select ) {
const { getCurrentUserData, getNotes, getNotesError, isGetNotesRequesting } = select( 'wc-api' );
const userData = getCurrentUserData();
if ( ! userData ) {
return null;
}
const notesQuery = {
page: 1,
per_page: 1,
@ -33,6 +36,7 @@ export function getUnreadNotes( select ) {
export function getUnreadOrders( select ) {
const { getItems, getItemsTotalCount, getItemsError, isGetItemsRequesting } = select( 'wc-api' );
wcSettings.wcAdminSettings = wcSettings.wcAdminSettings || {};
const orderStatuses =
wcSettings.wcAdminSettings.woocommerce_actionable_order_statuses || DEFAULT_ACTIONABLE_STATUSES;

View File

@ -0,0 +1,92 @@
/** @format */
const defaults = {
adminUrl: '',
countries: [],
currency: {
code: 'USD',
precision: 2,
symbol: '$',
symbolPosition: 'left',
decimalSeparator: '.',
priceFormat: '%1$s%2$s',
thousandSeparator: ',',
},
defaultDateRange: 'period=month&compare=previous_year',
locale: {
siteLocale: 'en_US',
userLocale: 'en_US',
weekdaysShort: [ 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' ],
},
orderStatuses: [],
siteTitle: '',
wcAssetUrl: '',
};
const globalSharedSettings = typeof wcSettings === 'object' ? wcSettings : {};
// Use defaults or global settings, depending on what is set.
const allSettings = {
...defaults,
...globalSharedSettings,
};
allSettings.currency = {
...defaults.currency,
...allSettings.currency,
};
allSettings.locale = {
...defaults.locale,
...allSettings.locale,
};
// for anything you want exposed as non-mutable outside of its use in a module,
// import the constant. Otherwise use getSetting/setSetting for the value
// reference.
export const ADMIN_URL = allSettings.adminUrl;
export const COUNTRIES = allSettings.countries;
export const CURRENCY = allSettings.currency;
export const LOCALE = allSettings.locale;
export const ORDER_STATUSES = allSettings.orderStatuses;
export const SITE_TITLE = allSettings.siteTitle;
export const WC_ASSET_URL = allSettings.wcAssetUrl;
export const DEFAULT_DATE_RANGE = allSettings.defaultDateRange;
/**
* Retrieves a setting value from the setting state.
*
* @export
* @param {string} name The identifier for the setting.
* @param {mixed} [fallback=false] The value to use as a fallback
* if the setting is not in the
* state.
* @param {function} [filter=( val ) => val] A callback for filtering the
* value before it's returned.
* Receives both the found value
* (if it exists for the key) and
* the provided fallback arg.
*
* @returns {mixed} The value present in the settings state for the given
* name.
*/
export function getSetting( name, fallback = false, filter = val => val ) {
const value = allSettings.hasOwnProperty( name ) ? allSettings[ name ] : fallback;
return filter( value, fallback );
}
/**
* Sets a value to a property on the settings state.
*
* @export
* @param {string} name The setting property key for the
* setting being mutated.
* @param {mixed} value The value to set.
* @param {function} [filter=( val ) => val] Allows for providing a callback
* to sanitize the setting (eg.
* ensure it's a number)
*/
export function setSetting( name, value, filter = val => val ) {
value = filter( value );
allSettings[ name ] = filter( value );
}

View File

@ -0,0 +1,28 @@
/**
* External dependencies
*
* @format
*/
import * as SHARED from '@woocommerce/settings';
/**
* Internal dependencies
*/
import * as FALLBACKS from './fallbacks';
// If `getSetting` is not set, then it was not available so let's do
// defaults.
const SOURCE = ! SHARED || typeof SHARED.getSetting === 'undefined' ? FALLBACKS : SHARED;
export const ADMIN_URL = SOURCE.ADMIN_URL;
export const COUNTRIES = SOURCE.COUNTRIES;
export const CURRENCY = SOURCE.CURRENCY;
export const LOCALE = SOURCE.LOCALE;
export const ORDER_STATUSES = SOURCE.ORDER_STATUSES;
export const SITE_TITLE = SOURCE.SITE_TITLE;
export const WC_ASSET_URL = SOURCE.WC_ASSET_URL;
export const DEFAULT_DATE_RANGE = SOURCE.DEFAULT_DATE_RANGE;
export const getSetting = SOURCE.getSetting;
export const setSetting = SOURCE.setSetting;

View File

@ -3,7 +3,7 @@
* Internal dependencies
*/
import { AdvancedFilters } from '@woocommerce/components';
const { orderStatuses } = wcSettings;
const { ORDER_STATUSES } = '@woocommerce/wc-admin-settings';
const path = ( new URL( document.location ) ).searchParams.get( 'path' ) || '/devdocs';
const query = {
@ -33,9 +33,9 @@ const advancedFilters = {
],
input: {
component: 'SelectControl',
options: Object.keys( orderStatuses ).map( key => ( {
options: Object.keys( ORDER_STATUSES ).map( key => ( {
value: key,
label: orderStatuses[ key ],
label: ORDER_STATUSES[ key ],
} ) ),
},
},

View File

@ -21,6 +21,7 @@ import {
getQueryFromActiveFilters,
getHistory,
} from '@woocommerce/navigation';
import { LOCALE } from '@woocommerce/wc-admin-settings';
/**
* Internal dependencies
@ -37,6 +38,8 @@ const matches = [
{ value: 'any', label: __( 'Any', 'woocommerce-admin' ) },
];
const { siteLocale } = LOCALE;
/**
* Displays a configurable set of filters which can modify query parameters.
*/
@ -186,7 +189,6 @@ class AdvancedFilters extends Component {
}
isEnglish() {
const { siteLocale } = wcSettings;
return /en-/.test( siteLocale );
}

View File

@ -19,6 +19,7 @@ import { textContent } from './utils';
* WooCommerce dependencies
*/
import { formatCurrency } from '@woocommerce/currency';
import { CURRENCY } from '@woocommerce/wc-admin-settings';
class NumberFilter extends Component {
getBetweenString() {
@ -71,8 +72,7 @@ class NumberFilter extends Component {
getFormControl( { type, value, label, onChange } ) {
if ( 'currency' === type ) {
const currencySymbol = get( wcSettings, [ 'currency', 'symbol' ] );
const symbolPosition = get( wcSettings, [ 'currency', 'position' ] );
const { symbol: currencySymbol, symbolPosition } = CURRENCY;
return (
0 === symbolPosition.indexOf( 'right' )

View File

@ -6,7 +6,7 @@ import { __, sprintf } from '@wordpress/i18n';
import classNames from 'classnames';
import { Component, createRef, Fragment } from '@wordpress/element';
import { formatDefaultLocale as d3FormatDefaultLocale } from 'd3-format';
import { get, isEqual, partial, without } from 'lodash';
import { isEqual, partial, without } from 'lodash';
import Gridicon from 'gridicons';
import { IconButton, NavigableMenu, SelectControl } from '@wordpress/components';
import { interpolateViridis as d3InterpolateViridis } from 'd3-scale-chromatic';
@ -18,6 +18,7 @@ import { withViewportMatch } from '@wordpress/viewport';
* WooCommerce dependencies
*/
import { getIdsFromQuery, updateQueryString } from '@woocommerce/navigation';
import { CURRENCY } from '@woocommerce/wc-admin-settings';
/**
* Internal dependencies
@ -42,12 +43,16 @@ function getD3CurrencyFormat( symbol, position ) {
}
}
const currencySymbol = get( wcSettings, [ 'currency', 'symbol' ], '' );
const symbolPosition = get( wcSettings, [ 'currency', 'position' ], 'left' );
const {
symbol: currencySymbol,
symbolPosition,
decimalSeparator: decimal,
thousandSeparator: thousands,
} = CURRENCY;
d3FormatDefaultLocale( {
decimal: get( wcSettings, [ 'currency', 'decimal_separator' ], '.' ),
thousands: get( wcSettings, [ 'currency', 'thousand_separator' ], ',' ),
decimal,
thousands,
grouping: [ 3 ],
currency: getD3CurrencyFormat( currencySymbol, symbolPosition ),
} );

View File

@ -9,7 +9,7 @@ import {
ReportFilters,
Section,
} from '@woocommerce/components';
const { orderStatuses } = wcSettings;
const { ORDER_STATUSES } = '@woocommerce/wc-admin-settings';
const path = '';
const query = {};
@ -49,9 +49,9 @@ const advancedFilters = {
],
input: {
component: 'SelectControl',
options: Object.keys( orderStatuses ).map( key => ( {
options: Object.keys( ORDER_STATUSES ).map( key => ( {
value: key,
label: orderStatuses[ key ],
label: ORDER_STATUSES[ key ],
} ) ),
},
},

View File

@ -2,13 +2,14 @@
/**
* External dependencies
*/
import { get, isNaN } from 'lodash';
import { isNaN } from 'lodash';
import { sprintf } from '@wordpress/i18n';
/**
* WooCommerce dependencies
*/
import { numberFormat } from '@woocommerce/number';
import { CURRENCY as currency } from '@woocommerce/wc-admin-settings';
/**
* Formats money with a given currency code. Uses site's currency settings for formatting.
@ -18,14 +19,13 @@ import { numberFormat } from '@woocommerce/number';
* @returns {?String} A formatted string.
*/
export function formatCurrency( number, currencySymbol ) {
// default to wcSettings (and then to $) if currency symbol is not passed in
if ( ! currencySymbol ) {
currencySymbol = get( wcSettings, [ 'currency', 'symbol' ], '$' );
currencySymbol = currency.symbol;
}
const precision = get( wcSettings, [ 'currency', 'precision' ], 2 );
const precision = currency.precision;
const formattedNumber = numberFormat( number, precision );
const priceFormat = get( wcSettings, [ 'currency', 'price_format' ], '%1$s%2$s' );
const priceFormat = currency.priceFormat;
if ( '' === formattedNumber ) {
return formattedNumber;
@ -42,7 +42,7 @@ export function formatCurrency( number, currencySymbol ) {
* @return {Number} The original number rounded to a decimal point
*/
export function getCurrencyFormatDecimal( number ) {
const { precision = 2 } = wcSettings.currency;
const { precision = 2 } = currency;
if ( 'number' !== typeof number ) {
number = parseFloat( number );
}
@ -60,7 +60,7 @@ export function getCurrencyFormatDecimal( number ) {
* @return {String} The original number rounded to a decimal point
*/
export function getCurrencyFormatString( number ) {
const { precision = 2 } = wcSettings.currency;
const { precision = 2 } = currency;
if ( 'number' !== typeof number ) {
number = parseFloat( number );
}

View File

@ -2,21 +2,52 @@
/**
* Internal dependencies
*/
import { formatCurrency, getCurrencyFormatDecimal, getCurrencyFormatString } from '../src';
import {
formatCurrency,
getCurrencyFormatDecimal,
getCurrencyFormatString,
} from '../src';
/**
* WooCommerce dependencies
* Note: setCurrencyProp doesn't exist on the module alias, it's used for mocking
* values.
*/
import { setCurrencyProp, resetMock } from '@woocommerce/wc-admin-settings';
beforeEach( () => {
resetMock();
} );
jest.mock( '@woocommerce/wc-admin-settings', () => {
let mockedCurrency = jest.requireActual( '@woocommerce/wc-admin-settings' ).CURRENCY;
const originalCurrency = {
...mockedCurrency,
};
const reset = () => {
mockedCurrency = Object.assign( mockedCurrency, originalCurrency );
};
return {
setCurrencyProp: ( prop, value ) => {
mockedCurrency[ prop ] = value;
},
resetMock: reset,
CURRENCY: mockedCurrency,
};
} );
describe( 'formatCurrency', () => {
it( 'should default to wcSettings or USD when currency not passed in', () => {
it( 'should use defaults (USD) when currency not passed in', () => {
expect( formatCurrency( 9.99 ) ).toBe( '$9.99' );
expect( formatCurrency( 30 ) ).toBe( '$30.00' );
} );
it( 'should uses store currency settings, not locale-based', () => {
global.wcSettings.currency.code = 'JPY';
global.wcSettings.currency.precision = 3;
global.wcSettings.currency.decimal_separator = ',';
global.wcSettings.currency.thousand_separator = '.';
global.wcSettings.currency.price_format = '%2$s%1$s';
setCurrencyProp( 'code', 'JPY' );
setCurrencyProp( 'precision', 3 );
setCurrencyProp( 'priceFormat', '%2$s%1$s' );
setCurrencyProp( 'thousandSeparator', '.' );
setCurrencyProp( 'decimalSeparator', ',' );
expect( formatCurrency( 9.49258, '¥' ) ).toBe( '9,493¥' );
expect( formatCurrency( 3000, '¥' ) ).toBe( '3.000,000¥' );
expect( formatCurrency( 3.0002, '¥' ) ).toBe( '3,000¥' );
@ -31,31 +62,23 @@ describe( 'formatCurrency', () => {
describe( 'getCurrencyFormatDecimal', () => {
it( 'should round a number to 2 decimal places in USD', () => {
global.wcSettings.currency.precision = 2;
expect( getCurrencyFormatDecimal( 9.49258 ) ).toBe( 9.49 );
expect( getCurrencyFormatDecimal( 30 ) ).toBe( 30 );
expect( getCurrencyFormatDecimal( 3.0002 ) ).toBe( 3 );
} );
it( 'should round a number to 0 decimal places in JPY', () => {
global.wcSettings.currency.precision = 0;
setCurrencyProp( 'precision', 0 );
expect( getCurrencyFormatDecimal( 1239.88 ) ).toBe( 1240 );
expect( getCurrencyFormatDecimal( 1500 ) ).toBe( 1500 );
expect( getCurrencyFormatDecimal( 33715.02 ) ).toBe( 33715 );
} );
it( 'should correctly convert and round a string', () => {
global.wcSettings.currency.precision = 2;
expect( getCurrencyFormatDecimal( '19.80' ) ).toBe( 19.8 );
} );
it( 'should default to a precision of 2 if none set', () => {
delete global.wcSettings.currency.precision;
expect( getCurrencyFormatDecimal( 59.282 ) ).toBe( 59.28 );
} );
it( "should return 0 when given an input that isn't a number", () => {
global.wcSettings.currency.precision = 2;
expect( getCurrencyFormatDecimal( 'abc' ) ).toBe( 0 );
expect( getCurrencyFormatDecimal( false ) ).toBe( 0 );
expect( getCurrencyFormatDecimal( null ) ).toBe( 0 );
@ -64,31 +87,23 @@ describe( 'getCurrencyFormatDecimal', () => {
describe( 'getCurrencyFormatString', () => {
it( 'should round a number to 2 decimal places in USD', () => {
global.wcSettings.currency.precision = 2;
expect( getCurrencyFormatString( 9.49258 ) ).toBe( '9.49' );
expect( getCurrencyFormatString( 30 ) ).toBe( '30.00' );
expect( getCurrencyFormatString( 3.0002 ) ).toBe( '3.00' );
} );
it( 'should round a number to 0 decimal places in JPY', () => {
global.wcSettings.currency.precision = 0;
setCurrencyProp( 'precision', 0 );
expect( getCurrencyFormatString( 1239.88 ) ).toBe( '1240' );
expect( getCurrencyFormatString( 1500 ) ).toBe( '1500' );
expect( getCurrencyFormatString( 33715.02 ) ).toBe( '33715' );
} );
it( 'should correctly convert and round a string', () => {
global.wcSettings.currency.precision = 2;
expect( getCurrencyFormatString( '19.80' ) ).toBe( '19.80' );
} );
it( 'should default to a precision of 2 if none set', () => {
delete global.wcSettings.currency.precision;
expect( getCurrencyFormatString( '59.282' ) ).toBe( '59.28' );
} );
it( "should return empty string when given an input that isn't a number", () => {
global.wcSettings.currency.precision = 2;
expect( getCurrencyFormatString( 'abc' ) ).toBe( '' );
expect( getCurrencyFormatString( false ) ).toBe( '' );
expect( getCurrencyFormatString( null ) ).toBe( '' );

View File

@ -7,12 +7,17 @@ import { find } from 'lodash';
import { __ } from '@wordpress/i18n';
import { parse } from 'qs';
/**
* WooCommerce dependencies
*/
import { getSetting } from '@woocommerce/wc-admin-settings';
export const isoDateFormat = 'YYYY-MM-DD';
/**
* DateValue Object
*
* @typedef {Object} DateValue - Describes the date range supplied by the date picker.
* @typedef {Object} DateValue - Describes the date range supplied by the date picker.
* @property {string} label - The translated value of the period.
* @property {string} range - The human readable value of a date range.
* @property {moment.Moment} after - Start of the date range.
@ -273,7 +278,7 @@ export const getDateParamsFromQuery = ( { period, compare, after, before } ) =>
before: before ? moment( before ) : null,
};
}
wcSettings.wcAdminSettings = wcSettings.wcAdminSettings || {};
const defaultDateRange =
wcSettings.wcAdminSettings.woocommerce_default_date_range ||
'period=month&compare=previous_year';
@ -519,7 +524,7 @@ export function getDateFormatsForInterval( interval, ticks = 0 ) {
* of moment style js formats.
*/
export function loadLocaleData() {
const { userLocale, weekdaysShort } = wcSettings.l10n;
const { userLocale, weekdaysShort } = getSetting( 'locale' );
// Don't update if the wp locale hasn't been set yet, like in unit tests, for instance.
if ( 'en' !== moment.locale() ) {
moment.updateLocale( userLocale, {

View File

@ -4,6 +4,14 @@
*/
import moment from 'moment';
/**
* WooCommerce settings
*/
import {
setSetting,
getSetting,
} from '@woocommerce/wc-admin-settings';
/**
* Internal dependencies
*/
@ -506,25 +514,27 @@ describe( 'getRangeLabel', () => {
} );
describe( 'loadLocaleData', () => {
const originalLocale = getSetting( 'locale' );
beforeEach( () => {
// Reset to default settings
wcSettings.l10n = {
userLocale: 'en_US',
weekdaysShort: [ 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' ],
};
setSetting( 'locale', originalLocale );
} );
it( 'should load locale data on user locale', () => {
wcSettings.l10n = {
userLocale: 'fr_FR',
weekdaysShort: [ 'dim', 'lun', 'mar', 'mer', 'jeu', 'ven', 'sam' ],
};
setSetting(
'locale',
{
userLocale: 'fr_FR',
weekdaysShort: [ 'dim', 'lun', 'mar', 'mer', 'jeu', 'ven', 'sam' ],
}
);
// initialize locale. Gutenberg normaly does this, but not in test environment.
moment.locale( 'fr_FR', {} );
loadLocaleData();
expect( moment.localeData().weekdaysMin() ).toEqual( wcSettings.l10n.weekdaysShort );
expect( moment.localeData().weekdaysMin() )
.toEqual( getSetting( 'locale' ).weekdaysShort );
} );
} );

View File

@ -2,7 +2,13 @@
/**
* External dependencies
*/
import { get, isFinite } from 'lodash';
import { isFinite } from 'lodash';
/**
* WooCommerce dependencies
*/
import { CURRENCY } from '@woocommerce/wc-admin-settings';
const number_format = require( 'locutus/php/strings/number_format' );
/**
@ -22,8 +28,10 @@ export function numberFormat( number, precision = null ) {
return '';
}
const decimalSeparator = get( wcSettings, [ 'currency', 'decimal_separator' ], '.' );
const thousandSeparator = get( wcSettings, [ 'currency', 'thousand_separator' ], ',' );
const {
decimalSeparator,
thousandSeparator,
} = CURRENCY;
precision = parseInt( precision );
if ( isNaN( precision ) ) {

View File

@ -4,7 +4,34 @@
*/
import { numberFormat } from '../index';
/**
* WooCommerce dependencies
* Note: setCurrencyProp doesn't exist on the module alias, it's used for mocking
* values.
*/
import { setCurrencyProp, resetMock } from '@woocommerce/wc-admin-settings';
jest.mock( '@woocommerce/wc-admin-settings', () => {
let mockedCurrency = jest.requireActual( '@woocommerce/wc-admin-settings' ).CURRENCY;
const originalCurrency = {
...mockedCurrency,
};
const reset = () => {
mockedCurrency = Object.assign( mockedCurrency, originalCurrency );
};
return {
setCurrencyProp: ( prop, value ) => {
mockedCurrency[ prop ] = value;
},
resetMock: reset,
CURRENCY: mockedCurrency,
};
} );
describe( 'numberFormat', () => {
beforeEach( () => {
resetMock();
} );
it( 'should default to precision=null decimal=. thousands=,', () => {
expect( numberFormat( 1000 ) ).toBe( '1,000' );
} );
@ -30,10 +57,8 @@ describe( 'numberFormat', () => {
} );
it( 'uses store currency settings, not locale', () => {
global.wcSettings.siteLocale = 'en-US';
global.wcSettings.currency.decimal_separator = ',';
global.wcSettings.currency.thousand_separator = '.';
setCurrencyProp( 'decimalSeparator', ',' );
setCurrencyProp( 'thousandSeparator', '.' );
expect( numberFormat( '12345.6789', 3 ) ).toBe( '12.345,679' );
} );
} );

View File

@ -37,7 +37,10 @@ class ActivityPanels {
*/
public function __construct() {
add_filter( 'wc_admin_get_user_data_fields', array( $this, 'add_user_data_fields' ) );
add_action( 'woocommerce_components_settings', array( $this, 'component_settings' ), 20 ); // Run after Automattic\WooCommerce\Admin\Loader.
// Run after Automattic\WooCommerce\Admin\Loader.
add_filter( 'woocommerce_components_settings', array( $this, 'component_settings' ), 20 );
// new settings injection
add_filter( 'woocommerce_shared_settings', array( $this, 'component_settings' ), 20 );
add_action( 'woocommerce_updated', array( $this, 'woocommerce_updated_note' ) );
}

View File

@ -57,8 +57,11 @@ class Onboarding {
if ( $this->should_show_tasks() ) {
OnboardingTasks::get_instance();
}
add_action( 'woocommerce_components_settings', array( $this, 'component_settings' ), 20 ); // Run after Automattic\WooCommerce\Admin\Loader.
// old settings injection
// Run after Automattic\WooCommerce\Admin\Loader.
add_filter( 'woocommerce_components_settings', array( $this, 'component_settings' ), 20 );
// new settings injection
add_filter( 'woocommerce_shared_settings', array( $this, 'component_settings' ), 20 );
add_filter( 'woocommerce_component_settings_preload_endpoints', array( $this, 'add_preload_endpoints' ) );
add_action( 'woocommerce_theme_installed', array( $this, 'delete_themes_transient' ) );
add_action( 'after_switch_theme', array( $this, 'delete_themes_transient' ) );

View File

@ -41,7 +41,11 @@ class OnboardingTasks {
*/
public function __construct() {
add_action( 'admin_enqueue_scripts', array( $this, 'add_media_scripts' ) );
add_action( 'woocommerce_components_settings', array( $this, 'component_settings' ), 30 ); // Run after Onboarding.
// old settings injection
// Run after Onboarding.
add_filter( 'woocommerce_components_settings', array( $this, 'component_settings' ), 30 );
// new settings injection
add_filter( 'woocommerce_shared_settings', array( $this, 'component_settings' ), 30 );
add_action( 'admin_init', array( $this, 'set_active_task' ), 20 );
add_action( 'current_screen', array( $this, 'check_active_task_completion' ), 1000 );
}

View File

@ -8,6 +8,8 @@
namespace Automattic\WooCommerce\Admin;
use \_WP_Dependency;
/**
* Loader Class.
*/
@ -47,9 +49,13 @@ class Loader {
*/
public function __construct() {
add_action( 'init', array( __CLASS__, 'load_features' ) );
add_action( 'admin_enqueue_scripts', array( __CLASS__, 'register_scripts' ) );
; add_action( 'admin_enqueue_scripts', array( __CLASS__, 'register_scripts' ) );
add_action( 'admin_enqueue_scripts', array( __CLASS__, 'inject_wc_settings_dependencies' ), 14 );
add_action( 'admin_enqueue_scripts', array( __CLASS__, 'load_scripts' ), 15 );
add_action( 'woocommerce_components_settings', array( __CLASS__, 'add_component_settings' ) );
// old settings injection
add_filter( 'woocommerce_components_settings', array( __CLASS__, 'add_component_settings' ) );
// new settings injection
add_filter( 'woocommerce_shared_settings', array( __CLASS__, 'add_component_settings' ) );
add_filter( 'admin_body_class', array( __CLASS__, 'add_admin_body_classes' ) );
add_action( 'admin_menu', array( __CLASS__, 'register_page_handler' ) );
add_filter( 'admin_title', array( __CLASS__, 'update_admin_title' ) );
@ -518,6 +524,23 @@ class Loader {
* @return array Array of component settings.
*/
public static function add_component_settings( $settings ) {
if ( ! function_exists( 'wc_blocks_container' ) ) {
global $wp_locale;
// inject data not available via older versions of wc_blocks/woo.
$settings['orderStatuses'] = self::get_order_statuses( wc_get_order_statuses() );
$settings['currency'] = self::get_currency_settings();
$settings['locale'] = [
'siteLocale' => isset( $settings['siteLocale'] )
? $settings['siteLocale']
: get_locale(),
'userLocale' => isset( $settings['l10n']['userLocale'] )
? $settings['l10n']['userLocale']
: get_user_locale(),
'weekdaysShort' => isset( $settings['l10n']['weekdaysShort'] )
? $settings['l10n']['weekdaysShort']
: array_values( $wp_locale->weekday_abbrev )
];
}
$preload_data_endpoints = apply_filters( 'woocommerce_component_settings_preload_endpoints', array( '/wc/v3' ) );
if ( ! empty( $preload_data_endpoints ) ) {
$preload_data = array_reduce(
@ -530,10 +553,7 @@ class Loader {
foreach ( self::get_user_data_fields() as $user_field ) {
$current_user_data[ $user_field ] = json_decode( get_user_meta( get_current_user_id(), 'wc_admin_' . $user_field, true ) );
}
$settings['orderStatuses'] = self::get_order_statuses( wc_get_order_statuses() );
$settings['currentUserData'] = $current_user_data;
$settings['currency'] = self::get_currency_settings();
$settings['reviewsEnabled'] = get_option( 'woocommerce_enable_reviews' );
$settings['manageStock'] = get_option( 'woocommerce_manage_stock' );
$settings['commentModeration'] = get_option( 'comment_moderation' );
@ -543,6 +563,9 @@ class Loader {
$settings['wcAdminAssetUrl'] = plugins_url( 'images/', plugin_dir_path( dirname( __DIR__ ) ) . 'woocommerce-admin.php' );
if ( ! empty( $preload_data_endpoints ) ) {
$settings['dataEndpoints'] = isset( $settings['dataEndpoints'] )
? $settings['dataEndpoints']
: [];
foreach ( $preload_data_endpoints as $key => $endpoint ) {
// Handle error case: rest_do_request() doesn't guarantee success.
if ( empty( $preload_data[ $endpoint ] ) ) {
@ -553,11 +576,9 @@ class Loader {
}
}
$settings = self::get_custom_settings( $settings );
if ( self::is_embed_page() ) {
$settings['embedBreadcrumbs'] = self::get_embed_breadcrumbs();
}
return $settings;
}
@ -664,13 +685,13 @@ class Loader {
return apply_filters(
'wc_currency_settings',
array(
'code' => $code,
'precision' => wc_get_price_decimals(),
'symbol' => html_entity_decode( get_woocommerce_currency_symbol( $code ) ),
'position' => get_option( 'woocommerce_currency_pos' ),
'decimal_separator' => wc_get_price_decimal_separator(),
'thousand_separator' => wc_get_price_thousand_separator(),
'price_format' => html_entity_decode( get_woocommerce_price_format() ),
'code' => $code,
'precision' => wc_get_price_decimals(),
'symbol' => html_entity_decode( get_woocommerce_currency_symbol( $code ) ),
'symbolPosition' => get_option( 'woocommerce_currency_pos' ),
'decimalSeparator' => wc_get_price_decimal_separator(),
'thousandSeparator' => wc_get_price_thousand_separator(),
'priceFormat' => html_entity_decode( get_woocommerce_price_format() ),
)
);
}
@ -737,4 +758,26 @@ class Loader {
public static function get_user_data_fields() {
return apply_filters( 'wc_admin_get_user_data_fields', array() );
}
/**
* Injects wp-shared-settings as a dependency if it's present.
*/
public static function inject_wc_settings_dependencies() {
if ( wp_script_is( 'wc-settings', 'registered' ) ) {
$handles_for_injection = [
'wc-csv',
'wc-currency',
'wc-navigation',
'wc-number',
'wc-date',
'wc-components',
];
foreach( $handles_for_injection as $handle ) {
$script = wp_scripts()->query( $handle, 'registered' );
if ( $script instanceof _WP_Dependency ) {
$script->deps[] = 'wc-settings';
}
}
}
}
}

View File

@ -10,6 +10,7 @@
"moduleDirectories": ["node_modules", "<rootDir>/client", "<rootDir>/packages"],
"moduleNameMapper": {
"tinymce": "<rootDir>/tests/js/mocks/tinymce",
"@woocommerce/(settings|wc-admin-settings)": "<rootDir>/client/settings/index.js",
"@woocommerce/(.*)": "<rootDir>/packages/$1/src"
},
"setupFiles": [

View File

@ -30,6 +30,43 @@ const wooCommercePackages = [
'number',
];
// aliases
global.wcSettings = {
adminUrl: 'https://vagrant.local/wp/wp-admin/',
countries: [],
currency: {
code: 'USD',
precision: 2,
symbol: '$',
symbolPosition: 'left',
decimalSeparator: '.',
priceFormat: '%1$s%2$s',
thousandSeparator: ',',
},
defaultDateRange: 'period=month&compare=previous_year',
date: {
dow: 0,
},
locale: {
siteLocale: 'en_US',
userLocale: 'en_US',
weekdaysShort: [ 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' ],
},
orderStatuses: {
pending: 'Pending payment',
processing: 'Processing',
'on-hold': 'On hold',
completed: 'Completed',
cancelled: 'Cancelled',
refunded: 'Refunded',
failed: 'Failed',
},
wcAdminSettings: {
woocommerce_actionable_order_statuses: [],
woocommerce_excluded_report_order_statuses: [],
},
};
wordPressPackages.forEach( lib => {
Object.defineProperty( global.wp, lib, {
get: () => require( `@wordpress/${ lib }` ),
@ -42,32 +79,6 @@ wooCommercePackages.forEach( lib => {
} );
} );
global.wcSettings = {
adminUrl: 'https://vagrant.local/wp/wp-admin/',
locale: 'en-US',
currency: { code: 'USD', precision: 2, symbol: '$' },
date: {
dow: 0,
},
orderStatuses: {
pending: 'Pending payment',
processing: 'Processing',
'on-hold': 'On hold',
completed: 'Completed',
cancelled: 'Cancelled',
refunded: 'Refunded',
failed: 'Failed',
},
l10n: {
userLocale: 'en_US',
weekdaysShort: [ 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' ],
},
wcAdminSettings: {
woocommerce_actionable_order_statuses: [],
woocommerce_excluded_report_order_statuses: [],
},
};
const config = require( '../../config/development.json' );
window.wcAdminFeatures = config && config.features ? config.features : {};

View File

@ -34,6 +34,7 @@ const externals = {
'@wordpress/html-entities': { this: [ 'wp', 'htmlEntities' ] },
'@wordpress/i18n': { this: [ 'wp', 'i18n' ] },
'@wordpress/keycodes': { this: [ 'wp', 'keycodes' ] },
'@woocommerce/settings': { this: [ 'wc', 'wcSettings' ] },
tinymce: 'tinymce',
moment: 'moment',
react: 'React',
@ -150,6 +151,10 @@ const webpackConfig = {
'gutenberg-components': path.resolve( __dirname, 'node_modules/@wordpress/components/src' ),
// @todo - remove once https://github.com/WordPress/gutenberg/pull/16196 is released.
'react-spring': 'react-spring/web.cjs',
'@woocommerce/wc-admin-settings': path.resolve(
__dirname,
'client/settings/index.js'
),
},
},
plugins: [