Merge branch 'master' into fix/2243

This commit is contained in:
Ron Rennick 2019-08-19 11:34:05 -03:00
commit effb5b8219
33 changed files with 628 additions and 167 deletions

View File

@ -61,6 +61,10 @@ else
exit 1
fi
# Install PHP dependencies
status "Gathering PHP dependencies... 🐿️"
composer install --no-dev
# Run the build.
status "Generating build... 👷‍♀️"
npm run build
@ -78,6 +82,8 @@ zip -r woocommerce-admin.zip \
$build_files \
languages/woocommerce-admin.pot \
languages/woocommerce-admin.php \
readme.txt
readme.txt \
src/ \
vendor/
success "Done. You've built WooCommerce Admin! 🎉 "

View File

@ -78,10 +78,6 @@ status "Run docs script to make sure docs are updated."
npm run docs
status "Remove changes to package-lock.json to prevent merge conflicts."
git checkout package-lock.json
status "Here are the changes so far. Make sure the following changes are reflected."
echo "- docs/: folder will have changes to documentation, if any."

26
plugins/woocommerce-admin/bin/update-version.php Normal file → Executable file
View File

@ -7,16 +7,22 @@
$package_json = file_get_contents( 'package.json' );
$package = json_decode( $package_json );
$plugin_file = file( 'woocommerce-admin.php' );
$lines = array();
foreach ( $plugin_file as $line ) {
if ( stripos( $line, ' * Version: ' ) !== false ) {
$line = " * Version: {$package->version}\n";
function replace_version( $filename, $package_json ) {
$lines = array();
$file = file( $filename );
foreach ( $file as $line ) {
if ( stripos( $line, ' * Version: ' ) !== false ) {
$line = " * Version: {$package_json->version}\n";
}
if ( stripos( $line, ">define( 'WC_ADMIN_VERSION_NUMBER'," ) !== false ) {
$line = "\t\t\$this->define( 'WC_ADMIN_VERSION_NUMBER', '{$package_json->version}' );\n";
}
$lines[] = $line;
}
if ( stripos( $line, ">define( 'WC_ADMIN_VERSION_NUMBER'," ) !== false ) {
$line = "\t\t\$this->define( 'WC_ADMIN_VERSION_NUMBER', '{$package->version}' );\n";
}
$lines[] = $line;
file_put_contents( $filename, $lines );
}
file_put_contents( 'woocommerce-admin.php', $lines );
replace_version( 'woocommerce-admin.php', $package );
replace_version( 'src/FeaturePlugin.php', $package );

View File

@ -74,3 +74,29 @@
padding-bottom: 10px;
}
}
.woocommerce-dashboard__body {
background: $muriel-gray-0;
color: $muriel-gray-600;
font-family: $default-font;
#wpbody-content {
min-height: 100vh;
}
/* Hide wp-admin and WooCommerce elements when the dashboard body class is present */
#adminmenumain,
.woocommerce-layout__header,
.update-nag,
.woocommerce-store-alerts,
.woocommerce-message,
.notice,
.error,
.updated {
display: none;
}
#wpcontent {
margin-left: 0;
}
}

View File

@ -42,12 +42,84 @@
}
// Gutenberg mixins. These are temporary until Gutenberg's mixins are exposed.
/**
* Breakpoint mixins
*/
@mixin break-huge() {
@media (min-width: #{ ($break-huge) }) {
@content;
}
}
@mixin break-wide() {
@media (min-width: #{ ($break-wide) }) {
@content;
}
}
@mixin break-xlarge() {
@media (min-width: #{ ($break-xlarge) }) {
@content;
}
}
@mixin break-large() {
@media (min-width: #{ ($break-large) }) {
@content;
}
}
@mixin break-medium() {
@media (min-width: #{ ($break-medium) }) {
@content;
}
}
@mixin break-small() {
@media (min-width: #{ ($break-small) }) {
@content;
}
}
@mixin break-mobile() {
@media (min-width: #{ ($break-mobile) }) {
@content;
}
}
@mixin break-zoomed-in() {
@media (min-width: #{ ($break-zoomed-in) }) {
@content;
}
}
// Buttons with rounded corners.
@mixin button-style__disabled {
opacity: 0.6;
cursor: default;
}
@mixin button-style__hover {
background-color: $white;
color: $dark-gray-900;
box-shadow: inset 0 0 0 1px $light-gray-500, inset 0 0 0 2px $white,
0 1px 1px rgba($dark-gray-900, 0.2);
}
@mixin button-style__active() {
outline: none;
background-color: $white;
color: $dark-gray-900;
box-shadow: inset 0 0 0 1px $light-gray-700, inset 0 0 0 2px $white;
}
@mixin button-style__focus-active() {
background-color: $white;
color: $dark-gray-900;
box-shadow: inset 0 0 0 1px $dark-gray-300, inset 0 0 0 2px $white;
// Windows High Contrast mode will show this outline, but not the box-shadow
// Windows High Contrast mode will show this outline, but not the box-shadow.
outline: 2px solid transparent;
outline-offset: -2px;
}
@ -77,6 +149,15 @@
}
}
// Gutenberg Switch.
@mixin switch-style__focus-active() {
box-shadow: 0 0 0 2px $white, 0 0 0 3px $dark-gray-300;
// Windows High Contrast mode will show this outline, but not the box-shadow.
outline: 2px solid transparent;
outline-offset: 2px;
}
// Sets positions for children of grid elements
@mixin set-grid-item-position( $wrap-after, $number-of-items ) {
@for $i from 1 through $number-of-items {

View File

@ -23,19 +23,55 @@ $sidebar-width: 272px;
$spacing: 16px;
// Gutenberg variables. These are temporary until Gutenberg's variables are exposed.
$break-huge: 1440px;
$break-wide: 1280px;
$break-xlarge: 1080px;
$break-large: 960px; // admin sidebar auto folds
$break-medium: 782px; // adminbar goes big
$break-small: 600px;
$break-mobile: 480px;
$break-zoomed-in: 280px;
$border-width: 1px;
$default-font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell,
'Helvetica Neue', sans-serif;
$default-font-size: 13px;
$default-line-height: 1.4;
$break-small: 600px;
$border-width: 1px;
$blue-medium-900: #006589;
$blue-medium-800: #00739c;
$blue-medium-700: #007fac;
$blue-medium-600: #008dbe;
$blue-medium-500: #00a0d2;
$blue-medium-400: #33b3db;
$blue-medium-300: #66c6e4;
$blue-medium-200: #bfe7f3;
$blue-medium-100: #e5f5fa;
$blue-medium-highlight: #b3e7fe;
$blue-medium-focus: #007cba;
$light-gray-100: $core-grey-light-100;
$light-gray-200: $core-grey-light-200;
$light-gray-300: $core-grey-light-300;
$light-gray-400: $core-grey-light-400;
$light-gray-500: $core-grey-light-500;
$dark-gray-300: $core-grey-dark-300;
$light-gray-600: $core-grey-light-600;
$light-gray-700: $core-grey-light-700;
$light-gray-800: $core-grey-light-800;
$light-gray-900: $core-grey-light-900;
$dark-gray-100: $core-grey-dark-100;
$dark-gray-200: $core-grey-dark-200;
$dark-gray-300: $core-grey-dark-300; // This & below have 4.5+ contrast against white
$dark-gray-400: $core-grey-dark-400;
$dark-gray-500: $core-grey-dark-500;
$dark-gray-600: $core-grey-dark-600;
$dark-gray-700: $core-grey-dark-700;
$dark-gray-800: $core-grey-dark-800;
$dark-gray-900: $core-grey-dark-900;
$alert-red: $error-red;
$alert-yellow: $notice-yellow;
$alert-green: $valid-green;
$toggle-border-width: 2px;
$radius-round-rectangle: 4px;
$icon-button-size: 36px;
$icon-button-size-small: 24px;
// WordPress defaults
$adminbar-height: 32px;

View File

@ -5,4 +5,13 @@ Import Gutenberg component SCSS so webpack's postcss process can handle theme-in
allows Woo themed components based on the config found in postcss.config.js
*/
@import 'gutenberg-components/button/style.scss';
@import 'gutenberg-components/checkbox-control/style.scss';
@import 'gutenberg-components/dashicon/style.scss';
@import 'gutenberg-components/form-toggle/style.scss';
@import 'gutenberg-components/icon-button/style.scss';
@import 'gutenberg-components/notice/style.scss';
@import 'gutenberg-components/select-control/style.scss';
@import 'gutenberg-components/snackbar/style.scss';
@import 'gutenberg-components/spinner/style.scss';
@import 'gutenberg-components/text-control/style.scss';
@import 'gutenberg-components/tooltip/style.scss';

View File

@ -7,7 +7,7 @@
"prefer-stable": true,
"minimum-stability": "dev",
"require": {
"composer/installers": "1.6.0"
"composer/installers": "1.7.0"
},
"require-dev": {
"phpunit/phpunit": "6.5.13",

View File

@ -1,23 +1,23 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "c4e5044bed13f99e535b3d692d12005c",
"content-hash": "4b09720e59ab60b00e569bfb72bfd5f4",
"packages": [
{
"name": "composer/installers",
"version": "v1.6.0",
"version": "v1.7.0",
"source": {
"type": "git",
"url": "https://github.com/composer/installers.git",
"reference": "cfcca6b1b60bc4974324efb5783c13dca6932b5b"
"reference": "141b272484481432cda342727a427dc1e206bfa0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/composer/installers/zipball/cfcca6b1b60bc4974324efb5783c13dca6932b5b",
"reference": "cfcca6b1b60bc4974324efb5783c13dca6932b5b",
"url": "https://api.github.com/repos/composer/installers/zipball/141b272484481432cda342727a427dc1e206bfa0",
"reference": "141b272484481432cda342727a427dc1e206bfa0",
"shasum": ""
},
"require": {
@ -73,6 +73,7 @@
"RadPHP",
"SMF",
"Thelia",
"Whmcs",
"WolfCMS",
"agl",
"aimeos",
@ -95,6 +96,7 @@
"installer",
"itop",
"joomla",
"known",
"kohana",
"laravel",
"lavalite",
@ -124,7 +126,7 @@
"zend",
"zikula"
],
"time": "2018-08-27T06:10:37+00:00"
"time": "2019-08-12T15:00:31+00:00"
}
],
"packages-dev": [
@ -168,9 +170,9 @@
"authors": [
{
"name": "Franck Nijhof",
"role": "Developer / IT Manager",
"email": "franck.nijhof@dealerdirect.com",
"homepage": "http://www.frenck.nl",
"role": "Developer / IT Manager"
"homepage": "http://www.frenck.nl"
}
],
"description": "PHP_CodeSniffer Standards Composer Installer Plugin",
@ -336,18 +338,18 @@
"authors": [
{
"name": "Arne Blankerts",
"email": "arne@blankerts.de",
"role": "Developer"
"role": "Developer",
"email": "arne@blankerts.de"
},
{
"name": "Sebastian Heuer",
"email": "sebastian@phpeople.de",
"role": "Developer"
"role": "Developer",
"email": "sebastian@phpeople.de"
},
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de",
"role": "Developer"
"role": "Developer",
"email": "sebastian@phpunit.de"
}
],
"description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
@ -383,18 +385,18 @@
"authors": [
{
"name": "Arne Blankerts",
"email": "arne@blankerts.de",
"role": "Developer"
"role": "Developer",
"email": "arne@blankerts.de"
},
{
"name": "Sebastian Heuer",
"email": "sebastian@phpeople.de",
"role": "Developer"
"role": "Developer",
"email": "sebastian@phpeople.de"
},
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de",
"role": "Developer"
"role": "Developer",
"email": "sebastian@phpunit.de"
}
],
"description": "Library for handling version information and constraints",
@ -871,8 +873,8 @@
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sb@sebastian-bergmann.de",
"role": "lead"
"role": "lead",
"email": "sb@sebastian-bergmann.de"
}
],
"description": "FilterIterator implementation that filters files based on a list of suffixes.",
@ -913,8 +915,8 @@
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de",
"role": "lead"
"role": "lead",
"email": "sebastian@phpunit.de"
}
],
"description": "Simple template engine.",
@ -962,8 +964,8 @@
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sb@sebastian-bergmann.de",
"role": "lead"
"role": "lead",
"email": "sb@sebastian-bergmann.de"
}
],
"description": "Utility class for timing",
@ -1163,6 +1165,7 @@
"mock",
"xunit"
],
"abandoned": true,
"time": "2018-08-09T05:50:03+00:00"
},
{
@ -1716,8 +1719,8 @@
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de",
"role": "lead"
"role": "lead",
"email": "sebastian@phpunit.de"
}
],
"description": "Library that helps with managing the version number of Git-hosted PHP projects",
@ -1969,12 +1972,12 @@
"version": "1.2.1",
"source": {
"type": "git",
"url": "https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards.git",
"url": "https://github.com/WordPress/WordPress-Coding-Standards.git",
"reference": "f328bcafd97377e8e5e5d7b244d5ddbf301a3a5c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/WordPress-Coding-Standards/WordPress-Coding-Standards/zipball/f328bcafd97377e8e5e5d7b244d5ddbf301a3a5c",
"url": "https://api.github.com/repos/WordPress/WordPress-Coding-Standards/zipball/f328bcafd97377e8e5e5d7b244d5ddbf301a3a5c",
"reference": "f328bcafd97377e8e5e5d7b244d5ddbf301a3a5c",
"shasum": ""
},

View File

@ -19,6 +19,7 @@
* [EmptyContent](components/packages/empty-content.md)
* [Filters](components/packages/filters.md)
* [Flag](components/packages/flag.md)
* [Form](components/packages/form.md)
* [Gravatar](components/packages/gravatar.md)
* [ImageAsset](components/packages/image-asset.md)
* [Link](components/packages/link.md)
@ -40,4 +41,5 @@
* [Table](components/packages/table.md)
* [Tag](components/packages/tag.md)
* [TextControlWithAffixes](components/packages/text-control-with-affixes.md)
* [ViewMoreList](components/packages/view-more-list.md)
* [ViewMoreList](components/packages/view-more-list.md)
* [WebPreview](components/packages/web-preview.md)

View File

@ -0,0 +1,51 @@
`Form` (component)
==================
A form component to handle form state and provide input helper props.
Props
-----
### `children`
- Type: *
- Default: null
A renderable component in which to pass this component's state and helpers.
Generally a number of input or other form elements.
### `errors`
- Type: Object
- Default: `{}`
Object of all initial errors to store in state.
### `initialValues`
- Type: Object
- Default: `{}`
Object key:value pair list of all initial field values.
### `onSubmitCallback`
- Type: Function
- Default: `noop`
Function to call when a form is submitted with valid fields.
### `validate`
- Type: Function
- Default: null
A function that is passed a list of all values and
should return an `errors` object with error response.
### `touched`
- Type: undefined
- Default: `{}`

View File

@ -27,17 +27,19 @@ The current step's key.
- Type: Array
- key: String - Key used to identify step.
- label: String - Label displayed in stepper.
- description: String - Description displayed beneath the label.
- isComplete: Boolean - Optionally mark a step complete regardless of step index.
- content: ReactNode - Content displayed when the step is active.
- Default: null
An array of steps used.
### `direction`
### `isVertical`
- Type: One of: 'horizontal', 'vertical'
- Default: `'horizontal'`
- Type: Boolean
- Default: `false`
Direction of the stepper.
If the stepper is vertical instead of horizontal.
### `isPending`

View File

@ -0,0 +1,45 @@
`WebPreview` (component)
========================
WebPreview component to display an iframe of another page.
Props
-----
### `className`
- Type: String
- Default: null
Additional class name to style the component.
### `loadingContent`
- Type: ReactNode
- Default: `<Spinner />`
Content shown when iframe is still loading.
### `onLoad`
- Type: Function
- Default: `noop`
Function to fire when iframe content is loaded.
### `src`
- **Required**
- Type: String
- Default: null
Iframe src to load.
### `title`
- **Required**
- Type: String
- Default: null
Iframe title.

View File

@ -1,6 +1,6 @@
{
"name": "@woocommerce/admin-library",
"version": "0.16.0",
"version": "0.17.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@ -7158,9 +7158,9 @@
}
},
"d3-scale-chromatic": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-1.3.3.tgz",
"integrity": "sha512-BWTipif1CimXcYfT02LKjAyItX5gKiwxuPRgr4xM58JwlLocWbjPLI7aMEjkcoOQXMkYsmNsvv3d2yl/OKuHHw==",
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-1.4.0.tgz",
"integrity": "sha512-0vyEt8ZqhdgzC+IvdkJZL7fc3k7UZyJvMxR3zvU312z/HilJ0N+WSY3099jAxdfhe99ak9VhcK1ChDVVGc8Q0Q==",
"requires": {
"d3-color": "1",
"d3-interpolate": "1"
@ -8338,9 +8338,9 @@
}
},
"eslint-plugin-jest": {
"version": "22.15.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-22.15.0.tgz",
"integrity": "sha512-hgnPbSqAIcLLS9ePb12hNHTRkXnkVaCfOwCt2pzQ8KpOKPWGA4HhLMaFN38NBa/0uvLfrZpcIRjT+6tMAfr58Q==",
"version": "22.15.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-22.15.1.tgz",
"integrity": "sha512-CWq/RR/3tLaKFB+FZcCJwU9hH5q/bKeO3rFP8G07+q7hcDCFNqpvdphVbEbGE6o6qo1UbciEev4ejUWv7brUhw==",
"dev": true,
"requires": {
"@typescript-eslint/experimental-utils": "^1.13.0"
@ -9303,8 +9303,7 @@
},
"ansi-regex": {
"version": "2.1.1",
"bundled": true,
"optional": true
"bundled": true
},
"aproba": {
"version": "1.2.0",
@ -9322,13 +9321,11 @@
},
"balanced-match": {
"version": "1.0.0",
"bundled": true,
"optional": true
"bundled": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
"optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@ -9341,18 +9338,15 @@
},
"code-point-at": {
"version": "1.1.0",
"bundled": true,
"optional": true
"bundled": true
},
"concat-map": {
"version": "0.0.1",
"bundled": true,
"optional": true
"bundled": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true,
"optional": true
"bundled": true
},
"core-util-is": {
"version": "1.0.2",
@ -9455,8 +9449,7 @@
},
"inherits": {
"version": "2.0.3",
"bundled": true,
"optional": true
"bundled": true
},
"ini": {
"version": "1.3.5",
@ -9466,7 +9459,6 @@
"is-fullwidth-code-point": {
"version": "1.0.0",
"bundled": true,
"optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@ -9479,20 +9471,17 @@
"minimatch": {
"version": "3.0.4",
"bundled": true,
"optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
},
"minimist": {
"version": "0.0.8",
"bundled": true,
"optional": true
"bundled": true
},
"minipass": {
"version": "2.3.5",
"bundled": true,
"optional": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
@ -9509,7 +9498,6 @@
"mkdirp": {
"version": "0.5.1",
"bundled": true,
"optional": true,
"requires": {
"minimist": "0.0.8"
}
@ -9582,8 +9570,7 @@
},
"number-is-nan": {
"version": "1.0.1",
"bundled": true,
"optional": true
"bundled": true
},
"object-assign": {
"version": "4.1.1",
@ -9593,7 +9580,6 @@
"once": {
"version": "1.4.0",
"bundled": true,
"optional": true,
"requires": {
"wrappy": "1"
}
@ -9669,8 +9655,7 @@
},
"safe-buffer": {
"version": "5.1.2",
"bundled": true,
"optional": true
"bundled": true
},
"safer-buffer": {
"version": "2.1.2",
@ -9700,7 +9685,6 @@
"string-width": {
"version": "1.0.2",
"bundled": true,
"optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@ -9718,7 +9702,6 @@
"strip-ansi": {
"version": "3.0.1",
"bundled": true,
"optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@ -9757,13 +9740,11 @@
},
"wrappy": {
"version": "1.0.2",
"bundled": true,
"optional": true
"bundled": true
},
"yallist": {
"version": "3.0.3",
"bundled": true,
"optional": true
"bundled": true
}
}
},
@ -10880,9 +10861,9 @@
"integrity": "sha1-ELMKOGCF9Dzt41PMj6fLDe7qZos="
},
"html-to-react": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/html-to-react/-/html-to-react-1.4.0.tgz",
"integrity": "sha512-VmpVO6gAw75MxRu7OgptdwtG5/thOFxTiXevsBt3gdmup2srUewHGNJWilknb334YNsMIIS0/+sGztxyClGuZA==",
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/html-to-react/-/html-to-react-1.4.1.tgz",
"integrity": "sha512-Ys2gGxF8LBF9bD8tbnsU0xgEDOTC3Sy81mtpIH/61hSqGE1l4QetnN1yv0oAK/PuvwABmiNS+ggqvuzo+GfoiA==",
"requires": {
"domhandler": "^3.0",
"htmlparser2": "^4.0",
@ -14190,9 +14171,9 @@
}
},
"node-watch": {
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/node-watch/-/node-watch-0.6.2.tgz",
"integrity": "sha512-qmb/2ehVk1DC4gZYox7JgWXNucKnVk7uQmcoSeRaC7kzXsT8VOPIe7mbrR9Vc2TpGggS2yGUcgC98A2fKE53AA==",
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/node-watch/-/node-watch-0.6.3.tgz",
"integrity": "sha512-InVPsg51EemnMVH3fvrrSVgqVBMlksZ/mK7ZDWx/NuWdNQi28wcVJX1/BP38alraPFXbRi9jZ35OfK4Ra7l8Bg==",
"dev": true
},
"node-wp-i18n": {
@ -18908,9 +18889,9 @@
}
},
"readline-sync": {
"version": "1.4.9",
"resolved": "https://registry.npmjs.org/readline-sync/-/readline-sync-1.4.9.tgz",
"integrity": "sha1-PtqOZfI80qF+YTAbHwADOWr17No=",
"version": "1.4.10",
"resolved": "https://registry.npmjs.org/readline-sync/-/readline-sync-1.4.10.tgz",
"integrity": "sha512-gNva8/6UAe8QYepIQH/jQ2qn91Qj0B9sYjMBBs3QOB8F2CXcKgLxQaJRP76sWVRQt+QU+8fAkCbCvjjMFu7Ycw==",
"dev": true
},
"realpath-native": {

View File

@ -1,6 +1,6 @@
{
"name": "@woocommerce/admin-library",
"version": "0.16.0",
"version": "0.17.0",
"homepage": "https://woocommerce.github.io/woocommerce-admin/",
"repository": {
"type": "git",
@ -86,7 +86,7 @@
"d3-axis": "1.0.12",
"d3-format": "1.3.2",
"d3-scale": "2.2.2",
"d3-scale-chromatic": "1.3.3",
"d3-scale-chromatic": "1.4.0",
"d3-selection": "1.4.0",
"d3-shape": "1.3.5",
"d3-time-format": "2.1.3",
@ -96,7 +96,7 @@
"gfm-code-blocks": "1.0.0",
"gridicons": "3.3.1",
"history": "4.9.0",
"html-to-react": "1.4.0",
"html-to-react": "1.4.1",
"interpolate-components": "1.1.1",
"marked": "0.7.0",
"memoize-one": "5.0.5",
@ -143,7 +143,7 @@
"eslint": "5.16.0",
"eslint-config-wpcalypso": "4.0.1",
"eslint-loader": "2.2.1",
"eslint-plugin-jest": "22.15.0",
"eslint-plugin-jest": "22.15.1",
"eslint-plugin-jsx-a11y": "6.2.3",
"eslint-plugin-react": "7.14.3",
"eslint-plugin-wpcalypso": "4.1.0",
@ -155,7 +155,7 @@
"locutus": "2.0.11",
"mini-css-extract-plugin": "0.8.0",
"node-sass": "4.12.0",
"node-watch": "0.6.2",
"node-watch": "0.6.3",
"postcss-color-function": "4.1.0",
"postcss-loader": "3.0.0",
"prettier": "github:automattic/calypso-prettier#c56b4251",
@ -163,7 +163,7 @@
"prop-types": "15.7.2",
"raw-loader": "1.0.0",
"react-docgen": "2.21.0",
"readline-sync": "1.4.9",
"readline-sync": "1.4.10",
"recast": "0.18.1",
"replace": "1.1.0",
"request-promise": "4.2.4",

View File

@ -1,14 +1,16 @@
# unreleased
- SearchListItem component: new `countLabel` prop that will overwrite the `item.count` value.
- AdvancedFilters component: fire `onAdvancedFilterAction` for match changes.
- TableCard component: add `onSearch` an `onSort` function props.
- Add new component `<List />` for displaying interactive list items.
- Fix z-index issue in `<Chart />` empty message.
- Added a new `<SimpleSelectControl />` component.
- Added a new `<WebPreview />` component.
- SearchListItem component: fix long count values being cut-off in IE11.
- Add `disabled` prop to CompareButton, Search, and TableCard components.
- Table component: add empty table display.
# 3.1.0
- Added support for a countLabel prop on SearchListItem to allow custom counts.
- Added support for a `countLabel` prop on `SearchListItem` to allow custom counts.
# 3.0.0
- <DateInput> and <DatePicker> got a `disabled` prop.

View File

@ -12,8 +12,8 @@ import { Button, Tooltip } from '@wordpress/components';
*
* @return { object } -
*/
const CompareButton = ( { className, count, children, helpText, onClick } ) =>
count < 2 ? (
const CompareButton = ( { className, count, children, disabled, helpText, onClick } ) =>
! disabled && count < 2 ? (
<Tooltip text={ helpText }>
<span className={ className }>
<Button className="woocommerce-compare-button" isDefault disabled={ true }>
@ -26,6 +26,7 @@ const CompareButton = ( { className, count, children, helpText, onClick } ) =>
className={ classnames( 'woocommerce-compare-button', className ) }
isDefault
onClick={ onClick }
disabled={ disabled }
>
{ children }
</Button>
@ -52,6 +53,10 @@ CompareButton.propTypes = {
* The function called when the button is clicked.
*/
onClick: PropTypes.func.isRequired,
/**
* Whether the control is disabled or not.
*/
disabled: PropTypes.bool,
};
export default CompareButton;

View File

@ -175,7 +175,7 @@
}
.woocommerce-search-list__item-count {
flex: 0;
flex: 0 1 auto;
padding: $gap-smallest/2 $gap-smaller;
border: 1px solid $core-grey-light-500;
border-radius: 12px;

View File

@ -178,6 +178,7 @@ class Search extends Component {
selected,
showClearButton,
staticResults,
disabled,
} = this.props;
const { value = '', isActive } = this.state;
const aria = {
@ -239,6 +240,7 @@ class Search extends Component {
shouldRenderTags ? `search-inline-input-${ instanceId }` : null
}
{ ...aria }
disabled={ disabled }
/>
<span id={ `search-inline-input-${ instanceId }` } className="screen-reader-text">
{ __( 'Move backward for selected items', 'woocommerce-admin' ) }
@ -257,6 +259,7 @@ class Search extends Component {
aria-owns={ listBoxId }
aria-activedescendant={ activeId }
{ ...aria }
disabled={ disabled }
/>
</Fragment>
)
@ -338,6 +341,10 @@ Search.propTypes = {
* Render results list positioned statically instead of absolutely.
*/
staticResults: PropTypes.bool,
/**
* Whether the control is disabled or not.
*/
disabled: PropTypes.bool,
};
Search.defaultProps = {
@ -347,6 +354,7 @@ Search.defaultProps = {
inlineTags: false,
showClearButton: false,
staticResults: false,
disabled: false,
};
export default withInstanceId( Search );

View File

@ -250,7 +250,8 @@ class TableCard extends Component {
getAllCheckbox() {
const { ids = [] } = this.props;
const { selectedRows } = this.state;
const isAllChecked = ids.length > 0 && ids.length === selectedRows.length;
const hasData = ids.length > 0;
const isAllChecked = hasData && ids.length === selectedRows.length;
return {
cellClassName: 'is-checkbox-column',
label: (
@ -259,6 +260,7 @@ class TableCard extends Component {
onChange={ this.selectAllRows }
aria-label={ __( 'Select All' ) }
checked={ isAllChecked }
disabled={ ! hasData }
/>
),
required: true,
@ -295,6 +297,7 @@ class TableCard extends Component {
} );
headers = [ this.getAllCheckbox(), ...headers ];
}
const hasData = 0 < totalRows;
const className = classnames( 'woocommerce-analytics__card', {
'woocommerce-table': true,
@ -316,6 +319,7 @@ class TableCard extends Component {
labels.helpText || __( 'Check at least two items below to compare', 'woocommerce-admin' )
}
onClick={ this.onCompare }
disabled={ ! hasData }
>
{ labels.compareButton || __( 'Compare', 'woocommerce-admin' ) }
</CompareButton>
@ -330,13 +334,14 @@ class TableCard extends Component {
selected={ searchedLabels }
showClearButton={ true }
type={ searchBy }
disabled={ ! hasData }
/>
),
( downloadable || onClickDownload ) && (
<IconButton
key="download"
className="woocommerce-table__download-button"
disabled={ isLoading }
disabled={ isLoading || ! hasData }
onClick={ this.onClickDownload }
isLink
>

View File

@ -186,10 +186,15 @@
}
.woocommerce-table__header,
.woocommerce-table__item {
@include font-size( 13 );
.woocommerce-table__item,
.woocommerce-table__empty-item {
padding: $gap $gap-large;
border-bottom: 1px solid $core-grey-light-500;
}
.woocommerce-table__header,
.woocommerce-table__item {
@include font-size( 13 );
text-align: left;
> a:only-child {
@ -243,6 +248,17 @@
}
}
.woocommerce-table__empty-item {
text-align: center;
@include font-size( 18 );
color: $core-grey-dark-300;
font-weight: bold;
@include breakpoint( '<782px' ) {
@include font-size( 13 );
}
}
th.woocommerce-table__item {
font-weight: normal;
}

View File

@ -117,6 +117,7 @@ class Table extends Component {
} );
const sortedBy = query.orderby || get( find( headers, { defaultSort: true } ), 'key', false );
const sortDir = query.order || get( find( headers, { key: sortedBy } ), 'defaultOrder', DESC );
const hasData = !! rows.length;
return (
<div
@ -183,7 +184,7 @@ class Table extends Component {
)
}
aria-describedby={ labelId }
onClick={ this.sortBy( key ) }
onClick={ hasData ? this.sortBy( key ) : noop }
isDefault
>
{ textLabel }
@ -199,25 +200,36 @@ class Table extends Component {
);
} ) }
</tr>
{ rows.map( ( row, i ) => (
<tr key={ i }>
{ row.map( ( cell, j ) => {
const { cellClassName, isLeftAligned, isNumeric } = headers[ j ];
const isHeader = rowHeader === j;
const Cell = isHeader ? 'th' : 'td';
const cellClasses = classnames( 'woocommerce-table__item', cellClassName, {
'is-left-aligned': isLeftAligned,
'is-numeric': isNumeric,
'is-sorted': sortedBy === headers[ j ].key,
} );
return (
<Cell scope={ isHeader ? 'row' : null } key={ j } className={ cellClasses }>
{ getDisplay( cell ) }
</Cell>
);
} ) }
</tr>
) ) }
{ hasData
? (
rows.map( ( row, i ) => (
<tr key={ i }>
{ row.map( ( cell, j ) => {
const { cellClassName, isLeftAligned, isNumeric } = headers[ j ];
const isHeader = rowHeader === j;
const Cell = isHeader ? 'th' : 'td';
const cellClasses = classnames( 'woocommerce-table__item', cellClassName, {
'is-left-aligned': isLeftAligned,
'is-numeric': isNumeric,
'is-sorted': sortedBy === headers[ j ].key,
} );
return (
<Cell scope={ isHeader ? 'row' : null } key={ j } className={ cellClasses }>
{ getDisplay( cell ) }
</Cell>
);
} ) }
</tr>
) )
)
: (
<tr>
<td className="woocommerce-table__empty-item" colSpan={ headers.length }>
{ __( 'No data for the selected date range', 'woocommerce-admin' ) }
</td>
</tr>
)
}
</tbody>
</table>
</div>

View File

@ -28,7 +28,7 @@
</rule>
<rule ref="WordPress.Files.FileName.InvalidClassFileName">
<exclude-pattern>includes/**/abstract-*.php</exclude-pattern>
<exclude-pattern>src/*</exclude-pattern>
<exclude-pattern>tests/*</exclude-pattern>
<exclude-pattern>woocommerce-admin.php</exclude-pattern>
</rule>

View File

@ -71,6 +71,26 @@ Release and roadmap notes are available on the [WooCommerce Developers Blog](htt
== Changelog ==
= 0.17.0 2019-08-15 =
- Fix: chart data fetch/render over long time periods #2785 (Analytics)
- Task: update the class filename exclusion to /src/ for PSR-4 #2794
- Tweak: Increase zIndex on popover elements. #2777
- Fix: chart display when comparing categories. #2710 (Analytics)
- Fix: Allow WooCommerce Admin to be deleted through the plugin screen when WooCommerce is not active. #2762
- Fix: Charts being partially rendered on long time periods. #2776 (Analytics)
- Task: update WC tested to version to 3.7.0 #2782
- Fix: Customer last active date showing `Invalid date`. #2764 (Analytics)
- Task: Update report endpoints to be PSR-4 autoloaded #2755 (Build)
- Bug: Fix daily cron event (PSR-4) #2754 (Build)
- Fix: issue where product category update button was not always clickable #2753
- Fix: Add version parameter to `_doing_it_wrong` on `current_screen`. #2733
- Task: Update feature classes to be PSR-4 autoloaded. #2736 (Build)
- Fix: Short circuit admin title filter when applied by third parties too early. #2744
- Fix: chart display when comparing categories. #2708 (Analytics)
- Bug: Only apply current submenu CSS reset on non-embed pages. #2687
- Dev: Add `wc_admin_get_feature_config` filter to feature config array. #2689
= 0.16.0 2019-07-24 =
- Tweak: Change verbiage of feedback notification. #2677

View File

@ -122,8 +122,9 @@ class OnboardingPlugins extends \WC_REST_Data_Controller {
return apply_filters(
'woocommerce_onboarding_plugins_whitelist',
array(
'jetpack' => 'jetpack/jetpack.php',
'woocommerce-services' => 'woocommerce-services/woocommerce-services.php',
'facebook-for-woocommerce' => 'facebook-for-woocommerce/facebook-for-woocommerce.php',
'jetpack' => 'jetpack/jetpack.php',
'woocommerce-services' => 'woocommerce-services/woocommerce-services.php',
)
);
}

View File

@ -151,6 +151,10 @@ class Segmenter {
foreach ( $result1 as $segment_data ) {
$segment_id = $segment_data[ $segment_dimension ];
if ( ! isset( $segment_labels[ $segment_id ] ) ) {
continue;
}
unset( $segment_data[ $segment_dimension ] );
$result_segments[ $segment_id ] = array(
'segment_label' => $segment_labels[ $segment_id ],
@ -161,6 +165,10 @@ class Segmenter {
foreach ( $result2 as $segment_data ) {
$segment_id = $segment_data[ $segment_dimension ];
if ( ! isset( $segment_labels[ $segment_id ] ) ) {
continue;
}
unset( $segment_data[ $segment_dimension ] );
if ( ! isset( $result_segments[ $segment_id ] ) ) {
$result_segments[ $segment_id ] = array(
@ -216,14 +224,19 @@ class Segmenter {
$segment_labels = $this->get_segment_labels();
foreach ( $result1 as $segment_data ) {
$segment_id = $segment_data[ $segment_dimension ];
if ( ! isset( $segment_labels[ $segment_id ] ) ) {
continue;
}
$time_interval = $segment_data['time_interval'];
if ( ! isset( $result_segments[ $time_interval ] ) ) {
$result_segments[ $time_interval ] = array();
$result_segments[ $time_interval ]['segments'] = array();
}
unset( $segment_data['time_interval'] );
unset( $segment_data['datetime_anchor'] );
$segment_id = $segment_data[ $segment_dimension ];
unset( $segment_data[ $segment_dimension ] );
$segment_datum = array(
'segment_label' => $segment_labels[ $segment_id ],
@ -234,14 +247,19 @@ class Segmenter {
}
foreach ( $result2 as $segment_data ) {
$segment_id = $segment_data[ $segment_dimension ];
if ( ! isset( $segment_labels[ $segment_id ] ) ) {
continue;
}
$time_interval = $segment_data['time_interval'];
if ( ! isset( $result_segments[ $time_interval ] ) ) {
$result_segments[ $time_interval ] = array();
$result_segments[ $time_interval ]['segments'] = array();
}
unset( $segment_data['time_interval'] );
unset( $segment_data['datetime_anchor'] );
$segment_id = $segment_data[ $segment_dimension ];
unset( $segment_data[ $segment_dimension ] );
if ( ! isset( $result_segments[ $time_interval ]['segments'][ $segment_id ] ) ) {

View File

@ -10,6 +10,7 @@ namespace Automattic\WooCommerce\Admin;
defined( 'ABSPATH' ) || exit;
use \Automattic\WooCommerce\Admin\Notes\WC_Admin_Notes_Facebook_Extension;
use \Automattic\WooCommerce\Admin\Notes\WC_Admin_Notes_Giving_Feedback_Notes;
use \Automattic\WooCommerce\Admin\Notes\WC_Admin_Notes_Mobile_App;
use \Automattic\WooCommerce\Admin\Notes\WC_Admin_Notes_New_Sales_Record;
@ -60,5 +61,6 @@ class Events {
WC_Admin_Notes_New_Sales_Record::possibly_add_sales_record_note();
WC_Admin_Notes_Giving_Feedback_Notes::add_notes_for_admin_giving_feedback();
WC_Admin_Notes_Mobile_App::possibly_add_mobile_app_note();
WC_Admin_Notes_Facebook_Extension::possibly_add_facebook_note();
}
}

View File

@ -10,6 +10,7 @@ namespace Automattic\WooCommerce\Admin;
defined( 'ABSPATH' ) || exit;
use \Automattic\WooCommerce\Admin\Notes\WC_Admin_Notes;
use \Automattic\WooCommerce\Admin\Notes\WC_Admin_Notes_Facebook_Extension;
use \Automattic\WooCommerce\Admin\Notes\WC_Admin_Notes_Historical_Data;
use \Automattic\WooCommerce\Admin\Notes\WC_Admin_Notes_Order_Milestones;
use \Automattic\WooCommerce\Admin\Notes\WC_Admin_Notes_Welcome_Message;
@ -121,7 +122,7 @@ class FeaturePlugin {
$this->define( 'WC_ADMIN_PLUGIN_FILE', WC_ADMIN_ABSPATH . 'woocommerce-admin.php' );
// WARNING: Do not directly edit this version number constant.
// It is updated as part of the prebuild process from the package.json value.
$this->define( 'WC_ADMIN_VERSION_NUMBER', '0.16.0' );
$this->define( 'WC_ADMIN_VERSION_NUMBER', '0.17.0' );
}
/**
@ -151,6 +152,7 @@ class FeaturePlugin {
new WC_Admin_Notes_Historical_Data();
new WC_Admin_Notes_Order_Milestones();
new WC_Admin_Notes_Welcome_Message();
new WC_Admin_Notes_Facebook_Extension();
}
/**
@ -313,4 +315,4 @@ class FeaturePlugin {
* Prevent unserializing.
*/
private function __wakeup() {}
}
}

View File

@ -0,0 +1,36 @@
<?php
/**
* WC Admin Note Traits
*
* WC Admin Note Traits class that houses shared functionality across notes.
*
* @package WooCommerce Admin/Classes
*/
namespace Automattic\WooCommerce\Admin\Notes;
defined( 'ABSPATH' ) || exit;
/**
* NoteTraits class.
*/
trait NoteTraits {
/**
* Test how long WooCommerce Admin has been active.
*
* @param int $seconds Time in seconds to check.
* @return bool Whether or not WooCommerce admin has been active for $seconds.
*/
public static function wc_admin_active_for( $seconds ) {
// Getting install timestamp reference class-wc-admin-install.php.
$wc_admin_installed = get_option( 'wc_admin_install_timestamp', false );
if ( false === $wc_admin_installed ) {
update_option( 'wc_admin_install_timestamp', time() );
return false;
}
return ( ( time() - $wc_admin_installed ) >= $seconds );
}
}

View File

@ -0,0 +1,99 @@
<?php
/**
* WooCommerce Admin Facebook Extension Note Provider.
*
* Adds a note to the merchant's inbox showing the benefits of the Facebook extension.
*
* @package WooCommerce Admin
*/
namespace Automattic\WooCommerce\Admin\Notes;
defined( 'ABSPATH' ) || exit;
/**
* WC_Admin_Notes_Facebook_Extension
*/
class WC_Admin_Notes_Facebook_Extension {
/**
* Note traits.
*/
use NoteTraits;
/**
* Name of the note for use in the database.
*/
const NOTE_NAME = 'wc-admin-facebook-extension';
/**
* Attach hooks.
*/
public function __construct() {
add_action( 'woocommerce_admin_note_action_install-now', array( $this, 'install_facebook_extension' ) );
}
/**
* Possibly add Facebook extension note.
*/
public static function possibly_add_facebook_note() {
// Only show the Facebook note to stores with products.
$products = wp_count_posts( 'product' );
if ( (int) $products->publish < 1 ) {
return;
}
// We want to show the Facebook note after day 3.
$three_days_in_seconds = 3 * DAY_IN_SECONDS;
if ( ! self::wc_admin_active_for( $three_days_in_seconds ) ) {
return;
}
$data_store = \WC_Data_Store::load( 'admin-note' );
// We already have this note? Then exit, we're done.
$note_ids = $data_store->get_notes_with_name( self::NOTE_NAME );
if ( ! empty( $note_ids ) ) {
return;
}
include_once ABSPATH . '/wp-admin/includes/plugin.php';
$content = __( 'Grow your business by targeting the right people and driving sales with Facebook. You can install this free extension now.', 'woocommerce-admin' );
$note = new WC_Admin_Note();
$note->set_title( __( 'Market on Facebook', 'woocommerce-admin' ) );
$note->set_content( $content );
$note->set_content_data( (object) array() );
$note->set_type( WC_Admin_Note::E_WC_ADMIN_NOTE_INFORMATIONAL );
$note->set_icon( 'thumbs-up' );
$note->set_name( self::NOTE_NAME );
$note->set_source( 'woocommerce-admin' );
$note->add_action( 'learn-more', __( 'Learn more', 'woocommerce-admin' ), 'https://woocommerce.com/products/facebook/', WC_Admin_Note::E_WC_ADMIN_NOTE_UNACTIONED );
$note->add_action( 'install-now', __( 'Install now', 'woocommerce-admin' ), false, WC_Admin_Note::E_WC_ADMIN_NOTE_ACTIONED, true );
// Create the note as "actioned" if the Facebook extension is already installed.
if ( 0 === validate_plugin( 'facebook-for-woocommerce/facebook-for-woocommerce.php' ) ) {
$note->set_status( WC_Admin_Note::E_WC_ADMIN_NOTE_ACTIONED );
}
$note->save();
}
/**
* Install Facebook extension when note is actioned.
*/
public function install_facebook_extension( $note ) {
if ( self::NOTE_NAME === $note->get_name() ) {
$plugin = array( 'plugin' => 'facebook-for-woocommerce' );
$installer = new \Automattic\WooCommerce\Admin\API\OnboardingPlugins();
$result = $installer->install_plugin( $plugin );
if ( is_wp_error( $result ) ) {
// @todo Reset note actioned status?
return;
}
$installer->activate_plugin( $plugin );
}
}
}

View File

@ -15,6 +15,11 @@ defined( 'ABSPATH' ) || exit;
* WC_Admin_Notes_Giving_Feedback_Notes
*/
class WC_Admin_Notes_Giving_Feedback_Notes {
/**
* Note traits.
*/
use NoteTraits;
/**
* Add notes for admin giving feedback.
*/
@ -36,18 +41,9 @@ class WC_Admin_Notes_Giving_Feedback_Notes {
return;
}
// Getting install timestamp reference class-wc-admin-install.php.
$wc_admin_installed = get_option( 'wc_admin_install_timestamp', false );
if ( false === $wc_admin_installed ) {
$wc_admin_installed = time();
update_option( 'wc_admin_install_timestamp', $wc_admin_installed );
}
$current_time = time();
$three_days_in_seconds = 259200;
// We need to show Admin Giving feeback notification after 3 days of install.
if ( $current_time - $wc_admin_installed < $three_days_in_seconds ) {
$three_days_in_seconds = 3 * DAY_IN_SECONDS;
if ( ! self::wc_admin_active_for( $three_days_in_seconds ) ) {
return;
}

View File

@ -15,6 +15,10 @@ defined( 'ABSPATH' ) || exit;
* WC_Admin_Notes_Mobile_App
*/
class WC_Admin_Notes_Mobile_App {
/**
* Note traits.
*/
use NoteTraits;
/**
* Name of the note for use in the database.
@ -25,18 +29,9 @@ class WC_Admin_Notes_Mobile_App {
* Possibly add mobile app note.
*/
public static function possibly_add_mobile_app_note() {
$wc_admin_installed = get_option( 'wc_admin_install_timestamp', false );
if ( false === $wc_admin_installed ) {
$wc_admin_installed = time();
update_option( 'wc_admin_install_timestamp', $wc_admin_installed );
}
$current_time = time();
$two_days_in_seconds = 172800;
// We want to show the mobile app note after day 2.
if ( $current_time - $wc_admin_installed < $two_days_in_seconds ) {
$two_days_in_seconds = 2 * DAY_IN_SECONDS;
if ( ! self::wc_admin_active_for( $two_days_in_seconds ) ) {
return;
}

View File

@ -7,7 +7,7 @@
* Author URI: https://woocommerce.com/
* Text Domain: woocommerce-admin
* Domain Path: /languages
* Version: 0.16.0
* Version: 0.17.0
* Requires at least: 5.2.0
* Requires PHP: 5.6.20
*