Try: Add Lerna to split out utility packages (https://github.com/woocommerce/woocommerce-admin/pull/678)

* Add lerna & GB package-building script

* Move currency library to lerna module

* Update lerna config

* Add publish commands

* Add currency as an faux-external module

* Add separate command to build just core files

* Update dependency path

* Update build script to build all packages into `dist`

* Add packages to the jest test setup

* Move date library to packages

* Update imports to use @woocommerce/date

* Output wcSettings definition before any scripts are output

Fixes issues where wc-dates lib relies on settings object

* Add the build step into travis

* Update jest config to dynamically get package paths

* Update package postcss config to match wc-admin’s main config

* Add combined watch scripts for package+app, add a `clean` command to clean up old build files

* Ignore PHPCS error (leave todo message to fix)

* Concat files with a space, fix issue where all files join in one continuous string and fail the check
This commit is contained in:
Kelly Dwan 2018-10-30 14:57:48 -04:00 committed by GitHub
parent f6940db59c
commit f62537fc17
44 changed files with 4312 additions and 128 deletions

View File

@ -1,18 +1,21 @@
# Directories/files that may be generated by this project
node_modules/
dist
build
build-module
build-style
languages/*
!languages/README.md
wc-admin.zip
# Directories/files that may appear in your environment
.DS_Store
phpcs.xml
phpunit.xml
Thumbs.db
wp-cli.local.yml
node_modules/
*.sql
*.tar.gz
*.zip
vendor/
dist
languages/*
!languages/README.md
.idea
.vscode/

View File

@ -27,6 +27,7 @@ node_js:
script:
- npm run lint
- npm run build
- npm test
- bash bin/phpunit.sh
- bash bin/phpcs.sh

View File

@ -0,0 +1,222 @@
/**
* script to build packages into `build/` directory.
*
* Example:
* node ./bin/packages/build.js
*/
/**
* External dependencies
*/
const fs = require( 'fs' );
const path = require( 'path' );
const glob = require( 'glob' );
const babel = require( '@babel/core' );
const chalk = require( 'chalk' );
const mkdirp = require( 'mkdirp' );
const sass = require( 'node-sass' );
const postcss = require( 'postcss' );
const deasync = require( 'deasync' );
/**
* Internal dependencies
*/
const getPackages = require( './get-packages' );
const getBabelConfig = require( './get-babel-config' );
/**
* Module Constants
*/
const PACKAGES_DIR = path.resolve( __dirname, '../../packages' );
const SRC_DIR = 'src';
const BUILD_DIR = {
main: 'build',
module: 'build-module',
style: 'build-style',
};
const DONE = chalk.reset.inverse.bold.green( ' DONE ' );
/**
* Get the package name for a specified file
*
* @param {string} file File name
* @return {string} Package name
*/
function getPackageName( file ) {
return path.relative( PACKAGES_DIR, file ).split( path.sep )[ 0 ];
}
const isJsFile = ( filepath ) => {
return /.\.js$/.test( filepath );
};
const isScssFile = ( filepath ) => {
return /.\.scss$/.test( filepath );
};
/**
* Get Build Path for a specified file
*
* @param {string} file File to build
* @param {string} buildFolder Output folder
* @return {string} Build path
*/
function getBuildPath( file, buildFolder ) {
const pkgName = getPackageName( file );
const pkgSrcPath = path.resolve( PACKAGES_DIR, pkgName, SRC_DIR );
const pkgBuildPath = path.resolve( PACKAGES_DIR, pkgName, buildFolder );
const relativeToSrcPath = path.relative( pkgSrcPath, file );
return path.resolve( pkgBuildPath, relativeToSrcPath );
}
/**
* Given a list of scss and js filepaths, divide them into sets them and rebuild.
*
* @param {Array} files list of files to rebuild
*/
function buildFiles( files ) {
// Reduce files into a unique sets of javaScript files and scss packages.
const buildPaths = files.reduce( ( accumulator, filePath ) => {
if ( isJsFile( filePath ) ) {
accumulator.jsFiles.add( filePath );
} else if ( isScssFile( filePath ) ) {
const pkgName = getPackageName( filePath );
const pkgPath = path.resolve( PACKAGES_DIR, pkgName );
accumulator.scssPackagePaths.add( pkgPath );
}
return accumulator;
}, { jsFiles: new Set(), scssPackagePaths: new Set() } );
buildPaths.jsFiles.forEach( buildJsFile );
buildPaths.scssPackagePaths.forEach( buildPackageScss );
}
/**
* Build a javaScript file for the required environments (node and ES5)
*
* @param {string} file File path to build
* @param {boolean} silent Show logs
*/
function buildJsFile( file, silent ) {
buildJsFileFor( file, silent, 'main' );
buildJsFileFor( file, silent, 'module' );
}
/**
* Build a package's scss styles
*
* @param {string} packagePath The path to the package.
*/
function buildPackageScss( packagePath ) {
const srcDir = path.resolve( packagePath, SRC_DIR );
const scssFiles = glob.sync( `${ srcDir }/*.scss` );
// Build scss files individually.
scssFiles.forEach( buildScssFile );
}
function buildScssFile( styleFile ) {
const outputFile = getBuildPath( styleFile.replace( '.scss', '.css' ), BUILD_DIR.style );
const outputFileRTL = getBuildPath( styleFile.replace( '.scss', '-rtl.css' ), BUILD_DIR.style );
mkdirp.sync( path.dirname( outputFile ) );
const builtSass = sass.renderSync( {
file: styleFile,
includePaths: [ path.resolve( __dirname, '../../assets/stylesheets' ) ],
data: (
[
'colors',
'breakpoints',
'variables',
'mixins',
'animations',
'z-index',
].map( ( imported ) => `@import "${ imported }";` ).join( ' ' ) +
fs.readFileSync( styleFile, 'utf8' )
),
} );
const postCSSSync = ( callback ) => {
postcss( require( './post-css-config' ) )
.process( builtSass.css, { from: 'src/app.css', to: 'dest/app.css' } )
.then( ( result ) => callback( null, result ) );
};
const postCSSRTLSync = ( ltrCSS, callback ) => {
postcss( [ require( 'rtlcss' )() ] )
.process( ltrCSS, { from: 'src/app.css', to: 'dest/app.css' } )
.then( ( result ) => callback( null, result ) );
};
const result = deasync( postCSSSync )();
fs.writeFileSync( outputFile, result.css );
const resultRTL = deasync( postCSSRTLSync )( result );
fs.writeFileSync( outputFileRTL, resultRTL );
}
/**
* Build a file for a specific environment
*
* @param {string} file File path to build
* @param {boolean} silent Show logs
* @param {string} environment Dist environment (node or es5)
*/
function buildJsFileFor( file, silent, environment ) {
const buildDir = BUILD_DIR[ environment ];
const destPath = getBuildPath( file, buildDir );
const babelOptions = getBabelConfig( environment );
babelOptions.sourceMaps = true;
babelOptions.sourceFileName = file;
mkdirp.sync( path.dirname( destPath ) );
const transformed = babel.transformFileSync( file, babelOptions );
fs.writeFileSync( destPath + '.map', JSON.stringify( transformed.map ) );
fs.writeFileSync( destPath, transformed.code + '\n//# sourceMappingURL=' + path.basename( destPath ) + '.map' );
if ( ! silent ) {
process.stdout.write(
chalk.green( ' \u2022 ' ) +
path.relative( PACKAGES_DIR, file ) +
chalk.green( ' \u21D2 ' ) +
path.relative( PACKAGES_DIR, destPath ) +
'\n'
);
}
}
/**
* Build the provided package path
*
* @param {string} packagePath absolute package path
*/
function buildPackage( packagePath ) {
const srcDir = path.resolve( packagePath, SRC_DIR );
const jsFiles = glob.sync( `${ srcDir }/**/*.js`, {
ignore: [
`${ srcDir }/**/test/**/*.js`,
`${ srcDir }/**/__mocks__/**/*.js`,
],
nodir: true,
} );
process.stdout.write( `${ path.basename( packagePath ) }\n` );
// Build js files individually.
jsFiles.forEach( ( file ) => buildJsFile( file, true ) );
// Build package CSS files
buildPackageScss( packagePath );
process.stdout.write( `${ DONE }\n` );
}
const files = process.argv.slice( 2 );
if ( files.length ) {
buildFiles( files );
} else {
process.stdout.write( chalk.inverse( '>> Building packages \n' ) );
getPackages()
.forEach( buildPackage );
process.stdout.write( '\n' );
}

View File

@ -0,0 +1,71 @@
/**
* External dependencies
*/
const { get, map } = require( 'lodash' );
const babel = require( '@babel/core' );
/**
* WordPress dependencies
*/
const { options: babelDefaultConfig } = babel.loadPartialConfig( {
configFile: '@wordpress/babel-preset-default',
} );
const plugins = babelDefaultConfig.plugins;
if ( ! process.env.SKIP_JSX_PRAGMA_TRANSFORM ) {
plugins.push( [ '@wordpress/babel-plugin-import-jsx-pragma', {
scopeVariable: 'createElement',
source: '@wordpress/element',
isDefault: false,
} ] );
}
const overrideOptions = ( target, targetName, options ) => {
if ( get( target, [ 'file', 'request' ] ) === targetName ) {
return [ targetName, Object.assign(
{},
target.options,
options
) ];
}
return target;
};
const babelConfigs = {
main: Object.assign(
{},
babelDefaultConfig,
{
plugins,
presets: map(
babelDefaultConfig.presets,
( preset ) => overrideOptions( preset, '@babel/preset-env', {
modules: 'commonjs',
} )
),
}
),
module: Object.assign(
{},
babelDefaultConfig,
{
plugins: map(
plugins,
( plugin ) => overrideOptions( plugin, '@babel/plugin-transform-runtime', {
useESModules: true,
} )
),
presets: map(
babelDefaultConfig.presets,
( preset ) => overrideOptions( preset, '@babel/preset-env', {
modules: false,
} )
),
}
),
};
function getBabelConfig( environment ) {
return babelConfigs[ environment ];
}
module.exports = getBabelConfig;

View File

@ -0,0 +1,83 @@
/**
* External dependencies
*/
const fs = require( 'fs' );
const path = require( 'path' );
const { overEvery, compact, includes, negate } = require( 'lodash' );
/**
* Absolute path to packages directory.
*
* @type {string}
*/
const PACKAGES_DIR = path.resolve( __dirname, '../../packages' );
const {
/**
* Comma-separated string of packages to include in build.
*
* @type {string}
*/
INCLUDE_PACKAGES,
/**
* Comma-separated string of packages to exclude from build.
*
* @type {string}
*/
EXCLUDE_PACKAGES,
} = process.env;
/**
* Given a comma-separated string, returns a filter function which returns true
* if the item is contained within as a comma-separated entry.
*
* @param {Function} filterFn Filter function to call with item to test.
* @param {string} list Comma-separated list of items.
*
* @return {Function} Filter function.
*/
const createCommaSeparatedFilter = ( filterFn, list ) => {
const listItems = list.split( ',' );
return ( item ) => filterFn( listItems, item );
};
/**
* Returns true if the given base file name for a file within the packages
* directory is itself a directory.
*
* @param {string} file Packages directory file.
*
* @return {boolean} Whether file is a directory.
*/
function isDirectory( file ) {
return fs.lstatSync( path.resolve( PACKAGES_DIR, file ) ).isDirectory();
}
/**
* Filter predicate, returning true if the given base file name is to be
* included in the build.
*
* @param {string} pkg File base name to test.
*
* @return {boolean} Whether to include file in build.
*/
const filterPackages = overEvery( compact( [
isDirectory,
INCLUDE_PACKAGES && createCommaSeparatedFilter( includes, INCLUDE_PACKAGES ),
EXCLUDE_PACKAGES && createCommaSeparatedFilter( negate( includes ), EXCLUDE_PACKAGES ),
] ) );
/**
* Returns the absolute path of all WordPress packages
*
* @return {Array} Package paths
*/
function getPackages() {
return fs
.readdirSync( PACKAGES_DIR )
.filter( filterPackages )
.map( ( file ) => path.resolve( PACKAGES_DIR, file ) );
}
module.exports = getPackages;

View File

@ -0,0 +1,22 @@
module.exports = [
require( './node_modules/@wordpress/postcss-themes' )( {
defaults: {
primary: '#0085ba',
secondary: '#11a0d2',
toggle: '#11a0d2',
button: '#0085ba',
outlines: '#007cba',
},
themes: {
'woocommerce-page': {
primary: '#95588a',
secondary: '#95588a',
toggle: '#95588a',
button: '#95588a',
outlines: '#95588a',
},
},
} ),
require( 'autoprefixer' ),
require( 'postcss-color-function' ),
];

View File

@ -0,0 +1,76 @@
/**
* External dependencies
*/
const fs = require( 'fs' );
const { execSync } = require( 'child_process' );
const path = require( 'path' );
const chalk = require( 'chalk' );
/**
* Internal dependencies
*/
const getPackages = require( './get-packages' );
const BUILD_CMD = `node ${ path.resolve( __dirname, './build.js' ) }`;
let filesToBuild = new Map();
const exists = ( filename ) => {
try {
return fs.statSync( filename ).isFile();
} catch ( e ) {}
return false;
};
// Exclude deceitful source-like files, such as editor swap files.
const isSourceFile = ( filename ) => {
return /.\.(js|scss)$/.test( filename );
};
const rebuild = ( filename ) => filesToBuild.set( filename, true );
getPackages().forEach( ( p ) => {
const srcDir = path.resolve( p, 'src' );
try {
fs.accessSync( srcDir, fs.F_OK );
fs.watch( path.resolve( p, 'src' ), { recursive: true }, ( event, filename ) => {
const filePath = path.resolve( srcDir, filename );
if ( ! isSourceFile( filename ) ) {
return;
}
if ( ( event === 'change' || event === 'rename' ) && exists( filePath ) ) {
// eslint-disable-next-line no-console
console.log( chalk.green( '->' ), `${ event }: ${ filename }` );
rebuild( filePath );
} else {
const buildFile = path.resolve( srcDir, '..', 'build', filename );
try {
fs.unlinkSync( buildFile );
process.stdout.write(
chalk.red( ' \u2022 ' ) +
path.relative( path.resolve( srcDir, '..', '..' ), buildFile ) +
' (deleted)' +
'\n'
);
} catch ( e ) {}
}
} );
} catch ( e ) {
// doesn't exist
}
} );
setInterval( () => {
const files = Array.from( filesToBuild.keys() );
if ( files.length ) {
filesToBuild = new Map();
try {
execSync( `${ BUILD_CMD } ${ files.join( ' ' ) }`, { stdio: [ 0, 1, 2 ] } );
} catch ( e ) {}
}
}, 100 );
// eslint-disable-next-line no-console
console.log( chalk.red( '->' ), chalk.cyan( 'Watching for changes...' ) );

View File

@ -105,7 +105,7 @@ files.forEach( file => {
hasPhpLintErrors = true;
}
phpFiles += '' + file;
phpFiles += ' ' + file;
} );
if ( hasPhpLintErrors ) {

View File

@ -10,7 +10,7 @@ import { withSelect } from '@wordpress/data';
import PropTypes from 'prop-types';
/**
* Internal dependencies
* WooCommerce dependencies
*/
import { Chart, ChartPlaceholder } from '@woocommerce/components';
import {
@ -19,7 +19,11 @@ import {
getDateFormatsForInterval,
getIntervalForQuery,
getPreviousDate,
} from 'lib/date';
} from '@woocommerce/date';
/**
* Internal dependencies
*/
import { getReportChartData } from 'store/reports/utils';
import ReportError from 'analytics/components/report-error';

View File

@ -9,16 +9,20 @@ import { map } from 'lodash';
import { withSelect } from '@wordpress/data';
import PropTypes from 'prop-types';
/**
* WooCommerce dependencies
*/
import { formatCurrency } from '@woocommerce/currency';
import { getDateParamsFromQuery } from '@woocommerce/date';
import { SummaryList, SummaryListPlaceholder, SummaryNumber } from '@woocommerce/components';
/**
* Internal dependencies
*/
import { formatCurrency } from 'lib/currency';
import { getNewPath } from 'lib/nav-utils';
import { SummaryList, SummaryListPlaceholder, SummaryNumber } from '@woocommerce/components';
import { getDateParamsFromQuery } from 'lib/date';
import { getSummaryNumbers } from 'store/reports/utils';
import ReportError from 'analytics/components/report-error';
import { numberFormat } from 'lib/number';
import ReportError from 'analytics/components/report-error';
class ReportSummary extends Component {
render() {

View File

@ -6,10 +6,14 @@ import { Component, Fragment } from '@wordpress/element';
import PropTypes from 'prop-types';
/**
* Internal dependencies
* WooCommerce dependencies
*/
import { ReportFilters } from '@woocommerce/components';
import { filters, advancedFilters } from './config';
/**
* Internal dependencies
*/
import { advancedFilters, filters } from './config';
import OrdersReportChart from './chart';
import OrdersReportTable from './table';

View File

@ -10,16 +10,20 @@ import { withSelect } from '@wordpress/data';
import { get, map, orderBy } from 'lodash';
/**
* Internal dependencies
* WooCommerce dependencies
*/
import { Link, OrderStatus, TableCard, ViewMoreList } from '@woocommerce/components';
import { formatCurrency, getCurrencyFormatDecimal } from 'lib/currency';
import { formatCurrency, getCurrencyFormatDecimal } from '@woocommerce/currency';
import {
appendTimestamp,
getCurrentDates,
getIntervalForQuery,
getDateFormatsForInterval,
} from 'lib/date';
} from '@woocommerce/date';
/**
* Internal dependencies
*/
import { getAdminLink, onQueryChange } from 'lib/nav-utils';
import ReportError from 'analytics/components/report-error';
import { QUERY_DEFAULTS } from 'store/constants';

View File

@ -5,11 +5,15 @@
import { Component, Fragment } from '@wordpress/element';
import PropTypes from 'prop-types';
/**
* WooCommerce dependencies
*/
import { ReportFilters } from '@woocommerce/components';
/**
* Internal dependencies
*/
import { filters } from './config';
import { ReportFilters } from '@woocommerce/components';
import ProductsReportChart from './chart';
import ProductsReportTable from './table';

View File

@ -9,11 +9,15 @@ import { withSelect } from '@wordpress/data';
import { get, map, orderBy } from 'lodash';
/**
* Internal dependencies
* WooCommerce dependencies
*/
import { Link, TableCard } from '@woocommerce/components';
import { formatCurrency, getCurrencyFormatDecimal } from 'lib/currency';
import { appendTimestamp, getCurrentDates } from 'lib/date';
import { formatCurrency, getCurrencyFormatDecimal } from '@woocommerce/currency';
import { appendTimestamp, getCurrentDates } from '@woocommerce/date';
/**
* Internal dependencies
*/
import { getNewPath, getTimeRelatedQuery, onQueryChange } from 'lib/nav-utils';
import ReportError from 'analytics/components/report-error';
import { getFilterQuery, getReportChartData } from 'store/reports/utils';

View File

@ -6,9 +6,13 @@ import { Component, Fragment } from '@wordpress/element';
import PropTypes from 'prop-types';
/**
* Internal dependencies
* WooCommerce dependencies
*/
import { ReportFilters } from '@woocommerce/components';
/**
* Internal dependencies
*/
import RevenueReportChart from './chart';
import RevenueReportTable from './table';

View File

@ -10,16 +10,20 @@ import { withSelect } from '@wordpress/data';
import { get, map } from 'lodash';
/**
* Internal dependencies
* WooCommerce dependencies
*/
import { Link, TableCard } from '@woocommerce/components';
import { formatCurrency, getCurrencyFormatDecimal } from 'lib/currency';
import { formatCurrency, getCurrencyFormatDecimal } from '@woocommerce/currency';
import {
appendTimestamp,
getCurrentDates,
getDateFormatsForInterval,
getIntervalForQuery,
} from 'lib/date';
} from '@woocommerce/date';
/**
* Internal dependencies
*/
import { onQueryChange } from 'lib/nav-utils';
import ReportError from 'analytics/components/report-error';
import { QUERY_DEFAULTS } from 'store/constants';

View File

@ -17,13 +17,17 @@ import classnames from 'classnames';
import PropTypes from 'prop-types';
import 'react-dates/lib/css/_datepicker.css';
/**
* WooCommerce dependencies
*/
import { validateDateInputForRange } from '@woocommerce/date';
/**
* Internal dependencies
*/
import DateInput from './input';
import { isMobileViewport } from 'lib/ui';
import phrases from './phrases';
import { validateDateInputForRange } from 'lib/date';
import './style.scss';
/**

View File

@ -6,11 +6,15 @@ import classNames from 'classnames';
import { Component } from '@wordpress/element';
import PropTypes from 'prop-types';
/**
* WooCommerce dependencies
*/
import { formatCurrency } from '@woocommerce/currency';
/**
* Internal dependencies
*/
import './style.scss';
import { formatCurrency } from 'lib/currency';
import { getColor } from './utils';
function getFormatedTotal( total, valueType ) {

View File

@ -17,10 +17,10 @@ import { line as d3Line } from 'd3-shape';
import { format as formatDate } from '@wordpress/date';
/**
* Internal dependencies
* WooCommerce dependencies
*/
import { formatCurrency } from 'lib/currency';
import { dayTicksThreshold } from 'lib/date';
import { dayTicksThreshold } from '@woocommerce/date';
import { formatCurrency } from '@woocommerce/currency';
/**
* Describes `smallestFactor`

View File

@ -6,11 +6,15 @@ import { __ } from '@wordpress/i18n';
import { Component } from '@wordpress/element';
import PropTypes from 'prop-types';
/**
* WooCommerce dependencies
*/
import { periods } from '@woocommerce/date';
/**
* Internal dependencies
*/
import SegmentedSelection from 'components/segmented-selection';
import { periods } from 'lib/date';
class ComparePeriods extends Component {
render() {

View File

@ -7,12 +7,16 @@ import { __ } from '@wordpress/i18n';
import { Dropdown } from '@wordpress/components';
import PropTypes from 'prop-types';
/**
* WooCommerce dependencies
*/
import { getCurrentDates, getDateParamsFromQuery, isoDateFormat } from '@woocommerce/date';
/**
* Internal dependencies
*/
import DatePickerContent from './content';
import DropdownButton from 'components/dropdown-button';
import { getCurrentDates, getDateParamsFromQuery, isoDateFormat } from 'lib/date';
import { updateQueryString } from 'lib/nav-utils';
import './style.scss';

View File

@ -7,11 +7,15 @@ import { Component } from '@wordpress/element';
import { filter } from 'lodash';
import PropTypes from 'prop-types';
/**
* WooCommerce dependencies
*/
import { presetValues } from '@woocommerce/date';
/**
* Internal dependencies
*/
import SegmentedSelection from 'components/segmented-selection';
import { presetValues } from 'lib/date';
class PresetPeriods extends Component {
render() {

View File

@ -9,12 +9,16 @@ import { compose } from '@wordpress/compose';
import { withSelect } from '@wordpress/data';
/**
* Internal dependencies
* WooCommerce dependencies
*/
import { Card, EmptyTable, TableCard } from '@woocommerce/components';
import { formatCurrency, getCurrencyFormatDecimal } from '@woocommerce/currency';
/**
* Internal dependencies
*/
import { getAdminLink } from 'lib/nav-utils';
import { numberFormat } from 'lib/number';
import { formatCurrency, getCurrencyFormatDecimal } from 'lib/currency';
import { NAMESPACE } from 'store/constants';
import './style.scss';

View File

@ -7,12 +7,16 @@ import TestRenderer from 'react-test-renderer';
import { shallow } from 'enzyme';
import { createRegistry, RegistryProvider } from '@wordpress/data';
/**
* WooCommerce dependencies
*/
import { formatCurrency, getCurrencyFormatDecimal } from '@woocommerce/currency';
/**
* Internal dependencies
*/
import TopSellingProductsWithSelect, { TopSellingProducts } from '../';
import { numberFormat } from 'lib/number';
import { formatCurrency, getCurrencyFormatDecimal } from 'lib/currency';
import mockData from '../__mocks__/top-selling-products-mock-data';
// Mock <Table> to avoid tests failing due to it using DOM properties that

View File

@ -9,11 +9,8 @@ import PropTypes from 'prop-types';
import { noop } from 'lodash';
/**
* Internal dependencies
* WooCommerce dependencies
*/
import { ActivityCard } from '../activity-card';
import ActivityHeader from '../activity-header';
import ActivityOutboundLink from '../activity-outbound-link';
import {
EllipsisMenu,
Gravatar,
@ -23,7 +20,14 @@ import {
OrderStatus,
Section,
} from '@woocommerce/components';
import { formatCurrency, getCurrencyFormatDecimal } from 'lib/currency';
import { formatCurrency, getCurrencyFormatDecimal } from '@woocommerce/currency';
/**
* Internal dependencies
*/
import { ActivityCard } from '../activity-card';
import ActivityHeader from '../activity-header';
import ActivityOutboundLink from '../activity-outbound-link';
import { getOrderRefundTotal } from 'lib/order-values';
function OrdersPanel( { orders } ) {

View File

@ -5,11 +5,15 @@
*/
import { find, forEach, isNull } from 'lodash';
/**
* WooCommerce dependencies
*/
import { appendTimestamp, getCurrentDates, getIntervalForQuery } from '@woocommerce/date';
/**
* Internal dependencies
*/
import { MAX_PER_PAGE } from 'store/constants';
import { appendTimestamp, getCurrentDates, getIntervalForQuery } from 'lib/date';
import { getActiveFiltersFromQuery, getUrlKey } from 'components/filters/advanced/utils';
import { flatenFilters } from 'components/filters/filter/utils';
import * as couponsConfig from 'analytics/report/coupons/config';

View File

@ -290,7 +290,7 @@ class WC_Admin_Reports_Data_Store {
*/
protected function get_cache_key( $params ) {
// TODO: this is not working in PHP 5.2 (but revenue class has static methods, so it cannot use object property).
return 'woocommerce_' . $this::TABLE_NAME . '_' . md5( wp_json_encode( $params ) );
return 'woocommerce_' . $this::TABLE_NAME . '_' . md5( wp_json_encode( $params ) ); // phpcs:ignore PHPCompatibility.Syntax.NewDynamicAccessToStatic
}
/**

View File

@ -0,0 +1,15 @@
{
"command": {
"publish": {
"message": "chore(release): publish"
}
},
"ignoreChanges": [
"**/CHANGELOG.md",
"**/test/**"
],
"packages": [
"packages/*"
],
"version": "independent"
}

View File

@ -13,50 +13,87 @@ function wc_admin_register_script() {
$screen_id = wc_admin_get_current_screen_id();
if ( in_array( $screen_id, wc_admin_get_embed_enabled_screen_ids() ) ) {
$js_entry = 'dist/embedded.js';
$css_entry = 'dist/css/embedded.css';
$entry = 'embedded';
} else {
$js_entry = 'dist/index.js';
$css_entry = 'dist/css/index.css';
$entry = 'app';
}
wp_register_script(
'wc-components',
wc_admin_url( 'dist/components.js' ),
array( 'wp-components', 'wp-data', 'wp-element', 'wp-hooks', 'wp-i18n', 'wp-keycodes' ),
filemtime( wc_admin_dir_path( 'dist/components.js' ) ),
'wc-currency',
wc_admin_url( 'dist/currency/index.js' ),
array(),
filemtime( wc_admin_dir_path( 'dist/currency/index.js' ) ),
true
);
wp_register_style(
wp_register_script(
'wc-date',
wc_admin_url( 'dist/date/index.js' ),
array( 'wp-date', 'wp-i18n' ),
filemtime( wc_admin_dir_path( 'dist/date/index.js' ) ),
true
);
wp_register_script(
'wc-components',
wc_admin_url( 'dist/css/components.css' ),
array( 'wp-edit-blocks' ),
filemtime( wc_admin_dir_path( 'dist/css/components.css' ) )
wc_admin_url( 'dist/components/index.js' ),
array(
'wp-components',
'wp-data',
'wp-element',
'wp-hooks',
'wp-i18n',
'wp-keycodes',
'wc-currency',
'wc-date',
),
filemtime( wc_admin_dir_path( 'dist/components/index.js' ) ),
true
);
wp_register_script(
WC_ADMIN_APP,
wc_admin_url( $js_entry ),
wc_admin_url( "dist/{$entry}/index.js" ),
array( 'wc-components', 'wp-date', 'wp-html-entities', 'wp-keycodes' ),
filemtime( wc_admin_dir_path( $js_entry ) ),
filemtime( wc_admin_dir_path( "dist/{$entry}/index.js" ) ),
true
);
wp_register_style(
WC_ADMIN_APP,
wc_admin_url( $css_entry ),
array( 'wc-components' ),
filemtime( wc_admin_dir_path( $css_entry ) )
);
// Set up the text domain and translations.
$locale_data = gutenberg_get_jed_locale_data( 'wc-admin' );
$content = 'wp.i18n.setLocaleData( ' . json_encode( $locale_data ) . ', "wc-admin" );';
wp_add_inline_script( 'wc-components', $content, 'before' );
// Resets lodash to wp-admin's version of lodash.
wp_add_inline_script(
WC_ADMIN_APP,
'_.noConflict();',
'after'
);
wp_register_style(
'wc-components',
wc_admin_url( 'dist/components/style.css' ),
array( 'wp-edit-blocks' ),
filemtime( wc_admin_dir_path( 'dist/components/style.css' ) )
);
wp_register_style(
WC_ADMIN_APP,
wc_admin_url( "dist/{$entry}/style.css" ),
array( 'wc-components' ),
filemtime( wc_admin_dir_path( "dist/{$entry}/style.css" ) )
);
}
add_action( 'admin_enqueue_scripts', 'wc_admin_register_script' );
/**
* Output the wcSettings global before printing any script tags.
*/
function wc_admin_print_script_settings() {
// Add Tracks script to the DOM if tracking is opted in, and Jetpack is installed/activated.
$tracking_enabled = 'yes' === get_option( 'woocommerce_allow_tracking', 'no' );
$tracking_script = '';
if ( $tracking_enabled && defined( 'JETPACK__VERSION' ) ) {
$tracking_script = "var wc_tracking_script = document.createElement( 'script' );\n";
$tracking_script .= "wc_tracking_script.src = '//stats.wp.com/w.js';\n"; // TODO Version/cache buster.
@ -65,9 +102,7 @@ function wc_admin_register_script() {
$tracking_script .= "wc_tracking_script.defer = true;\n";
$tracking_script .= "window._tkq = window._tkq || [];\n";
$tracking_script .= "document.head.appendChild( wc_tracking_script );\n";
wp_add_inline_script( 'wc-components', $tracking_script, 'before' );
}
/**
* TODO: On merge, once plugin images are added to core WooCommerce, `wcAdminAssetUrl` can be retired, and
* `wcAssetUrl` can be used in its place throughout the codebase.
@ -89,22 +124,16 @@ function wc_admin_register_script() {
'siteTitle' => get_bloginfo( 'name' ),
'trackingEnabled' => $tracking_enabled,
);
wp_add_inline_script(
'wc-components',
'var wcSettings = ' . json_encode( $settings ) . ';',
'before'
);
// Resets lodash to wp-admin's version of lodash.
wp_add_inline_script(
WC_ADMIN_APP,
'_.noConflict();',
'after'
);
?>
<script type="text/javascript">
<?php
echo $tracking_script; // WPCS: XSS ok.
?>
var wcSettings = <?php echo json_encode( $settings ); ?>;
</script>
<?php
}
add_action( 'admin_enqueue_scripts', 'wc_admin_register_script' );
add_action( 'admin_print_footer_scripts', 'wc_admin_print_script_settings', 1 );
/**
* Load plugin text domain for translations.

File diff suppressed because it is too large Load Diff

View File

@ -12,11 +12,15 @@
"scripts": {
"install-if-deps-outdated": "node bin/install-if-deps-outdated.js",
"install-if-no-packages": "node bin/install-if-no-packages.js",
"clean": "rimraf ./dist ./packages/*/build ./packages/*/build-module ./packages/*/build-style",
"prebuild": "npm run -s install-if-deps-outdated",
"build": "cross-env NODE_ENV=production webpack",
"build:packages": "node ./bin/packages/build.js",
"build:core": "cross-env NODE_ENV=production webpack",
"build": "npm run build:packages && npm run build:core",
"postbuild": "npm run -s i18n:php && npm run -s i18n:pot",
"prestart": "npm run -s install-if-deps-outdated",
"start": "webpack --watch",
"dev:packages": "node ./bin/packages/watch.js",
"start": "npm run build:packages && concurrently \"cross-env webpack --watch\" \"npm run dev:packages\"",
"i18n:js": "cross-env NODE_ENV=production babel client -o /dev/null",
"i18n:php": "pot-to-php ./languages/wc-admin.pot ./languages/wc-admin.php wc-admin",
"i18n:pot": "grunt makepot",
@ -34,7 +38,10 @@
"test:help": "wp-scripts test-unit-js --help",
"test": "wp-scripts test-unit-js --config tests/js/jest.config.json",
"test:watch": "npm run test -- --watch",
"docs": "node ./bin/generate-docs"
"docs": "node ./bin/generate-docs",
"publish:check": "npm run build:packages && lerna updated",
"publish:dev": "npm run build:packages && lerna publish --npm-tag next",
"publish:prod": "npm run build:packages && lerna publish"
},
"devDependencies": {
"@babel/cli": "7.1.2",
@ -66,9 +73,11 @@
"babel-plugin-transform-class-properties": "6.24.1",
"buble": "0.19.4",
"chalk": "2.4.1",
"concurrently": "^4.0.1",
"core-js": "2.5.7",
"cross-env": "5.2.0",
"css-loader": "1.0.1",
"deasync": "^0.1.13",
"deep-freeze": "0.0.1",
"docsify-cli": "github:docsifyjs/docsify-cli#5df38996",
"eslint": "5.8.0",
@ -88,6 +97,7 @@
"html-to-react": "1.3.3",
"husky": "1.1.2",
"interpolate-components": "1.1.1",
"lerna": "^3.4.3",
"marked": "0.5.1",
"node-sass": "4.9.4",
"postcss-color-function": "4.0.1",
@ -104,6 +114,7 @@
"react-world-flags": "1.2.4",
"readline-sync": "1.4.9",
"recast": "0.16.0",
"rimraf": "^2.6.2",
"sass-loader": "7.1.0",
"style-loader": "0.23.1",
"stylelint": "9.7.0",

View File

@ -0,0 +1 @@
package-lock=false

View File

@ -0,0 +1,32 @@
# Currency
A collection of utilities to display and work with currency values.
## Installation
Install the module
```bash
npm install @woocommerce/currency --save
```
_This package assumes that your code will run in an **ES2015+** environment. If you're using an environment that has limited or no support for ES2015+ such as lower versions of IE then using [core-js](https://github.com/zloirock/core-js) or [@babel/polyfill](https://babeljs.io/docs/en/next/babel-polyfill) will add support for these methods. Learn more about it in [Babel docs](https://babeljs.io/docs/en/next/caveats)._
## Usage
```JS
import { formatCurrency, getCurrencyFormatDecimal, getCurrencyFormatString } from '@woocommerce/currency';
// Formats money with a given currency code. Uses site's current locale for symbol formatting,
// from the wcSettings global. Defaults to `en-US`. If no currency provided, this is also
// pulled from wcSettings, and defaults to USD.
const total = formatCurrency( 20.923, 'USD' ); // '$20.92'
// Get the rounded decimal value of a number at the precision used for the current currency,
// from the wcSettings global. Defaults to 2.
const total = getCurrencyFormatDecimal( '6.2892' ); // 6.29 https://google.com/?q=test
// Get the string representation of a floating point number to the precision used by the current
// currency. This is different from `formatCurrency` by not returning the currency symbol.
const total = getCurrencyFormatString( 1088.478 ); // '1088.48'
```

View File

@ -0,0 +1,30 @@
{
"name": "@woocommerce/currency",
"version": "1.0.0-alpha.0",
"description": "WooCommerce currency utilities.",
"author": "Automattic",
"license": "GPL-2.0-or-later",
"keywords": [
"wordpress",
"woocommerce",
"currency"
],
"homepage": "https://github.com/WooCommerce/wc-admin/tree/master/packages/currency/README.md",
"repository": {
"type": "git",
"url": "https://github.com/WooCommerce/wc-admin.git"
},
"bugs": {
"url": "https://github.com/WooCommerce/wc-admin/issues"
},
"main": "build/index.js",
"module": "build-module/index.js",
"react-native": "src/index",
"dependencies": {
"@babel/runtime": "^7.0.0",
"lodash": "^4.17.11"
},
"publishConfig": {
"access": "public"
}
}

View File

@ -2,7 +2,7 @@
/**
* Internal dependencies
*/
import { formatCurrency, getCurrencyFormatDecimal, getCurrencyFormatString } from '../index';
import { formatCurrency, getCurrencyFormatDecimal, getCurrencyFormatString } from '../src';
describe( 'formatCurrency', () => {
it( 'should default to wcSettings or USD when currency not passed in', () => {

View File

@ -0,0 +1 @@
package-lock=false

View File

@ -0,0 +1,15 @@
# Date
A collection of utilities to display and work with date values.
## Installation
Install the module
```bash
npm install @woocommerce/date --save
```
_This package assumes that your code will run in an **ES2015+** environment. If you're using an environment that has limited or no support for ES2015+ such as lower versions of IE then using [core-js](https://github.com/zloirock/core-js) or [@babel/polyfill](https://babeljs.io/docs/en/next/babel-polyfill) will add support for these methods. Learn more about it in [Babel docs](https://babeljs.io/docs/en/next/caveats)._
## Usage

View File

@ -0,0 +1,33 @@
{
"name": "@woocommerce/date",
"version": "1.0.0-alpha.0",
"description": "WooCommerce date utilities.",
"author": "Automattic",
"license": "GPL-2.0-or-later",
"keywords": [
"wordpress",
"woocommerce",
"date"
],
"homepage": "https://github.com/WooCommerce/wc-admin/tree/master/packages/date/README.md",
"repository": {
"type": "git",
"url": "https://github.com/WooCommerce/wc-admin.git"
},
"bugs": {
"url": "https://github.com/WooCommerce/wc-admin/issues"
},
"main": "build/index.js",
"module": "build-module/index.js",
"react-native": "src/index",
"dependencies": {
"@babel/runtime": "^7.0.0",
"@wordpress/date": "2.0.3",
"@wordpress/i18n": "2.0.0",
"lodash": "^4.17.11",
"moment": "^2.22.2"
},
"publishConfig": {
"access": "public"
}
}

View File

@ -22,7 +22,7 @@ import {
isoDateFormat,
getDateDifferenceInDays,
getPreviousDate,
} from 'lib/date';
} from '../src';
describe( 'appendTimestamp', () => {
it( 'should append `start` timestamp', () => {

View File

@ -2,14 +2,16 @@
"rootDir": "../../",
"collectCoverageFrom": [
"client/**/*.js",
"packages/**/*.js",
"!**/node_modules/**",
"!**/vendor/**",
"!**/test/**"
],
"moduleDirectories": ["node_modules", "<rootDir>/client"],
"moduleDirectories": ["node_modules", "<rootDir>/client", "<rootDir>/packages"],
"moduleNameMapper": {
"tinymce": "<rootDir>/tests/js/mocks/tinymce",
"@woocommerce/components": "<rootDir>/client/components"
"@woocommerce/components": "<rootDir>/client/components",
"@woocommerce/(.*)": "<rootDir>/packages/$1/src"
},
"setupFiles": [
"<rootDir>/node_modules/@wordpress/jest-preset-default/scripts/setup-globals.js",
@ -17,7 +19,9 @@
],
"preset": "@wordpress/jest-preset-default",
"testPathIgnorePatterns": [
"/node_modules/"
"/node_modules/",
"<rootDir>/.*/build/",
"<rootDir>/.*/build-module/"
],
"verbose": true
}

View File

@ -16,16 +16,27 @@ global.wp = {
global.wc = {};
Object.defineProperty( global.wp, 'element', {
get: () => require( '@wordpress/element' ),
const wordPressPackages = [
'element',
'date',
];
const wooCommercePackages = [
'components',
'currency',
'date',
];
wordPressPackages.forEach( lib => {
Object.defineProperty( global.wp, lib, {
get: () => require( `@wordpress/${ lib }` ),
} );
} );
Object.defineProperty( global.wp, 'date', {
get: () => require( '@wordpress/date' ),
} );
Object.defineProperty( global.wc, 'components', {
get: () => require( '@woocommerce/components' ),
wooCommercePackages.forEach( lib => {
Object.defineProperty( global.wc, lib, {
get: () => require( `@woocommerce/${ lib }` ),
} );
} );
global.wcSettings = {

View File

@ -1,10 +1,15 @@
/** @format */
/**
* External dependencies
*/
const path = require( 'path' );
const ExtractTextPlugin = require( 'extract-text-webpack-plugin' );
const NODE_ENV = process.env.NODE_ENV || 'development';
const externals = {
'@woocommerce/components': { this: [ 'wc', 'components' ] },
'@woocommerce/currency': { this: [ 'wc', 'currency' ] },
'@woocommerce/date': { this: [ 'wc', 'date' ] },
'@wordpress/api-fetch': { this: [ 'wp', 'apiFetch' ] },
'@wordpress/blocks': { this: [ 'wp', 'blocks' ] },
'@wordpress/components': { this: [ 'wp', 'components' ] },
@ -22,16 +27,28 @@ const externals = {
'react-dom': 'ReactDOM',
};
const wcAdminPackages = {
components: './client/components',
currency: './packages/currency',
date: './packages/date',
};
Object.keys( wcAdminPackages ).forEach( ( name ) => {
externals[ `@woocommerce/${ name }` ] = {
this: [ 'wc', name ],
};
} );
const webpackConfig = {
mode: NODE_ENV,
entry: {
index: './client/index.js',
components: './client/components/index.js',
app: './client/index.js',
embedded: './client/embedded.js',
...wcAdminPackages,
},
output: {
path: path.resolve( 'dist' ),
filename: '[name].js',
filename: './dist/[name]/index.js',
path: __dirname,
library: [ 'wc', '[name]' ],
libraryTarget: 'this',
},
@ -77,12 +94,16 @@ const webpackConfig = {
},
resolve: {
extensions: [ '.json', '.js', '.jsx' ],
modules: [ path.join( __dirname, 'client' ), 'node_modules' ],
modules: [ path.join( __dirname, 'client' ), path.join( __dirname, 'packages' ), 'node_modules' ],
alias: {
'gutenberg-components': path.resolve( __dirname, 'node_modules/@wordpress/components/src' ),
},
},
plugins: [ new ExtractTextPlugin( 'css/[name].css' ) ],
plugins: [
new ExtractTextPlugin( {
filename: './dist/[name]/style.css',
} ),
],
};
if ( webpackConfig.mode !== 'production' ) {