Merge branch 'trunk' into update/32508_pnpx_deprecated
This commit is contained in:
commit
0a0c6b45cf
|
@ -25,13 +25,10 @@ Closes # .
|
|||
* [ ] Have you added an explanation of what your changes do and why you'd like us to include them?
|
||||
* [ ] Have you written new tests for your changes, as applicable?
|
||||
* [ ] Have you successfully run tests with your changes locally?
|
||||
* [ ] Have you created a changelog file by running `pnpm nx affected --target=changelog`?
|
||||
|
||||
<!-- Mark completed items with an [x] -->
|
||||
|
||||
### Changelog entry
|
||||
|
||||
> Enter a summary of all changes on this Pull Request. This will appear in the changelog if accepted.
|
||||
|
||||
### FOR PR REVIEWER ONLY:
|
||||
|
||||
* [ ] I have reviewed that everything is sanitized/escaped appropriately for any SQL or XSS injection possibilities. I made sure Linting is not ignored or disabled.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
name: Run lint checks potentially affected projects across the monorepo
|
||||
name: Run lint checks potentially affecting projects across the monorepo
|
||||
on: pull_request
|
||||
concurrency:
|
||||
group: changelogger-${{ github.event_name }}-${{ github.ref }}
|
||||
|
@ -9,10 +9,10 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
fetch-depth: 10
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
|
|
|
@ -57,7 +57,6 @@ echo "The pull request was merged by: $merger_user_name\n";
|
|||
|
||||
$comment_body = "Hi @$merger_user_name, thanks for merging this pull request. Please take a look at these follow-up tasks you may need to perform:
|
||||
|
||||
- [ ] Add the `release: add changelog` label
|
||||
- [ ] Add the `release: add testing instructions` label";
|
||||
|
||||
$add_comment_mutation = "
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
pnpm install
|
||||
pnpm nx affected --target="composer-install" --base=ORIG_HEAD --head=HEAD
|
|
@ -1,4 +1,4 @@
|
|||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
node bin/pre-push-hook.js
|
||||
./bin/pre-push.sh
|
|
@ -0,0 +1,24 @@
|
|||
#!/bin/sh
|
||||
|
||||
PROTECTED_BRANCH="trunk"
|
||||
CURRENT_BRANCH=$(git branch --show-current)
|
||||
if [ $PROTECTED_BRANCH = $CURRENT_BRANCH ]; then
|
||||
if [ "$TERM" = "dumb" ]; then
|
||||
>&2 echo "Sorry, you are unable to push to $PROTECTED_BRANCH using a GUI client! Please use git CLI."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
printf "%sYou're about to push to $PROTECTED_BRANCH, is that what you intended? [y/N]: %s" "$(tput setaf 3)" "$(tput sgr0)"
|
||||
read -r PROCEED < /dev/tty
|
||||
echo
|
||||
|
||||
if [ "$(echo "${PROCEED:-n}" | tr "[:upper:]" "[:lower:]")" = "y" ]; then
|
||||
echo "$(tput setaf 2)Brace yourself! Pushing to the $PROTECTED_BRANCH branch...$(tput sgr0)"
|
||||
echo
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "$(tput setaf 2)Push to $PROTECTED_BRANCH cancelled!$(tput sgr0)"
|
||||
echo
|
||||
exit 1
|
||||
fi
|
|
@ -1,5 +1,103 @@
|
|||
== Changelog ==
|
||||
|
||||
= 6.4.0 2022-04-12 =
|
||||
|
||||
**WooCommerce**
|
||||
|
||||
- Add - Scaffolding for the custom orders table feature. ([#31692](https://github.com/woocommerce/woocommerce/pull/31692))
|
||||
- Add - Add DB table structure for custom order tables. ([#31811](https://github.com/woocommerce/woocommerce/pull/31811))
|
||||
- Add - Primary key for the product attributes lookup table. ([#32067](https://github.com/woocommerce/woocommerce/pull/32067))
|
||||
- Add - Tracks to the dashboard status widget and setup widget. ([#31857](https://github.com/woocommerce/woocommerce/pull/31857))
|
||||
- Add - Check around setup widget display when features are disabled. ([#31884](https://github.com/woocommerce/woocommerce/pull/31884))
|
||||
- Add - 'woocommerce_get_formatted_meta_data_include_all_meta_lines' filter hook. This can be used to control whether metadata lines are shown in the order meta box. ([#30948](https://github.com/woocommerce/woocommerce/pull/30948))
|
||||
- Enhancement - Introduce rate_limit_remaining column in the wc_rate_limits table. ([#32041](https://github.com/woocommerce/woocommerce/pull/32041))
|
||||
- Tweak - Update PayPal Standard JS used in the admin environment to avoid deprecated functionality. ([#32076](https://github.com/woocommerce/woocommerce/pull/32076))
|
||||
- Tweak - Change level of escaping used to render the CSV import error log. ([#32000](https://github.com/woocommerce/woocommerce/pull/32000))
|
||||
- Tweak - Make the payment_url field available via the REST API's orders endpoint. ([#31826](https://github.com/woocommerce/woocommerce/pull/31826))
|
||||
- Tweak - Rename WC_API_Exception code woocommerce_api_cannot_edit_product_catgory into woocommerce_api_cannot_edit_product_category ([#31785](https://github.com/woocommerce/woocommerce/pull/31785))
|
||||
- Tweak - Updated default email color to new Woo purple ([#30586](https://github.com/woocommerce/woocommerce/pull/30586))
|
||||
- Fix - Avoid depending on the presence of a theme header template to clear the cart after payment is made. ([#31877](https://github.com/woocommerce/woocommerce/pull/31877))
|
||||
- Fix - Payments tab tracking. ([#31844](https://github.com/woocommerce/woocommerce/pull/31844))
|
||||
- Fix - Remove unnecessary duplicate style in email-styles template. ([#31860](https://github.com/woocommerce/woocommerce/pull/31860))
|
||||
- Fix - incorrect position value for registering menu pages. ([#31779](https://github.com/woocommerce/woocommerce/pull/31779))
|
||||
- Fix - SZL currency symbol. Updated from 'L' to 'E'. ([#30602](https://github.com/woocommerce/woocommerce/pull/30602))
|
||||
- Fix - Removed execution of at least one hook ignoring the `woocommerce_load_webhooks_limit` filter value. ([#29002](https://github.com/woocommerce/woocommerce/pull/29002))
|
||||
- Dev - Added has_options() to REST API v3 product endpoint response. ([#32031](https://github.com/woocommerce/woocommerce/pull/32031))
|
||||
- Dev - Added woocommerce_admin_order_should_render_refunds hook to allow control over the refunds UI within the order editor. ([#31414](https://github.com/woocommerce/woocommerce/pull/31414))
|
||||
|
||||
**WooCommerce Admin - 3.3.0 & 3.3.1 & 3.3.2**
|
||||
|
||||
- Add - Add asynchronous plugin install and activation endpoints ([#8079](https://github.com/woocommerce/woocommerce-admin/pull/8079))
|
||||
- Performance - Avoid expensive get_notes() queries in CouponPageMoved admin_init actions by using new Notes::get_note_by_name() helper method. ([#8202](https://github.com/woocommerce/woocommerce-admin/pull/8202))
|
||||
- Enhancement - Add chart color filter for overriding default chart colors. ([#8258](https://github.com/woocommerce/woocommerce-admin/pull/8258))
|
||||
- Enhancement - Added Typescript type declarations to build for @woocommerce/components ([#8282](https://github.com/woocommerce/woocommerce-admin/pull/8282))
|
||||
- Enhancement - Increase color selection limit to ten and add additional colors. ([#8258](https://github.com/woocommerce/woocommerce-admin/pull/8258))
|
||||
- Enhancement - Made @woocommerce/components/Stepper a Typescript file ([#8286](https://github.com/woocommerce/woocommerce-admin/pull/8286))
|
||||
- Enhancement - Prompts a modal to save any unsaved changes when the users try to move to a different step ([#8278](https://github.com/woocommerce/woocommerce-admin/pull/8278))
|
||||
- Tweak - OBW: Override Country/Region label line-height style to avoid truncated descenders. ([#8186](https://github.com/woocommerce/woocommerce-admin/pull/8186))
|
||||
- Tweak - Show single success message for theme install and activation ([#8236](https://github.com/woocommerce/woocommerce-admin/pull/8236))
|
||||
- Tweak - Use WC_VERSION as cache buster for assets ([#8308](https://github.com/woocommerce/woocommerce-admin/pull/8308))
|
||||
- Update - Adjust time range and add an image for the Jetpack Backup note. ([#8293](https://github.com/woocommerce/woocommerce-admin/pull/8293))
|
||||
- Update - Implement MailChimp API request threshold for MailchimpScheduler. ([#8342](https://github.com/woocommerce/woocommerce-admin/pull/8342))
|
||||
- Update - Reintroduce CES on product add, product update, and order update. ([#8238](https://github.com/woocommerce/woocommerce-admin/pull/8238))
|
||||
- Update - Replace mysql image with mariadb ([#8220](https://github.com/woocommerce/woocommerce-admin/pull/8220))
|
||||
- Update - Update country support list for WooCommerce Payments Task. ([#8517](https://github.com/woocommerce/woocommerce-admin/pull/8517))
|
||||
- Fix - Fix handling of paid themes in purchase task. ([#8493](https://github.com/woocommerce/woocommerce-admin/pull/8493))
|
||||
- Fix - Make sure the paid extension task is also shown for themes. ([#8412](https://github.com/woocommerce/woocommerce-admin/pull/8412))
|
||||
- Fix - Reintroduce emphasis on inbox note action button. ([#8411](https://github.com/woocommerce/woocommerce-admin/pull/8411))
|
||||
- Fix - Remove class ExtendedPayments. ([#8461](https://github.com/woocommerce/woocommerce-admin/pull/8461))
|
||||
- Fix - Added random IDs to SVG checkmarks in stepper component ([#8222](https://github.com/woocommerce/woocommerce-admin/pull/8222))
|
||||
- Fix - Fix Google Listings plugin is always shown in free features despite already activated. ([#8330](https://github.com/woocommerce/woocommerce-admin/pull/8330))
|
||||
- Fix - Fix hidden notes in `admin/notes` endpoint when the user is not in the tasklist experiment. ([#8328](https://github.com/woocommerce/woocommerce-admin/pull/8328))
|
||||
- Fix - Fix missing product name in variation analytic page for the deleted products. ([#8255](https://github.com/woocommerce/woocommerce-admin/pull/8255))
|
||||
- Fix - Fix payments extensions displayed below the offline payments options. ([#8232](https://github.com/woocommerce/woocommerce-admin/pull/8232))
|
||||
- Fix - Fix setup wizard title and flash of content ([#8201](https://github.com/woocommerce/woocommerce-admin/pull/8201))
|
||||
- Fix - Fix too many pending run_remote_notifications actions. ([#8285](https://github.com/woocommerce/woocommerce-admin/pull/8285))
|
||||
- Fix - Fix view logic for Setup additional payment providers task. ([#8391](https://github.com/woocommerce/woocommerce-admin/pull/8391))
|
||||
- Fix - OBW: fix copy on Business Details when "WooCommerce Shipping" is not listed ([#8324](https://github.com/woocommerce/woocommerce-admin/pull/8324))
|
||||
- Fix - Only add product data on REST requests and task list ([#8235](https://github.com/woocommerce/woocommerce-admin/pull/8235))
|
||||
- Fix - Stop showing actioned inbox items ([#8394](https://github.com/woocommerce/woocommerce-admin/pull/8394))
|
||||
- Fix - WC Payments task is not visible after installing the plugin ([#8514](https://github.com/woocommerce/woocommerce-admin/pull/8514))
|
||||
- Fix - PHP warning when default param is missing in payments spec. ([#8519](https://github.com/woocommerce/woocommerce-admin/pull/8519))
|
||||
- Dev - Added a test for tracks event recording for PaymentGatewaySuggestions ([#8306](https://github.com/woocommerce/woocommerce-admin/pull/8306))
|
||||
- Dev - Add README to hook reference generation script ([#8004](https://github.com/woocommerce/woocommerce-admin/pull/8004))
|
||||
- Dev - Add reset WooCommerce functionality to E2E tests, so tests have a fresh state. ([#8219](https://github.com/woocommerce/woocommerce-admin/pull/8219))
|
||||
- Dev - Enabled optional typescript checking on ./client subfolder ([#8372](https://github.com/woocommerce/woocommerce-admin/pull/8372))
|
||||
- Dev - Fix formatting and add filter param for changelog types for the testing instructions script. ([#8256](https://github.com/woocommerce/woocommerce-admin/pull/8256))
|
||||
- Dev - Refactor MerchantEmailNotifications ([#8304](https://github.com/woocommerce/woocommerce-admin/pull/8304))
|
||||
- Dev - Remove preloaded countries from data endpoints and use data store instead. ([#8380](https://github.com/woocommerce/woocommerce-admin/pull/8380))
|
||||
- Dev - Remove unused pre loaded setting data displaying all the routes. ([#8379](https://github.com/woocommerce/woocommerce-admin/pull/8379))
|
||||
- Dev - Remove unused task styling classes ([#8234](https://github.com/woocommerce/woocommerce-admin/pull/8234))
|
||||
- Dev - Update dependencies to support react 17 and drop support for IE11. ([#8305](https://github.com/woocommerce/woocommerce-admin/pull/8305))
|
||||
- Dev - Update task list data structure to better handle new designs. ([#8332](https://github.com/woocommerce/woocommerce-admin/pull/8332))
|
||||
|
||||
**WooCommerce Blocks - 7.2.0 & 7.2.1**
|
||||
|
||||
- Enhancement - Add Global Styles support to the Product Price block. ([5950](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5950))
|
||||
- Enhancement - Add Global Styles support to the Add To Cart Button block. ([5816](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5816))
|
||||
- Enhancement - Store API - Introduced `wc/store/v1` namespace. ([5911](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5911))
|
||||
- Enhancement - Renamed WooCommerce block templates to more e-commerce related names. ([5935](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5935))
|
||||
- Enhancement - Featured Product block: Add the ability to reset to a previously set custom background image. ([5886](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5886))
|
||||
- Enhancement - Add a remove image button to the WooCommerce Feature Category block. ([5719](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5719))
|
||||
- Enhancement - Add support for the global style for the On-Sale Badge block. ([5565](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5565))
|
||||
- Enhancement - Add support for the global style for the Attribute Filter block. ([5557](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5557))
|
||||
- Enhancement - Category List block: Add support for global style. ([5516](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5516))
|
||||
- Fix - Fixed typo in `wooocommerce_store_api_validate_add_to_cart` and `wooocommerce_store_api_validate_cart_item` hook names. ([5926](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5926))
|
||||
- Fix - Fix loading WC core translations in locales where WC Blocks is not localized for some strings. ([5910](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5910))
|
||||
- Fix - Fixed an issue where clear customizations functionality was not working for WooCommerce templates. ([5746](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5746))
|
||||
- Fix - Fixed hover and focus states for button components. ([5712](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5712))
|
||||
- Fix - Add to Cart button on Products listing blocks will respect the "Redirect to the cart page after successful addition" setting. ([5708](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5708))
|
||||
- Fix - Fixes Twenty Twenty Two issues with sales price and added to cart "View Cart" call out styling in the "Products by Category" block. ([5684](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5684))
|
||||
- Fix - StoreAPI: Clear all wc notice types in the cart validation context [#5983](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5983)
|
||||
- Fix - Don't trigger class deprecations notices if headers are already sent [#6074](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/6074)
|
||||
- Various - Remove v1 string from Store Keys. ([5987](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5987))
|
||||
- Various - Introduce the `InvalidCartException` for handling cart validation. ([5904](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5904))
|
||||
- Various - Renamed Store API custom headers to remove `X-WC-Store-API` prefixes. [#5983](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5983)
|
||||
- Various - Normalised Store API error codes [#5992](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5992)
|
||||
- Various - Deprecated `woocommerce_blocks_checkout_order_processed` in favour of `woocommerce_store_api_checkout_order_processed`
|
||||
- Various - Deprecated `woocommerce_blocks_checkout_update_order_meta` in favour of `woocommerce_store_api_checkout_update_order_meta`
|
||||
- Various - Deprecated `woocommerce_blocks_checkout_update_order_from_request` in favour of `woocommerce_store_api_checkout_update_order_from_request`
|
||||
|
||||
= 6.3.1 2022-03-10 =
|
||||
|
||||
**WooCommerce**
|
||||
|
|
|
@ -14,7 +14,9 @@
|
|||
"url": "https://github.com/woocommerce/woocommerce/issues"
|
||||
},
|
||||
"scripts": {
|
||||
"preinstall": "npx only-allow pnpm"
|
||||
"preinstall": "npx only-allow pnpm",
|
||||
"postinstall": "pnpm git:update-hooks",
|
||||
"git:update-hooks": "rm -r .git/hooks && mkdir -p .git/hooks && husky install"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@automattic/nx-composer": "^0.1.0",
|
||||
|
@ -30,7 +32,9 @@
|
|||
"@wordpress/prettier-config": "^1.1.1",
|
||||
"chalk": "^4.1.2",
|
||||
"glob": "^7.2.0",
|
||||
"husky": "^7.0.4",
|
||||
"jest": "^27.3.1",
|
||||
"lint-staged": "^12.3.7",
|
||||
"mkdirp": "^1.0.4",
|
||||
"node-stream-zip": "^1.15.0",
|
||||
"prettier": "npm:wp-prettier@^2.2.1-beta-1",
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
# Unreleased
|
||||
|
||||
- Add E2E tests to disabled welcome modal #32505
|
||||
|
||||
- Update test for payment task. #32467
|
||||
|
||||
# 1.0.0
|
||||
|
||||
- Add returned type annotations and remove unused vars. #8020
|
||||
|
|
|
@ -56,5 +56,10 @@
|
|||
"clean": "pnpm exec rimraf tsconfig.tsbuildinfo build build-*",
|
||||
"lint": "eslint src",
|
||||
"prepack": "pnpm run clean && pnpm run build"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.(t|j)s?(x)": [
|
||||
"eslint --fix"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,15 @@ export class PaymentsSetup extends BasePage {
|
|||
await this.clickButtonWithText( 'Got it' );
|
||||
}
|
||||
|
||||
async showOtherPaymentMethods(): Promise< void > {
|
||||
const selector = '.woocommerce-task-payments button.toggle-button';
|
||||
await this.page.waitForSelector( selector );
|
||||
const toggleButton = await this.page.$(
|
||||
`${ selector }[aria-expanded=false]`
|
||||
);
|
||||
await toggleButton?.click();
|
||||
}
|
||||
|
||||
async goToPaymentMethodSetup(
|
||||
method: PaymentMethodWithSetupButton
|
||||
): Promise< void > {
|
||||
|
@ -41,14 +50,6 @@ export class PaymentsSetup extends BasePage {
|
|||
}
|
||||
}
|
||||
|
||||
async methodHasBeenSetup( method: PaymentMethod ): Promise< void > {
|
||||
const selector = `.woocommerce-task-payment-${ method }`;
|
||||
await this.page.waitForSelector( selector );
|
||||
expect(
|
||||
await getElementByText( '*', 'Manage', selector )
|
||||
).toBeDefined();
|
||||
}
|
||||
|
||||
async enableCashOnDelivery(): Promise< void > {
|
||||
await this.page.waitForSelector( '.woocommerce-task-payment-cod' );
|
||||
await this.clickButtonWithText( 'Enable' );
|
||||
|
|
|
@ -24,12 +24,7 @@ export class WcHomescreen extends BasePage {
|
|||
}
|
||||
|
||||
async possiblyDismissWelcomeModal(): Promise< void > {
|
||||
const modalText = 'Welcome to your WooCommerce store’s online HQ!';
|
||||
const modal = await waitForElementByTextWithoutThrow(
|
||||
'h2',
|
||||
modalText,
|
||||
10
|
||||
);
|
||||
const modal = await this.isWelcomeModalVisible();
|
||||
|
||||
if ( modal ) {
|
||||
await this.clickButtonWithText( 'Next' );
|
||||
|
@ -41,6 +36,16 @@ export class WcHomescreen extends BasePage {
|
|||
}
|
||||
}
|
||||
|
||||
async isWelcomeModalVisible(): Promise< boolean > {
|
||||
const modalText = 'Welcome to your WooCommerce store’s online HQ!';
|
||||
const modal = await waitForElementByTextWithoutThrow(
|
||||
'h2',
|
||||
modalText,
|
||||
10
|
||||
);
|
||||
return modal;
|
||||
}
|
||||
|
||||
async getTaskList(): Promise< Array< string | null > > {
|
||||
await page.waitForSelector(
|
||||
'.woocommerce-task-card .woocommerce-task-list__item-title'
|
||||
|
|
|
@ -42,8 +42,22 @@ export class WcSettings extends BasePage {
|
|||
);
|
||||
}
|
||||
|
||||
async paymentMethodIsEnabled( method = '' ): Promise< boolean > {
|
||||
await this.navigate( 'checkout' );
|
||||
await waitForElementByText( 'h2', 'Payment methods' );
|
||||
const className = await getAttribute(
|
||||
`tr[data-gateway_id=${ method }] .woocommerce-input-toggle`,
|
||||
'className'
|
||||
);
|
||||
return (
|
||||
( className as string ).indexOf(
|
||||
'woocommerce-input-toggle--disabled'
|
||||
) === -1
|
||||
);
|
||||
}
|
||||
|
||||
async cleanPaymentMethods(): Promise< void > {
|
||||
this.navigate( 'checkout' );
|
||||
await this.navigate( 'checkout' );
|
||||
await waitForElementByText( 'h2', 'Payment methods' );
|
||||
const paymentMethods = await page.$$( 'span.woocommerce-input-toggle' );
|
||||
for ( const method of paymentMethods ) {
|
||||
|
|
|
@ -597,10 +597,37 @@ const testBusinessDetailsForm = () => {
|
|||
} );
|
||||
};
|
||||
|
||||
const testAdminHomescreen = () => {
|
||||
describe( 'Homescreen', () => {
|
||||
const profileWizard = new OnboardingWizard( page );
|
||||
const homeScreen = new WcHomescreen( page );
|
||||
const login = new Login( page );
|
||||
|
||||
beforeAll( async () => {
|
||||
await login.login();
|
||||
await resetWooCommerceState();
|
||||
await profileWizard.navigate();
|
||||
await profileWizard.skipStoreSetup();
|
||||
} );
|
||||
|
||||
afterAll( async () => {
|
||||
await login.logout();
|
||||
} );
|
||||
|
||||
it( 'should not show welcome modal', async () => {
|
||||
await homeScreen.isDisplayed();
|
||||
await expect( homeScreen.isWelcomeModalVisible() ).resolves.toBe(
|
||||
false
|
||||
);
|
||||
} );
|
||||
} );
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
testAdminOnboardingWizard,
|
||||
testSelectiveBundleWCPay,
|
||||
testDifferentStoreCurrenciesWCPay,
|
||||
testSubscriptionsInclusion,
|
||||
testBusinessDetailsForm,
|
||||
testAdminHomescreen,
|
||||
};
|
||||
|
|
|
@ -53,6 +53,7 @@ const testAdminPaymentSetupTask = () => {
|
|||
} );
|
||||
|
||||
it( 'Saving valid bank account transfer details enables the payment method', async () => {
|
||||
await paymentsSetup.showOtherPaymentMethods();
|
||||
await paymentsSetup.goToPaymentMethodSetup( 'bacs' );
|
||||
await bankTransferSetup.saveAccountDetails( {
|
||||
accountNumber: '1234',
|
||||
|
@ -62,12 +63,11 @@ const testAdminPaymentSetupTask = () => {
|
|||
iban: '12 3456 7890',
|
||||
swiftCode: 'ABBA',
|
||||
} );
|
||||
|
||||
await homeScreen.isDisplayed();
|
||||
await waitForTimeout( 1000 );
|
||||
await homeScreen.clickOnTaskList( 'Set up payments' );
|
||||
await paymentsSetup.isDisplayed();
|
||||
await paymentsSetup.methodHasBeenSetup( 'bacs' );
|
||||
expect( await settings.paymentMethodIsEnabled( 'bacs' ) ).toBe(
|
||||
true
|
||||
);
|
||||
await homeScreen.navigate();
|
||||
} );
|
||||
|
||||
it( 'Enabling cash on delivery enables the payment method', async () => {
|
||||
|
@ -76,13 +76,13 @@ const testAdminPaymentSetupTask = () => {
|
|||
await homeScreen.isDisplayed();
|
||||
await waitForTimeout( 1000 );
|
||||
await homeScreen.clickOnTaskList( 'Set up payments' );
|
||||
await paymentsSetup.enableCashOnDelivery();
|
||||
await homeScreen.navigate();
|
||||
await homeScreen.isDisplayed();
|
||||
await waitForTimeout( 1000 );
|
||||
await homeScreen.clickOnTaskList( 'Set up payments' );
|
||||
await paymentsSetup.isDisplayed();
|
||||
await paymentsSetup.methodHasBeenSetup( 'cod' );
|
||||
await paymentsSetup.showOtherPaymentMethods();
|
||||
await paymentsSetup.enableCashOnDelivery();
|
||||
await waitForTimeout( 1000 );
|
||||
expect( await settings.paymentMethodIsEnabled( 'cod' ) ).toBe(
|
||||
true
|
||||
);
|
||||
} );
|
||||
} );
|
||||
};
|
||||
|
|
|
@ -33,5 +33,10 @@
|
|||
},
|
||||
"bin": {
|
||||
"wc-api-tests": "bin/wc-api-tests.sh"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.(t|j)s?(x)": [
|
||||
"eslint --fix"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,5 +52,10 @@
|
|||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.(t|j)s?(x)": [
|
||||
"eslint --fix"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
# Unreleased
|
||||
|
||||
- Fix documentation for `TableCard` component
|
||||
- Update dependency `@wordpress/hooks` to ^3.5.0
|
||||
- Update dependency `@wordpress/icons` to ^8.1.0
|
||||
|
||||
# 10.0.0
|
||||
- Replace deprecated wp.compose.withState with wp.element.useState. #8338
|
||||
- Add missing dependencies. #8349
|
||||
|
|
|
@ -39,10 +39,10 @@
|
|||
"@wordpress/deprecated": "^3.3.1",
|
||||
"@wordpress/dom": "^3.3.2",
|
||||
"@wordpress/element": "^4.1.1",
|
||||
"@wordpress/hooks": "^2.12.3",
|
||||
"@wordpress/hooks": "^3.5.0",
|
||||
"@wordpress/html-entities": "^3.3.1",
|
||||
"@wordpress/i18n": "^4.3.1",
|
||||
"@wordpress/icons": "^6.3.0",
|
||||
"@wordpress/icons": "^8.1.0",
|
||||
"@wordpress/keycodes": "^3.3.1",
|
||||
"@wordpress/url": "^3.4.1",
|
||||
"@wordpress/viewport": "^4.1.2",
|
||||
|
@ -123,5 +123,11 @@
|
|||
"test:nobuild": "jest --config ./jest.config.json",
|
||||
"test:update-snapshots": "pnpm run test:nobuild -- --updateSnapshot",
|
||||
"test-staged": "jest --bail --config ./jest.config.json --findRelatedTests"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.(t|j)s?(x)": [
|
||||
"eslint --fix",
|
||||
"pnpm test-staged"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,8 +67,8 @@ Name | Type | Default | Description
|
|||
`downloadable` | Boolean | `false` | Whether the table must be downloadable. If true, the download button will appear
|
||||
`onClickDownload` | Function | `null` | A callback function called when the "download" button is pressed. Optional, if used, the download button will appear
|
||||
`query` | Object | `{}` | An object of the query parameters passed to the page, ex `{ page: 2, per_page: 5 }`
|
||||
`rowHeader` | One of type: number, bool | `0` | An array of arrays of display/value object pairs (see `Table` props)
|
||||
`rows` | Array | `[]` | Which column should be the row header, defaults to the first item (`0`) (see `Table` props)
|
||||
`rowHeader` | One of type: number, bool | `0` | Which column should be the row header, defaults to the first item (`0`) (see `Table` props)
|
||||
`rows` | Array | `[]` | (required) An array of arrays of display/value object pairs (see `Table` props)
|
||||
`rowsPerPage` | Number | `null` | (required) The total number of rows to display per page
|
||||
`searchBy` | String | `null` | The string to use as a query parameter when searching row items
|
||||
`showMenu` | Boolean | `true` | Boolean to determine whether or not ellipsis menu is shown
|
||||
|
|
|
@ -308,11 +308,12 @@ TableCard.propTypes = {
|
|||
*/
|
||||
query: PropTypes.object,
|
||||
/**
|
||||
* An array of arrays of display/value object pairs (see `Table` props).
|
||||
* Which column should be the row header, defaults to the first item (`0`) (but could be set to `1`, if the first col
|
||||
* is checkboxes, for example). Set to false to disable row headers.
|
||||
*/
|
||||
rowHeader: PropTypes.oneOfType( [ PropTypes.number, PropTypes.bool ] ),
|
||||
/**
|
||||
* Which column should be the row header, defaults to the first item (`0`) (see `Table` props).
|
||||
* An array of arrays of display/value object pairs (see `Table` props).
|
||||
*/
|
||||
rows: PropTypes.arrayOf(
|
||||
PropTypes.arrayOf(
|
||||
|
|
|
@ -46,5 +46,11 @@
|
|||
"rimraf": "^3.0.2",
|
||||
"ts-jest": "^27.1.3",
|
||||
"typescript": "^4.6.2"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.(t|j)s?(x)": [
|
||||
"eslint --fix",
|
||||
"pnpm test-staged"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,5 +49,11 @@
|
|||
"rimraf": "^3.0.2",
|
||||
"ts-jest": "^27.1.3",
|
||||
"typescript": "^4.6.2"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.(t|j)s?(x)": [
|
||||
"eslint --fix",
|
||||
"pnpm test-staged"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,5 +70,11 @@
|
|||
"test": "pnpm run build && pnpm run test:nobuild",
|
||||
"test:nobuild": "jest --config ./jest.config.json",
|
||||
"test-staged": "jest --bail --config ./jest.config.json --findRelatedTests"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.(t|j)s?(x)": [
|
||||
"eslint --fix",
|
||||
"pnpm test-staged"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
# Unreleased
|
||||
|
||||
- Update dependency `@wordpress/hooks` to ^3.5.0
|
||||
- Add `is_offline` attribute for `Plugin` type. #32467
|
||||
|
||||
# 3.1.0
|
||||
|
||||
- Add "moment" to peerDependencies. #8349
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
"@wordpress/data-controls": "^2.3.2",
|
||||
"@wordpress/deprecated": "^3.3.1",
|
||||
"@wordpress/element": "^4.1.1",
|
||||
"@wordpress/hooks": "^2.12.3",
|
||||
"@wordpress/hooks": "^3.5.0",
|
||||
"@wordpress/i18n": "^4.3.1",
|
||||
"@wordpress/url": "^3.4.1",
|
||||
"dompurify": "^2.3.6",
|
||||
|
@ -70,5 +70,11 @@
|
|||
"test": "pnpm run build && pnpm run test:nobuild",
|
||||
"test:nobuild": "jest --config ./jest.config.json",
|
||||
"test-staged": "jest --bail --config ./jest.config.json --findRelatedTests"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.(t|j)s?(x)": [
|
||||
"eslint --fix",
|
||||
"pnpm test-staged"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ export { withPluginsHydration } from './plugins/with-plugins-hydration';
|
|||
|
||||
export { ONBOARDING_STORE_NAME } from './onboarding';
|
||||
export { withOnboardingHydration } from './onboarding/with-onboarding-hydration';
|
||||
export { getVisibleTasks } from './onboarding/utils';
|
||||
export type { TaskType, TaskListType } from './onboarding/types';
|
||||
|
||||
export { USER_STORE_NAME } from './user';
|
||||
|
|
|
@ -9,12 +9,22 @@ export type TaskType = {
|
|||
isSnoozed: boolean;
|
||||
isVisible: boolean;
|
||||
isSnoozable: boolean;
|
||||
isDisabled: boolean;
|
||||
snoozedUntil: number;
|
||||
time: string;
|
||||
title: string;
|
||||
isVisited: boolean;
|
||||
};
|
||||
|
||||
export type TaskListSection = {
|
||||
id: string;
|
||||
title: string;
|
||||
description: string;
|
||||
image: string;
|
||||
tasks: string[];
|
||||
isComplete: boolean;
|
||||
};
|
||||
|
||||
export type TaskListType = {
|
||||
id: string;
|
||||
isCollapsible?: boolean;
|
||||
|
@ -25,4 +35,5 @@ export type TaskListType = {
|
|||
title: string;
|
||||
eventPrefix: string;
|
||||
displayProgressHeader: boolean;
|
||||
sections?: TaskListSection[];
|
||||
};
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { TaskType } from './types';
|
||||
|
||||
/**
|
||||
* Filters tasks to only visible tasks, taking in account snoozed tasks.
|
||||
*/
|
||||
export function getVisibleTasks( tasks: TaskType[] ) {
|
||||
const nowTimestamp = Date.now();
|
||||
return tasks.filter(
|
||||
( task ) =>
|
||||
! task.isDismissed &&
|
||||
( ! task.isSnoozed || task.snoozedUntil < nowTimestamp )
|
||||
);
|
||||
}
|
|
@ -55,4 +55,8 @@ export const pluginNames = {
|
|||
'google-listings-and-ads': __( 'Google Listings and Ads', 'woocommerce' ),
|
||||
'woo-razorpay': __( 'Razorpay', 'woocommerce' ),
|
||||
mailpoet: __( 'MailPoet', 'woocommerce' ),
|
||||
'pinterest-for-woocommerce': __(
|
||||
'Pinterest for WooCommerce',
|
||||
'woocommerce'
|
||||
),
|
||||
};
|
||||
|
|
|
@ -39,6 +39,7 @@ export type Plugin = {
|
|||
recommendation_priority?: number;
|
||||
is_visible?: boolean;
|
||||
is_local_partner?: boolean;
|
||||
is_offline?: boolean;
|
||||
};
|
||||
|
||||
type PaypalOnboardingState = 'unknown' | 'start' | 'progressive' | 'onboarded';
|
||||
|
|
|
@ -52,5 +52,11 @@
|
|||
"test": "pnpm run build && pnpm run test:nobuild",
|
||||
"test:nobuild": "jest --config ./jest.config.json",
|
||||
"test-staged": "jest --bail --config ./jest.config.json --findRelatedTests"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.(t|j)s?(x)": [
|
||||
"eslint --fix",
|
||||
"pnpm test-staged"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,5 +34,10 @@
|
|||
"typescript": "^4.6.2",
|
||||
"webpack": "^5.70.0",
|
||||
"webpack-cli": "^3.3.12"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.(t|j)s?(x)": [
|
||||
"eslint --fix"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,5 +48,10 @@
|
|||
"clean": "rm -rf ./build ./build-module",
|
||||
"compile": "node ./../bin/build.js",
|
||||
"build": "./bin/build.sh && pnpm run clean && pnpm run compile"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.(t|j)s?(x)": [
|
||||
"eslint --fix"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -77,5 +77,10 @@
|
|||
},
|
||||
"bin": {
|
||||
"wc-e2e": "bin/wc-e2e.sh"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.(t|j)s?(x)": [
|
||||
"eslint --fix"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,5 +45,10 @@
|
|||
"build": "pnpm run clean && pnpm run compile",
|
||||
"prepare": "pnpm run build",
|
||||
"lint": "eslint src"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.(t|j)s?(x)": [
|
||||
"eslint --fix"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
# Unreleased
|
||||
|
||||
- Update dependency `@wordpress/icons` to ^8.1.0
|
||||
|
||||
# 3.0.1
|
||||
|
||||
- Update all js packages with minor/patch version changes. #8392
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
"@wordpress/components": "^19.5.0",
|
||||
"@wordpress/element": "^4.1.1",
|
||||
"@wordpress/i18n": "^4.3.1",
|
||||
"@wordpress/icons": "^6.3.0",
|
||||
"@wordpress/icons": "^8.1.0",
|
||||
"@wordpress/keycodes": "^3.3.1",
|
||||
"classnames": "^2.3.1",
|
||||
"dompurify": "^2.3.6",
|
||||
|
@ -83,5 +83,11 @@
|
|||
"test": "pnpm run build && pnpm run test:nobuild",
|
||||
"test:nobuild": "jest --config ./jest.config.json",
|
||||
"test-staged": "jest --bail --config ./jest.config.json --findRelatedTests"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.(t|j)s?(x)": [
|
||||
"eslint --fix",
|
||||
"pnpm test-staged"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -130,7 +130,7 @@ export const TaskItem: React.FC< TaskItemProps > = ( {
|
|||
}, [ expanded ] );
|
||||
|
||||
const className = classnames( 'woocommerce-task-list__item', {
|
||||
complete: completed,
|
||||
'is-complete': completed,
|
||||
expanded: isTaskExpanded,
|
||||
'level-2': level === 2 && ! completed,
|
||||
'level-1': level === 1 && ! completed,
|
||||
|
|
|
@ -121,7 +121,7 @@ $task-alert-yellow: #f0b849;
|
|||
left: 5px;
|
||||
}
|
||||
|
||||
&.complete {
|
||||
&.is-complete {
|
||||
.woocommerce-task__icon {
|
||||
background-color: var(--wp-admin-theme-color);
|
||||
}
|
||||
|
@ -136,7 +136,7 @@ $task-alert-yellow: #f0b849;
|
|||
}
|
||||
}
|
||||
|
||||
&:not(.complete) {
|
||||
&:not(.is-complete) {
|
||||
.woocommerce-task__icon {
|
||||
border: 1px solid $gray-100;
|
||||
background: $white;
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
# Unreleased
|
||||
|
||||
- Update dependency `@wordpress/hooks` to ^3.5.0
|
||||
|
||||
# 2.1.0
|
||||
|
||||
- Add missing dependencies. #8349
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
"@automattic/explat-client": "^0.0.3",
|
||||
"@automattic/explat-client-react-helpers": "^0.0.4",
|
||||
"@wordpress/api-fetch": "^6.0.1",
|
||||
"@wordpress/hooks": "^2.12.3",
|
||||
"@wordpress/hooks": "^3.5.0",
|
||||
"cookie": "^0.4.2",
|
||||
"qs": "^6.10.3"
|
||||
},
|
||||
|
@ -54,5 +54,11 @@
|
|||
"test": "pnpm run build && pnpm run test:nobuild",
|
||||
"test:nobuild": "jest --config ./jest.config.json",
|
||||
"test-staged": "jest --bail --config ./jest.config.json --findRelatedTests"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.(t|j)s?(x)": [
|
||||
"eslint --fix",
|
||||
"pnpm test-staged"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,5 +40,10 @@
|
|||
"rimraf": "^3.0.2",
|
||||
"ts-jest": "^27.1.3",
|
||||
"typescript": "^4.6.2"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.(t|j)s?(x)": [
|
||||
"eslint --fix"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -107,7 +107,7 @@ wooCommercePackages.forEach( ( lib ) => {
|
|||
} );
|
||||
} );
|
||||
|
||||
const config = require( '../../../../plugins/woocommerce-admin/config/development.json' );
|
||||
const config = require( '../../../../plugins/woocommerce/client/admin/config/development.json' );
|
||||
|
||||
// Check if test is jsdom or node
|
||||
if ( global.window ) {
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
# Unreleased
|
||||
|
||||
- Update dependency `@wordpress/hooks` to ^3.5.0
|
||||
|
||||
# 7.0.1
|
||||
|
||||
- Add missing dependencies. #8349
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
"@wordpress/components": "^19.5.0",
|
||||
"@wordpress/compose": "^5.1.2",
|
||||
"@wordpress/element": "^4.1.1",
|
||||
"@wordpress/hooks": "^2.12.3",
|
||||
"@wordpress/hooks": "^3.5.0",
|
||||
"@wordpress/notices": "^3.3.2",
|
||||
"@wordpress/url": "^3.4.1",
|
||||
"history": "^4.10.1",
|
||||
|
@ -57,5 +57,11 @@
|
|||
"rimraf": "^3.0.2",
|
||||
"ts-jest": "^27.1.3",
|
||||
"typescript": "^4.6.2"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.(t|j)s?(x)": [
|
||||
"eslint --fix",
|
||||
"pnpm test-staged"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
# Unreleased
|
||||
|
||||
- Update dependency `@wordpress/a11y` to ^3.5.0
|
||||
|
||||
# 4.0.1
|
||||
|
||||
- Update all js packages with minor/patch version changes. #8392
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
"module": "build-module/index.js",
|
||||
"react-native": "src/index",
|
||||
"dependencies": {
|
||||
"@wordpress/a11y": "^2.15.3",
|
||||
"@wordpress/a11y": "^3.5.0",
|
||||
"@wordpress/data": "^6.3.0",
|
||||
"@wordpress/notices": "^3.3.2"
|
||||
},
|
||||
|
@ -51,5 +51,10 @@
|
|||
"rimraf": "^3.0.2",
|
||||
"ts-jest": "^27.1.3",
|
||||
"typescript": "^4.6.2"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.(t|j)s?(x)": [
|
||||
"eslint --fix"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,5 +45,11 @@
|
|||
"rimraf": "^3.0.2",
|
||||
"ts-jest": "^27.1.3",
|
||||
"typescript": "^4.6.2"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.(t|j)s?(x)": [
|
||||
"eslint --fix",
|
||||
"pnpm test-staged"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
# Unreleased
|
||||
|
||||
- Update TaskList types.
|
||||
|
||||
# 3.0.1
|
||||
|
||||
- Add missing dependency.
|
||||
|
|
|
@ -59,5 +59,10 @@
|
|||
"start": "concurrently \"tsc --build --watch\" \"webpack --watch\"",
|
||||
"prepack": "pnpm run clean && pnpm run build",
|
||||
"lint": "eslint src"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.(t|j)s?(x)": [
|
||||
"eslint --fix"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"@automattic/color-studio": "^2.5.0",
|
||||
"@wordpress/base-styles": "^3.6.0",
|
||||
"@wordpress/base-styles": "^4.3.0",
|
||||
"@wordpress/postcss-plugins-preset": "^1.6.0",
|
||||
"css-loader": "^3.6.0",
|
||||
"mini-css-extract-plugin": "^2.6.0",
|
||||
|
@ -42,5 +42,10 @@
|
|||
"ts-jest": "^27.1.3",
|
||||
"typescript": "^4.6.2",
|
||||
"webpack": "^5.70.0"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.(t|j)s?(x)": [
|
||||
"eslint --fix"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,5 +42,10 @@
|
|||
"rimraf": "^3.0.2",
|
||||
"ts-jest": "^27.1.3",
|
||||
"typescript": "^4.6.2"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.(t|j)s?(x)": [
|
||||
"eslint --fix"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
<!-- Configs -->
|
||||
<config name="minimum_supported_wp_version" value="5.2" />
|
||||
<config name="testVersion" value="7.0-" />
|
||||
<config name="testVersion" value="7.2-" />
|
||||
|
||||
<!-- Rules -->
|
||||
<rule ref="WooCommerce-Core" />
|
||||
|
|
|
@ -1,62 +0,0 @@
|
|||
/* eslint-disable */
|
||||
module.exports = function ( grunt ) {
|
||||
'use strict';
|
||||
|
||||
// Project configuration
|
||||
grunt.initConfig( {
|
||||
makepot: {
|
||||
target: {
|
||||
options: {
|
||||
domainPath: '/languages',
|
||||
exclude: [ '.git/*', 'bin/*', 'node_modules/*', 'tests/*' ],
|
||||
mainFile: '../woocommerce/woocommerce.php',
|
||||
potFilename: 'woocommerce-admin.pot',
|
||||
potHeaders: {
|
||||
poedit: true,
|
||||
'x-poedit-keywordslist': true,
|
||||
},
|
||||
type: 'wp-plugin',
|
||||
updateTimestamp: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
checktextdomain: {
|
||||
options: {
|
||||
text_domain: 'woocommerce',
|
||||
keywords: [
|
||||
'__:1,2d',
|
||||
'_e:1,2d',
|
||||
'_x:1,2c,3d',
|
||||
'esc_html__:1,2d',
|
||||
'esc_html_e:1,2d',
|
||||
'esc_html_x:1,2c,3d',
|
||||
'esc_attr__:1,2d',
|
||||
'esc_attr_e:1,2d',
|
||||
'esc_attr_x:1,2c,3d',
|
||||
'_ex:1,2c,3d',
|
||||
'_n:1,2,4d',
|
||||
'_nx:1,2,4c,5d',
|
||||
'_n_noop:1,2,3d',
|
||||
'_nx_noop:1,2,3c,4d',
|
||||
],
|
||||
},
|
||||
files: {
|
||||
src: [
|
||||
'**/*.php', // Include all files/
|
||||
'!node_modules/**', // Exclude node_modules/
|
||||
'!tests/**', // Exclude tests/
|
||||
'!vendor/**', // Exclude vendor/
|
||||
'!tmp/**', // Exclude tmp/
|
||||
],
|
||||
expand: true,
|
||||
},
|
||||
},
|
||||
} );
|
||||
|
||||
// Load NPM tasks to be used here.
|
||||
grunt.loadNpmTasks( 'grunt-wp-i18n' );
|
||||
grunt.loadNpmTasks( 'grunt-checktextdomain' );
|
||||
|
||||
grunt.util.linefeed = '\n';
|
||||
};
|
|
@ -22,16 +22,7 @@ module.exports = function ( api ) {
|
|||
],
|
||||
ignore: [ 'packages/**/node_modules' ],
|
||||
env: {
|
||||
production: {
|
||||
plugins: [
|
||||
[
|
||||
'@wordpress/babel-plugin-makepot',
|
||||
{
|
||||
output: 'languages/woocommerce-admin.po',
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
production: {},
|
||||
|
||||
storybook: {
|
||||
plugins: [
|
||||
|
|
|
@ -1,104 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Command line script for merging two .pot files.
|
||||
*
|
||||
* @package WooCommerce\Admin
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the two file names from the command line.
|
||||
*/
|
||||
if ( $argc < 2 ) {
|
||||
echo "Usage: php -f {$argv[0]} source-file.pot destination-file.pot\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
for ( $index = 1; $index <= 2; $index++ ) {
|
||||
if ( ! is_file( $argv[ $index ] ) ) {
|
||||
echo "File not found: {$argv[ $index ]}\n";
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether an output locale has been requested.
|
||||
*/
|
||||
if ( isset( $argv[3] ) && 0 === stripos( $argv[3], 'lang=' ) ) {
|
||||
$locale = substr( $argv[3], 5 );
|
||||
$target_file = preg_replace( '|\.pot?|', "-{$locale}.po", $argv[2] );
|
||||
} else {
|
||||
$target_file = $argv[2];
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a .pot file into an array.
|
||||
*
|
||||
* @param string $file_name Pot file name.
|
||||
* @return array
|
||||
*/
|
||||
function woocommerce_admin_parse_pot( $file_name ) {
|
||||
$fh = fopen( $file_name, 'r' );
|
||||
$originals = array();
|
||||
$references = array();
|
||||
$messages = array();
|
||||
$have_msgid = false;
|
||||
|
||||
while ( ! feof( $fh ) ) {
|
||||
$line = trim( fgets( $fh ) );
|
||||
if ( ! $line ) {
|
||||
$message = implode( "\n", $messages );
|
||||
$originals[ $message ] = $references;
|
||||
$references = array();
|
||||
$messages = array();
|
||||
$have_msgid = false;
|
||||
$message = '';
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( 'msgid' == substr( $line, 0, 5 ) ) {
|
||||
$have_msgid = true;
|
||||
}
|
||||
|
||||
if ( $have_msgid ) {
|
||||
$messages[] = $line;
|
||||
} else {
|
||||
$references[] = $line;
|
||||
}
|
||||
}
|
||||
|
||||
fclose( $fh );
|
||||
|
||||
$message = implode( "\n", $messages );
|
||||
$originals[ $message ] = $references;
|
||||
return $originals;
|
||||
}
|
||||
|
||||
// Read the translation files.
|
||||
$originals_1 = woocommerce_admin_parse_pot( $argv[1] );
|
||||
$originals_2 = woocommerce_admin_parse_pot( $argv[2] );
|
||||
// Delete the original sources.
|
||||
unlink( $argv[1] );
|
||||
unlink( $argv[2] );
|
||||
// We don't want two .pot headers in the output.
|
||||
array_shift( $originals_1 );
|
||||
|
||||
$fh = fopen( $target_file, 'w' );
|
||||
foreach ( $originals_2 as $message => $original ) {
|
||||
// Use the complete message section to match strings to be translated.
|
||||
if ( isset( $originals_1[ $message ] ) ) {
|
||||
$original = array_merge( $original, $originals_1[ $message ] );
|
||||
unset( $originals_1[ $message ] );
|
||||
}
|
||||
|
||||
fwrite( $fh, implode( "\n", $original ) );
|
||||
fwrite( $fh, "\n" . $message ."\n\n" );
|
||||
}
|
||||
|
||||
foreach ( $originals_1 as $message => $original ) {
|
||||
fwrite( $fh, implode( "\n", $original ) );
|
||||
fwrite( $fh, "\n" . $message ."\n\n" );
|
||||
}
|
||||
|
||||
fclose( $fh );
|
||||
|
||||
echo "Created {$target_file}\n";
|
|
@ -1,23 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Check for required version
|
||||
WPCLI_VERSION=`wp cli version | cut -f2 -d' '`
|
||||
if [ ${WPCLI_VERSION:0:1} -lt "2" -o ${WPCLI_VERSION:0:1} -eq "2" -a ${WPCLI_VERSION:2:1} -lt "1" ]; then
|
||||
echo WP-CLI version 2.1.0 or greater is required to make JSON translation files
|
||||
exit
|
||||
fi
|
||||
|
||||
# Substitute JS source references with build references
|
||||
for T in `find languages -name "*.po"`
|
||||
do
|
||||
sed \
|
||||
-e 's/ client\/[^:]*:/ dist\/app\/index.js:/gp' \
|
||||
-e 's/ packages\/components[^:]*:/ dist\/components\/index.js:/gp' \
|
||||
-e 's/ packages\/date[^:]*:/ dist\/date\/index.js:/gp' \
|
||||
$T | uniq > $T-build
|
||||
rm $T
|
||||
mv $T-build $T
|
||||
done
|
||||
|
||||
# Make the JSON files
|
||||
wp i18n make-json languages --no-purge
|
|
@ -0,0 +1,4 @@
|
|||
Significance: minor
|
||||
Type: Add
|
||||
|
||||
Add support for sections in our TaskList class and create a new sectional task list component. #32302
|
|
@ -100,6 +100,10 @@ function getMarketingItems( props ) {
|
|||
link:
|
||||
'https://woocommerce.com/document/google-listings-and-ads/?utm_medium=product#get-started',
|
||||
},
|
||||
activePlugins.includes( 'pinterest-for-woocommerce' ) && {
|
||||
title: __( 'Set up Pinterest for WooCommerce', 'woocommerce' ),
|
||||
link: 'https://woocommerce.com/products/pinterest-for-woocommerce/',
|
||||
},
|
||||
activePlugins.includes( 'mailchimp-for-woocommerce' ) && {
|
||||
title: __( 'Connect Mailchimp for WooCommerce', 'woocommerce' ),
|
||||
link:
|
||||
|
|
|
@ -121,7 +121,7 @@ Leaderboard.propTypes = {
|
|||
*/
|
||||
query: PropTypes.object,
|
||||
/**
|
||||
* Which column should be the row header, defaults to the first item (`0`) (see `Table` props).
|
||||
* An array of arrays of display/value object pairs (see `Table` props).
|
||||
*/
|
||||
rows: PropTypes.arrayOf(
|
||||
PropTypes.arrayOf(
|
||||
|
|
|
@ -42,6 +42,7 @@ import { WelcomeModal } from './welcome-modal';
|
|||
import { useHeadercardExperimentHook } from './hooks/use-headercard-experiment-hook';
|
||||
import './style.scss';
|
||||
import '../dashboard/style.scss';
|
||||
import { getAdminSetting } from '~/utils/admin-settings';
|
||||
|
||||
const Tasks = lazy( () =>
|
||||
import( /* webpackChunkName: "tasks" */ '../tasks' )
|
||||
|
@ -63,6 +64,8 @@ export const Layout = ( {
|
|||
query,
|
||||
taskListComplete,
|
||||
hasTaskList,
|
||||
showingProgressHeader,
|
||||
isLoadingTaskLists,
|
||||
shouldShowWelcomeModal,
|
||||
shouldShowWelcomeFromCalypsoModal,
|
||||
isTaskListHidden,
|
||||
|
@ -140,7 +143,9 @@ export const Layout = ( {
|
|||
<Column shouldStick={ shouldStickColumns }>
|
||||
{ ! isLoadingExperimentAssignment &&
|
||||
! isLoadingTwoColExperimentAssignment &&
|
||||
! isRunningTaskListExperiment && (
|
||||
! isRunningTaskListExperiment &&
|
||||
! isLoadingTaskLists &&
|
||||
! showingProgressHeader && (
|
||||
<ActivityHeader
|
||||
className="your-store-today"
|
||||
title={ __(
|
||||
|
@ -285,8 +290,13 @@ export default compose(
|
|||
const { getOption, hasFinishedResolution } = select(
|
||||
OPTIONS_STORE_NAME
|
||||
);
|
||||
const { getTaskList, getTaskLists } = select( ONBOARDING_STORE_NAME );
|
||||
const {
|
||||
getTaskList,
|
||||
getTaskLists,
|
||||
hasFinishedResolution: taskListFinishResolution,
|
||||
} = select( ONBOARDING_STORE_NAME );
|
||||
const taskLists = getTaskLists();
|
||||
const isLoadingTaskLists = ! taskListFinishResolution( 'getTaskLists' );
|
||||
|
||||
const welcomeFromCalypsoModalDismissed =
|
||||
getOption( WELCOME_FROM_CALYPSO_MODAL_DISMISSED_OPTION_NAME ) !==
|
||||
|
@ -336,8 +346,12 @@ export default compose(
|
|||
isBatchUpdating: isNotesRequesting( 'batchUpdateNotes' ),
|
||||
shouldShowWelcomeModal,
|
||||
shouldShowWelcomeFromCalypsoModal,
|
||||
isLoadingTaskLists,
|
||||
isTaskListHidden: getTaskList( 'setup' )?.isHidden,
|
||||
hasTaskList: !! taskLists.find( ( list ) => list.isVisible ),
|
||||
hasTaskList: getAdminSetting( 'visibleTaskListIds', [] ).length > 0,
|
||||
showingProgressHeader: !! taskLists.find(
|
||||
( list ) => list.isVisible && list.displayProgressHeader
|
||||
),
|
||||
taskListComplete: getTaskList( 'setup' )?.isComplete,
|
||||
installTimestamp,
|
||||
installTimestampHasResolved,
|
||||
|
|
|
@ -79,10 +79,21 @@ const PaymentRecommendations: React.FC = () => {
|
|||
[ isInstalled ]
|
||||
);
|
||||
|
||||
const supportsWCPayments =
|
||||
paymentGatewaySuggestions &&
|
||||
paymentGatewaySuggestions.filter( ( paymentGatewaySuggestion ) => {
|
||||
return (
|
||||
paymentGatewaySuggestion.id.indexOf(
|
||||
'woocommerce_payments'
|
||||
) === 0
|
||||
);
|
||||
} ).length === 1;
|
||||
|
||||
const triggeredPageViewRef = useRef( false );
|
||||
const shouldShowRecommendations =
|
||||
paymentGatewaySuggestions &&
|
||||
paymentGatewaySuggestions.length > 0 &&
|
||||
! supportsWCPayments &&
|
||||
! isDismissed;
|
||||
|
||||
useEffect( () => {
|
||||
|
|
|
@ -201,7 +201,10 @@ class BusinessDetails extends Component {
|
|||
|
||||
const promises = [
|
||||
this.persistProfileItems( {
|
||||
business_extensions: businessExtensions,
|
||||
business_extensions: [
|
||||
...businessExtensions,
|
||||
...alreadyActivatedExtensions,
|
||||
],
|
||||
} ),
|
||||
];
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
@import 'node_modules/@wordpress/base-styles/colors.native';
|
||||
// By using CSS variables, we can switch the spacing rhythm using a single media query.
|
||||
:root {
|
||||
--large-gap: 40px;
|
||||
|
@ -37,6 +38,14 @@
|
|||
max-width: 100%;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.components-panel__body > .components-panel__body-title,
|
||||
.woocommerce-experimental-list__item,
|
||||
.woocommerce-inbox-message {
|
||||
&:hover {
|
||||
background: $gray-0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
body.woocommerce-page {
|
||||
|
|
|
@ -19,9 +19,9 @@ $progress-complete-color: #007cba;
|
|||
appearance: none;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 16px;
|
||||
height: 10px;
|
||||
height: 12px;
|
||||
width: 100%;
|
||||
margin-bottom: 20px;
|
||||
margin-bottom: 0;
|
||||
|
||||
// Firefox
|
||||
& {
|
||||
|
|
|
@ -4,7 +4,11 @@
|
|||
import { __, sprintf } from '@wordpress/i18n';
|
||||
import { useMemo } from '@wordpress/element';
|
||||
import { useSelect } from '@wordpress/data';
|
||||
import { ONBOARDING_STORE_NAME, TaskListType } from '@woocommerce/data';
|
||||
import {
|
||||
getVisibleTasks,
|
||||
ONBOARDING_STORE_NAME,
|
||||
TaskListType,
|
||||
} from '@woocommerce/data';
|
||||
import { getSetting } from '@woocommerce/settings';
|
||||
|
||||
/**
|
||||
|
@ -20,37 +24,38 @@ type ProgressHeaderProps = {
|
|||
export const ProgressHeader: React.FC< ProgressHeaderProps > = ( {
|
||||
taskListId,
|
||||
} ) => {
|
||||
const { loading, tasksCount, completedCount, hasVisitedTasks } = useSelect(
|
||||
( select ) => {
|
||||
const taskList: TaskListType = select(
|
||||
ONBOARDING_STORE_NAME
|
||||
).getTaskList( taskListId );
|
||||
const finishedResolution = select(
|
||||
ONBOARDING_STORE_NAME
|
||||
).hasFinishedResolution( 'getTaskList', [ taskListId ] );
|
||||
const nowTimestamp = Date.now();
|
||||
const visibleTasks = taskList?.tasks.filter(
|
||||
( task ) =>
|
||||
! task.isDismissed &&
|
||||
( ! task.isSnoozed || task.snoozedUntil < nowTimestamp )
|
||||
);
|
||||
const {
|
||||
loading,
|
||||
tasksCount,
|
||||
completedCount,
|
||||
hasVisitedTasks,
|
||||
disabledCompletedCount,
|
||||
} = useSelect( ( select ) => {
|
||||
const taskList: TaskListType = select(
|
||||
ONBOARDING_STORE_NAME
|
||||
).getTaskList( taskListId );
|
||||
const finishedResolution = select(
|
||||
ONBOARDING_STORE_NAME
|
||||
).hasFinishedResolution( 'getTaskList', [ taskListId ] );
|
||||
const visibleTasks = getVisibleTasks( taskList?.tasks );
|
||||
|
||||
return {
|
||||
loading: ! finishedResolution,
|
||||
tasksCount: visibleTasks?.length,
|
||||
completedCount: visibleTasks?.filter(
|
||||
( task ) => task.isComplete
|
||||
).length,
|
||||
hasVisitedTasks:
|
||||
visibleTasks?.filter( ( task ) => task.isVisited ).length >
|
||||
0,
|
||||
};
|
||||
}
|
||||
);
|
||||
return {
|
||||
loading: ! finishedResolution,
|
||||
tasksCount: visibleTasks?.length,
|
||||
completedCount: visibleTasks?.filter( ( task ) => task.isComplete )
|
||||
.length,
|
||||
disabledCompletedCount: visibleTasks?.filter(
|
||||
( task ) => task.isComplete && task.isDisabled
|
||||
).length,
|
||||
hasVisitedTasks:
|
||||
visibleTasks?.filter( ( task ) => task.isVisited ).length > 0,
|
||||
};
|
||||
} );
|
||||
|
||||
const progressTitle = useMemo( () => {
|
||||
if (
|
||||
( ! hasVisitedTasks && completedCount < 2 ) ||
|
||||
( ! hasVisitedTasks &&
|
||||
completedCount < 2 + disabledCompletedCount ) ||
|
||||
completedCount === tasksCount
|
||||
) {
|
||||
const siteTitle = getSetting( 'siteTitle' );
|
||||
|
|
|
@ -24,7 +24,7 @@ export const Action = ( {
|
|||
markConfigured,
|
||||
onSetUp = () => {},
|
||||
onSetupCallback,
|
||||
setupButtonText = __( 'Set up', 'woocommerce' ),
|
||||
setupButtonText = __( 'Get started', 'woocommerce' ),
|
||||
} ) => {
|
||||
const [ isBusy, setIsBusy ] = useState( false );
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { Card, CardHeader } from '@wordpress/components';
|
||||
import { Card, CardHeader, CardFooter } from '@wordpress/components';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
|
@ -15,10 +15,11 @@ export const List = ( {
|
|||
markConfigured,
|
||||
recommendation,
|
||||
paymentGateways,
|
||||
footerLink,
|
||||
} ) => {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader as="h2">{ heading }</CardHeader>
|
||||
{ heading && <CardHeader as="h2">{ heading }</CardHeader> }
|
||||
{ paymentGateways.map( ( paymentGateway ) => {
|
||||
const { id } = paymentGateway;
|
||||
return (
|
||||
|
@ -30,6 +31,9 @@ export const List = ( {
|
|||
/>
|
||||
);
|
||||
} ) }
|
||||
{ footerLink && (
|
||||
<CardFooter isBorderless>{ footerLink }</CardFooter>
|
||||
) }
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -6,14 +6,15 @@
|
|||
overflow: hidden;
|
||||
|
||||
.components-card__media {
|
||||
width: 170px;
|
||||
width: 85px;
|
||||
flex-shrink: 0;
|
||||
align-self: flex-start;
|
||||
|
||||
img,
|
||||
svg,
|
||||
.is-placeholder {
|
||||
margin: auto;
|
||||
max-width: 100px;
|
||||
max-width: 36px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ describe( 'PaymentGatewaySuggestions > List', () => {
|
|||
expect( queryByRole( 'button' ) ).toHaveTextContent( 'Enable' );
|
||||
} );
|
||||
|
||||
it( 'should display the "Set up" button when setup is required', () => {
|
||||
it( 'should display the "Get started" button when setup is required', () => {
|
||||
const props = {
|
||||
...defaultProps,
|
||||
paymentGateways: [
|
||||
|
@ -63,7 +63,7 @@ describe( 'PaymentGatewaySuggestions > List', () => {
|
|||
|
||||
const { queryByRole } = render( <List { ...props } /> );
|
||||
|
||||
expect( queryByRole( 'button' ) ).toHaveTextContent( 'Set up' );
|
||||
expect( queryByRole( 'button' ) ).toHaveTextContent( 'Get started' );
|
||||
} );
|
||||
|
||||
it( 'should display the SetupRequired component when appropriate', () => {
|
||||
|
|
|
@ -156,7 +156,7 @@ export const Configure = ( { markConfigured, paymentGateway } ) => {
|
|||
</p>
|
||||
) }
|
||||
<Button isPrimary href={ settingsUrl }>
|
||||
{ __( 'Set up', 'woocommerce' ) }
|
||||
{ __( 'Get started', 'woocommerce' ) }
|
||||
</Button>
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -81,7 +81,7 @@ describe( 'Configure', () => {
|
|||
const { container } = render( <Configure { ...props } /> );
|
||||
|
||||
const button = container.querySelector( 'a' );
|
||||
expect( button.textContent ).toBe( 'Set up' );
|
||||
expect( button.textContent ).toBe( 'Get started' );
|
||||
expect( button.href ).toBe( mockGateway.settingsUrl );
|
||||
} );
|
||||
} );
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { Button } from '@wordpress/components';
|
||||
import ChevronUpIcon from 'gridicons/dist/chevron-up';
|
||||
import ChevronDownIcon from 'gridicons/dist/chevron-down';
|
||||
import { useState } from '@wordpress/element';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import './Toggle.scss';
|
||||
|
||||
export const Toggle = ( { children, heading, onToggle } ) => {
|
||||
const [ isShow, setIsShow ] = useState( false );
|
||||
const onClick = () => {
|
||||
onToggle( isShow );
|
||||
setIsShow( ! isShow );
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="toggle">
|
||||
<Button
|
||||
isTertiary
|
||||
onClick={ onClick }
|
||||
aria-expanded={ isShow }
|
||||
frameBorder={ 0 }
|
||||
className="toggle-button"
|
||||
>
|
||||
{ heading }
|
||||
{ isShow ? (
|
||||
<ChevronUpIcon size={ 18 } />
|
||||
) : (
|
||||
<ChevronDownIcon size={ 18 } />
|
||||
) }
|
||||
</Button>
|
||||
{ isShow ? children : null }
|
||||
</div>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,9 @@
|
|||
.woocommerce-task-payments {
|
||||
.toggle-button {
|
||||
margin: $gap-small 0;
|
||||
|
||||
.gridicon {
|
||||
margin-left: 4px;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
export { Toggle } from './Toggle';
|
|
@ -13,17 +13,23 @@ import { useMemo, useCallback, useEffect } from '@wordpress/element';
|
|||
import { registerPlugin } from '@wordpress/plugins';
|
||||
import { WooOnboardingTask } from '@woocommerce/onboarding';
|
||||
import { getNewPath } from '@woocommerce/navigation';
|
||||
import { Button } from '@wordpress/components';
|
||||
import ExternalIcon from 'gridicons/dist/external';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { List, Placeholder as ListPlaceholder } from './components/List';
|
||||
import { Setup, Placeholder as SetupPlaceholder } from './components/Setup';
|
||||
import { Toggle } from './components/Toggle/Toggle';
|
||||
import { WCPaySuggestion } from './components/WCPay';
|
||||
import { getPluginSlug } from '~/utils';
|
||||
import './plugins/Bacs';
|
||||
import './payment-gateway-suggestions.scss';
|
||||
|
||||
const SEE_MORE_LINK =
|
||||
'https://woocommerce.com/product-category/woocommerce-extensions/payment-gateways/?utm_source=payments_recommendations';
|
||||
|
||||
const comparePaymentGatewaysByPriority = ( a, b ) =>
|
||||
a.recommendation_priority - b.recommendation_priority;
|
||||
|
||||
|
@ -179,7 +185,7 @@ export const PaymentGatewaySuggestions = ( { onComplete, query } ) => {
|
|||
return gateway;
|
||||
}, [ isResolving, query, paymentGateways ] );
|
||||
|
||||
const [ wcPayGateway, enabledGateways, additionalGateways ] = useMemo(
|
||||
const [ wcPayGateway, offlineGateways, additionalGateways ] = useMemo(
|
||||
() =>
|
||||
Array.from( paymentGateways.values() )
|
||||
.sort( ( a, b ) => {
|
||||
|
@ -196,7 +202,7 @@ export const PaymentGatewaySuggestions = ( { onComplete, query } ) => {
|
|||
} )
|
||||
.reduce(
|
||||
( all, gateway ) => {
|
||||
const [ wcPay, enabled, additional ] = all;
|
||||
const [ wcPay, offline, additional ] = all;
|
||||
|
||||
// WCPay is handled separately when not installed and configured
|
||||
if (
|
||||
|
@ -205,8 +211,8 @@ export const PaymentGatewaySuggestions = ( { onComplete, query } ) => {
|
|||
! ( gateway.installed && ! gateway.needsSetup )
|
||||
) {
|
||||
wcPay.push( gateway );
|
||||
} else if ( gateway.enabled ) {
|
||||
enabled.push( gateway );
|
||||
} else if ( gateway.is_offline ) {
|
||||
offline.push( gateway );
|
||||
} else {
|
||||
additional.push( gateway );
|
||||
}
|
||||
|
@ -218,6 +224,20 @@ export const PaymentGatewaySuggestions = ( { onComplete, query } ) => {
|
|||
[ paymentGateways ]
|
||||
);
|
||||
|
||||
const isEligibleWCPay = !! wcPayGateway.length;
|
||||
|
||||
const trackSeeMore = () => {
|
||||
recordEvent( 'tasklist_payment_see_more', {} );
|
||||
};
|
||||
|
||||
const trackToggle = ( isShow ) => {
|
||||
recordEvent( 'tasklist_payment_show_toggle', {
|
||||
toggle: isShow ? 'hide' : 'show',
|
||||
payment_method_count:
|
||||
offlineGateways.length + additionalGateways.length,
|
||||
} );
|
||||
};
|
||||
|
||||
if ( query.id && ! currentGateway ) {
|
||||
return <SetupPlaceholder />;
|
||||
}
|
||||
|
@ -231,32 +251,59 @@ export const PaymentGatewaySuggestions = ( { onComplete, query } ) => {
|
|||
);
|
||||
}
|
||||
|
||||
const additionalSection = !! additionalGateways.length && (
|
||||
<List
|
||||
heading={
|
||||
isEligibleWCPay
|
||||
? null
|
||||
: __( 'Choose a payment provider', 'woocommerce' )
|
||||
}
|
||||
recommendation={ recommendation }
|
||||
paymentGateways={ additionalGateways }
|
||||
markConfigured={ markConfigured }
|
||||
footerLink={
|
||||
<Button
|
||||
href={ SEE_MORE_LINK }
|
||||
target="_blank"
|
||||
onClick={ trackSeeMore }
|
||||
isTertiary
|
||||
>
|
||||
{ __( 'See more', 'woocommerce' ) }
|
||||
<ExternalIcon size={ 18 } />
|
||||
</Button>
|
||||
}
|
||||
></List>
|
||||
);
|
||||
|
||||
const offlineSection = !! offlineGateways.length && (
|
||||
<List
|
||||
heading={ __( 'Offline payment methods', 'woocommerce' ) }
|
||||
recommendation={ recommendation }
|
||||
paymentGateways={ offlineGateways }
|
||||
markConfigured={ markConfigured }
|
||||
/>
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="woocommerce-task-payments">
|
||||
{ ! paymentGateways.size && <ListPlaceholder /> }
|
||||
|
||||
{ !! wcPayGateway.length && (
|
||||
<WCPaySuggestion paymentGateway={ wcPayGateway[ 0 ] } />
|
||||
) }
|
||||
|
||||
{ !! enabledGateways.length && (
|
||||
<List
|
||||
heading={ __( 'Enabled payment gateways', 'woocommerce' ) }
|
||||
recommendation={ recommendation }
|
||||
paymentGateways={ enabledGateways }
|
||||
/>
|
||||
) }
|
||||
|
||||
{ !! additionalGateways.length && (
|
||||
<List
|
||||
heading={ __(
|
||||
'Additional payment gateways',
|
||||
'woocommerce'
|
||||
) }
|
||||
recommendation={ recommendation }
|
||||
paymentGateways={ additionalGateways }
|
||||
markConfigured={ markConfigured }
|
||||
/>
|
||||
{ isEligibleWCPay ? (
|
||||
<>
|
||||
<WCPaySuggestion paymentGateway={ wcPayGateway[ 0 ] } />
|
||||
<Toggle
|
||||
heading={ __( 'Other payment methods', 'woocommerce' ) }
|
||||
onToggle={ trackToggle }
|
||||
>
|
||||
{ additionalSection }
|
||||
{ offlineSection }
|
||||
</Toggle>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
{ additionalSection }
|
||||
{ offlineSection }
|
||||
</>
|
||||
) }
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -22,6 +22,14 @@
|
|||
margin: 0;
|
||||
}
|
||||
|
||||
.components-card__footer {
|
||||
a.components-button {
|
||||
.gridicon {
|
||||
margin-left: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.woocommerce-task-payment__recommended-pill {
|
||||
border: 1px solid $studio-gray-5;
|
||||
border-radius: 28px;
|
||||
|
|
|
@ -49,6 +49,7 @@ const paymentGatewaySuggestions = [
|
|||
image:
|
||||
'http://localhost:8888/wp-content/plugins/woocommerce-admin/images/onboarding/cod.svg',
|
||||
is_visible: true,
|
||||
is_offline: true,
|
||||
},
|
||||
{
|
||||
id: 'bacs',
|
||||
|
@ -57,6 +58,7 @@ const paymentGatewaySuggestions = [
|
|||
image:
|
||||
'http://localhost:8888/wp-content/plugins/woocommerce-admin/images/onboarding/bacs.svg',
|
||||
is_visible: true,
|
||||
is_offline: true,
|
||||
},
|
||||
{
|
||||
id: 'woocommerce_payments:non-us',
|
||||
|
@ -83,8 +85,12 @@ const paymentGatewaySuggestions = [
|
|||
},
|
||||
];
|
||||
|
||||
const paymentGatewaySuggestionsWithoutWCPay = paymentGatewaySuggestions.filter(
|
||||
( p ) => p.title !== 'WooCommerce Payments'
|
||||
);
|
||||
|
||||
describe( 'PaymentGatewaySuggestions', () => {
|
||||
test( 'should render payment gateway lists', () => {
|
||||
test( 'should render only WCPay if its suggested', () => {
|
||||
const onComplete = jest.fn();
|
||||
const query = {};
|
||||
useSelect.mockImplementation( () => ( {
|
||||
|
@ -109,6 +115,38 @@ describe( 'PaymentGatewaySuggestions', () => {
|
|||
( e ) => e.textContent
|
||||
);
|
||||
|
||||
expect( paymentTitles ).toEqual( [] );
|
||||
|
||||
expect(
|
||||
container.getElementsByTagName( 'title' )[ 0 ].textContent
|
||||
).toBe( 'WooCommerce Payments' );
|
||||
} );
|
||||
|
||||
test( 'should render all payment gateways if no WCPay', () => {
|
||||
const onComplete = jest.fn();
|
||||
const query = {};
|
||||
useSelect.mockImplementation( () => ( {
|
||||
isResolving: false,
|
||||
getPaymentGateway: jest.fn(),
|
||||
paymentGatewaySuggestions: paymentGatewaySuggestionsWithoutWCPay,
|
||||
installedPaymentGateways: [],
|
||||
} ) );
|
||||
|
||||
const { container } = render(
|
||||
<PaymentGatewaySuggestions
|
||||
onComplete={ onComplete }
|
||||
query={ query }
|
||||
/>
|
||||
);
|
||||
|
||||
const paymentTitleElements = container.querySelectorAll(
|
||||
'.woocommerce-task-payment__title'
|
||||
);
|
||||
|
||||
const paymentTitles = Array.from( paymentTitleElements ).map(
|
||||
( e ) => e.textContent
|
||||
);
|
||||
|
||||
expect( paymentTitles ).toEqual( [
|
||||
'Stripe',
|
||||
'PayPal Payments',
|
||||
|
@ -116,10 +154,6 @@ describe( 'PaymentGatewaySuggestions', () => {
|
|||
'Cash on delivery',
|
||||
'Direct bank transfer',
|
||||
] );
|
||||
|
||||
expect(
|
||||
container.getElementsByTagName( 'title' )[ 0 ].textContent
|
||||
).toBe( 'WooCommerce Payments' );
|
||||
} );
|
||||
|
||||
test( 'should the payment gateway offline options at the bottom', () => {
|
||||
|
@ -128,7 +162,7 @@ describe( 'PaymentGatewaySuggestions', () => {
|
|||
useSelect.mockImplementation( () => ( {
|
||||
isResolving: false,
|
||||
getPaymentGateway: jest.fn(),
|
||||
paymentGatewaySuggestions,
|
||||
paymentGatewaySuggestions: paymentGatewaySuggestionsWithoutWCPay,
|
||||
installedPaymentGateways: [],
|
||||
} ) );
|
||||
|
||||
|
@ -154,7 +188,7 @@ describe( 'PaymentGatewaySuggestions', () => {
|
|||
useSelect.mockImplementation( () => ( {
|
||||
isResolving: false,
|
||||
getPaymentGateway: jest.fn(),
|
||||
paymentGatewaySuggestions,
|
||||
paymentGatewaySuggestions: paymentGatewaySuggestionsWithoutWCPay,
|
||||
installedPaymentGateways: [
|
||||
{
|
||||
id: 'ppcp-gateway',
|
||||
|
@ -184,7 +218,7 @@ describe( 'PaymentGatewaySuggestions', () => {
|
|||
useSelect.mockImplementation( () => ( {
|
||||
isResolving: false,
|
||||
getPaymentGateway: jest.fn(),
|
||||
paymentGatewaySuggestions,
|
||||
paymentGatewaySuggestions: paymentGatewaySuggestionsWithoutWCPay,
|
||||
installedPaymentGateways: [
|
||||
{
|
||||
id: 'ppcp-gateway',
|
||||
|
@ -211,4 +245,59 @@ describe( 'PaymentGatewaySuggestions', () => {
|
|||
selected: 'ppcp_gateway',
|
||||
} );
|
||||
} );
|
||||
|
||||
test( 'should record event correctly when other payment methods is clicked', () => {
|
||||
const onComplete = jest.fn();
|
||||
const query = {};
|
||||
useSelect.mockImplementation( () => ( {
|
||||
isResolving: false,
|
||||
getPaymentGateway: jest.fn(),
|
||||
paymentGatewaySuggestions,
|
||||
installedPaymentGateways: [],
|
||||
} ) );
|
||||
|
||||
render(
|
||||
<PaymentGatewaySuggestions
|
||||
onComplete={ onComplete }
|
||||
query={ query }
|
||||
/>
|
||||
);
|
||||
|
||||
fireEvent.click( screen.getByText( 'Other payment methods' ) );
|
||||
|
||||
// By default it's hidden, so when toggle it shows.
|
||||
expect( recordEvent ).toHaveBeenCalledWith(
|
||||
'tasklist_payment_show_toggle',
|
||||
{
|
||||
toggle: 'show',
|
||||
payment_method_count: paymentGatewaySuggestions.length - 1, // Minus one for WCPay since it's not counted in "other payment methods".
|
||||
}
|
||||
);
|
||||
} );
|
||||
|
||||
test( 'should record event correctly when see more is clicked', () => {
|
||||
const onComplete = jest.fn();
|
||||
const query = {};
|
||||
useSelect.mockImplementation( () => ( {
|
||||
isResolving: false,
|
||||
getPaymentGateway: jest.fn(),
|
||||
paymentGatewaySuggestions,
|
||||
installedPaymentGateways: [],
|
||||
} ) );
|
||||
|
||||
render(
|
||||
<PaymentGatewaySuggestions
|
||||
onComplete={ onComplete }
|
||||
query={ query }
|
||||
/>
|
||||
);
|
||||
|
||||
fireEvent.click( screen.getByText( 'Other payment methods' ) );
|
||||
fireEvent.click( screen.getByText( 'See more' ) );
|
||||
|
||||
expect( recordEvent ).toHaveBeenCalledWith(
|
||||
'tasklist_payment_see_more',
|
||||
{}
|
||||
);
|
||||
} );
|
||||
} );
|
||||
|
|
|
@ -15,7 +15,7 @@ import { ONBOARDING_STORE_NAME, PLUGINS_STORE_NAME } from '@woocommerce/data';
|
|||
import CartModal from '../../dashboard/components/cart-modal';
|
||||
import { getCategorizedOnboardingProducts } from '../../dashboard/utils';
|
||||
|
||||
const PurchaseTaskItem = () => {
|
||||
const PurchaseTaskItem = ( { defaultTaskItem } ) => {
|
||||
const [ cartModalOpen, setCartModalOpen ] = useState( false );
|
||||
|
||||
const { installedPlugins, productTypes, profileItems } = useSelect(
|
||||
|
@ -47,25 +47,32 @@ const PurchaseTaskItem = () => {
|
|||
installedPlugins
|
||||
);
|
||||
const { remainingProducts } = groupedProducts;
|
||||
const DefaultTaskItem = defaultTaskItem;
|
||||
|
||||
return (
|
||||
<>
|
||||
<DefaultTaskItem
|
||||
onClick={ () => {
|
||||
if ( remainingProducts.length ) {
|
||||
toggleCartModal();
|
||||
}
|
||||
} }
|
||||
/>
|
||||
{ cartModalOpen && (
|
||||
<CartModal
|
||||
onClose={ () => toggleCartModal() }
|
||||
onClickPurchaseLater={ () => toggleCartModal() }
|
||||
/>
|
||||
) }
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const PurchaseTaskItemFill = () => {
|
||||
return (
|
||||
<WooOnboardingTaskListItem id="purchase">
|
||||
{ ( { defaultTaskItem: DefaultTaskItem } ) => (
|
||||
<>
|
||||
<DefaultTaskItem
|
||||
onClick={ () => {
|
||||
if ( remainingProducts.length ) {
|
||||
toggleCartModal();
|
||||
}
|
||||
} }
|
||||
/>
|
||||
{ cartModalOpen && (
|
||||
<CartModal
|
||||
onClose={ () => toggleCartModal() }
|
||||
onClickPurchaseLater={ () => toggleCartModal() }
|
||||
/>
|
||||
) }
|
||||
</>
|
||||
{ ( { defaultTaskItem } ) => (
|
||||
<PurchaseTaskItem defaultTaskItem={ defaultTaskItem } />
|
||||
) }
|
||||
</WooOnboardingTaskListItem>
|
||||
);
|
||||
|
@ -73,5 +80,5 @@ const PurchaseTaskItem = () => {
|
|||
|
||||
registerPlugin( 'woocommerce-admin-task-purchase', {
|
||||
scope: 'woocommerce-tasks',
|
||||
render: PurchaseTaskItem,
|
||||
render: PurchaseTaskItemFill,
|
||||
} );
|
||||
|
|
|
@ -6,7 +6,11 @@ import { useEffect, useRef, useState } from '@wordpress/element';
|
|||
import { Card, CardHeader } from '@wordpress/components';
|
||||
import { useSelect } from '@wordpress/data';
|
||||
import { Badge } from '@woocommerce/components';
|
||||
import { ONBOARDING_STORE_NAME, TaskListType } from '@woocommerce/data';
|
||||
import {
|
||||
getVisibleTasks,
|
||||
ONBOARDING_STORE_NAME,
|
||||
TaskListType,
|
||||
} from '@woocommerce/data';
|
||||
import { recordEvent } from '@woocommerce/tracks';
|
||||
import { Text, List, CollapsibleList } from '@woocommerce/experimental';
|
||||
|
||||
|
@ -45,12 +49,7 @@ export const TaskList: React.FC< TaskListProps > = ( {
|
|||
};
|
||||
} );
|
||||
const prevQueryRef = useRef( query );
|
||||
const nowTimestamp = Date.now();
|
||||
const visibleTasks = tasks.filter(
|
||||
( task ) =>
|
||||
! task.isDismissed &&
|
||||
( ! task.isSnoozed || task.snoozedUntil < nowTimestamp )
|
||||
);
|
||||
const visibleTasks = getVisibleTasks( tasks );
|
||||
|
||||
const incompleteTasks = tasks.filter(
|
||||
( task ) => ! task.isComplete && ! task.isDismissed
|
||||
|
|
|
@ -236,7 +236,7 @@
|
|||
}
|
||||
|
||||
.woocommerce-task-list__setup_experiment_1 {
|
||||
.woocommerce-experimental-list .woocommerce-experimental-list__item.complete {
|
||||
.woocommerce-experimental-list .woocommerce-experimental-list__item.is-complete {
|
||||
text-decoration: line-through;
|
||||
|
||||
.woocommerce-task-list__item-title {
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
import { __ } from '@wordpress/i18n';
|
||||
import { MenuGroup, MenuItem } from '@wordpress/components';
|
||||
import { check } from '@wordpress/icons';
|
||||
import { Fragment, useEffect, lazy, Suspense } from '@wordpress/element';
|
||||
import { Fragment, useEffect } from '@wordpress/element';
|
||||
import { useDispatch, useSelect } from '@wordpress/data';
|
||||
import { ONBOARDING_STORE_NAME, OPTIONS_STORE_NAME } from '@woocommerce/data';
|
||||
import { useExperiment } from '@woocommerce/explat';
|
||||
|
@ -15,37 +15,41 @@ import { recordEvent } from '@woocommerce/tracks';
|
|||
*/
|
||||
import { DisplayOption } from '~/activity-panel/display-options';
|
||||
import { Task } from './task';
|
||||
import { TasksPlaceholder } from './placeholder';
|
||||
import { TasksPlaceholder, TasksPlaceholderProps } from './placeholder';
|
||||
import './tasks.scss';
|
||||
import { TaskListProps } from './task-list';
|
||||
import { TaskListProps, TaskList } from './task-list';
|
||||
import { TaskList as TwoColumnTaskList } from '../two-column-tasks/task-list';
|
||||
import { SectionedTaskList } from '../two-column-tasks/sectioned-task-list';
|
||||
import TwoColumnTaskListPlaceholder from '../two-column-tasks/placeholder';
|
||||
import '../two-column-tasks/style.scss';
|
||||
import { getAdminSetting } from '~/utils/admin-settings';
|
||||
|
||||
export type TasksProps = {
|
||||
query: { task?: string };
|
||||
};
|
||||
|
||||
const TaskList = lazy(
|
||||
() => import( /* webpackChunkName: "task-list" */ './task-list' )
|
||||
);
|
||||
|
||||
const TwoColumnTaskList = lazy(
|
||||
() =>
|
||||
import(
|
||||
/* webpackChunkName: "two-column-task-list" */ '../two-column-tasks/task-list'
|
||||
)
|
||||
);
|
||||
|
||||
function getTaskListComponent(
|
||||
taskListId: string
|
||||
): React.LazyExoticComponent< React.FC< TaskListProps > > {
|
||||
function getTaskListComponent( taskListId: string ): React.FC< TaskListProps > {
|
||||
switch ( taskListId ) {
|
||||
case 'setup_experiment_1':
|
||||
return TwoColumnTaskList;
|
||||
case 'setup_experiment_2':
|
||||
return SectionedTaskList;
|
||||
default:
|
||||
return TaskList;
|
||||
}
|
||||
}
|
||||
|
||||
function getTaskListPlaceholderComponent(
|
||||
taskListId: string
|
||||
): React.FC< TasksPlaceholderProps > {
|
||||
switch ( taskListId ) {
|
||||
case 'setup_experiment_1':
|
||||
return TwoColumnTaskListPlaceholder;
|
||||
default:
|
||||
return TasksPlaceholder;
|
||||
}
|
||||
}
|
||||
|
||||
export const Tasks: React.FC< TasksProps > = ( { query } ) => {
|
||||
const { task } = query;
|
||||
const { hideTaskList } = useDispatch( ONBOARDING_STORE_NAME );
|
||||
|
@ -56,9 +60,9 @@ export const Tasks: React.FC< TasksProps > = ( { query } ) => {
|
|||
|
||||
const { isResolving, taskLists } = useSelect( ( select ) => {
|
||||
return {
|
||||
isResolving: select( ONBOARDING_STORE_NAME ).isResolving(
|
||||
'getTaskLists'
|
||||
),
|
||||
isResolving: ! select(
|
||||
ONBOARDING_STORE_NAME
|
||||
).hasFinishedResolution( 'getTaskLists' ),
|
||||
taskLists: select( ONBOARDING_STORE_NAME ).getTaskLists(),
|
||||
};
|
||||
} );
|
||||
|
@ -108,8 +112,13 @@ export const Tasks: React.FC< TasksProps > = ( { query } ) => {
|
|||
return null;
|
||||
}
|
||||
|
||||
const taskListIds = getAdminSetting( 'visibleTaskListIds', [] );
|
||||
const TaskListPlaceholderComponent = getTaskListPlaceholderComponent(
|
||||
taskListIds[ 0 ]
|
||||
);
|
||||
|
||||
if ( isResolving ) {
|
||||
return <TasksPlaceholder query={ query } />;
|
||||
return <TaskListPlaceholderComponent query={ query } />;
|
||||
}
|
||||
|
||||
if ( currentTask ) {
|
||||
|
@ -121,7 +130,7 @@ export const Tasks: React.FC< TasksProps > = ( { query } ) => {
|
|||
}
|
||||
|
||||
if ( isLoadingExperiment ) {
|
||||
return <TasksPlaceholder query={ query } />;
|
||||
return <TaskListPlaceholderComponent query={ query } />;
|
||||
}
|
||||
|
||||
return taskLists
|
||||
|
@ -131,17 +140,7 @@ export const Tasks: React.FC< TasksProps > = ( { query } ) => {
|
|||
: ! id.endsWith( 'two_column' )
|
||||
)
|
||||
.map( ( taskList ) => {
|
||||
const {
|
||||
id,
|
||||
eventPrefix,
|
||||
isComplete,
|
||||
isHidden,
|
||||
isVisible,
|
||||
isToggleable,
|
||||
title,
|
||||
tasks,
|
||||
displayProgressHeader,
|
||||
} = taskList;
|
||||
const { id, isHidden, isVisible, isToggleable } = taskList;
|
||||
|
||||
if ( ! isVisible ) {
|
||||
return null;
|
||||
|
@ -151,22 +150,14 @@ export const Tasks: React.FC< TasksProps > = ( { query } ) => {
|
|||
|
||||
return (
|
||||
<Fragment key={ id }>
|
||||
<Suspense fallback={ null }>
|
||||
<TaskListComponent
|
||||
id={ id }
|
||||
eventPrefix={ eventPrefix }
|
||||
isComplete={ isComplete }
|
||||
isExpandable={
|
||||
experimentAssignment?.variationName ===
|
||||
'treatment'
|
||||
}
|
||||
query={ query }
|
||||
tasks={ tasks }
|
||||
title={ title }
|
||||
twoColumns={ false }
|
||||
displayProgressHeader={ displayProgressHeader }
|
||||
/>
|
||||
</Suspense>
|
||||
<TaskListComponent
|
||||
isExpandable={
|
||||
experimentAssignment?.variationName === 'treatment'
|
||||
}
|
||||
query={ query }
|
||||
twoColumns={ false }
|
||||
{ ...taskList }
|
||||
/>
|
||||
{ isToggleable && (
|
||||
<DisplayOption>
|
||||
<MenuGroup
|
||||
|
|
|
@ -27,10 +27,13 @@ jest.mock( '@wordpress/data', () => {
|
|||
jest.mock( '@woocommerce/explat' );
|
||||
jest.mock( '@woocommerce/tracks' );
|
||||
|
||||
jest.mock( '../task-list', () => ( { id } ) => <div>task-list:{ id }</div> );
|
||||
jest.mock( '../../two-column-tasks/task-list', () => ( { id } ) => (
|
||||
<div>two-column-list:{ id }</div>
|
||||
) );
|
||||
jest.mock( '../task-list', () => ( {
|
||||
TaskList: ( { id } ) => <div>task-list:{ id }</div>,
|
||||
} ) );
|
||||
|
||||
jest.mock( '../../two-column-tasks/task-list', () => ( {
|
||||
TaskList: ( { id } ) => <div>two-column-list:{ id }</div>,
|
||||
} ) );
|
||||
|
||||
jest.mock( '../task', () => ( {
|
||||
Task: ( { query } ) => <div>task:{ query.task }</div>,
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
.woocommerce-task-section-header__container {
|
||||
display: flex;
|
||||
|
||||
.woocommerce-task-header__illustration {
|
||||
max-width: 150px;
|
||||
width: 34%;
|
||||
margin-left: auto;
|
||||
margin-right: 7%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.illustration-background {
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.woocommerce-task-header__contents p {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.woocommerce-task-header__contents h1 {
|
||||
font-size: 20px;
|
||||
line-height: 28px;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import './section-header.scss';
|
||||
|
||||
type Props = {
|
||||
title: string;
|
||||
description: string;
|
||||
image: string;
|
||||
};
|
||||
|
||||
const SectionHeader: React.FC< Props > = ( { title, description, image } ) => {
|
||||
return (
|
||||
<div className="woocommerce-task-header__contents-container woocommerce-task-section-header__container">
|
||||
<div className="woocommerce-task-header__contents">
|
||||
<h1>{ title }</h1>
|
||||
<p>{ description }</p>
|
||||
</div>
|
||||
<div className="woocommerce-task-header__illustration">
|
||||
<img
|
||||
src={ image }
|
||||
alt={ title }
|
||||
className="illustration-background"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SectionHeader;
|
|
@ -3,7 +3,7 @@
|
|||
*/
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { useSelect } from '@wordpress/data';
|
||||
import { ONBOARDING_STORE_NAME, OPTIONS_STORE_NAME } from '@woocommerce/data';
|
||||
import { ONBOARDING_STORE_NAME } from '@woocommerce/data';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
|
@ -14,25 +14,7 @@ import TaskList from './task-list';
|
|||
import TaskListPlaceholder from './placeholder';
|
||||
import { Task } from '../tasks/task';
|
||||
|
||||
const taskDashboardSelect = ( select ) => {
|
||||
const { getOption, hasFinishedResolution } = select( OPTIONS_STORE_NAME );
|
||||
|
||||
return {
|
||||
keepCompletedTaskList: getOption(
|
||||
'woocommerce_task_list_keep_completed'
|
||||
),
|
||||
isResolving: ! hasFinishedResolution( 'getOption', [
|
||||
'woocommerce_task_list_keep_completed',
|
||||
] ),
|
||||
};
|
||||
};
|
||||
|
||||
const TaskDashboard = ( { query, twoColumns } ) => {
|
||||
const {
|
||||
keepCompletedTaskList,
|
||||
isResolving: isResolvingOptions,
|
||||
} = useSelect( taskDashboardSelect );
|
||||
|
||||
const { task } = query;
|
||||
|
||||
const { isResolving, taskLists } = useSelect( ( select ) => {
|
||||
|
@ -72,7 +54,7 @@ const TaskDashboard = ( { query, twoColumns } ) => {
|
|||
return null;
|
||||
}
|
||||
|
||||
if ( isResolving || isResolvingOptions || ! taskLists[ 0 ] ) {
|
||||
if ( isResolving || ! taskLists[ 0 ] ) {
|
||||
return <TaskListPlaceholder twoColumns={ twoColumns } />;
|
||||
}
|
||||
|
||||
|
@ -104,7 +86,7 @@ const TaskDashboard = ( { query, twoColumns } ) => {
|
|||
id={ taskList.id }
|
||||
eventName="tasklist"
|
||||
twoColumns={ twoColumns }
|
||||
keepCompletedTaskList={ keepCompletedTaskList }
|
||||
keepCompletedTaskList={ taskList.keepCompletedTaskList }
|
||||
dismissedTasks={ dismissedTasks || [] }
|
||||
isComplete={ isTaskListComplete }
|
||||
query={ query }
|
||||
|
|
|
@ -8,7 +8,15 @@ import classnames from 'classnames';
|
|||
*/
|
||||
import './style.scss';
|
||||
|
||||
const TaskListPlaceholder = ( props ) => {
|
||||
type TasksPlaceholderProps = {
|
||||
numTasks?: number;
|
||||
twoColumns?: boolean;
|
||||
query: {
|
||||
task?: string;
|
||||
};
|
||||
};
|
||||
|
||||
const TaskListPlaceholder: React.FC< TasksPlaceholderProps > = ( props ) => {
|
||||
const { numTasks = 5, twoColumns = false } = props;
|
||||
|
||||
return (
|
|
@ -0,0 +1,53 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { Badge } from '@woocommerce/components';
|
||||
import { TaskListSection, TaskType } from '@woocommerce/data';
|
||||
import { Icon, check } from '@wordpress/icons';
|
||||
import { Text } from '@woocommerce/experimental';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import SectionHeader from './headers/section-header';
|
||||
|
||||
type SectionPanelTitleProps = {
|
||||
section: TaskListSection;
|
||||
active: boolean;
|
||||
tasks: TaskType[];
|
||||
};
|
||||
|
||||
export const SectionPanelTitle: React.FC< SectionPanelTitleProps > = ( {
|
||||
section,
|
||||
active,
|
||||
tasks,
|
||||
} ) => {
|
||||
if ( active ) {
|
||||
return (
|
||||
<div className="wooocommerce-task-card__header-container">
|
||||
<div className="wooocommerce-task-card__header">
|
||||
<SectionHeader { ...section } />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const uncompletedTasksCount = tasks.filter(
|
||||
( task ) => ! task.isComplete && section.tasks.includes( task.id )
|
||||
).length;
|
||||
const isComplete = section.isComplete || uncompletedTasksCount === 0;
|
||||
|
||||
return (
|
||||
<>
|
||||
<Text variant="title.small" size="20" lineHeight="28px">
|
||||
{ section.title }
|
||||
</Text>
|
||||
{ ! isComplete && <Badge count={ uncompletedTasksCount } /> }
|
||||
{ isComplete && (
|
||||
<div className="woocommerce-task__icon">
|
||||
<Icon icon={ check } />
|
||||
</div>
|
||||
) }
|
||||
</>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,92 @@
|
|||
.woocommerce-sectioned-task-list {
|
||||
.components-panel {
|
||||
width: 100%;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.components-panel__body {
|
||||
padding-bottom: 0;
|
||||
margin-bottom: $gap-smaller;
|
||||
background: #fff;
|
||||
border: 1px solid $gray-200;
|
||||
|
||||
&.is-opened {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.components-panel__body-title {
|
||||
margin-bottom: 0;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
|
||||
&:hover {
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
}
|
||||
|
||||
> .components-button {
|
||||
font-size: 20px;
|
||||
font-weight: 400;
|
||||
padding-top: 20px;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
.components-panel__arrow {
|
||||
right: $gap-large;
|
||||
}
|
||||
}
|
||||
.wooocommerce-task-card__header-container {
|
||||
width: 100%;
|
||||
border-bottom: none;
|
||||
}
|
||||
.components-panel__body-toggle {
|
||||
box-shadow: none;
|
||||
padding-left: $gap-large;
|
||||
}
|
||||
&.is-opened .components-panel__body-toggle {
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
.components-panel__arrow {
|
||||
top: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
.woocommerce-experimental-list {
|
||||
width: calc(100% + 32px);
|
||||
margin: 0 -16px;
|
||||
}
|
||||
}
|
||||
ul li.woocommerce-task-list__item {
|
||||
padding-top: $gap;
|
||||
padding-bottom: $gap;
|
||||
|
||||
&.is-disabled {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
&:not(.is-complete) .woocommerce-task-list__item-before .woocommerce-task__icon {
|
||||
border-color: $gray-300;
|
||||
}
|
||||
}
|
||||
|
||||
.woocommerce-task-list__item.is-complete .woocommerce-task__icon {
|
||||
background-color: $alert-green;
|
||||
}
|
||||
|
||||
.components-panel__body-title {
|
||||
.woocommerce-badge {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
.woocommerce-task__icon {
|
||||
margin-left: $gap;
|
||||
background-color: $alert-green;
|
||||
border-radius: 50%;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
svg {
|
||||
fill: #fff;
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,252 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { useEffect, useRef, useState } from '@wordpress/element';
|
||||
import { Panel, PanelBody, PanelRow } from '@wordpress/components';
|
||||
import { useSelect, useDispatch } from '@wordpress/data';
|
||||
import { updateQueryString } from '@woocommerce/navigation';
|
||||
import {
|
||||
OPTIONS_STORE_NAME,
|
||||
ONBOARDING_STORE_NAME,
|
||||
TaskType,
|
||||
getVisibleTasks,
|
||||
} from '@woocommerce/data';
|
||||
import { recordEvent } from '@woocommerce/tracks';
|
||||
import { List, TaskItem } from '@woocommerce/experimental';
|
||||
import classnames from 'classnames';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import '../tasks/task-list.scss';
|
||||
import './sectioned-task-list.scss';
|
||||
import TaskListCompleted from './completed';
|
||||
import { TaskListProps } from '~/tasks/task-list';
|
||||
import { ProgressHeader } from '~/task-lists/progress-header';
|
||||
import { SectionPanelTitle } from './section-panel-title';
|
||||
|
||||
type PanelBodyProps = Omit< PanelBody.Props, 'title' | 'onToggle' > & {
|
||||
title: string | React.ReactNode | undefined;
|
||||
onToggle?: ( isOpen: boolean ) => void;
|
||||
};
|
||||
const PanelBodyWithUpdatedType = PanelBody as React.ComponentType< PanelBodyProps >;
|
||||
|
||||
export const SectionedTaskList: React.FC< TaskListProps > = ( {
|
||||
query,
|
||||
id,
|
||||
eventName,
|
||||
tasks,
|
||||
keepCompletedTaskList,
|
||||
isComplete,
|
||||
sections,
|
||||
displayProgressHeader,
|
||||
} ) => {
|
||||
const { createNotice } = useDispatch( 'core/notices' );
|
||||
const { updateOptions, dismissTask, undoDismissTask } = useDispatch(
|
||||
OPTIONS_STORE_NAME
|
||||
);
|
||||
const { profileItems } = useSelect( ( select ) => {
|
||||
const { getProfileItems } = select( ONBOARDING_STORE_NAME );
|
||||
return {
|
||||
profileItems: getProfileItems(),
|
||||
};
|
||||
} );
|
||||
const { hideTaskList } = useDispatch( ONBOARDING_STORE_NAME );
|
||||
const [ openPanel, setOpenPanel ] = useState< string | null >(
|
||||
sections?.find( ( section ) => ! section.isComplete )?.id || null
|
||||
);
|
||||
|
||||
const prevQueryRef = useRef( query );
|
||||
|
||||
const visibleTasks = getVisibleTasks( tasks );
|
||||
|
||||
const recordTaskListView = () => {
|
||||
if ( query.task ) {
|
||||
return;
|
||||
}
|
||||
|
||||
recordEvent( `${ eventName }_view`, {
|
||||
number_tasks: visibleTasks.length,
|
||||
store_connected: profileItems.wccom_connected,
|
||||
} );
|
||||
};
|
||||
|
||||
useEffect( () => {
|
||||
recordTaskListView();
|
||||
}, [] );
|
||||
|
||||
useEffect( () => {
|
||||
const { task: prevTask } = prevQueryRef.current;
|
||||
const { task } = query;
|
||||
|
||||
if ( prevTask !== task ) {
|
||||
window.document.documentElement.scrollTop = 0;
|
||||
prevQueryRef.current = query;
|
||||
}
|
||||
}, [ query ] );
|
||||
|
||||
const onDismissTask = ( taskId: string ) => {
|
||||
dismissTask( taskId );
|
||||
createNotice( 'success', __( 'Task dismissed' ), {
|
||||
actions: [
|
||||
{
|
||||
label: __( 'Undo', 'woocommerce-admin' ),
|
||||
onClick: () => undoDismissTask( taskId ),
|
||||
},
|
||||
],
|
||||
} );
|
||||
};
|
||||
|
||||
const hideTasks = () => {
|
||||
hideTaskList( id );
|
||||
};
|
||||
|
||||
const keepTasks = () => {
|
||||
const updateOptionsParams = {
|
||||
woocommerce_task_list_keep_completed: 'yes',
|
||||
};
|
||||
|
||||
updateOptions( {
|
||||
...updateOptionsParams,
|
||||
} );
|
||||
};
|
||||
|
||||
let selectedHeaderCard = visibleTasks.find(
|
||||
( listTask ) => listTask.isComplete === false
|
||||
);
|
||||
|
||||
// If nothing is selected, default to the last task since everything is completed.
|
||||
if ( ! selectedHeaderCard ) {
|
||||
selectedHeaderCard = visibleTasks[ visibleTasks.length - 1 ];
|
||||
}
|
||||
|
||||
const trackClick = ( task: TaskType ) => {
|
||||
recordEvent( `${ eventName }_click`, {
|
||||
task_name: task.id,
|
||||
} );
|
||||
};
|
||||
|
||||
const goToTask = ( task: TaskType ) => {
|
||||
trackClick( task );
|
||||
updateQueryString( { task: task.id } );
|
||||
};
|
||||
|
||||
const onTaskSelected = ( task: TaskType ) => {
|
||||
goToTask( task );
|
||||
};
|
||||
|
||||
const getSectionTasks = ( sectionTaskIds: string[] ) => {
|
||||
return visibleTasks.filter( ( task ) =>
|
||||
sectionTaskIds.includes( task.id )
|
||||
);
|
||||
};
|
||||
|
||||
if ( ! visibleTasks.length ) {
|
||||
return <div className="woocommerce-task-dashboard__container"></div>;
|
||||
}
|
||||
|
||||
if ( isComplete && ! keepCompletedTaskList ) {
|
||||
return (
|
||||
<>
|
||||
<TaskListCompleted
|
||||
hideTasks={ hideTasks }
|
||||
keepTasks={ keepTasks }
|
||||
twoColumns={ false }
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{ displayProgressHeader ? (
|
||||
<ProgressHeader taskListId={ id } />
|
||||
) : null }
|
||||
<div
|
||||
className={ classnames(
|
||||
`woocommerce-task-dashboard__container woocommerce-sectioned-task-list two-column-experiment woocommerce-task-list__${ id }`
|
||||
) }
|
||||
>
|
||||
<Panel>
|
||||
{ ( sections || [] ).map( ( section ) => (
|
||||
<PanelBodyWithUpdatedType
|
||||
key={ section.id }
|
||||
title={
|
||||
<SectionPanelTitle
|
||||
section={ section }
|
||||
tasks={ tasks }
|
||||
active={ openPanel === section.id }
|
||||
/>
|
||||
}
|
||||
opened={ openPanel === section.id }
|
||||
onToggle={ ( isOpen: boolean ) => {
|
||||
if ( ! isOpen && openPanel === section.id ) {
|
||||
setOpenPanel( null );
|
||||
} else {
|
||||
setOpenPanel( section.id );
|
||||
}
|
||||
} }
|
||||
initialOpen={ false }
|
||||
>
|
||||
<PanelRow>
|
||||
<List animation="custom">
|
||||
{ getSectionTasks( section.tasks ).map(
|
||||
( task ) => {
|
||||
const className = classnames(
|
||||
'woocommerce-task-list__item',
|
||||
{
|
||||
'is-complete':
|
||||
task.isComplete,
|
||||
'is-disabled':
|
||||
task.isDisabled,
|
||||
}
|
||||
);
|
||||
return (
|
||||
<TaskItem
|
||||
key={ task.id }
|
||||
className={ className }
|
||||
title={ task.title }
|
||||
completed={
|
||||
task.isComplete
|
||||
}
|
||||
expanded={
|
||||
! task.isComplete
|
||||
}
|
||||
content={ task.content }
|
||||
onClick={ () => {
|
||||
if (
|
||||
! task.isDisabled
|
||||
) {
|
||||
onTaskSelected(
|
||||
task
|
||||
);
|
||||
}
|
||||
} }
|
||||
onDismiss={
|
||||
task.isDismissable
|
||||
? () =>
|
||||
onDismissTask(
|
||||
task.id
|
||||
)
|
||||
: undefined
|
||||
}
|
||||
action={ () => {} }
|
||||
actionLabel={
|
||||
task.actionLabel
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
) }
|
||||
</List>
|
||||
</PanelRow>
|
||||
</PanelBodyWithUpdatedType>
|
||||
) ) }
|
||||
</Panel>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default SectionedTaskList;
|
|
@ -19,10 +19,10 @@
|
|||
flex: 1;
|
||||
}
|
||||
|
||||
.woocommerce-ellipsis-menu.setup {
|
||||
.woocommerce-ellipsis-menu {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
right: 16px;
|
||||
top: $gap;
|
||||
right: $gap-large;
|
||||
}
|
||||
|
||||
.woocommerce-task-card.is-loading {
|
||||
|
@ -103,7 +103,7 @@
|
|||
margin: 0 auto;
|
||||
justify-content: space-between;
|
||||
|
||||
ul li.complete .woocommerce-task-list__item-title {
|
||||
ul li.is-complete .woocommerce-task-list__item-title {
|
||||
font-weight: 600;
|
||||
color: $gray-600;
|
||||
}
|
||||
|
@ -130,11 +130,11 @@
|
|||
}
|
||||
|
||||
.woocommerce-task-header__contents {
|
||||
max-width: 380px;
|
||||
max-width: calc(60% - 2%);
|
||||
}
|
||||
|
||||
.svg-background {
|
||||
right: 0.5%;
|
||||
right: 2%;
|
||||
width: 40%;
|
||||
}
|
||||
}
|
||||
|
@ -143,6 +143,13 @@
|
|||
@include single-column;
|
||||
}
|
||||
|
||||
&.two-columns .svg-background {
|
||||
top: 50%;
|
||||
bottom: 50%;
|
||||
margin-top: auto;
|
||||
margin-bottom: auto;
|
||||
}
|
||||
|
||||
ul {
|
||||
display: flex;
|
||||
li {
|
||||
|
@ -171,10 +178,13 @@
|
|||
height: 100%;
|
||||
}
|
||||
}
|
||||
.woocommerce-task-list__item:not(.complete) .woocommerce-task__icon {
|
||||
.woocommerce-task-list__item:not(.is-complete) .woocommerce-task__icon {
|
||||
border: 1px solid var(--wp-admin-theme-color);
|
||||
background: transparent;
|
||||
}
|
||||
.woocommerce-task-list__item.is-complete:not(.complete) .woocommerce-task__icon {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.woocommerce-task-list__item-before {
|
||||
display: block;
|
||||
|
@ -196,7 +206,7 @@
|
|||
}
|
||||
|
||||
@for $i from 1 through 10 {
|
||||
.woocommerce-task-list__item:not(.complete).index-#{$i} .woocommerce-task__icon::after {
|
||||
.woocommerce-task-list__item:not(.is-complete).index-#{$i} .woocommerce-task__icon::after {
|
||||
content: '#{$i}';
|
||||
@extend .numbered-circle;
|
||||
color: var(--wp-admin-theme-color);
|
||||
|
@ -229,10 +239,6 @@
|
|||
position: absolute;
|
||||
z-index: 0;
|
||||
right: 6%;
|
||||
top: 50%;
|
||||
bottom: 50%;
|
||||
margin-top: auto;
|
||||
margin-bottom: auto;
|
||||
|
||||
.admin-theme-color {
|
||||
fill: var(--wp-admin-theme-color);
|
||||
|
|
|
@ -16,6 +16,7 @@ import {
|
|||
ONBOARDING_STORE_NAME,
|
||||
TaskType,
|
||||
useUserPreferences,
|
||||
getVisibleTasks,
|
||||
} from '@woocommerce/data';
|
||||
import { recordEvent } from '@woocommerce/tracks';
|
||||
import { List, TaskItem } from '@woocommerce/experimental';
|
||||
|
@ -63,12 +64,7 @@ export const TaskList: React.FC< TaskListProps > = ( {
|
|||
|
||||
const prevQueryRef = useRef( query );
|
||||
|
||||
const nowTimestamp = Date.now();
|
||||
const visibleTasks = tasks.filter(
|
||||
( task ) =>
|
||||
! task.isDismissed &&
|
||||
( ! task.isSnoozed || task.snoozedUntil < nowTimestamp )
|
||||
);
|
||||
const visibleTasks = getVisibleTasks( tasks );
|
||||
|
||||
const recordTaskListView = () => {
|
||||
if ( query.task ) {
|
||||
|
@ -295,7 +291,7 @@ export const TaskList: React.FC< TaskListProps > = ( {
|
|||
const className = classnames(
|
||||
'woocommerce-task-list__item index-' + index,
|
||||
{
|
||||
complete: task.isComplete,
|
||||
'is-complete': task.isComplete,
|
||||
'is-active': task.id === activeTaskId,
|
||||
}
|
||||
);
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
# Languages
|
||||
|
||||
## Contributing a Translation
|
||||
If you'd like to contribute a translation, please follow the Localizing section in [CONTRIBUTING.md](https://github.com/woocommerce/woocommerce-admin/blob/main/CONTRIBUTING.md).
|
||||
|
||||
## Generating POT
|
||||
|
||||
The generated POT template file is not included in this repository. To create this file locally, follow instructions from [README.md](https://github.com/woocommerce/woocommerce-admin/blob/main/README.md) to install the project, then run the following command:
|
||||
|
||||
```
|
||||
pnpm run i18n lang=xx_YY
|
||||
```
|
||||
|
||||
After the build completes, you'll find a `woocommerce-admin-xx_YY.po` (eg. `woocommerce-admin-fr_FR.po`) strings file in this directory.
|
||||
|
||||
## Generating JSON
|
||||
|
||||
To generate JSON from your translations, save your translation file in this directory then run the following command:
|
||||
|
||||
```
|
||||
pnpm run i18n:json
|
||||
```
|
|
@ -1,47 +0,0 @@
|
|||
module.exports = {
|
||||
'*.scss': [ 'pnpm run lint:css-fix' ],
|
||||
'client/**/*.(t|j)s?(x)': [
|
||||
'wp-scripts format-js',
|
||||
'wp-scripts lint-js',
|
||||
'pnpm run test-staged',
|
||||
],
|
||||
'packages/**/*.(t|j)s?(x)': ( packageFiles ) => {
|
||||
const globalScripts = [
|
||||
`wp-scripts format-js ${ packageFiles.join( ' ' ) }`,
|
||||
`wp-scripts lint-js ${ packageFiles.join( ' ' ) }`,
|
||||
];
|
||||
|
||||
const filesByPackage = packageFiles.reduce(
|
||||
( packages, packageFile ) => {
|
||||
const packageNameMatch = packageFile.match(
|
||||
/\/packages\/([a-z0-9\-]+)\//
|
||||
);
|
||||
|
||||
if ( ! packageNameMatch ) {
|
||||
return packages;
|
||||
}
|
||||
|
||||
const packageName = packageNameMatch[ 1 ];
|
||||
|
||||
if ( Array.isArray( packages[ packageName ] ) ) {
|
||||
packages[ packageName ].push( packageFile );
|
||||
} else {
|
||||
packages[ packageName ] = [ packageFile ];
|
||||
}
|
||||
|
||||
return packages;
|
||||
},
|
||||
{}
|
||||
);
|
||||
|
||||
const workspaceScripts = Object.keys( filesByPackage ).map(
|
||||
( packageName ) =>
|
||||
`pnpm --filter @woocommerce/${ packageName } run test-staged -- ${ filesByPackage[
|
||||
packageName
|
||||
].join( ' ' ) }`
|
||||
);
|
||||
|
||||
return globalScripts.concat( workspaceScripts );
|
||||
},
|
||||
'*.php': [ 'php -d display_errors=1 -l', 'composer run-script phpcs' ],
|
||||
};
|
|
@ -1,92 +1,63 @@
|
|||
{
|
||||
"name": "@woocommerce/admin-library",
|
||||
"version": "3.3.0",
|
||||
"homepage": "https://woocommerce.github.io/woocommerce-admin/",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com:woocommerce/woocommerce-admin.git"
|
||||
},
|
||||
"license": "GPL-3.0-or-later",
|
||||
"author": "Automattic",
|
||||
"files": [
|
||||
"dist/**/*.css",
|
||||
"dist/**/*.js",
|
||||
"dist/feature-config-core.php",
|
||||
"includes/class-wc-admin-loader.php",
|
||||
"includes/features/**/*.php",
|
||||
"languages/**/*.json",
|
||||
"license.txt"
|
||||
],
|
||||
"homepage": "https://github.com/woocommerce/woocommerce/tree/trunk/plugins/woocommerce-admin/README.md",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com:woocommerce/woocommerce.git"
|
||||
},
|
||||
"scripts": {
|
||||
"preinstall": "npx only-allow pnpm",
|
||||
"prebuild": "pnpm run install-if-deps-outdated",
|
||||
"run:packages": "pnpm run --filter ../../packages/js/",
|
||||
"packages:fix:textdomain": "node ./bin/package-update-textdomain.js",
|
||||
"build": "pnpm run build:feature-config && cross-env NODE_ENV=production webpack",
|
||||
"analyze": "cross-env NODE_ENV=production ANALYZE=true webpack",
|
||||
"postbuild": "pnpm run -s i18n:pot && pnpm run -s i18n:build",
|
||||
"prebuild": "pnpm run install-if-deps-outdated",
|
||||
"build": "pnpm run build:feature-config && cross-env NODE_ENV=production webpack",
|
||||
"build-storybook": "build-storybook -c ./storybook/.storybook",
|
||||
"build:feature-config": "php ../woocommerce/bin/generate-feature-config.php",
|
||||
"build:packages": "cross-env NODE_ENV=production pnpm run:packages -- build",
|
||||
"build:release": "./bin/build-plugin-zip.sh",
|
||||
"clean": "rimraf ./dist && pnpm run:packages -- clean --parallel",
|
||||
"clean": "rimraf ../woocommerce/assets/client/admin/* && pnpm run:packages -- clean --parallel",
|
||||
"client:watch": "cross-env WC_ADMIN_PHASE=development pnpm run build:feature-config && cross-env WC_ADMIN_PHASE=development webpack --watch",
|
||||
"create-hook-reference": "node ./bin/hook-reference/index.js",
|
||||
"create-wc-extension": "node ./bin/starter-pack/starter-pack.js",
|
||||
"predev": "pnpm run -s install-if-deps-outdated",
|
||||
"dev": "cross-env WC_ADMIN_PHASE=development pnpm run build:feature-config && cross-env WC_ADMIN_PHASE=development pnpm run build:packages && cross-env WC_ADMIN_PHASE=development webpack",
|
||||
"client:watch": "cross-env WC_ADMIN_PHASE=development pnpm run build:feature-config && cross-env WC_ADMIN_PHASE=development webpack --watch",
|
||||
"packages:watch": "cross-env WC_ADMIN_PHASE=development pnpm run:packages -- start --parallel",
|
||||
"docs": "./bin/import-wp-css-storybook.sh && BABEL_ENV=storybook STORYBOOK=true pnpm exec build-storybook -c storybook/.storybook -o ./docs/components/storybook",
|
||||
"i18n": "pnpm run -s i18n:js && pnpm run -s i18n:check && pnpm run -s i18n:pot && pnpm run -s i18n:build",
|
||||
"i18n:build": "php bin/combine-pot-files.php languages/woocommerce-admin.po languages/woocommerce-admin.pot",
|
||||
"i18n:check": "grunt checktextdomain",
|
||||
"i18n:js": "pnpm run clean && cross-env NODE_ENV=production babel client packages -o /dev/null",
|
||||
"i18n:json": "./bin/make-i18n-json.sh",
|
||||
"i18n:pot": "grunt makepot",
|
||||
"example": "webpack --config docs/examples/extensions/examples.config.js --watch",
|
||||
"preinstall": "npx only-allow pnpm",
|
||||
"install-if-deps-outdated": "node bin/install-if-deps-outdated.js",
|
||||
"install-if-no-packages": "node bin/install-if-no-packages.js",
|
||||
"labels:dry": "github-label-sync --labels ./.github/label-sync-config.json --allow-added-labels --dry-run woocommerce/woocommerce-admin",
|
||||
"labels:sync": "github-label-sync --labels ./.github/label-sync-config.json --allow-added-labels woocommerce/woocommerce-admin",
|
||||
"lint": "pnpm run lint:js && pnpm run lint:css",
|
||||
"lint:css": "stylelint '**/*.scss'",
|
||||
"lint:css-fix": "stylelint '**/*.scss' --fix --ip 'storybook/wordpress'",
|
||||
"lint:js": "wp-scripts lint-js ./client --ext=js,ts,tsx",
|
||||
"lint:js-packages": "wp-scripts lint-js ../../packages/js --ext=js,ts,tsx",
|
||||
"lint:js-fix": "pnpm run lint:js -- --fix --ext=js,ts,tsx",
|
||||
"lint:php": "./vendor/bin/phpcs --standard=phpcs.xml.dist $(git ls-files | grep .php$)",
|
||||
"lint:php-fix": "./vendor/bin/phpcbf --standard=phpcs.xml.dist $(git ls-files | grep .php$)",
|
||||
"ts:check": "tsc --build ./tsconfig.json --pretty",
|
||||
"ts:check:watch": "npm run ts:check -- --watch",
|
||||
"reformat-files": "wp-scripts format-js -- --ignore-path .eslintignore",
|
||||
"lint:js-packages": "wp-scripts lint-js ../../packages/js --ext=js,ts,tsx",
|
||||
"lint:js-pre-commit": "wp-scripts lint-js --ext=js,ts,tsx",
|
||||
"prepack": "pnpm install && pnpm run lint && pnpm run test && cross-env WC_ADMIN_PHASE=core pnpm run build",
|
||||
"packages:fix:textdomain": "node ./bin/package-update-textdomain.js",
|
||||
"packages:watch": "cross-env WC_ADMIN_PHASE=development pnpm run:packages -- start --parallel",
|
||||
"pre-release": "./bin/pre-release.sh",
|
||||
"publish-packages:check": "pnpm run build:packages && pnpm publish --dry-run --filter ../../packages/js/ --publish-branch main --report-summary && cat ../../pnpm-publish-summary.json && rimraf ../../pnpm-publish-summary.json",
|
||||
"publish-packages:dev": "pnpm run build:packages && pnpm publish --filter ../../packages/js/ --publish-branch main --tag next",
|
||||
"publish-packages:prod": "pnpm run build:packages && pnpm publish --filter ../../packages/js/ --publish-branch main",
|
||||
"reformat-files": "wp-scripts format-js -- --ignore-path .eslintignore",
|
||||
"run:packages": "pnpm run --filter ../../packages/js/",
|
||||
"prestart": "pnpm run install-if-deps-outdated",
|
||||
"start": "cross-env WC_ADMIN_PHASE=development pnpm run build:packages && cross-env WC_ADMIN_PHASE=development pnpm run build:feature-config && concurrently \"cross-env WC_ADMIN_PHASE=development webpack --watch\" \"cross-env WC_ADMIN_PHASE=development pnpm run:packages -- start --parallel\"",
|
||||
"start:package": "pnpm run:packages -- start --parallel",
|
||||
"pretest": "pnpm run -s install-if-no-packages",
|
||||
"test:debug": "node --inspect-brk ./node_modules/.bin/jest --config client/jest.config.js --watch --runInBand --no-cache",
|
||||
"test:client": "jest --config client/jest.config.js",
|
||||
"test:packages": "pnpm run --filter ../../packages/js/ --filter !api-core-tests test",
|
||||
"test": "pnpm nx build @woocommerce/js-tests && pnpm run test:client",
|
||||
"test:e2e": "pnpm run build && test -z \"$(docker ps | grep woocommerce-admin-e2e)\" || pnpm exec wc-e2e docker:down && pnpm run e2e:docker-up && pnpm exec wc-e2e test:e2e",
|
||||
"e2e:docker-up": "WC_E2E_FOLDER=../../../ pnpm exec wc-e2e docker:up ./tests/e2e/docker/initialize.sh",
|
||||
"test-staged": "pnpm run test:client -- --bail --findRelatedTests",
|
||||
"test:help": "wp-scripts test-unit-js --help",
|
||||
"test:php": "docker-compose -f docker/wc-admin-php-test-suite/docker-compose.yml run --rm phpunit",
|
||||
"posttest:php": "docker-compose -f docker/wc-admin-php-test-suite/docker-compose.yml down",
|
||||
"test:update-snapshots": "pnpm run test:client -- --updateSnapshot && pnpm run --filter @woocommerce/components test:update-snapshots",
|
||||
"test:watch": "tsc --build || concurrently \"pnpm run test:client -- --watch\" \"pnpm run:packages -- test:nobuild --parallel -- --watch\"",
|
||||
"test:zip": "pnpm run clean && composer i && ./bin/build-test-zip.sh",
|
||||
"example": "webpack --config docs/examples/extensions/examples.config.js --watch",
|
||||
"pre-release": "./bin/pre-release.sh",
|
||||
"create-wc-extension": "node ./bin/starter-pack/starter-pack.js",
|
||||
"storybook": "./bin/import-wp-css-storybook.sh && BABEL_ENV=storybook STORYBOOK=true start-storybook -c ./storybook/.storybook -p 6007 --ci",
|
||||
"storybook-rtl": "USE_RTL_STYLE=true pnpm run storybook",
|
||||
"build-storybook": "build-storybook -c ./storybook/.storybook",
|
||||
"changelog": "node ./bin/changelog --changelogSrcType='ZENHUB_RELEASE'",
|
||||
"wp-env-mysql-port": "node ./docker/wc-admin-wp-env/mysql-port.js",
|
||||
"create-hook-reference": "node ./bin/hook-reference/index.js",
|
||||
"changelogger": "./vendor/bin/changelogger",
|
||||
"test-instruction-logger": "./bin/test-instruction-logger/bin/test-instruction-logger"
|
||||
"pretest": "pnpm run -s install-if-no-packages",
|
||||
"test": "pnpm nx build @woocommerce/js-tests && pnpm run test:client",
|
||||
"test-staged": "pnpm run test:client -- --bail --findRelatedTests",
|
||||
"test:client": "jest --config client/jest.config.js",
|
||||
"test:debug": "node --inspect-brk ./node_modules/.bin/jest --config client/jest.config.js --watch --runInBand --no-cache",
|
||||
"test:help": "wp-scripts test-unit-js --help",
|
||||
"test:packages": "pnpm run --filter ../../packages/js/ --filter !api-core-tests test",
|
||||
"test:update-snapshots": "pnpm run test:client -- --updateSnapshot && pnpm run --filter @woocommerce/components test:update-snapshots",
|
||||
"test:watch": "tsc --build || concurrently \"pnpm run test:client -- --watch\" \"pnpm run:packages -- test:nobuild --parallel -- --watch\"",
|
||||
"ts:check": "tsc --build ./tsconfig.json --pretty",
|
||||
"ts:check:watch": "npm run ts:check -- --watch"
|
||||
},
|
||||
"dependencies": {
|
||||
"@automattic/explat-client": "^0.0.3",
|
||||
|
@ -96,9 +67,9 @@
|
|||
"@woocommerce/api": "^0.2.0",
|
||||
"@woocommerce/e2e-environment": "^0.3.0",
|
||||
"@woocommerce/e2e-utils": "^0.2.0",
|
||||
"@wordpress/a11y": "^2.15.3",
|
||||
"@wordpress/a11y": "^3.5.0",
|
||||
"@wordpress/api-fetch": "^6.0.1",
|
||||
"@wordpress/base-styles": "^3.6.0",
|
||||
"@wordpress/base-styles": "^4.3.0",
|
||||
"@wordpress/components": "^19.5.0",
|
||||
"@wordpress/compose": "^5.1.2",
|
||||
"@wordpress/core-data": "^4.1.2",
|
||||
|
@ -107,10 +78,10 @@
|
|||
"@wordpress/dom": "^3.3.2",
|
||||
"@wordpress/dom-ready": "^3.3.1",
|
||||
"@wordpress/element": "^4.1.1",
|
||||
"@wordpress/hooks": "^2.12.3",
|
||||
"@wordpress/hooks": "^3.5.0",
|
||||
"@wordpress/html-entities": "^3.3.1",
|
||||
"@wordpress/i18n": "^4.3.1",
|
||||
"@wordpress/icons": "^6.3.0",
|
||||
"@wordpress/icons": "^8.1.0",
|
||||
"@wordpress/keycodes": "^3.3.1",
|
||||
"@wordpress/notices": "^3.3.2",
|
||||
"@wordpress/plugins": "^4.1.3",
|
||||
|
@ -205,7 +176,6 @@
|
|||
"@woocommerce/onboarding": "workspace:*",
|
||||
"@woocommerce/style-build": "workspace:*",
|
||||
"@woocommerce/tracks": "workspace:*",
|
||||
"@wordpress/babel-plugin-makepot": "^2.1.3",
|
||||
"@wordpress/babel-preset-default": "^6.5.1",
|
||||
"@wordpress/browserslist-config": "^4.1.1",
|
||||
"@wordpress/custom-templated-path-webpack-plugin": "^2.1.2",
|
||||
|
@ -238,14 +208,9 @@
|
|||
"expose-loader": "^3.1.0",
|
||||
"fork-ts-checker-webpack-plugin": "^6.5.0",
|
||||
"fs-extra": "^8.1.0",
|
||||
"grunt": "^1.4.1",
|
||||
"grunt-checktextdomain": "^1.0.1",
|
||||
"grunt-wp-i18n": "^1.0.3",
|
||||
"husky": "^7.0.0",
|
||||
"jest": "^27.5.1",
|
||||
"jest-environment-jsdom": "~27.5.0",
|
||||
"jest-environment-node": "^27.5.1",
|
||||
"lint-staged": "^12.3.5",
|
||||
"md5": "^2.3.0",
|
||||
"merge-config": "^2.0.0",
|
||||
"mini-css-extract-plugin": "^2.6.0",
|
||||
|
@ -282,6 +247,14 @@
|
|||
"peerDependencies": {
|
||||
"@wordpress/data": "^6.3.0"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.scss": [ "pnpm lint:css-fix" ],
|
||||
"client/**/*.(t|j)s?(x)": [
|
||||
"pnpm reformat-files",
|
||||
"pnpm wp-scripts lint-js",
|
||||
"pnpm test-staged"
|
||||
]
|
||||
},
|
||||
"engines": {
|
||||
"node": "^16.13.1",
|
||||
"pnpm": "^6.24.2"
|
||||
|
|
|
@ -47,7 +47,7 @@ class UnminifyWebpackPlugin {
|
|||
compilation.hooks.processAssets.tap(
|
||||
{
|
||||
name: 'UnminifyWebpackPlugin',
|
||||
stage: webpack.Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_INLINE,
|
||||
stage: webpack.Compilation.PROCESS_ASSETS_STAGE_DERIVED,
|
||||
},
|
||||
( assets ) => {
|
||||
Object.entries( assets ).forEach(
|
||||
|
|
|
@ -11,8 +11,6 @@
|
|||
"homepage": "http://github.com/woocommerce/woocommerce-beta-tester",
|
||||
"devDependencies": {
|
||||
"eslint": "5.16.0",
|
||||
"husky": "1.3.1",
|
||||
"lint-staged": "8.1.5",
|
||||
"uglify-js": "^3.5.3"
|
||||
},
|
||||
"assets": {
|
||||
|
@ -32,28 +30,17 @@
|
|||
"node": ">=10.15.0",
|
||||
"npm": ">=6.4.1"
|
||||
},
|
||||
"husky": {
|
||||
"hooks": {
|
||||
"pre-commit": "lint-staged"
|
||||
}
|
||||
},
|
||||
"lint-staged": {
|
||||
"linters": {
|
||||
"*.php": [
|
||||
"php -d display_errors=1 -l",
|
||||
"composer run-script phpcs-pre-commit"
|
||||
],
|
||||
"*.js": [
|
||||
"eslint --fix",
|
||||
"git add"
|
||||
]
|
||||
},
|
||||
"ignore": [
|
||||
"*.min.js"
|
||||
]
|
||||
},
|
||||
"woorelease": {
|
||||
"svn_reauth": "true",
|
||||
"wp_org_slug": "woocommerce-beta-tester"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.php": [
|
||||
"php -d display_errors=1 -l",
|
||||
"composer --working-dir=./plugins/woocommerce-beta-tester run-script phpcs-pre-commit"
|
||||
],
|
||||
"!(*min).js": [
|
||||
"eslint --fix"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 4.8 KiB |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue