Merge branch 'trunk' into update/ai-product-endpoint-last-product-param
This commit is contained in:
commit
00b7b78ee8
|
@ -26,7 +26,7 @@ jobs:
|
|||
- uses: './.github/actions/setup-woocommerce-monorepo'
|
||||
name: 'Setup Monorepo'
|
||||
with:
|
||||
install: false
|
||||
install: true
|
||||
- uses: actions/github-script@v6
|
||||
id: 'project-matrix'
|
||||
name: 'Build Matrix'
|
||||
|
@ -46,6 +46,7 @@ jobs:
|
|||
runs-on: 'ubuntu-20.04'
|
||||
needs: 'project-matrix'
|
||||
if: ${{ needs.project-matrix.outputs.matrix != '[]' }}
|
||||
timeout-minutes: 30
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
|
|
33
.syncpackrc
33
.syncpackrc
|
@ -42,9 +42,6 @@
|
|||
"dependencies": [
|
||||
"@types/react"
|
||||
],
|
||||
"dependencyTypes": [
|
||||
"devDependencies"
|
||||
],
|
||||
"pinVersion": "^17.0.2",
|
||||
"packages": [
|
||||
"**"
|
||||
|
@ -61,7 +58,9 @@
|
|||
},
|
||||
{
|
||||
"dependencies": [
|
||||
"@types/react",
|
||||
"react",
|
||||
"@types/react-dom",
|
||||
"react-dom"
|
||||
],
|
||||
"packages": [
|
||||
|
@ -82,9 +81,6 @@
|
|||
"dependencies": [
|
||||
"eslint"
|
||||
],
|
||||
"dependencyTypes": [
|
||||
"devDependencies"
|
||||
],
|
||||
"packages": [
|
||||
"**"
|
||||
],
|
||||
|
@ -183,9 +179,6 @@
|
|||
"dependencies": [
|
||||
"postcss-loader"
|
||||
],
|
||||
"dependencyTypes": [
|
||||
"devDependencies"
|
||||
],
|
||||
"packages": [
|
||||
"**"
|
||||
],
|
||||
|
@ -209,6 +202,28 @@
|
|||
],
|
||||
"pinVersion": "^16.18.18"
|
||||
},
|
||||
{
|
||||
"dependencies": [
|
||||
"jest",
|
||||
"jest-cli",
|
||||
"jest-environment-jsdom",
|
||||
"jest-environment-node",
|
||||
"babel-jest"
|
||||
],
|
||||
"packages": [
|
||||
"**"
|
||||
],
|
||||
"pinVersion": "~27.5.1"
|
||||
},
|
||||
{
|
||||
"dependencies": [
|
||||
"ts-jest"
|
||||
],
|
||||
"packages": [
|
||||
"**"
|
||||
],
|
||||
"pinVersion": "~29.1.1"
|
||||
},
|
||||
{
|
||||
"label": "Only manage versions for these dependencies",
|
||||
"dependencies": [
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
"css-loader": "^6.7.3",
|
||||
"glob": "^7.2.3",
|
||||
"husky": "^7.0.4",
|
||||
"jest": "^27.5.1",
|
||||
"jest": "~27.5.1",
|
||||
"lint-staged": "^12.5.0",
|
||||
"mkdirp": "^1.0.4",
|
||||
"moment": "^2.29.4",
|
||||
|
@ -74,7 +74,8 @@
|
|||
"pnpm": {
|
||||
"overrides": {
|
||||
"@types/react": "^17.0.2",
|
||||
"react": "^17.0.2"
|
||||
"react": "^17.0.2",
|
||||
"react-resize-aware": "3.1.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,11 +45,11 @@
|
|||
"@woocommerce/api": "^0.2.0",
|
||||
"@woocommerce/eslint-plugin": "workspace:*",
|
||||
"eslint": "^8.32.0",
|
||||
"jest": "^27.5.1",
|
||||
"jest-cli": "^27.5.1",
|
||||
"jest": "~27.5.1",
|
||||
"jest-cli": "~27.5.1",
|
||||
"jest-mock-extended": "^1.0.18",
|
||||
"rimraf": "^3.0.2",
|
||||
"ts-jest": "^27.1.3",
|
||||
"ts-jest": "~29.1.1",
|
||||
"typescript": "^5.1.6"
|
||||
},
|
||||
"publishConfig": {
|
||||
|
|
|
@ -49,14 +49,14 @@
|
|||
"concurrently": "^7.0.0",
|
||||
"css-loader": "^3.6.0",
|
||||
"eslint": "^8.32.0",
|
||||
"jest": "^27.5.1",
|
||||
"jest-cli": "^27.5.1",
|
||||
"jest": "~27.5.1",
|
||||
"jest-cli": "~27.5.1",
|
||||
"postcss-loader": "^4.3.0",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"rimraf": "^3.0.2",
|
||||
"sass-loader": "^10.2.1",
|
||||
"ts-jest": "^27.1.3",
|
||||
"ts-jest": "~29.1.1",
|
||||
"typescript": "^5.1.6",
|
||||
"webpack": "^5.70.0",
|
||||
"webpack-cli": "^3.3.12"
|
||||
|
|
|
@ -34,21 +34,21 @@
|
|||
"debug": "^4.3.3",
|
||||
"dompurify": "^2.3.6",
|
||||
"prop-types": "^15.8.1",
|
||||
"react-router-dom": "^6.3.0"
|
||||
"react-router-dom": "~6.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.21.3",
|
||||
"@babel/runtime": "^7.17.2",
|
||||
"@testing-library/jest-dom": "^5.16.2",
|
||||
"@testing-library/react": "^12.1.3",
|
||||
"@testing-library/react-hooks": "^8.0.1",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"@testing-library/jest-dom": "5.16.2",
|
||||
"@testing-library/react": "12.1.3",
|
||||
"@testing-library/react-hooks": "8.0.1",
|
||||
"@testing-library/user-event": "13.5.0",
|
||||
"@types/debug": "^4.1.7",
|
||||
"@types/dompurify": "^2.3.3",
|
||||
"@types/jest": "^27.4.1",
|
||||
"@types/react": "^17.0.2",
|
||||
"@types/testing-library__jest-dom": "^5.14.3",
|
||||
"@types/wordpress__core-data": "^2.4.5",
|
||||
"@types/wordpress__core-data": "2.4.5",
|
||||
"@woocommerce/eslint-plugin": "workspace:*",
|
||||
"@woocommerce/internal-js-tests": "workspace:*",
|
||||
"@woocommerce/internal-style-build": "workspace:*",
|
||||
|
@ -57,8 +57,8 @@
|
|||
"copy-webpack-plugin": "^9.1.0",
|
||||
"css-loader": "^3.6.0",
|
||||
"eslint": "^8.32.0",
|
||||
"jest": "^27.5.1",
|
||||
"jest-cli": "^27.5.1",
|
||||
"jest": "~27.5.1",
|
||||
"jest-cli": "~27.5.1",
|
||||
"postcss": "^8.4.7",
|
||||
"postcss-loader": "^4.3.0",
|
||||
"react": "^17.0.2",
|
||||
|
@ -66,7 +66,7 @@
|
|||
"react-hooks^8.0.1": "link:@testing-library/react-hooks^8.0.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"sass-loader": "^10.2.1",
|
||||
"ts-jest": "^27.1.3",
|
||||
"ts-jest": "~29.1.1",
|
||||
"typescript": "^5.1.6",
|
||||
"webpack": "^5.70.0",
|
||||
"webpack-cli": "^3.3.12"
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
"dependencies": {
|
||||
"allure-commandline": "^2.17.2",
|
||||
"dotenv": "^10.0.0",
|
||||
"jest": "^27.5.1",
|
||||
"jest": "~27.5.1",
|
||||
"jest-allure": "^0.1.3",
|
||||
"jest-runner-groups": "^2.1.0",
|
||||
"postman-collection": "^4.1.0",
|
||||
|
|
|
@ -57,8 +57,8 @@
|
|||
"@woocommerce/eslint-plugin": "workspace:*",
|
||||
"axios-mock-adapter": "^1.20.0",
|
||||
"eslint": "^8.32.0",
|
||||
"jest": "^27",
|
||||
"ts-jest": "^27",
|
||||
"jest": "~27.5.1",
|
||||
"ts-jest": "~29.1.1",
|
||||
"typescript": "^5.1.6"
|
||||
},
|
||||
"publishConfig": {
|
||||
|
|
|
@ -37,13 +37,13 @@
|
|||
"devDependencies": {
|
||||
"@babel/core": "^7.21.3",
|
||||
"@babel/runtime": "^7.17.2",
|
||||
"@testing-library/jest-dom": "^5.16.2",
|
||||
"@testing-library/react-hooks": "^8.0.1",
|
||||
"@testing-library/jest-dom": "5.16.2",
|
||||
"@testing-library/react-hooks": "8.0.1",
|
||||
"@types/jest": "^27.4.1",
|
||||
"@types/react": "^17.0.2",
|
||||
"@types/testing-library__jest-dom": "^5.14.3",
|
||||
"@types/wordpress__block-editor": "^7.0.0",
|
||||
"@types/wordpress__blocks": "^11.0.7",
|
||||
"@types/wordpress__block-editor": "7.0.0",
|
||||
"@types/wordpress__blocks": "11.0.7",
|
||||
"@woocommerce/eslint-plugin": "workspace:*",
|
||||
"@woocommerce/internal-js-tests": "workspace:*",
|
||||
"@woocommerce/internal-style-build": "workspace:*",
|
||||
|
@ -51,15 +51,15 @@
|
|||
"copy-webpack-plugin": "^9.1.0",
|
||||
"css-loader": "^3.6.0",
|
||||
"eslint": "^8.32.0",
|
||||
"jest": "^27.5.1",
|
||||
"jest-cli": "^27.5.1",
|
||||
"jest": "~27.5.1",
|
||||
"jest-cli": "~27.5.1",
|
||||
"postcss": "^8.4.7",
|
||||
"postcss-loader": "^4.3.0",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"rimraf": "^3.0.2",
|
||||
"sass-loader": "^10.2.1",
|
||||
"ts-jest": "^27.1.3",
|
||||
"ts-jest": "~29.1.1",
|
||||
"typescript": "^5.1.6",
|
||||
"webpack": "^5.70.0",
|
||||
"webpack-cli": "^3.3.12"
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
Significance: patch
|
||||
Type: dev
|
||||
Comment: Remove unused @wordpress/scripts dependency
|
||||
|
||||
|
|
@ -33,11 +33,11 @@
|
|||
"@automattic/calypso-color-schemes": "^2.1.1",
|
||||
"@automattic/interpolate-components": "^1.2.0",
|
||||
"@automattic/tour-kit": "^1.1.1",
|
||||
"@types/wordpress__block-editor": "^7.0.0",
|
||||
"@types/wordpress__block-library": "^2.6.1",
|
||||
"@types/wordpress__blocks": "^11.0.7",
|
||||
"@types/wordpress__block-editor": "7.0.0",
|
||||
"@types/wordpress__block-library": "2.6.1",
|
||||
"@types/wordpress__blocks": "11.0.7",
|
||||
"@types/wordpress__components": "^19.10.3",
|
||||
"@types/wordpress__rich-text": "^3.4.6",
|
||||
"@types/wordpress__rich-text": "3.4.6",
|
||||
"@woocommerce/csv-export": "workspace:*",
|
||||
"@woocommerce/currency": "workspace:*",
|
||||
"@woocommerce/data": "workspace:*",
|
||||
|
@ -112,36 +112,36 @@
|
|||
"@storybook/core-events": "^6.5.17-alpha.0",
|
||||
"@storybook/react": "^6.5.17-alpha.0",
|
||||
"@storybook/theming": "^6.5.17-alpha.0",
|
||||
"@testing-library/dom": "^8.11.3",
|
||||
"@testing-library/jest-dom": "^5.16.2",
|
||||
"@testing-library/react": "^12.1.3",
|
||||
"@testing-library/react-hooks": "^8.0.1",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"@testing-library/dom": "8.11.3",
|
||||
"@testing-library/jest-dom": "5.16.2",
|
||||
"@testing-library/react": "12.1.3",
|
||||
"@testing-library/react-hooks": "8.0.1",
|
||||
"@testing-library/user-event": "13.5.0",
|
||||
"@types/jest": "^27.4.1",
|
||||
"@types/lodash": "^4.14.184",
|
||||
"@types/prop-types": "^15.7.4",
|
||||
"@types/testing-library__jest-dom": "^5.14.3",
|
||||
"@types/uuid": "^8.3.0",
|
||||
"@types/wordpress__components": "^19.10.3",
|
||||
"@types/wordpress__data": "^6.0.0",
|
||||
"@types/wordpress__media-utils": "^3.0.0",
|
||||
"@types/wordpress__viewport": "^2.5.4",
|
||||
"@types/wordpress__data": "6.0.0",
|
||||
"@types/wordpress__media-utils": "3.0.0",
|
||||
"@types/wordpress__viewport": "2.5.4",
|
||||
"@woocommerce/eslint-plugin": "workspace:*",
|
||||
"@woocommerce/internal-js-tests": "workspace:*",
|
||||
"@woocommerce/internal-style-build": "workspace:*",
|
||||
"@wordpress/babel-preset-default": "^6.5.1",
|
||||
"@wordpress/browserslist-config": "wp-6.0",
|
||||
"@wordpress/scripts": "^12.6.1",
|
||||
"concurrently": "^7.0.0",
|
||||
"css-loader": "^3.6.0",
|
||||
"eslint": "^8.32.0",
|
||||
"jest": "^27.5.1",
|
||||
"jest-cli": "^27.5.1",
|
||||
"jest": "~27.5.1",
|
||||
"jest-cli": "~27.5.1",
|
||||
"postcss": "^8.4.7",
|
||||
"postcss-loader": "^4.3.0",
|
||||
"react": "^17.0.2",
|
||||
"rimraf": "^3.0.2",
|
||||
"sass-loader": "^10.2.1",
|
||||
"ts-jest": "^29.1.1",
|
||||
"ts-jest": "~29.1.1",
|
||||
"typescript": "^5.1.6",
|
||||
"uuid": "^8.3.0",
|
||||
"webpack": "^5.70.0",
|
||||
|
@ -170,13 +170,5 @@
|
|||
"pnpm lint:fix",
|
||||
"pnpm test-staged"
|
||||
]
|
||||
},
|
||||
"pnpm": {
|
||||
"overrides": {
|
||||
"@types/react": "^17.0.2",
|
||||
"@types/react-dom": "^17.0.2",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,8 +143,7 @@ export const DateTimePickerControl = forwardRef(
|
|||
const formatDateTimeForDisplay = useCallback(
|
||||
( dateTime: Moment ) => {
|
||||
return dateTime.isValid()
|
||||
? // @ts-expect-error TODO - fix this type error with moment
|
||||
formatDate( displayFormat, dateTime.local() )
|
||||
? formatDate( displayFormat, dateTime.local() )
|
||||
: dateTime.creationData().input?.toString() || '';
|
||||
},
|
||||
[ displayFormat ]
|
||||
|
|
|
@ -103,7 +103,6 @@ describe( 'DateTimePickerControl', () => {
|
|||
|
||||
const input = container.querySelector( 'input' );
|
||||
expect( input?.value ).toBe(
|
||||
// @ts-expect-error TODO - fix this type error with moment
|
||||
formatDate( default24HourDateTimeFormat, dateTime )
|
||||
);
|
||||
} );
|
||||
|
@ -123,7 +122,6 @@ describe( 'DateTimePickerControl', () => {
|
|||
expect( input?.value ).toBe(
|
||||
formatDate(
|
||||
default24HourDateTimeFormat,
|
||||
// @ts-expect-error TODO - fix this type error with moment
|
||||
moment.utc( ambiguousISODateTimeString ).local()
|
||||
)
|
||||
);
|
||||
|
@ -144,7 +142,6 @@ describe( 'DateTimePickerControl', () => {
|
|||
expect( input?.value ).toBe(
|
||||
formatDate(
|
||||
default24HourDateTimeFormat,
|
||||
// @ts-expect-error TODO - fix this type error with moment
|
||||
moment.utc( unambiguousISODateTimeString ).local()
|
||||
)
|
||||
);
|
||||
|
@ -162,7 +159,6 @@ describe( 'DateTimePickerControl', () => {
|
|||
|
||||
const input = container.querySelector( 'input' );
|
||||
expect( input?.value ).toBe(
|
||||
// @ts-expect-error TODO - fix this type error with moment
|
||||
formatDate( default12HourDateTimeFormat, dateTime )
|
||||
);
|
||||
} );
|
||||
|
@ -179,7 +175,6 @@ describe( 'DateTimePickerControl', () => {
|
|||
);
|
||||
|
||||
const input = container.querySelector( 'input' );
|
||||
// @ts-expect-error TODO - fix this type error with moment
|
||||
expect( input?.value ).toBe( formatDate( dateTimeFormat, dateTime ) );
|
||||
} );
|
||||
|
||||
|
@ -203,7 +198,6 @@ describe( 'DateTimePickerControl', () => {
|
|||
|
||||
const input = container.querySelector( 'input' );
|
||||
expect( input?.value ).toBe(
|
||||
// @ts-expect-error TODO - fix this type error with moment
|
||||
formatDate( default24HourDateTimeFormat, updatedDateTime )
|
||||
);
|
||||
} );
|
||||
|
|
|
@ -184,7 +184,7 @@ function SelectControl< ItemType = DefaultItemType >( {
|
|||
highlightedIndex,
|
||||
getItemProps,
|
||||
selectItem,
|
||||
// @ts-expect-error - TODO fix this type.
|
||||
// @ts-expect-error We're allowed to use the property.
|
||||
selectedItem: comboboxSingleSelectedItem,
|
||||
openMenu,
|
||||
closeMenu,
|
||||
|
@ -208,7 +208,7 @@ function SelectControl< ItemType = DefaultItemType >( {
|
|||
onInputChange( value, changes );
|
||||
}
|
||||
},
|
||||
// @ts-expect-error - TODO fix this type.
|
||||
// @ts-expect-error We're allowed to use the property.
|
||||
stateReducer: ( state, actionAndChanges ) => {
|
||||
const { changes, type } = actionAndChanges;
|
||||
let newChanges;
|
||||
|
|
|
@ -21,7 +21,7 @@ export default () => {
|
|||
>
|
||||
<mask
|
||||
id={ maskId }
|
||||
mask-type="alpha"
|
||||
style={ { maskType: 'alpha' } }
|
||||
maskUnits="userSpaceOnUse"
|
||||
x="2"
|
||||
y="3"
|
||||
|
|
|
@ -54,11 +54,11 @@
|
|||
"@woocommerce/eslint-plugin": "workspace:*",
|
||||
"@woocommerce/internal-js-tests": "workspace:*",
|
||||
"eslint": "^8.32.0",
|
||||
"jest": "^27.5.1",
|
||||
"jest-cli": "^27.5.1",
|
||||
"jest": "~27.5.1",
|
||||
"jest-cli": "~27.5.1",
|
||||
"concurrently": "^7.0.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"ts-jest": "^27.1.3",
|
||||
"ts-jest": "~29.1.1",
|
||||
"typescript": "^5.1.6"
|
||||
},
|
||||
"lint-staged": {
|
||||
|
|
|
@ -57,11 +57,11 @@
|
|||
"@woocommerce/eslint-plugin": "workspace:*",
|
||||
"@woocommerce/internal-js-tests": "workspace:*",
|
||||
"eslint": "^8.32.0",
|
||||
"jest": "^27.5.1",
|
||||
"jest-cli": "^27.5.1",
|
||||
"jest": "~27.5.1",
|
||||
"jest-cli": "~27.5.1",
|
||||
"concurrently": "^7.0.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"ts-jest": "^27.1.3",
|
||||
"ts-jest": "~29.1.1",
|
||||
"typescript": "^5.1.6"
|
||||
},
|
||||
"lint-staged": {
|
||||
|
|
|
@ -41,12 +41,12 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.17.5",
|
||||
"@testing-library/react": "^12.1.3",
|
||||
"@testing-library/react": "12.1.3",
|
||||
"@types/jest": "^27.4.1",
|
||||
"@types/prop-types": "^15.7.4",
|
||||
"@types/testing-library__jest-dom": "^5.14.3",
|
||||
"@types/wordpress__components": "^19.10.3",
|
||||
"@types/wordpress__data": "^6.0.0",
|
||||
"@types/wordpress__data": "6.0.0",
|
||||
"@woocommerce/data": "workspace:*",
|
||||
"@woocommerce/eslint-plugin": "workspace:*",
|
||||
"@woocommerce/internal-style-build": "workspace:*",
|
||||
|
@ -57,13 +57,13 @@
|
|||
"concurrently": "^7.0.0",
|
||||
"css-loader": "^3.6.0",
|
||||
"eslint": "^8.32.0",
|
||||
"jest": "^27.5.1",
|
||||
"jest-cli": "^27.5.1",
|
||||
"jest": "~27.5.1",
|
||||
"jest-cli": "~27.5.1",
|
||||
"postcss": "^8.4.7",
|
||||
"postcss-loader": "^4.3.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"sass-loader": "^10.2.1",
|
||||
"ts-jest": "^27.1.3",
|
||||
"ts-jest": "~29.1.1",
|
||||
"typescript": "^5.1.6",
|
||||
"webpack": "^5.70.0",
|
||||
"webpack-cli": "^3.3.12"
|
||||
|
|
|
@ -50,27 +50,27 @@
|
|||
"@automattic/data-stores": "^2.0.1",
|
||||
"@babel/core": "^7.17.5",
|
||||
"@babel/runtime": "^7.17.2",
|
||||
"@testing-library/react": "^12.1.3",
|
||||
"@testing-library/react-hooks": "^7.0.2",
|
||||
"@testing-library/react": "12.1.3",
|
||||
"@testing-library/react-hooks": "7.0.2",
|
||||
"@types/jest": "^27.4.1",
|
||||
"@types/lodash": "^4.14.182",
|
||||
"@types/md5": "^2.3.2",
|
||||
"@types/qs": "^6.9.7",
|
||||
"@types/react": "^17.0.2",
|
||||
"@types/node": "^16.18.18",
|
||||
"@types/wordpress__compose": "^4.0.1",
|
||||
"@types/wordpress__core-data": "^2.4.5",
|
||||
"@types/wordpress__data": "^6.0.0",
|
||||
"@types/wordpress__data-controls": "^2.2.0",
|
||||
"@types/wordpress__compose": "4.0.1",
|
||||
"@types/wordpress__core-data": "2.4.5",
|
||||
"@types/wordpress__data": "6.0.0",
|
||||
"@types/wordpress__data-controls": "~2.2.0",
|
||||
"@woocommerce/eslint-plugin": "workspace:*",
|
||||
"@woocommerce/internal-js-tests": "workspace:*",
|
||||
"eslint": "^8.32.0",
|
||||
"jest": "^27.5.1",
|
||||
"jest-cli": "^27.5.1",
|
||||
"jest": "~27.5.1",
|
||||
"jest-cli": "~27.5.1",
|
||||
"concurrently": "^7.0.0",
|
||||
"redux": "^4.1.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"ts-jest": "^27.1.3",
|
||||
"ts-jest": "~29.1.1",
|
||||
"typescript": "^5.1.6"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
|
|
@ -43,11 +43,11 @@
|
|||
"@woocommerce/internal-js-tests": "workspace:*",
|
||||
"d3-time-format": "^2.3.0",
|
||||
"eslint": "^8.32.0",
|
||||
"jest": "^27.5.1",
|
||||
"jest-cli": "^27.5.1",
|
||||
"jest": "~27.5.1",
|
||||
"jest-cli": "~27.5.1",
|
||||
"concurrently": "^7.0.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"ts-jest": "^27.1.3",
|
||||
"ts-jest": "~29.1.1",
|
||||
"typescript": "^5.1.6"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
|
|
@ -31,10 +31,10 @@
|
|||
"@babel/core": "^7.17.5",
|
||||
"@woocommerce/eslint-plugin": "workspace:*",
|
||||
"eslint": "^8.32.0",
|
||||
"jest": "^27.5.1",
|
||||
"jest-cli": "^27.5.1",
|
||||
"jest": "~27.5.1",
|
||||
"jest-cli": "~27.5.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"ts-jest": "^27.1.3",
|
||||
"ts-jest": "~29.1.1",
|
||||
"typescript": "^5.1.6",
|
||||
"webpack": "^5.70.0",
|
||||
"webpack-cli": "^3.3.12"
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
"app-root-path": "^3.0.0",
|
||||
"commander": "4.1.1",
|
||||
"config": "3.3.7",
|
||||
"jest": "^27.5.1",
|
||||
"jest": "~27.5.1",
|
||||
"jest-circus": "27.5.1",
|
||||
"jest-each": "27.5.1",
|
||||
"jest-puppeteer": "^5.0.4",
|
||||
|
|
|
@ -49,10 +49,10 @@
|
|||
"devDependencies": {
|
||||
"@babel/core": "^7.17.5",
|
||||
"eslint": "^8.32.0",
|
||||
"jest": "^27.5.1",
|
||||
"jest-cli": "^27.5.1",
|
||||
"jest": "~27.5.1",
|
||||
"jest-cli": "~27.5.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"ts-jest": "^27.1.3",
|
||||
"ts-jest": "~29.1.1",
|
||||
"typescript": "^5.1.6"
|
||||
},
|
||||
"lint-staged": {
|
||||
|
|
|
@ -52,9 +52,9 @@
|
|||
"@storybook/addon-actions": "^6.5.17-alpha.0",
|
||||
"@storybook/addon-console": "^1.2.3",
|
||||
"@storybook/react": "^6.5.17-alpha.0",
|
||||
"@testing-library/dom": "^8.11.3",
|
||||
"@testing-library/react": "^12.1.3",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"@testing-library/dom": "8.11.3",
|
||||
"@testing-library/react": "12.1.3",
|
||||
"@testing-library/user-event": "13.5.0",
|
||||
"@types/dompurify": "^2.3.3",
|
||||
"@types/jest": "^27.4.1",
|
||||
"@types/react-transition-group": "^4.4.4",
|
||||
|
@ -67,13 +67,13 @@
|
|||
"concurrently": "^7.0.0",
|
||||
"css-loader": "^3.6.0",
|
||||
"eslint": "^8.32.0",
|
||||
"jest": "^27.5.1",
|
||||
"jest-cli": "^27.5.1",
|
||||
"jest": "~27.5.1",
|
||||
"jest-cli": "~27.5.1",
|
||||
"postcss": "^8.4.7",
|
||||
"postcss-loader": "^4.3.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"sass-loader": "^10.2.1",
|
||||
"ts-jest": "^27.1.3",
|
||||
"ts-jest": "~29.1.1",
|
||||
"typescript": "^5.1.6",
|
||||
"webpack": "^5.70.0",
|
||||
"webpack-cli": "^3.3.12"
|
||||
|
|
|
@ -47,11 +47,11 @@
|
|||
"@woocommerce/eslint-plugin": "workspace:*",
|
||||
"@woocommerce/internal-js-tests": "workspace:*",
|
||||
"eslint": "^8.32.0",
|
||||
"jest": "^27.5.1",
|
||||
"jest-cli": "^27.5.1",
|
||||
"jest": "~27.5.1",
|
||||
"jest-cli": "~27.5.1",
|
||||
"concurrently": "^7.0.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"ts-jest": "^27.1.3",
|
||||
"ts-jest": "~29.1.1",
|
||||
"typescript": "^5.1.6"
|
||||
},
|
||||
"scripts": {
|
||||
|
|
|
@ -54,10 +54,10 @@
|
|||
"@woocommerce/internal-js-tests": "workspace:*",
|
||||
"concurrently": "^7.0.0",
|
||||
"eslint": "^8.32.0",
|
||||
"jest": "^27.5.1",
|
||||
"jest-cli": "^27.5.1",
|
||||
"jest": "~27.5.1",
|
||||
"jest-cli": "~27.5.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"ts-jest": "^27.1.3",
|
||||
"ts-jest": "~29.1.1",
|
||||
"typescript": "^5.1.6"
|
||||
},
|
||||
"lint-staged": {
|
||||
|
|
|
@ -42,8 +42,8 @@
|
|||
"devDependencies": {
|
||||
"@babel/core": "^7.21.3",
|
||||
"@babel/runtime": "^7.17.2",
|
||||
"@testing-library/jest-dom": "^5.16.2",
|
||||
"@testing-library/react-hooks": "^8.0.1",
|
||||
"@testing-library/jest-dom": "5.16.2",
|
||||
"@testing-library/react-hooks": "8.0.1",
|
||||
"@types/jest": "^27.4.1",
|
||||
"@types/node": "^16.18.18",
|
||||
"@types/testing-library__jest-dom": "^5.14.3",
|
||||
|
@ -53,10 +53,10 @@
|
|||
"copy-webpack-plugin": "^9.1.0",
|
||||
"css-loader": "^3.6.0",
|
||||
"eslint": "^8.32.0",
|
||||
"jest": "^27.5.1",
|
||||
"jest-cli": "^27.5.1",
|
||||
"jest": "~27.5.1",
|
||||
"jest-cli": "~27.5.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"ts-jest": "^27.1.3",
|
||||
"ts-jest": "~29.1.1",
|
||||
"typescript": "^5.1.6",
|
||||
"webpack": "^5.70.0",
|
||||
"webpack-cli": "^3.3.12"
|
||||
|
|
|
@ -34,6 +34,8 @@ module.exports = {
|
|||
__dirname,
|
||||
'build/mocks/style-mock.js'
|
||||
),
|
||||
// Force module uuid to resolve with the CJS entry point, because Jest does not support package.json.exports. See https://github.com/uuidjs/uuid/issues/451
|
||||
"uuid": require.resolve('uuid'),
|
||||
},
|
||||
restoreMocks: true,
|
||||
setupFiles: [
|
||||
|
|
|
@ -30,8 +30,8 @@
|
|||
"lint:fix": "eslint src --fix"
|
||||
},
|
||||
"dependencies": {
|
||||
"@testing-library/jest-dom": "^5.16.2",
|
||||
"@testing-library/react": "^12.1.3",
|
||||
"@testing-library/jest-dom": "5.16.2",
|
||||
"@testing-library/react": "12.1.3",
|
||||
"@wordpress/data": "wp-6.0",
|
||||
"@wordpress/i18n": "wp-6.0",
|
||||
"@wordpress/jest-console": "^5.0.1",
|
||||
|
@ -41,12 +41,12 @@
|
|||
"@babel/core": "^7.17.5",
|
||||
"@woocommerce/eslint-plugin": "workspace:*",
|
||||
"eslint": "^8.32.0",
|
||||
"jest": "^27.5.1",
|
||||
"jest-cli": "^27.5.1",
|
||||
"jest": "~27.5.1",
|
||||
"jest-cli": "~27.5.1",
|
||||
"resize-observer-polyfill": "1.5.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"ts-jest": "^27.1.3",
|
||||
"babel-jest": "^27.5.1",
|
||||
"ts-jest": "~29.1.1",
|
||||
"babel-jest": "~27.5.1",
|
||||
"typescript": "^5.1.6"
|
||||
},
|
||||
"lint-staged": {
|
||||
|
|
|
@ -41,10 +41,10 @@
|
|||
"@babel/core": "^7.17.5",
|
||||
"@woocommerce/eslint-plugin": "workspace:*",
|
||||
"eslint": "^8.32.0",
|
||||
"jest": "^27.5.1",
|
||||
"jest-cli": "^27.5.1",
|
||||
"jest": "~27.5.1",
|
||||
"jest-cli": "~27.5.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"ts-jest": "^27.1.3",
|
||||
"ts-jest": "~29.1.1",
|
||||
"typescript": "^5.1.6",
|
||||
"webpack": "^5.70.0"
|
||||
},
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
"@wordpress/url": "wp-6.0",
|
||||
"history": "^5.3.0",
|
||||
"qs": "^6.10.3",
|
||||
"react-router-dom": "^6.3.0"
|
||||
"react-router-dom": "~6.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"lodash": "^4.17.0"
|
||||
|
@ -67,11 +67,11 @@
|
|||
"@woocommerce/eslint-plugin": "workspace:*",
|
||||
"@woocommerce/internal-js-tests": "workspace:*",
|
||||
"eslint": "^8.32.0",
|
||||
"jest": "^27.5.1",
|
||||
"jest-cli": "^27.5.1",
|
||||
"jest": "~27.5.1",
|
||||
"jest-cli": "~27.5.1",
|
||||
"concurrently": "^7.0.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"ts-jest": "^27.1.3",
|
||||
"ts-jest": "~29.1.1",
|
||||
"typescript": "^5.1.6"
|
||||
},
|
||||
"lint-staged": {
|
||||
|
|
|
@ -168,7 +168,6 @@ export const addHistoryListener = ( listener ) => {
|
|||
|
||||
if ( ! window.wcNavigation.historyPatched ) {
|
||||
( ( history ) => {
|
||||
/* global CustomEvent */
|
||||
const pushState = history.pushState;
|
||||
const replaceState = history.replaceState;
|
||||
history.pushState = function ( state ) {
|
||||
|
|
|
@ -53,16 +53,16 @@
|
|||
"@automattic/data-stores": "^2.0.1",
|
||||
"@babel/core": "^7.17.5",
|
||||
"@types/lodash": "^4.14.182",
|
||||
"@types/wordpress__data": "^6.0.0",
|
||||
"@types/wordpress__notices": "^3.5.0",
|
||||
"@types/wordpress__data": "6.0.0",
|
||||
"@types/wordpress__notices": "3.5.0",
|
||||
"@woocommerce/eslint-plugin": "workspace:*",
|
||||
"eslint": "^8.32.0",
|
||||
"jest": "^27.5.1",
|
||||
"jest-cli": "^27.5.1",
|
||||
"jest": "~27.5.1",
|
||||
"jest-cli": "~27.5.1",
|
||||
"concurrently": "^7.0.0",
|
||||
"redux": "^4.2.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"ts-jest": "^27.1.3",
|
||||
"ts-jest": "~29.1.1",
|
||||
"typescript": "^5.1.6"
|
||||
},
|
||||
"lint-staged": {
|
||||
|
|
|
@ -53,11 +53,11 @@
|
|||
"@woocommerce/eslint-plugin": "workspace:*",
|
||||
"@woocommerce/internal-js-tests": "workspace:*",
|
||||
"eslint": "^8.32.0",
|
||||
"jest": "^27.5.1",
|
||||
"jest-cli": "^27.5.1",
|
||||
"jest": "~27.5.1",
|
||||
"jest-cli": "~27.5.1",
|
||||
"concurrently": "^7.0.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"ts-jest": "^27.1.3",
|
||||
"ts-jest": "~29.1.1",
|
||||
"typescript": "^5.1.6"
|
||||
},
|
||||
"lint-staged": {
|
||||
|
|
|
@ -44,12 +44,12 @@
|
|||
"devDependencies": {
|
||||
"@babel/core": "^7.17.5",
|
||||
"@storybook/addon-knobs": "^7.0.2",
|
||||
"@testing-library/react": "^12.1.3",
|
||||
"@testing-library/react": "12.1.3",
|
||||
"@types/jest": "^27.4.1",
|
||||
"@types/react": "^17.0.2",
|
||||
"@types/string-similarity": "4.0.0",
|
||||
"@types/wordpress__components": "^19.10.3",
|
||||
"@types/wordpress__data": "^6.0.0",
|
||||
"@types/wordpress__data": "6.0.0",
|
||||
"@woocommerce/eslint-plugin": "workspace:*",
|
||||
"@woocommerce/internal-js-tests": "workspace:*",
|
||||
"@woocommerce/internal-style-build": "workspace:*",
|
||||
|
@ -57,13 +57,13 @@
|
|||
"concurrently": "^7.0.0",
|
||||
"css-loader": "^3.6.0",
|
||||
"eslint": "^8.32.0",
|
||||
"jest": "^27.5.1",
|
||||
"jest-cli": "^27.5.1",
|
||||
"jest": "~27.5.1",
|
||||
"jest-cli": "~27.5.1",
|
||||
"postcss": "^8.4.7",
|
||||
"postcss-loader": "^4.3.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"sass-loader": "^10.2.1",
|
||||
"ts-jest": "^27.1.3",
|
||||
"ts-jest": "~29.1.1",
|
||||
"typescript": "^5.1.6",
|
||||
"webpack": "^5.70.0",
|
||||
"webpack-cli": "^3.3.12"
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
Significance: minor
|
||||
Type: dev
|
||||
|
||||
Add max-width to tooltip #41797
|
|
@ -0,0 +1,4 @@
|
|||
Significance: patch
|
||||
Type: add
|
||||
|
||||
[Product Block Editor]: introduce UI state
|
|
@ -0,0 +1,4 @@
|
|||
Significance: patch
|
||||
Type: update
|
||||
|
||||
[Product Block Editor]: move Modal edittor out of the description block edit component
|
|
@ -30,7 +30,7 @@
|
|||
"dependencies": {
|
||||
"@types/lodash": "^4.14.179",
|
||||
"@types/prop-types": "^15.7.4",
|
||||
"@types/wordpress__blocks": "^11.0.7",
|
||||
"@types/wordpress__blocks": "11.0.7",
|
||||
"@woocommerce/admin-layout": "workspace:*",
|
||||
"@woocommerce/block-templates": "workspace:*",
|
||||
"@woocommerce/components": "workspace:*",
|
||||
|
@ -68,32 +68,32 @@
|
|||
"lodash": "^4.17.21",
|
||||
"moment": "^2.29.4",
|
||||
"prop-types": "^15.8.1",
|
||||
"react-router-dom": "^6.3.0"
|
||||
"react-router-dom": "~6.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.21.3",
|
||||
"@babel/runtime": "^7.17.2",
|
||||
"@testing-library/jest-dom": "^5.16.2",
|
||||
"@testing-library/react": "^12.1.3",
|
||||
"@testing-library/react-hooks": "^8.0.1",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"@testing-library/jest-dom": "5.16.2",
|
||||
"@testing-library/react": "12.1.3",
|
||||
"@testing-library/react-hooks": "8.0.1",
|
||||
"@testing-library/user-event": "13.5.0",
|
||||
"@types/dompurify": "^2.3.3",
|
||||
"@types/jest": "^27.4.1",
|
||||
"@types/react": "^17.0.2",
|
||||
"@types/testing-library__jest-dom": "^5.14.3",
|
||||
"@types/wordpress__block-editor": "^7.0.0",
|
||||
"@types/wordpress__block-library": "^2.6.1",
|
||||
"@types/wordpress__blocks": "^11.0.7",
|
||||
"@types/wordpress__block-editor": "7.0.0",
|
||||
"@types/wordpress__block-library": "2.6.1",
|
||||
"@types/wordpress__blocks": "11.0.7",
|
||||
"@types/wordpress__components": "^19.10.3",
|
||||
"@types/wordpress__core-data": "^2.4.5",
|
||||
"@types/wordpress__data": "^6.0.2",
|
||||
"@types/wordpress__date": "^3.3.2",
|
||||
"@types/wordpress__editor": "^13.0.0",
|
||||
"@types/wordpress__edit-post": "^7.5.4",
|
||||
"@types/wordpress__keycodes": "^2.3.1",
|
||||
"@types/wordpress__media-utils": "^3.0.0",
|
||||
"@types/wordpress__plugins": "^3.0.0",
|
||||
"@types/wordpress__rich-text": "^3.4.6",
|
||||
"@types/wordpress__core-data": "2.4.5",
|
||||
"@types/wordpress__data": "6.0.2",
|
||||
"@types/wordpress__date": "3.3.2",
|
||||
"@types/wordpress__editor": "13.0.0",
|
||||
"@types/wordpress__edit-post": "7.5.4",
|
||||
"@types/wordpress__keycodes": "2.3.1",
|
||||
"@types/wordpress__media-utils": "3.0.0",
|
||||
"@types/wordpress__plugins": "3.0.0",
|
||||
"@types/wordpress__rich-text": "3.4.6",
|
||||
"@woocommerce/eslint-plugin": "workspace:*",
|
||||
"@woocommerce/internal-js-tests": "workspace:*",
|
||||
"@woocommerce/internal-style-build": "workspace:*",
|
||||
|
@ -103,15 +103,15 @@
|
|||
"copy-webpack-plugin": "^9.1.0",
|
||||
"css-loader": "^3.6.0",
|
||||
"eslint": "^8.32.0",
|
||||
"jest": "^27.5.1",
|
||||
"jest-cli": "^27.5.1",
|
||||
"jest": "~27.5.1",
|
||||
"jest-cli": "~27.5.1",
|
||||
"postcss": "^8.4.7",
|
||||
"postcss-loader": "^4.3.0",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"rimraf": "^3.0.2",
|
||||
"sass-loader": "^10.2.1",
|
||||
"ts-jest": "^27.1.3",
|
||||
"ts-jest": "~29.1.1",
|
||||
"typescript": "^5.1.6",
|
||||
"webpack": "^5.70.0",
|
||||
"webpack-cli": "^3.3.12"
|
||||
|
|
|
@ -107,6 +107,8 @@ export function Edit( {
|
|||
<ToggleControl
|
||||
label={ label }
|
||||
checked={ isChecked() }
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore disabled prop exists
|
||||
disabled={ disabled }
|
||||
onChange={ handleChange }
|
||||
help={ help }
|
||||
|
|
|
@ -2,13 +2,14 @@
|
|||
* External dependencies
|
||||
*/
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { createElement, useState } from '@wordpress/element';
|
||||
import { createElement, useEffect } from '@wordpress/element';
|
||||
import {
|
||||
BlockAttributes,
|
||||
BlockInstance,
|
||||
parse,
|
||||
serialize,
|
||||
} from '@wordpress/blocks';
|
||||
import { useSelect, useDispatch } from '@wordpress/data';
|
||||
import { Button } from '@wordpress/components';
|
||||
import { useWooBlockProps } from '@woocommerce/block-templates';
|
||||
import { recordEvent } from '@woocommerce/tracks';
|
||||
|
@ -18,9 +19,9 @@ import { useEntityProp } from '@wordpress/core-data';
|
|||
* Internal dependencies
|
||||
*/
|
||||
import { ContentPreview } from '../../../components/content-preview';
|
||||
import { ModalEditor } from '../../../components/modal-editor';
|
||||
import { ProductEditorBlockEditProps } from '../../../types';
|
||||
import ModalEditorWelcomeGuide from '../../../components/modal-editor-welcome-guide';
|
||||
import { store } from '../../../store/product-editor-ui';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
|
@ -50,19 +51,50 @@ export function DescriptionBlockEdit( {
|
|||
attributes,
|
||||
}: ProductEditorBlockEditProps< BlockAttributes > ) {
|
||||
const blockProps = useWooBlockProps( attributes );
|
||||
const [ isModalOpen, setIsModalOpen ] = useState( false );
|
||||
const [ description, setDescription ] = useEntityProp< string >(
|
||||
'postType',
|
||||
'product',
|
||||
'description'
|
||||
);
|
||||
|
||||
// Pick Modal editor data from the store.
|
||||
const { isModalEditorOpen, modalEditorBlocks, hasChanged } = useSelect(
|
||||
( select ) => {
|
||||
return {
|
||||
isModalEditorOpen: select( store ).isModalEditorOpen(),
|
||||
modalEditorBlocks: select( store ).getModalEditorBlocks(),
|
||||
hasChanged: select( store ).getModalEditorContentHasChanged(),
|
||||
};
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
const { openModalEditor, setModalEditorBlocks } = useDispatch( store );
|
||||
|
||||
// Update the description when the blocks change.
|
||||
useEffect( () => {
|
||||
if ( ! hasChanged ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! modalEditorBlocks?.length ) {
|
||||
setDescription( '' );
|
||||
}
|
||||
|
||||
const html = serialize( clearDescriptionIfEmpty( modalEditorBlocks ) );
|
||||
setDescription( html );
|
||||
}, [ modalEditorBlocks, setDescription, hasChanged ] );
|
||||
|
||||
return (
|
||||
<div { ...blockProps }>
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={ () => {
|
||||
setIsModalOpen( true );
|
||||
if ( description ) {
|
||||
setModalEditorBlocks( parse( description ) );
|
||||
}
|
||||
|
||||
openModalEditor();
|
||||
recordEvent( 'product_add_description_click' );
|
||||
} }
|
||||
>
|
||||
|
@ -70,23 +102,12 @@ export function DescriptionBlockEdit( {
|
|||
? __( 'Edit description', 'woocommerce' )
|
||||
: __( 'Add description', 'woocommerce' ) }
|
||||
</Button>
|
||||
{ isModalOpen && (
|
||||
<ModalEditor
|
||||
initialBlocks={ parse( description ) }
|
||||
onChange={ ( blocks ) => {
|
||||
const html = serialize(
|
||||
clearDescriptionIfEmpty( blocks )
|
||||
);
|
||||
setDescription( html );
|
||||
} }
|
||||
onClose={ () => setIsModalOpen( false ) }
|
||||
title={ __( 'Edit description', 'woocommerce' ) }
|
||||
/>
|
||||
) }
|
||||
|
||||
{ !! description.length && (
|
||||
<ContentPreview content={ description } />
|
||||
) }
|
||||
{ isModalOpen && <ModalEditorWelcomeGuide /> }
|
||||
|
||||
{ isModalEditorOpen && <ModalEditorWelcomeGuide /> }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -143,6 +143,8 @@ export function Edit( {
|
|||
label={ __( 'Schedule sale', 'woocommerce' ) }
|
||||
checked={ showScheduleSale }
|
||||
onChange={ handleToggleChange }
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore disabled prop exists
|
||||
disabled={ ! isSalePriceGreaterThanZero }
|
||||
/>
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ import { createElement, useMemo, useLayoutEffect } from '@wordpress/element';
|
|||
import { useDispatch, useSelect, select as WPSelect } from '@wordpress/data';
|
||||
import { uploadMedia } from '@wordpress/media-utils';
|
||||
import { PluginArea } from '@wordpress/plugins';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore No types for this exist yet.
|
||||
|
@ -34,6 +35,8 @@ import {
|
|||
import { useConfirmUnsavedProductChanges } from '../../hooks/use-confirm-unsaved-product-changes';
|
||||
import { ProductEditorContext } from '../../types';
|
||||
import { PostTypeContext } from '../../contexts/post-type-context';
|
||||
import { ModalEditor } from '../modal-editor';
|
||||
import { store as productEditorUiStore } from '../../store/product-editor-ui';
|
||||
|
||||
type BlockEditorSettings = Partial<
|
||||
EditorSettings & EditorBlockListSettings
|
||||
|
@ -111,10 +114,26 @@ export function BlockEditor( {
|
|||
updateEditorSettings( settings ?? {} );
|
||||
}, [ productType, productId ] );
|
||||
|
||||
// Check if the Modal editor is open from the store.
|
||||
const isModalEditorOpen = useSelect( ( select ) => {
|
||||
return select( productEditorUiStore ).isModalEditorOpen();
|
||||
}, [] );
|
||||
|
||||
const { closeModalEditor } = useDispatch( productEditorUiStore );
|
||||
|
||||
if ( ! blocks ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ( isModalEditorOpen ) {
|
||||
return (
|
||||
<ModalEditor
|
||||
onClose={ closeModalEditor }
|
||||
title={ __( 'Edit description', 'woocommerce' ) }
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="woocommerce-product-block-editor">
|
||||
<BlockContextProvider value={ context }>
|
||||
|
@ -123,6 +142,7 @@ export function BlockEditor( {
|
|||
onInput={ onInput }
|
||||
onChange={ onChange }
|
||||
settings={ settings }
|
||||
useSubRegistry={ false }
|
||||
>
|
||||
{ /* eslint-disable-next-line @typescript-eslint/ban-ts-comment */ }
|
||||
{ /* @ts-ignore No types for this exist yet. */ }
|
||||
|
|
|
@ -37,3 +37,7 @@
|
|||
white-space: normal !important;
|
||||
}
|
||||
}
|
||||
|
||||
.components-tooltip {
|
||||
max-width: 300px;
|
||||
}
|
||||
|
|
|
@ -31,31 +31,41 @@ import { HeaderToolbar } from './header-toolbar/header-toolbar';
|
|||
import { ResizableEditor } from './resizable-editor';
|
||||
import { SecondarySidebar } from './secondary-sidebar/secondary-sidebar';
|
||||
import { useEditorHistory } from './hooks/use-editor-history';
|
||||
import { store as productEditorUiStore } from '../../store/product-editor-ui';
|
||||
|
||||
type IframeEditorProps = {
|
||||
closeModal?: () => void;
|
||||
initialBlocks?: BlockInstance[];
|
||||
onChange?: ( blocks: BlockInstance[] ) => void;
|
||||
onClose?: () => void;
|
||||
onInput?: ( blocks: BlockInstance[] ) => void;
|
||||
settings?: Partial< EditorSettings & EditorBlockListSettings > | undefined;
|
||||
showBackButton?: boolean;
|
||||
};
|
||||
|
||||
export function IframeEditor( {
|
||||
closeModal = () => {},
|
||||
initialBlocks = [],
|
||||
onChange = () => {},
|
||||
onClose,
|
||||
onInput = () => {},
|
||||
settings: __settings,
|
||||
showBackButton = false,
|
||||
}: IframeEditorProps ) {
|
||||
const [ resizeObserver ] = useResizeObserver();
|
||||
const [ blocks, setBlocks ] = useState< BlockInstance[] >( initialBlocks );
|
||||
const [ temporalBlocks, setTemporalBlocks ] =
|
||||
useState< BlockInstance[] >( initialBlocks );
|
||||
|
||||
// Pick the blocks from the store.
|
||||
const blocks: BlockInstance[] = useSelect( ( select ) => {
|
||||
return select( productEditorUiStore ).getModalEditorBlocks();
|
||||
}, [] );
|
||||
|
||||
const { setModalEditorBlocks: setBlocks, setModalEditorContentHasChanged } =
|
||||
useDispatch( productEditorUiStore );
|
||||
|
||||
const { appendEdit } = useEditorHistory( {
|
||||
setBlocks,
|
||||
} );
|
||||
|
||||
const {
|
||||
appendEdit: tempAppendEdit,
|
||||
hasRedo,
|
||||
|
@ -127,15 +137,16 @@ export function IframeEditor( {
|
|||
onSave={ () => {
|
||||
appendEdit( temporalBlocks );
|
||||
setBlocks( temporalBlocks );
|
||||
setModalEditorContentHasChanged( true );
|
||||
onChange( temporalBlocks );
|
||||
closeModal();
|
||||
onClose?.();
|
||||
} }
|
||||
onCancel={ () => {
|
||||
appendEdit( blocks );
|
||||
setBlocks( blocks );
|
||||
onChange( blocks );
|
||||
setTemporalBlocks( blocks );
|
||||
closeModal();
|
||||
onClose?.();
|
||||
} }
|
||||
/>
|
||||
<div className="woocommerce-iframe-editor__main">
|
||||
|
@ -157,7 +168,7 @@ export function IframeEditor( {
|
|||
{ /* eslint-disable-next-line @typescript-eslint/ban-ts-comment */ }
|
||||
{ /* @ts-ignore */ }
|
||||
<BlockEditorKeyboardShortcuts.Register />
|
||||
{ onClose && (
|
||||
{ showBackButton && onClose && (
|
||||
<BackButton
|
||||
onClick={ () => {
|
||||
setTimeout( onClose, 550 );
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
*/
|
||||
import { BlockInstance } from '@wordpress/blocks';
|
||||
import { createElement } from '@wordpress/element';
|
||||
import { useDispatch } from '@wordpress/data';
|
||||
import {
|
||||
EditorSettings,
|
||||
EditorBlockListSettings,
|
||||
|
@ -14,11 +15,12 @@ import { useDebounce } from '@wordpress/compose';
|
|||
* Internal dependencies
|
||||
*/
|
||||
import { IframeEditor } from '../iframe-editor';
|
||||
import { store as productEditorUiStore } from '../../store/product-editor-ui';
|
||||
|
||||
type ModalEditorProps = {
|
||||
initialBlocks?: BlockInstance[];
|
||||
onChange: ( blocks: BlockInstance[] ) => void;
|
||||
onClose: () => void;
|
||||
onChange?: ( blocks: BlockInstance[] ) => void;
|
||||
onClose?: () => void;
|
||||
settings?: Partial< EditorSettings & EditorBlockListSettings > | undefined;
|
||||
title: string;
|
||||
};
|
||||
|
@ -29,16 +31,19 @@ export function ModalEditor( {
|
|||
onClose,
|
||||
title,
|
||||
}: ModalEditorProps ) {
|
||||
const { closeModalEditor } = useDispatch( productEditorUiStore );
|
||||
|
||||
const debouncedOnChange = useDebounce( ( blocks: BlockInstance[] ) => {
|
||||
onChange( blocks );
|
||||
onChange?.( blocks );
|
||||
}, 250 );
|
||||
|
||||
function handleClose() {
|
||||
const blocks = debouncedOnChange.flush();
|
||||
if ( blocks ) {
|
||||
onChange( blocks );
|
||||
onChange?.( blocks );
|
||||
}
|
||||
onClose();
|
||||
closeModalEditor();
|
||||
onClose?.();
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -52,7 +57,7 @@ export function ModalEditor( {
|
|||
initialBlocks={ initialBlocks }
|
||||
onInput={ debouncedOnChange }
|
||||
onChange={ debouncedOnChange }
|
||||
closeModal={ handleClose }
|
||||
onClose={ handleClose }
|
||||
/>
|
||||
</Modal>
|
||||
);
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import registerProductEditorUiStore from './store/product-editor-ui';
|
||||
|
||||
export * from './components';
|
||||
export {
|
||||
DETAILS_SECTION_ID,
|
||||
|
@ -16,6 +21,11 @@ export * from './types';
|
|||
*/
|
||||
export * from './utils';
|
||||
|
||||
/*
|
||||
* Store
|
||||
*/
|
||||
export * from './store/product-editor-ui';
|
||||
|
||||
/**
|
||||
* Hooks
|
||||
*/
|
||||
|
@ -23,3 +33,6 @@ export * from './hooks';
|
|||
export { PostTypeContext } from './contexts/post-type-context';
|
||||
export { useValidation, useValidations } from './contexts/validation-context';
|
||||
export * from './contexts/validation-context/types';
|
||||
|
||||
// Init the store
|
||||
registerProductEditorUiStore();
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
# WooCommerce Product Editor UI Store
|
||||
|
||||
This module provides a @wordpress/data store for managing the UI state of a WooCommerce Product Editor.
|
||||
|
||||
## Structure
|
||||
|
||||
Defines action types for the UI state:
|
||||
- `ACTION_MODAL_EDITOR_OPEN`
|
||||
- `ACTION_MODAL_EDITOR_CLOSE`
|
||||
|
||||
### Actions
|
||||
|
||||
- `openModalEditor`
|
||||
- `closeModalEditor`
|
||||
|
||||
### Selectors
|
||||
|
||||
Selector function:
|
||||
|
||||
- `isModalEditorOpen`
|
||||
|
||||
|
||||
### Store
|
||||
|
||||
Registers the WooCommerce Product Editor UI store with the following:
|
||||
|
||||
- Store Name: `woo/product-editor-ui`
|
||||
|
||||
## Usage
|
|
@ -0,0 +1,38 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { BlockInstance } from '@wordpress/blocks';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import {
|
||||
ACTION_MODAL_EDITOR_CLOSE,
|
||||
ACTION_MODAL_EDITOR_OPEN,
|
||||
ACTION_MODAL_EDITOR_SET_BLOCKS,
|
||||
ACTION_MODAL_EDITOR_CONTENT_HAS_CHANGED,
|
||||
} from './constants';
|
||||
|
||||
const modalEditorActions = {
|
||||
openModalEditor: () => ( {
|
||||
type: ACTION_MODAL_EDITOR_OPEN,
|
||||
} ),
|
||||
|
||||
closeModalEditor: () => ( {
|
||||
type: ACTION_MODAL_EDITOR_CLOSE,
|
||||
} ),
|
||||
|
||||
setModalEditorBlocks: ( blocks: BlockInstance ) => ( {
|
||||
type: ACTION_MODAL_EDITOR_SET_BLOCKS,
|
||||
blocks,
|
||||
} ),
|
||||
|
||||
setModalEditorContentHasChanged: ( hasChanged: boolean ) => ( {
|
||||
type: ACTION_MODAL_EDITOR_CONTENT_HAS_CHANGED,
|
||||
hasChanged,
|
||||
} ),
|
||||
};
|
||||
|
||||
export default {
|
||||
...modalEditorActions,
|
||||
};
|
|
@ -0,0 +1,8 @@
|
|||
/**
|
||||
* Full editor actions
|
||||
*/
|
||||
export const ACTION_MODAL_EDITOR_OPEN = 'MODAL_EDITOR_OPEN';
|
||||
export const ACTION_MODAL_EDITOR_CLOSE = 'MODAL_EDITOR_CLOSE';
|
||||
export const ACTION_MODAL_EDITOR_SET_BLOCKS = 'MODAL_EDITOR_SET_BLOCKS';
|
||||
export const ACTION_MODAL_EDITOR_CONTENT_HAS_CHANGED =
|
||||
'MODAL_EDITOR_CONTENT_HAS_CHANGED';
|
|
@ -0,0 +1,26 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { createReduxStore, register } from '@wordpress/data';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import actions from './actions';
|
||||
import selectors from './selectors';
|
||||
import reducer from './reducer';
|
||||
/**
|
||||
* Types
|
||||
*/
|
||||
|
||||
export const store = 'woo/product-editor-ui';
|
||||
|
||||
const wooProductEditorUiStore = createReduxStore( store, {
|
||||
actions,
|
||||
selectors,
|
||||
reducer,
|
||||
} );
|
||||
|
||||
export default function registerProductEditorUiStore() {
|
||||
register( wooProductEditorUiStore );
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import {
|
||||
ACTION_MODAL_EDITOR_CONTENT_HAS_CHANGED,
|
||||
ACTION_MODAL_EDITOR_CLOSE,
|
||||
ACTION_MODAL_EDITOR_OPEN,
|
||||
ACTION_MODAL_EDITOR_SET_BLOCKS,
|
||||
} from './constants';
|
||||
import type {
|
||||
ProductEditorModalEditorAction,
|
||||
ProductEditorUIStateProps,
|
||||
} from './types';
|
||||
|
||||
/**
|
||||
* Types & Constants
|
||||
*/
|
||||
const INITIAL_STATE: ProductEditorUIStateProps = {
|
||||
modalEditor: {
|
||||
isOpen: false,
|
||||
blocks: [],
|
||||
hasChanged: false,
|
||||
},
|
||||
};
|
||||
|
||||
export default function reducer(
|
||||
state = INITIAL_STATE,
|
||||
action: ProductEditorModalEditorAction
|
||||
) {
|
||||
switch ( action.type ) {
|
||||
case ACTION_MODAL_EDITOR_OPEN:
|
||||
return {
|
||||
...state,
|
||||
modalEditor: {
|
||||
...state.modalEditor,
|
||||
isOpen: true,
|
||||
},
|
||||
};
|
||||
|
||||
case ACTION_MODAL_EDITOR_CLOSE:
|
||||
return {
|
||||
...state,
|
||||
modalEditor: {
|
||||
...state.modalEditor,
|
||||
isOpen: false,
|
||||
},
|
||||
};
|
||||
|
||||
case ACTION_MODAL_EDITOR_SET_BLOCKS:
|
||||
return {
|
||||
...state,
|
||||
modalEditor: {
|
||||
...state.modalEditor,
|
||||
blocks: action.blocks || [],
|
||||
},
|
||||
};
|
||||
|
||||
case ACTION_MODAL_EDITOR_CONTENT_HAS_CHANGED:
|
||||
return {
|
||||
...state,
|
||||
modalEditor: {
|
||||
...state.modalEditor,
|
||||
hasChanged: action?.hasChanged || false,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { BlockInstance } from '@wordpress/blocks';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import type { ProductEditorUIStateProps } from './types';
|
||||
|
||||
export default {
|
||||
isModalEditorOpen: function isModalEditorOpen(
|
||||
state: ProductEditorUIStateProps
|
||||
) {
|
||||
return state.modalEditor.isOpen;
|
||||
},
|
||||
|
||||
getModalEditorBlocks: function getModalEditorBlocks(
|
||||
state: ProductEditorUIStateProps
|
||||
): BlockInstance[] {
|
||||
return state.modalEditor.blocks;
|
||||
},
|
||||
|
||||
getModalEditorContentHasChanged: function getModalEditorContentHasChanged(
|
||||
state: ProductEditorUIStateProps
|
||||
): boolean {
|
||||
return !! state.modalEditor.hasChanged;
|
||||
},
|
||||
};
|
|
@ -0,0 +1,34 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { BlockInstance } from '@wordpress/blocks';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import {
|
||||
ACTION_MODAL_EDITOR_CONTENT_HAS_CHANGED,
|
||||
ACTION_MODAL_EDITOR_CLOSE,
|
||||
ACTION_MODAL_EDITOR_OPEN,
|
||||
ACTION_MODAL_EDITOR_SET_BLOCKS,
|
||||
} from './constants';
|
||||
|
||||
export type ProductEditorUIStateProps = {
|
||||
modalEditor: {
|
||||
isOpen: boolean;
|
||||
blocks: BlockInstance[];
|
||||
hasChanged?: boolean;
|
||||
};
|
||||
};
|
||||
|
||||
export type ProductEditorModalEditorAction = {
|
||||
type:
|
||||
| typeof ACTION_MODAL_EDITOR_OPEN
|
||||
| typeof ACTION_MODAL_EDITOR_CLOSE
|
||||
| typeof ACTION_MODAL_EDITOR_SET_BLOCKS
|
||||
| typeof ACTION_MODAL_EDITOR_CONTENT_HAS_CHANGED;
|
||||
|
||||
blocks?: BlockInstance[];
|
||||
|
||||
hasChanged?: boolean;
|
||||
};
|
|
@ -47,11 +47,11 @@
|
|||
"@types/debug": "^4.1.7",
|
||||
"@woocommerce/eslint-plugin": "workspace:*",
|
||||
"eslint": "^8.32.0",
|
||||
"jest": "^27.5.1",
|
||||
"jest-cli": "^27.5.1",
|
||||
"jest": "~27.5.1",
|
||||
"jest-cli": "~27.5.1",
|
||||
"concurrently": "^7.0.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"ts-jest": "^27.1.3",
|
||||
"ts-jest": "~29.1.1",
|
||||
"typescript": "^5.1.6"
|
||||
},
|
||||
"lint-staged": {
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
Significance: patch
|
||||
Type: fix
|
||||
|
||||
Woo AI - Fix z-index issue with Background Removal Spotlight.
|
|
@ -1,3 +1,3 @@
|
|||
body.post-type-product .woocommerce-tour-kit {
|
||||
z-index: 160001; /* value chosen to appear above media library modal */
|
||||
z-index: auto;
|
||||
}
|
||||
|
|
|
@ -247,6 +247,8 @@ function ScaledBlockPreview( {
|
|||
>
|
||||
<CustomIframeComponent
|
||||
aria-hidden
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore disabled prop exists
|
||||
scrolling={ isScrollable ? 'yes' : 'no' }
|
||||
tabIndex={ -1 }
|
||||
readonly={ ! isNavigable }
|
||||
|
|
|
@ -154,6 +154,13 @@ export const AssemblerHub: CustomizeStoreComponent = ( props ) => {
|
|||
useEffect( () => {
|
||||
onBackButtonClicked( () => setShowExitModal( true ) );
|
||||
}, [] );
|
||||
// @ts-expect-error temp fix
|
||||
// Since we load the assember hub in an iframe, we don't have access to
|
||||
// xstate's context values.
|
||||
// This is the best workaround I can think of for now.
|
||||
// Set the aiOnline value from the parent window so that any child components
|
||||
// can access it.
|
||||
props.context.aiOnline = window.parent?.window.cys_aiOnline;
|
||||
|
||||
return (
|
||||
<>
|
||||
|
|
|
@ -2,9 +2,15 @@
|
|||
* External dependencies
|
||||
*/
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { useState } from '@wordpress/element';
|
||||
import { useContext, useState } from '@wordpress/element';
|
||||
import { TourKit, TourKitTypes } from '@woocommerce/components';
|
||||
import { recordEvent } from '@woocommerce/tracks';
|
||||
import { Button, Modal } from '@wordpress/components';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { CustomizeStoreContext } from '..';
|
||||
export * from './use-onboarding-tour';
|
||||
|
||||
type OnboardingTourProps = {
|
||||
|
@ -23,7 +29,47 @@ export const OnboardingTour = ( {
|
|||
const [ placement, setPlacement ] =
|
||||
useState< TourKitTypes.WooConfig[ 'placement' ] >( 'left' );
|
||||
|
||||
const { context } = useContext( CustomizeStoreContext );
|
||||
const aiOnline = context.aiOnline;
|
||||
|
||||
if ( showWelcomeTour ) {
|
||||
const takeTour = () => {
|
||||
// Click on "Take a tour" button
|
||||
recordEvent( 'customize_your_store_assembler_hub_tour_start' );
|
||||
setShowWelcomeTour( false );
|
||||
};
|
||||
|
||||
const skipTour = () => {
|
||||
recordEvent( 'customize_your_store_assembler_hub_tour_skip' );
|
||||
onClose();
|
||||
};
|
||||
|
||||
if ( ! aiOnline ) {
|
||||
return (
|
||||
<Modal
|
||||
className="woocommerce-customize-store__onboarding-welcome-modal"
|
||||
title={ __( 'Welcome to your store!', 'woocommerce' ) }
|
||||
onRequestClose={ skipTour }
|
||||
shouldCloseOnClickOutside={ false }
|
||||
>
|
||||
<p>
|
||||
{ __(
|
||||
"We encountered some issues while generating content with AI. But don't worry — you can still customize the look and feel of your store, including adding your logo, and changing colors and layouts. Take a quick tour to discover what's possible.",
|
||||
'woocommerce'
|
||||
) }
|
||||
</p>
|
||||
<div className="woocommerce-customize-store__design-change-warning-modal-footer">
|
||||
<Button onClick={ skipTour } variant="link">
|
||||
{ __( 'Skip', 'woocommerce' ) }
|
||||
</Button>
|
||||
<Button onClick={ takeTour } variant="primary">
|
||||
{ __( 'Take a tour', 'woocommerce' ) }
|
||||
</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<TourKit
|
||||
config={ {
|
||||
|
@ -87,15 +133,9 @@ export const OnboardingTour = ( {
|
|||
closeHandler: ( _steps, _currentStepIndex, source ) => {
|
||||
if ( source === 'done-btn' ) {
|
||||
// Click on "Take a tour" button
|
||||
recordEvent(
|
||||
'customize_your_store_assembler_hub_tour_start'
|
||||
);
|
||||
setShowWelcomeTour( false );
|
||||
takeTour();
|
||||
} else {
|
||||
recordEvent(
|
||||
'customize_your_store_assembler_hub_tour_skip'
|
||||
);
|
||||
onClose();
|
||||
skipTour();
|
||||
}
|
||||
},
|
||||
} }
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { createContext } from '@wordpress/element';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { recordEvent } from '@woocommerce/tracks';
|
||||
|
||||
|
@ -10,6 +11,13 @@ import { recordEvent } from '@woocommerce/tracks';
|
|||
import { OnboardingTour } from '../index';
|
||||
|
||||
jest.mock( '@woocommerce/tracks', () => ( { recordEvent: jest.fn() } ) );
|
||||
jest.mock( '../../', () => ( {
|
||||
CustomizeStoreContext: createContext( {
|
||||
context: {
|
||||
aiOnline: true,
|
||||
},
|
||||
} ),
|
||||
} ) );
|
||||
|
||||
describe( 'OnboardingTour', () => {
|
||||
let props: {
|
||||
|
|
|
@ -11,7 +11,7 @@ export const SYSTEM_FONT_SLUG = 'system-font';
|
|||
|
||||
// Generated from /wpcom/v2/sites/{site_id}/global-styles-variation/font-pairings
|
||||
// TODO: Consider creating an API endpoint for this data
|
||||
export const FONT_PAIRINGS = [
|
||||
export const FONT_PAIRINGS_WHEN_AI_IS_OFFLINE = [
|
||||
{
|
||||
title: 'Inter + Inter',
|
||||
version: 2,
|
||||
|
@ -69,45 +69,6 @@ export const FONT_PAIRINGS = [
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Albert Sans + Lora',
|
||||
version: 2,
|
||||
lookAndFeel: [ 'Contemporary', 'Bold' ] as Look[],
|
||||
settings: {
|
||||
typography: {
|
||||
fontFamilies: {
|
||||
theme: [
|
||||
{
|
||||
fontFamily: 'Albert Sans',
|
||||
slug: 'albert-sans',
|
||||
},
|
||||
{
|
||||
fontFamily: 'Lora',
|
||||
slug: 'lora',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
styles: {
|
||||
elements: {
|
||||
heading: {
|
||||
typography: {
|
||||
fontFamily:
|
||||
'var(--wp--preset--font-family--albert-sans)',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '700',
|
||||
},
|
||||
},
|
||||
},
|
||||
typography: {
|
||||
fontFamily: 'var(--wp--preset--font-family--lora)',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '400',
|
||||
lineHeight: '1.67',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Bodoni Moda + Overpass',
|
||||
version: 2,
|
||||
|
@ -169,6 +130,277 @@ export const FONT_PAIRINGS = [
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Albert Sans + Lora',
|
||||
version: 2,
|
||||
lookAndFeel: [ 'Contemporary', 'Bold' ] as Look[],
|
||||
settings: {
|
||||
typography: {
|
||||
fontFamilies: {
|
||||
theme: [
|
||||
{
|
||||
fontFamily: 'Albert Sans',
|
||||
slug: 'albert-sans',
|
||||
},
|
||||
{
|
||||
fontFamily: 'Lora',
|
||||
slug: 'lora',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
styles: {
|
||||
elements: {
|
||||
heading: {
|
||||
typography: {
|
||||
fontFamily:
|
||||
'var(--wp--preset--font-family--albert-sans)',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '700',
|
||||
},
|
||||
},
|
||||
},
|
||||
typography: {
|
||||
fontFamily: 'var(--wp--preset--font-family--lora)',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '400',
|
||||
lineHeight: '1.67',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Montserrat + Arvo',
|
||||
version: 2,
|
||||
lookAndFeel: [ 'Contemporary', 'Bold' ] as Look[],
|
||||
settings: {
|
||||
typography: {
|
||||
fontFamilies: {
|
||||
theme: [
|
||||
{
|
||||
fontFamily: 'Montserrat',
|
||||
slug: 'montserrat',
|
||||
},
|
||||
{
|
||||
fontFamily: 'Arvo',
|
||||
slug: 'arvo',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
styles: {
|
||||
elements: {
|
||||
button: {
|
||||
typography: {
|
||||
fontFamily:
|
||||
'var(--wp--preset--font-family--montserrat)',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '500',
|
||||
},
|
||||
},
|
||||
heading: {
|
||||
typography: {
|
||||
fontFamily:
|
||||
'var(--wp--preset--font-family--montserrat)',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '700',
|
||||
lineHeight: '1.4',
|
||||
},
|
||||
},
|
||||
},
|
||||
blocks: {
|
||||
'core/site-title': {
|
||||
typography: {
|
||||
fontFamily:
|
||||
'var(--wp--preset--font-family--montserrat)',
|
||||
fontWeight: '700',
|
||||
},
|
||||
},
|
||||
'core/post-navigation-link': {
|
||||
typography: {
|
||||
fontFamily:
|
||||
'var(--wp--preset--font-family--montserrat)',
|
||||
},
|
||||
},
|
||||
},
|
||||
typography: {
|
||||
fontFamily: 'var(--wp--preset--font-family--arvo)',
|
||||
fontSize: 'var(--wp--preset--font-size--small)',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '400',
|
||||
lineHeight: '1.6',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Rubik + Inter',
|
||||
version: 2,
|
||||
lookAndFeel: [ 'Bold' ] as Look[],
|
||||
settings: {
|
||||
typography: {
|
||||
fontFamilies: {
|
||||
theme: [
|
||||
{
|
||||
fontFamily: 'Rubik',
|
||||
slug: 'rubik',
|
||||
},
|
||||
{
|
||||
fontFamily: 'Inter',
|
||||
slug: 'inter',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
styles: {
|
||||
elements: {
|
||||
button: {
|
||||
typography: {
|
||||
fontFamily: 'var(--wp--preset--font-family--inter)',
|
||||
fontWeight: '400',
|
||||
lineHeight: '1',
|
||||
},
|
||||
},
|
||||
heading: {
|
||||
typography: {
|
||||
fontFamily: 'var(--wp--preset--font-family--rubik)',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '800',
|
||||
},
|
||||
},
|
||||
},
|
||||
blocks: {
|
||||
'core/site-title': {
|
||||
typography: {
|
||||
fontFamily: 'var(--wp--preset--font-family--rubik)',
|
||||
fontWeight: '800',
|
||||
},
|
||||
},
|
||||
'core/post-navigation-link': {
|
||||
typography: {
|
||||
fontFamily: 'var(--wp--preset--font-family--rubik)',
|
||||
},
|
||||
},
|
||||
},
|
||||
typography: {
|
||||
fontFamily: 'var(--wp--preset--font-family--inter)',
|
||||
fontSize: 'var(--wp--preset--font-size--medium)',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '400',
|
||||
lineHeight: '1.6',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Newsreader + Newsreader',
|
||||
version: 2,
|
||||
lookAndFeel: [ 'Classic' ] as Look[],
|
||||
settings: {
|
||||
typography: {
|
||||
fontFamilies: {
|
||||
theme: [
|
||||
{
|
||||
fontFamily: 'Newsreader',
|
||||
slug: 'newsreader',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
styles: {
|
||||
elements: {
|
||||
heading: {
|
||||
typography: {
|
||||
fontFamily:
|
||||
'var(--wp--preset--font-family--newsreader)',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '400',
|
||||
},
|
||||
},
|
||||
},
|
||||
typography: {
|
||||
fontFamily: 'var(--wp--preset--font-family--newsreader)',
|
||||
fontSize: 'var(--wp--preset--font-size--medium)',
|
||||
lineHeight: '1.67',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Cormorant + Work Sans',
|
||||
version: 2,
|
||||
lookAndFeel: [] as Look[],
|
||||
settings: {
|
||||
typography: {
|
||||
fontFamilies: {
|
||||
theme: [
|
||||
{
|
||||
fontFamily: 'Cormorant',
|
||||
slug: 'cormorant',
|
||||
},
|
||||
{
|
||||
fontFamily: 'Work Sans',
|
||||
slug: 'work-sans',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
styles: {
|
||||
elements: {
|
||||
heading: {
|
||||
typography: {
|
||||
fontFamily: 'var(--wp--preset--font-family--cormorant)',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '500',
|
||||
},
|
||||
},
|
||||
},
|
||||
typography: {
|
||||
fontFamily: 'var(--wp--preset--font-family--work-sans)',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Raleway + Cormorant',
|
||||
version: 2,
|
||||
lookAndFeel: [ 'Classic', 'Bold' ] as Look[],
|
||||
settings: {
|
||||
typography: {
|
||||
fontFamilies: {
|
||||
theme: [
|
||||
{
|
||||
fontFamily: 'Raleway',
|
||||
slug: 'raleway',
|
||||
},
|
||||
{
|
||||
fontFamily: 'Cormorant',
|
||||
slug: 'cormorant',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
styles: {
|
||||
elements: {
|
||||
heading: {
|
||||
typography: {
|
||||
fontFamily: 'var(--wp--preset--font-family--raleway)',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '700',
|
||||
},
|
||||
},
|
||||
},
|
||||
typography: {
|
||||
fontFamily: 'var(--wp--preset--font-family--cormorant)',
|
||||
fontSize: 'var(--wp--preset--font-size--medium)',
|
||||
lineHeight: '1.67',
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
export const FONT_PAIRINGS = [
|
||||
{
|
||||
title: 'Commissioner + Crimson Pro',
|
||||
version: 2,
|
||||
|
@ -232,41 +464,6 @@ export const FONT_PAIRINGS = [
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Cormorant + Work Sans',
|
||||
version: 2,
|
||||
lookAndFeel: [] as Look[],
|
||||
settings: {
|
||||
typography: {
|
||||
fontFamilies: {
|
||||
theme: [
|
||||
{
|
||||
fontFamily: 'Cormorant',
|
||||
slug: 'cormorant',
|
||||
},
|
||||
{
|
||||
fontFamily: 'Work Sans',
|
||||
slug: 'work-sans',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
styles: {
|
||||
elements: {
|
||||
heading: {
|
||||
typography: {
|
||||
fontFamily: 'var(--wp--preset--font-family--cormorant)',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '500',
|
||||
},
|
||||
},
|
||||
},
|
||||
typography: {
|
||||
fontFamily: 'var(--wp--preset--font-family--work-sans)',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'DM Sans + IBM Plex Mono',
|
||||
version: 2,
|
||||
|
@ -403,168 +600,6 @@ export const FONT_PAIRINGS = [
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Libre Franklin + EB Garamond',
|
||||
version: 2,
|
||||
lookAndFeel: [ 'Classic' ] as Look[],
|
||||
settings: {
|
||||
typography: {
|
||||
fontFamilies: {
|
||||
theme: [
|
||||
{
|
||||
fontFamily: 'Libre Franklin',
|
||||
slug: 'libre-franklin',
|
||||
},
|
||||
{
|
||||
fontFamily: 'EB Garamond',
|
||||
slug: 'eb-garamond',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
styles: {
|
||||
elements: {
|
||||
button: {
|
||||
typography: {
|
||||
fontFamily:
|
||||
'var(--wp--preset--font-family--libre-franklin)',
|
||||
fontSize: 'var(--wp--preset--font-size--small)',
|
||||
fontWeight: '400',
|
||||
lineHeight: '1',
|
||||
},
|
||||
},
|
||||
heading: {
|
||||
typography: {
|
||||
fontFamily:
|
||||
'var(--wp--preset--font-family--libre-franklin)',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '700',
|
||||
},
|
||||
},
|
||||
},
|
||||
blocks: {
|
||||
'core/site-title': {
|
||||
typography: {
|
||||
fontFamily:
|
||||
'var(--wp--preset--font-family--libre-franklin)',
|
||||
fontWeight: '500',
|
||||
},
|
||||
},
|
||||
'core/post-navigation-link': {
|
||||
typography: {
|
||||
fontFamily:
|
||||
'var(--wp--preset--font-family--libre-franklin)',
|
||||
},
|
||||
},
|
||||
},
|
||||
typography: {
|
||||
fontFamily: 'var(--wp--preset--font-family--eb-garamond)',
|
||||
fontSize: 'var(--wp--preset--font-size--medium)',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '400',
|
||||
lineHeight: '1.6',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Montserrat + Arvo',
|
||||
version: 2,
|
||||
lookAndFeel: [ 'Contemporary', 'Bold' ] as Look[],
|
||||
settings: {
|
||||
typography: {
|
||||
fontFamilies: {
|
||||
theme: [
|
||||
{
|
||||
fontFamily: 'Montserrat',
|
||||
slug: 'montserrat',
|
||||
},
|
||||
{
|
||||
fontFamily: 'Arvo',
|
||||
slug: 'arvo',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
styles: {
|
||||
elements: {
|
||||
button: {
|
||||
typography: {
|
||||
fontFamily:
|
||||
'var(--wp--preset--font-family--montserrat)',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '500',
|
||||
},
|
||||
},
|
||||
heading: {
|
||||
typography: {
|
||||
fontFamily:
|
||||
'var(--wp--preset--font-family--montserrat)',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '700',
|
||||
lineHeight: '1.4',
|
||||
},
|
||||
},
|
||||
},
|
||||
blocks: {
|
||||
'core/site-title': {
|
||||
typography: {
|
||||
fontFamily:
|
||||
'var(--wp--preset--font-family--montserrat)',
|
||||
fontWeight: '700',
|
||||
},
|
||||
},
|
||||
'core/post-navigation-link': {
|
||||
typography: {
|
||||
fontFamily:
|
||||
'var(--wp--preset--font-family--montserrat)',
|
||||
},
|
||||
},
|
||||
},
|
||||
typography: {
|
||||
fontFamily: 'var(--wp--preset--font-family--arvo)',
|
||||
fontSize: 'var(--wp--preset--font-size--small)',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '400',
|
||||
lineHeight: '1.6',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Newsreader + Newsreader',
|
||||
version: 2,
|
||||
lookAndFeel: [ 'Classic' ] as Look[],
|
||||
settings: {
|
||||
typography: {
|
||||
fontFamilies: {
|
||||
theme: [
|
||||
{
|
||||
fontFamily: 'Newsreader',
|
||||
slug: 'newsreader',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
styles: {
|
||||
elements: {
|
||||
heading: {
|
||||
typography: {
|
||||
fontFamily:
|
||||
'var(--wp--preset--font-family--newsreader)',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '400',
|
||||
},
|
||||
},
|
||||
},
|
||||
typography: {
|
||||
fontFamily: 'var(--wp--preset--font-family--newsreader)',
|
||||
fontSize: 'var(--wp--preset--font-size--medium)',
|
||||
lineHeight: '1.67',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Playfair Display + Fira Sans',
|
||||
version: 2,
|
||||
|
@ -630,6 +665,70 @@ export const FONT_PAIRINGS = [
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Libre Franklin + EB Garamond',
|
||||
version: 2,
|
||||
lookAndFeel: [ 'Classic' ] as Look[],
|
||||
settings: {
|
||||
typography: {
|
||||
fontFamilies: {
|
||||
theme: [
|
||||
{
|
||||
fontFamily: 'Libre Franklin',
|
||||
slug: 'libre-franklin',
|
||||
},
|
||||
{
|
||||
fontFamily: 'EB Garamond',
|
||||
slug: 'eb-garamond',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
styles: {
|
||||
elements: {
|
||||
button: {
|
||||
typography: {
|
||||
fontFamily:
|
||||
'var(--wp--preset--font-family--libre-franklin)',
|
||||
fontSize: 'var(--wp--preset--font-size--small)',
|
||||
fontWeight: '400',
|
||||
lineHeight: '1',
|
||||
},
|
||||
},
|
||||
heading: {
|
||||
typography: {
|
||||
fontFamily:
|
||||
'var(--wp--preset--font-family--libre-franklin)',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '700',
|
||||
},
|
||||
},
|
||||
},
|
||||
blocks: {
|
||||
'core/site-title': {
|
||||
typography: {
|
||||
fontFamily:
|
||||
'var(--wp--preset--font-family--libre-franklin)',
|
||||
fontWeight: '500',
|
||||
},
|
||||
},
|
||||
'core/post-navigation-link': {
|
||||
typography: {
|
||||
fontFamily:
|
||||
'var(--wp--preset--font-family--libre-franklin)',
|
||||
},
|
||||
},
|
||||
},
|
||||
typography: {
|
||||
fontFamily: 'var(--wp--preset--font-family--eb-garamond)',
|
||||
fontSize: 'var(--wp--preset--font-size--medium)',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '400',
|
||||
lineHeight: '1.6',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Plus Jakarta Sans + Plus Jakarta Sans',
|
||||
version: 2,
|
||||
|
@ -663,102 +762,6 @@ export const FONT_PAIRINGS = [
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Raleway + Cormorant',
|
||||
version: 2,
|
||||
lookAndFeel: [ 'Classic', 'Bold' ] as Look[],
|
||||
settings: {
|
||||
typography: {
|
||||
fontFamilies: {
|
||||
theme: [
|
||||
{
|
||||
fontFamily: 'Raleway',
|
||||
slug: 'raleway',
|
||||
},
|
||||
{
|
||||
fontFamily: 'Cormorant',
|
||||
slug: 'cormorant',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
styles: {
|
||||
elements: {
|
||||
heading: {
|
||||
typography: {
|
||||
fontFamily: 'var(--wp--preset--font-family--raleway)',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '700',
|
||||
},
|
||||
},
|
||||
},
|
||||
typography: {
|
||||
fontFamily: 'var(--wp--preset--font-family--cormorant)',
|
||||
fontSize: 'var(--wp--preset--font-size--medium)',
|
||||
lineHeight: '1.67',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Rubik + Inter',
|
||||
version: 2,
|
||||
lookAndFeel: [ 'Bold' ] as Look[],
|
||||
settings: {
|
||||
typography: {
|
||||
fontFamilies: {
|
||||
theme: [
|
||||
{
|
||||
fontFamily: 'Rubik',
|
||||
slug: 'rubik',
|
||||
},
|
||||
{
|
||||
fontFamily: 'Inter',
|
||||
slug: 'inter',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
styles: {
|
||||
elements: {
|
||||
button: {
|
||||
typography: {
|
||||
fontFamily: 'var(--wp--preset--font-family--inter)',
|
||||
fontWeight: '400',
|
||||
lineHeight: '1',
|
||||
},
|
||||
},
|
||||
heading: {
|
||||
typography: {
|
||||
fontFamily: 'var(--wp--preset--font-family--rubik)',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '800',
|
||||
},
|
||||
},
|
||||
},
|
||||
blocks: {
|
||||
'core/site-title': {
|
||||
typography: {
|
||||
fontFamily: 'var(--wp--preset--font-family--rubik)',
|
||||
fontWeight: '800',
|
||||
},
|
||||
},
|
||||
'core/post-navigation-link': {
|
||||
typography: {
|
||||
fontFamily: 'var(--wp--preset--font-family--rubik)',
|
||||
},
|
||||
},
|
||||
},
|
||||
typography: {
|
||||
fontFamily: 'var(--wp--preset--font-family--inter)',
|
||||
fontSize: 'var(--wp--preset--font-size--medium)',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '400',
|
||||
lineHeight: '1.6',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Rubik + Rubik',
|
||||
version: 2,
|
||||
|
@ -854,4 +857,5 @@ export const FONT_PAIRINGS = [
|
|||
},
|
||||
},
|
||||
},
|
||||
...FONT_PAIRINGS_WHEN_AI_IS_OFFLINE,
|
||||
];
|
||||
|
|
|
@ -7,15 +7,16 @@
|
|||
import { __experimentalGrid as Grid, Spinner } from '@wordpress/components';
|
||||
import { OPTIONS_STORE_NAME } from '@woocommerce/data';
|
||||
import { useSelect } from '@wordpress/data';
|
||||
import { useMemo } from '@wordpress/element';
|
||||
import { useContext, useMemo } from '@wordpress/element';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { FONT_PAIRINGS } from './constants';
|
||||
import { FONT_PAIRINGS, FONT_PAIRINGS_WHEN_AI_IS_OFFLINE } from './constants';
|
||||
import { VariationContainer } from '../variation-container';
|
||||
import { FontPairingVariationPreview } from './preview';
|
||||
import { Look } from '~/customize-store/design-with-ai/types';
|
||||
import { CustomizeStoreContext } from '~/customize-store/assembler-hub';
|
||||
|
||||
export const FontPairing = () => {
|
||||
const { aiSuggestions, isLoading } = useSelect( ( select ) => {
|
||||
|
@ -31,14 +32,17 @@ export const FontPairing = () => {
|
|||
};
|
||||
} );
|
||||
|
||||
const { context } = useContext( CustomizeStoreContext );
|
||||
const aiOnline = context.aiOnline;
|
||||
|
||||
const fontPairings = useMemo(
|
||||
() =>
|
||||
aiSuggestions?.lookAndFeel
|
||||
aiOnline && aiSuggestions?.lookAndFeel
|
||||
? FONT_PAIRINGS.filter( ( font ) =>
|
||||
font.lookAndFeel.includes( aiSuggestions?.lookAndFeel )
|
||||
)
|
||||
: FONT_PAIRINGS,
|
||||
[ aiSuggestions ]
|
||||
: FONT_PAIRINGS_WHEN_AI_IS_OFFLINE,
|
||||
[ aiOnline, aiSuggestions?.lookAndFeel ]
|
||||
);
|
||||
|
||||
if ( isLoading ) {
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* External dependencies
|
||||
*/
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { createInterpolateElement } from '@wordpress/element';
|
||||
import { createInterpolateElement, useContext } from '@wordpress/element';
|
||||
import { Link } from '@woocommerce/components';
|
||||
import { recordEvent } from '@woocommerce/tracks';
|
||||
|
||||
|
@ -14,55 +14,63 @@ import { recordEvent } from '@woocommerce/tracks';
|
|||
import { SidebarNavigationScreen } from './sidebar-navigation-screen';
|
||||
import { ADMIN_URL } from '~/utils/admin-settings';
|
||||
import { FontPairing } from './global-styles';
|
||||
import { CustomizeStoreContext } from '..';
|
||||
|
||||
export const SidebarNavigationScreenTypography = () => {
|
||||
const { context } = useContext( CustomizeStoreContext );
|
||||
const aiOnline = context.aiOnline;
|
||||
|
||||
const label = aiOnline
|
||||
? __(
|
||||
"AI has selected a font pairing that's the best fit for your business. If you'd like to change them, select a new option below now, or later in <EditorLink>Editor</EditorLink> | <StyleLink>Styles</StyleLink>.",
|
||||
'woocommerce'
|
||||
)
|
||||
: __(
|
||||
'Select the pair of fonts that best suits your brand. The larger font will be used for headings, and the smaller for supporting content. You can change your font at any time in <EditorLink>Editor</EditorLink> | <StyleLink>Styles</StyleLink>.',
|
||||
'woocommerce'
|
||||
);
|
||||
|
||||
return (
|
||||
<SidebarNavigationScreen
|
||||
title={ __( 'Change your font', 'woocommerce' ) }
|
||||
description={ createInterpolateElement(
|
||||
__(
|
||||
"AI has selected a font pairing that's the best fit for your business. If you'd like to change them, select a new option below now, or later in <EditorLink>Editor</EditorLink> | <StyleLink>Styles</StyleLink>.",
|
||||
'woocommerce'
|
||||
description={ createInterpolateElement( label, {
|
||||
EditorLink: (
|
||||
<Link
|
||||
onClick={ () => {
|
||||
recordEvent(
|
||||
'customize_your_store_assembler_hub_editor_link_click',
|
||||
{
|
||||
source: 'typography',
|
||||
}
|
||||
);
|
||||
window.open(
|
||||
`${ ADMIN_URL }site-editor.php`,
|
||||
'_blank'
|
||||
);
|
||||
return false;
|
||||
} }
|
||||
href=""
|
||||
/>
|
||||
),
|
||||
{
|
||||
EditorLink: (
|
||||
<Link
|
||||
onClick={ () => {
|
||||
recordEvent(
|
||||
'customize_your_store_assembler_hub_editor_link_click',
|
||||
{
|
||||
source: 'typography',
|
||||
}
|
||||
);
|
||||
window.open(
|
||||
`${ ADMIN_URL }site-editor.php`,
|
||||
'_blank'
|
||||
);
|
||||
return false;
|
||||
} }
|
||||
href=""
|
||||
/>
|
||||
),
|
||||
StyleLink: (
|
||||
<Link
|
||||
onClick={ () => {
|
||||
recordEvent(
|
||||
'customize_your_store_assembler_hub_style_link_click',
|
||||
{
|
||||
source: 'typography',
|
||||
}
|
||||
);
|
||||
window.open(
|
||||
`${ ADMIN_URL }site-editor.php?path=%2Fwp_global_styles&canvas=edit`,
|
||||
'_blank'
|
||||
);
|
||||
return false;
|
||||
} }
|
||||
href=""
|
||||
/>
|
||||
),
|
||||
}
|
||||
) }
|
||||
StyleLink: (
|
||||
<Link
|
||||
onClick={ () => {
|
||||
recordEvent(
|
||||
'customize_your_store_assembler_hub_style_link_click',
|
||||
{
|
||||
source: 'typography',
|
||||
}
|
||||
);
|
||||
window.open(
|
||||
`${ ADMIN_URL }site-editor.php?path=%2Fwp_global_styles`,
|
||||
'_blank'
|
||||
);
|
||||
return false;
|
||||
} }
|
||||
href=""
|
||||
/>
|
||||
),
|
||||
} ) }
|
||||
content={
|
||||
<div className="woocommerce-customize-store_sidebar-typography-content">
|
||||
<FontPairing />
|
||||
|
|
|
@ -664,6 +664,21 @@
|
|||
box-shadow: none;
|
||||
}
|
||||
|
||||
&.ai-offline {
|
||||
.woocommerce-tour-kit-step {
|
||||
width: 430px;
|
||||
.components-card__header {
|
||||
background-image: none;
|
||||
height: auto;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.tour-kit-frame__container {
|
||||
bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.woocommerce-tour-kit-step {
|
||||
width: 335px;
|
||||
border-radius: 8px;
|
||||
|
|
|
@ -8,7 +8,10 @@ import { AnyInterpreter, Sender } from 'xstate';
|
|||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { CustomizeStoreComponent } from '../types';
|
||||
import {
|
||||
CustomizeStoreComponent,
|
||||
customizeStoreStateMachineContext,
|
||||
} from '../types';
|
||||
import { designWithAiStateMachineDefinition } from './state-machine';
|
||||
import { findComponentMeta } from '~/utils/xstate/find-component';
|
||||
import {
|
||||
|
@ -33,10 +36,15 @@ export type DesignWithAiComponentMeta = {
|
|||
|
||||
export const DesignWithAiController = ( {
|
||||
parentMachine,
|
||||
parentContext,
|
||||
}: {
|
||||
parentMachine?: AnyInterpreter;
|
||||
sendEventToParent?: Sender< customizeStoreStateMachineEvents >;
|
||||
parentContext?: customizeStoreStateMachineContext;
|
||||
} ) => {
|
||||
// Assign aiOnline value from the parent context if it exists. Otherwise, ai is online by default.
|
||||
designWithAiStateMachineDefinition.context.aiOnline =
|
||||
parentContext?.aiOnline ?? true;
|
||||
const [ state, send, service ] = useMachine(
|
||||
designWithAiStateMachineDefinition,
|
||||
{
|
||||
|
@ -84,10 +92,16 @@ export const DesignWithAiController = ( {
|
|||
};
|
||||
|
||||
//loader should send event 'THEME_SUGGESTED' when it's done
|
||||
export const DesignWithAi: CustomizeStoreComponent = ( { parentMachine } ) => {
|
||||
export const DesignWithAi: CustomizeStoreComponent = ( {
|
||||
parentMachine,
|
||||
context,
|
||||
} ) => {
|
||||
return (
|
||||
<>
|
||||
<DesignWithAiController parentMachine={ parentMachine } />
|
||||
<DesignWithAiController
|
||||
parentMachine={ parentMachine }
|
||||
parentContext={ context }
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -99,7 +99,10 @@ const loaderSteps = [
|
|||
];
|
||||
|
||||
// Make the loader last longer and provide a smoother progress by duplicating the steps.
|
||||
const createAugmentedSteps = ( steps: typeof loaderSteps ) => {
|
||||
const createAugmentedSteps = (
|
||||
steps: typeof loaderSteps,
|
||||
numOfDupes: number
|
||||
) => {
|
||||
// Duplicate each step, so we can animate each one
|
||||
// (e.g. each step will be duplicated 3 times, and each duplicate will
|
||||
// have different progress)
|
||||
|
@ -112,8 +115,7 @@ const createAugmentedSteps = ( steps: typeof loaderSteps ) => {
|
|||
if ( ! nextItem ) return [ item ];
|
||||
|
||||
// If there is a next item, we're not at the end of the array
|
||||
// so return the current item, plus two duplicates
|
||||
const numOfDupes = 2;
|
||||
// so return the current item, plus duplicates
|
||||
const duplicates = [ item ];
|
||||
const progressIncreaseBy =
|
||||
( nextItem.progress - item.progress ) / numOfDupes;
|
||||
|
@ -149,7 +151,10 @@ export const ApiCallLoader = () => {
|
|||
preload( openingTheDoors );
|
||||
}, [] );
|
||||
|
||||
const augmentedSteps = createAugmentedSteps( loaderSteps.slice( 0, -1 ) );
|
||||
const augmentedSteps = createAugmentedSteps(
|
||||
loaderSteps.slice( 0, -1 ),
|
||||
10
|
||||
);
|
||||
|
||||
return (
|
||||
<Loader>
|
||||
|
@ -182,7 +187,7 @@ export const ApiCallLoader = () => {
|
|||
|
||||
export const AssembleHubLoader = () => {
|
||||
// Show the last two steps of the loader so that the last frame is the shortest time possible
|
||||
const augmentedSteps = createAugmentedSteps( loaderSteps.slice( -2 ) );
|
||||
const augmentedSteps = createAugmentedSteps( loaderSteps.slice( -2 ), 10 );
|
||||
|
||||
const [ progress, setProgress ] = useState( augmentedSteps[ 0 ].progress );
|
||||
|
||||
|
|
|
@ -205,7 +205,7 @@ export const updateStorePatterns = async (
|
|||
try {
|
||||
// TODO: Probably move this to a more appropriate place with a check. We should set this when the user granted permissions during the onboarding phase.
|
||||
await dispatch( OPTIONS_STORE_NAME ).updateOptions( {
|
||||
woocommerce_blocks_allow_ai_connection: true,
|
||||
woocommerce_blocks_allow_ai_connection: 'yes',
|
||||
} );
|
||||
|
||||
const { images } = await apiFetch< {
|
||||
|
@ -440,7 +440,7 @@ export const assembleSite = async (
|
|||
};
|
||||
|
||||
const installAndActivateTheme = async () => {
|
||||
const themeSlug = 'twentytwentythree';
|
||||
const themeSlug = 'twentytwentyfour';
|
||||
|
||||
try {
|
||||
await apiFetch( {
|
||||
|
@ -473,6 +473,23 @@ const saveAiResponseToOption = ( context: designWithAiStateMachineContext ) => {
|
|||
} );
|
||||
};
|
||||
|
||||
const resetPatternsAndProducts = () => async () => {
|
||||
await dispatch( OPTIONS_STORE_NAME ).updateOptions( {
|
||||
woocommerce_blocks_allow_ai_connection: 'yes',
|
||||
} );
|
||||
|
||||
return Promise.all( [
|
||||
apiFetch( {
|
||||
path: '/wc/private/ai/patterns',
|
||||
method: 'DELETE',
|
||||
} ),
|
||||
apiFetch( {
|
||||
path: '/wc/private/ai/products',
|
||||
method: 'DELETE',
|
||||
} ),
|
||||
] );
|
||||
};
|
||||
|
||||
export const services = {
|
||||
browserPopstateHandler,
|
||||
queryAiEndpoint,
|
||||
|
@ -480,4 +497,5 @@ export const services = {
|
|||
updateStorePatterns,
|
||||
saveAiResponseToOption,
|
||||
installAndActivateTheme,
|
||||
resetPatternsAndProducts,
|
||||
};
|
||||
|
|
|
@ -38,6 +38,10 @@ export const hasStepInUrl = (
|
|||
);
|
||||
};
|
||||
|
||||
export const isAiOnline = ( _ctx: designWithAiStateMachineContext ) => {
|
||||
return _ctx.aiOnline;
|
||||
};
|
||||
|
||||
export const designWithAiStateMachineDefinition = createMachine(
|
||||
{
|
||||
id: 'designWithAi',
|
||||
|
@ -84,6 +88,7 @@ export const designWithAiStateMachineDefinition = createMachine(
|
|||
apiCallLoader: {
|
||||
hasErrors: false,
|
||||
},
|
||||
aiOnline: true,
|
||||
},
|
||||
initial: 'navigate',
|
||||
states: {
|
||||
|
@ -272,8 +277,19 @@ export const designWithAiStateMachineDefinition = createMachine(
|
|||
type: 'parallel',
|
||||
states: {
|
||||
chooseColorPairing: {
|
||||
initial: 'pending',
|
||||
initial: 'executeOrSkip',
|
||||
states: {
|
||||
executeOrSkip: {
|
||||
always: [
|
||||
{
|
||||
target: 'pending',
|
||||
cond: 'isAiOnline',
|
||||
},
|
||||
{
|
||||
target: 'success',
|
||||
},
|
||||
],
|
||||
},
|
||||
pending: {
|
||||
invoke: {
|
||||
src: 'queryAiEndpoint',
|
||||
|
@ -307,8 +323,19 @@ export const designWithAiStateMachineDefinition = createMachine(
|
|||
},
|
||||
},
|
||||
chooseFontPairing: {
|
||||
initial: 'pending',
|
||||
initial: 'executeOrSkip',
|
||||
states: {
|
||||
executeOrSkip: {
|
||||
always: [
|
||||
{
|
||||
target: 'pending',
|
||||
cond: 'isAiOnline',
|
||||
},
|
||||
{
|
||||
target: 'success',
|
||||
},
|
||||
],
|
||||
},
|
||||
pending: {
|
||||
entry: [ 'assignFontPairing' ],
|
||||
always: {
|
||||
|
@ -319,8 +346,19 @@ export const designWithAiStateMachineDefinition = createMachine(
|
|||
},
|
||||
},
|
||||
updateStorePatterns: {
|
||||
initial: 'pending',
|
||||
initial: 'executeOrSkip',
|
||||
states: {
|
||||
executeOrSkip: {
|
||||
always: [
|
||||
{
|
||||
target: 'pending',
|
||||
cond: 'isAiOnline',
|
||||
},
|
||||
{
|
||||
target: 'resetPatternsAndProducts',
|
||||
},
|
||||
],
|
||||
},
|
||||
pending: {
|
||||
invoke: {
|
||||
src: 'updateStorePatterns',
|
||||
|
@ -335,6 +373,20 @@ export const designWithAiStateMachineDefinition = createMachine(
|
|||
},
|
||||
},
|
||||
},
|
||||
resetPatternsAndProducts: {
|
||||
invoke: {
|
||||
src: 'resetPatternsAndProducts',
|
||||
onDone: {
|
||||
target: 'success',
|
||||
},
|
||||
onError: {
|
||||
actions: [
|
||||
'assignAPICallLoaderError',
|
||||
],
|
||||
target: '#toneOfVoice',
|
||||
},
|
||||
},
|
||||
},
|
||||
success: { type: 'final' },
|
||||
},
|
||||
},
|
||||
|
@ -429,6 +481,7 @@ export const designWithAiStateMachineDefinition = createMachine(
|
|||
services,
|
||||
guards: {
|
||||
hasStepInUrl,
|
||||
isAiOnline,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
|
|
@ -12,6 +12,6 @@
|
|||
|
||||
.progress-bar.smooth-transition {
|
||||
.woocommerce-onboarding-progress-bar__filler {
|
||||
transition: width linear 1s;
|
||||
transition: width linear 2s;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,6 +38,6 @@
|
|||
|
||||
.progress-bar.smooth-transition {
|
||||
.woocommerce-onboarding-progress-bar__filler {
|
||||
transition: width linear 1s;
|
||||
transition: width linear 2s;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ export type designWithAiStateMachineContext = {
|
|||
// If we require more data from options, previously provided core profiler details,
|
||||
// we can retrieve them in preBusinessInfoDescription and then assign them here
|
||||
spawnSaveDescriptionToOptionRef?: ReturnType< typeof spawn >;
|
||||
aiOnline: boolean;
|
||||
};
|
||||
export type designWithAiStateMachineEvents =
|
||||
| { type: 'AI_WIZARD_CLOSED_BEFORE_COMPLETION'; payload: { step: string } }
|
||||
|
|
|
@ -160,6 +160,7 @@ export const customizeStoreStateMachineDefinition = createMachine( {
|
|||
transitionalScreen: {
|
||||
hasCompleteSurvey: false,
|
||||
},
|
||||
aiOnline: true,
|
||||
} as customizeStoreStateMachineContext,
|
||||
invoke: {
|
||||
src: 'browserPopstateHandler',
|
||||
|
@ -214,22 +215,54 @@ export const customizeStoreStateMachineDefinition = createMachine( {
|
|||
initial: 'preIntro',
|
||||
states: {
|
||||
preIntro: {
|
||||
invoke: {
|
||||
src: 'fetchIntroData',
|
||||
onError: {
|
||||
actions: 'assignFetchIntroDataError',
|
||||
target: 'intro',
|
||||
type: 'parallel',
|
||||
states: {
|
||||
checkAiStatus: {
|
||||
initial: 'pending',
|
||||
states: {
|
||||
pending: {
|
||||
invoke: {
|
||||
src: 'fetchAiStatus',
|
||||
onDone: {
|
||||
actions: 'assignAiStatus',
|
||||
target: 'success',
|
||||
},
|
||||
onError: {
|
||||
actions: 'assignAiOffline',
|
||||
target: 'success',
|
||||
},
|
||||
},
|
||||
},
|
||||
success: { type: 'final' },
|
||||
},
|
||||
},
|
||||
onDone: {
|
||||
target: 'intro',
|
||||
actions: [
|
||||
'assignThemeData',
|
||||
'assignActiveThemeHasMods',
|
||||
'assignCustomizeStoreCompleted',
|
||||
'assignCurrentThemeIsAiGenerated',
|
||||
],
|
||||
fetchIntroData: {
|
||||
initial: 'pending',
|
||||
states: {
|
||||
pending: {
|
||||
invoke: {
|
||||
src: 'fetchIntroData',
|
||||
onError: {
|
||||
actions:
|
||||
'assignFetchIntroDataError',
|
||||
target: 'success',
|
||||
},
|
||||
onDone: {
|
||||
target: 'success',
|
||||
actions: [
|
||||
'assignThemeData',
|
||||
'assignActiveThemeHasMods',
|
||||
'assignCustomizeStoreCompleted',
|
||||
'assignCurrentThemeIsAiGenerated',
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
success: { type: 'final' },
|
||||
},
|
||||
},
|
||||
},
|
||||
onDone: 'intro',
|
||||
},
|
||||
intro: {
|
||||
meta: {
|
||||
|
@ -285,8 +318,21 @@ export const customizeStoreStateMachineDefinition = createMachine( {
|
|||
},
|
||||
},
|
||||
assemblerHub: {
|
||||
initial: 'assemblerHub',
|
||||
initial: 'checkAiStatus',
|
||||
states: {
|
||||
checkAiStatus: {
|
||||
invoke: {
|
||||
src: 'fetchAiStatus',
|
||||
onDone: {
|
||||
actions: 'assignAiStatus',
|
||||
target: 'assemblerHub',
|
||||
},
|
||||
onError: {
|
||||
actions: 'assignAiOffline',
|
||||
target: 'assemblerHub',
|
||||
},
|
||||
},
|
||||
},
|
||||
assemblerHub: {
|
||||
entry: [
|
||||
{ type: 'updateQueryStep', step: 'assembler-hub' },
|
||||
|
@ -388,6 +434,12 @@ export const CustomizeStoreController = ( {
|
|||
( cond as { step: string | undefined } ).step
|
||||
);
|
||||
},
|
||||
isAiOnline: ( _ctx ) => {
|
||||
return _ctx.aiOnline;
|
||||
},
|
||||
isAiOffline: ( _ctx ) => {
|
||||
return ! _ctx.aiOnline;
|
||||
},
|
||||
},
|
||||
} );
|
||||
}, [ actionOverrides, servicesOverrides ] );
|
||||
|
|
|
@ -9,6 +9,7 @@ import { recordEvent } from '@woocommerce/tracks';
|
|||
*/
|
||||
import { customizeStoreStateMachineEvents } from '..';
|
||||
import {
|
||||
aiStatusResponse,
|
||||
customizeStoreStateMachineContext,
|
||||
RecommendThemesAPIResponse,
|
||||
} from '../types';
|
||||
|
@ -103,3 +104,37 @@ export const assignCurrentThemeIsAiGenerated = assign<
|
|||
return { ...context.intro, currentThemeIsAiGenerated };
|
||||
},
|
||||
} );
|
||||
|
||||
export const assignAiStatus = assign<
|
||||
customizeStoreStateMachineContext,
|
||||
customizeStoreStateMachineEvents // this is actually the wrong type for the event but I still don't know how to type this properly
|
||||
>( {
|
||||
aiOnline: ( _context, _event ) => {
|
||||
const indicator = ( _event as DoneInvokeEvent< aiStatusResponse > ).data
|
||||
.status.indicator;
|
||||
const status = indicator !== 'critical' && indicator !== 'major';
|
||||
// @ts-expect-error temp workaround;
|
||||
window.cys_aiOnline = status;
|
||||
|
||||
recordEvent( 'customize_your_store_ai_status', {
|
||||
online: status ? 'yes' : 'no',
|
||||
} );
|
||||
|
||||
return status;
|
||||
},
|
||||
} );
|
||||
|
||||
export const assignAiOffline = assign<
|
||||
customizeStoreStateMachineContext,
|
||||
customizeStoreStateMachineEvents // this is actually the wrong type for the event but I still don't know how to type this properly
|
||||
>( {
|
||||
aiOnline: () => {
|
||||
// @ts-expect-error temp workaround;
|
||||
window.cys_aiOnline = false;
|
||||
recordEvent( 'customize_your_store_ai_status', {
|
||||
online: 'no',
|
||||
} );
|
||||
|
||||
return false;
|
||||
},
|
||||
} );
|
||||
|
|
|
@ -307,38 +307,3 @@
|
|||
padding: 0.5rem 0.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
.woocommerce-customize-store__design-change-warning-modal {
|
||||
width: 480px;
|
||||
max-width: 480px;
|
||||
|
||||
.components-modal__header {
|
||||
padding-top: 32px;
|
||||
}
|
||||
|
||||
p {
|
||||
padding: 16px 0 16px 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
a,
|
||||
button {
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
.components-button {
|
||||
padding: 8px 16px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
line-height: 28px;
|
||||
font-size: 20px;
|
||||
color: #1e1e1e;
|
||||
}
|
||||
|
||||
.woocommerce-customize-store__design-change-warning-modal-footer {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,19 @@ import { resolveSelect } from '@wordpress/data';
|
|||
import { ONBOARDING_STORE_NAME, OPTIONS_STORE_NAME } from '@woocommerce/data';
|
||||
import apiFetch from '@wordpress/api-fetch';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { aiStatusResponse } from '../types';
|
||||
|
||||
export const fetchAiStatus = () => async (): Promise< aiStatusResponse > => {
|
||||
const response = await fetch(
|
||||
'https://status.openai.com/api/v2/status.json'
|
||||
);
|
||||
const data = await response.json();
|
||||
return data;
|
||||
};
|
||||
|
||||
export const fetchThemeCards = async () => {
|
||||
const themes = await apiFetch( {
|
||||
path: '/wc-admin/onboarding/themes/recommended',
|
||||
|
|
|
@ -44,6 +44,7 @@ describe( 'Intro Banners', () => {
|
|||
transitionalScreen: {
|
||||
hasCompleteSurvey: false,
|
||||
},
|
||||
aiOnline: true,
|
||||
} }
|
||||
currentState={ 'intro' }
|
||||
parentMachine={ null as unknown as AnyInterpreter }
|
||||
|
@ -81,6 +82,7 @@ describe( 'Intro Banners', () => {
|
|||
transitionalScreen: {
|
||||
hasCompleteSurvey: false,
|
||||
},
|
||||
aiOnline: true,
|
||||
} }
|
||||
currentState={ 'intro' }
|
||||
parentMachine={ null as unknown as AnyInterpreter }
|
||||
|
@ -124,6 +126,7 @@ describe( 'Intro Banners', () => {
|
|||
transitionalScreen: {
|
||||
hasCompleteSurvey: false,
|
||||
},
|
||||
aiOnline: true,
|
||||
} }
|
||||
currentState={ 'intro' }
|
||||
parentMachine={ null as unknown as AnyInterpreter }
|
||||
|
|
|
@ -42,6 +42,7 @@ describe( 'Intro Modals', () => {
|
|||
transitionalScreen: {
|
||||
hasCompleteSurvey: false,
|
||||
},
|
||||
aiOnline: true,
|
||||
} }
|
||||
currentState={ 'intro' }
|
||||
parentMachine={ null as unknown as AnyInterpreter }
|
||||
|
@ -96,6 +97,7 @@ describe( 'Intro Modals', () => {
|
|||
transitionalScreen: {
|
||||
hasCompleteSurvey: false,
|
||||
},
|
||||
aiOnline: true,
|
||||
} }
|
||||
currentState={ 'intro' }
|
||||
parentMachine={ null as unknown as AnyInterpreter }
|
||||
|
@ -148,6 +150,7 @@ describe( 'Intro Modals', () => {
|
|||
transitionalScreen: {
|
||||
hasCompleteSurvey: false,
|
||||
},
|
||||
aiOnline: true,
|
||||
} }
|
||||
currentState={ 'intro' }
|
||||
parentMachine={ null as unknown as AnyInterpreter }
|
||||
|
|
|
@ -180,3 +180,39 @@ body.woocommerce-customize-store.js.is-fullscreen-mode {
|
|||
transition: opacity 1.2s linear;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.woocommerce-customize-store__onboarding-welcome-modal,
|
||||
.woocommerce-customize-store__design-change-warning-modal {
|
||||
width: 480px;
|
||||
max-width: 480px;
|
||||
|
||||
.components-modal__header {
|
||||
padding-top: 32px;
|
||||
}
|
||||
|
||||
p {
|
||||
padding: 16px 0 16px 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
a,
|
||||
button {
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
.components-button {
|
||||
padding: 8px 16px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
line-height: 28px;
|
||||
font-size: 20px;
|
||||
color: #1e1e1e;
|
||||
}
|
||||
|
||||
.woocommerce-customize-store__design-change-warning-modal-footer {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,12 @@ export type RecommendThemesAPIResponse = {
|
|||
};
|
||||
};
|
||||
|
||||
export type aiStatusResponse = {
|
||||
status: {
|
||||
indicator: 'major' | 'critical' | 'ok';
|
||||
};
|
||||
};
|
||||
|
||||
export type customizeStoreStateMachineContext = {
|
||||
themeConfiguration: Record< string, unknown >; // placeholder for theme configuration until we know what it looks like
|
||||
intro: {
|
||||
|
@ -42,4 +48,5 @@ export type customizeStoreStateMachineContext = {
|
|||
transitionalScreen: {
|
||||
hasCompleteSurvey: boolean;
|
||||
};
|
||||
aiOnline: boolean;
|
||||
};
|
||||
|
|
|
@ -8,7 +8,7 @@ export default () => (
|
|||
>
|
||||
<mask
|
||||
id="mask0"
|
||||
mask-type="alpha"
|
||||
style="mask-type:alpha"
|
||||
maskUnits="userSpaceOnUse"
|
||||
x="1"
|
||||
y="1"
|
||||
|
|
|
@ -76,7 +76,7 @@
|
|||
}
|
||||
|
||||
.is-alert-update {
|
||||
$alert-color: var(--wp-admin-theme-color);
|
||||
$alert-color: var(--wp-admin-theme-color, #11a0d2);
|
||||
|
||||
&::before {
|
||||
background-color: $alert-color;
|
||||
|
|
|
@ -10,6 +10,13 @@ import { recordPageView } from '@woocommerce/tracks';
|
|||
import { updateLinkHref } from '../controller';
|
||||
import { EmbedLayout } from '../index';
|
||||
|
||||
jest.mock( '@woocommerce/admin-layout', () => {
|
||||
return {
|
||||
LayoutContextProvider: () => null,
|
||||
getLayoutContextValue: () => null,
|
||||
};
|
||||
} );
|
||||
|
||||
describe( 'updateLinkHref', () => {
|
||||
const timeExcludedScreens = [ 'stock', 'settings', 'customers' ];
|
||||
|
||||
|
|
|
@ -21,9 +21,10 @@ const initialState = {
|
|||
error: undefined,
|
||||
},
|
||||
campaigns: {
|
||||
perPage: undefined,
|
||||
pages: undefined,
|
||||
total: undefined,
|
||||
pages: {},
|
||||
meta: {
|
||||
total: undefined,
|
||||
},
|
||||
},
|
||||
campaignTypes: {
|
||||
data: undefined,
|
||||
|
@ -66,13 +67,15 @@ export const reducer: Reducer< State, Action > = (
|
|||
};
|
||||
|
||||
case TYPES.RECEIVE_CAMPAIGNS:
|
||||
const { meta } = action;
|
||||
const key = `${ meta.page }-${ meta.perPage }`;
|
||||
|
||||
return {
|
||||
...state,
|
||||
campaigns: {
|
||||
perPage: action.meta.perPage,
|
||||
pages: {
|
||||
...state.campaigns.pages,
|
||||
[ action.meta.page ]: action.error
|
||||
[ key ]: action.error
|
||||
? {
|
||||
error: action.payload,
|
||||
}
|
||||
|
@ -80,7 +83,9 @@ export const reducer: Reducer< State, Action > = (
|
|||
data: action.payload,
|
||||
},
|
||||
},
|
||||
total: action.meta.total,
|
||||
meta: {
|
||||
total: meta.total,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -13,9 +13,17 @@ export const getRecommendedChannels = ( state: State ) => {
|
|||
|
||||
/**
|
||||
* Get campaigns from state.
|
||||
*
|
||||
* @param state State passed in from the data store.
|
||||
* @param page Page number. First page is `1`.
|
||||
* @param perPage Page size, i.e. number of records in one page.
|
||||
*/
|
||||
export const getCampaigns = ( state: State ) => {
|
||||
return state.campaigns;
|
||||
export const getCampaigns = ( state: State, page: number, perPage: number ) => {
|
||||
const key = `${ page }-${ perPage }`;
|
||||
return {
|
||||
campaignsPage: state.campaigns.pages[ key ] || null,
|
||||
meta: state.campaigns.meta,
|
||||
};
|
||||
};
|
||||
|
||||
export const getCampaignTypes = ( state: State ) => {
|
||||
|
|
|
@ -66,12 +66,20 @@ export type CampaignsPage = {
|
|||
error?: ApiFetchError;
|
||||
};
|
||||
|
||||
export type CampaignsState = {
|
||||
perPage?: number;
|
||||
pages?: Record< number, CampaignsPage >;
|
||||
export type CampaignsMeta = {
|
||||
total?: number;
|
||||
};
|
||||
|
||||
export type CampaignsState = {
|
||||
pages: Record< string, CampaignsPage >;
|
||||
meta: CampaignsMeta;
|
||||
};
|
||||
|
||||
export type CampaignsPagination = {
|
||||
campaignsPage: CampaignsPage | null;
|
||||
meta: CampaignsMeta;
|
||||
};
|
||||
|
||||
export type CampaignType = {
|
||||
id: string;
|
||||
name: string;
|
||||
|
|
|
@ -0,0 +1,230 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { renderHook } from '@testing-library/react-hooks/dom';
|
||||
import { waitFor } from '@testing-library/react';
|
||||
import { dispatch } from '@wordpress/data';
|
||||
import 'whatwg-fetch'; /* eslint-disable-line import/no-unresolved */ /* To make sure Response is available */
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { useCampaigns } from '../useCampaigns';
|
||||
import { useRegisteredChannels } from '../useRegisteredChannels';
|
||||
import { STORE_KEY } from '../../data-multichannel/constants';
|
||||
import { RegisteredChannel } from '../../types';
|
||||
import { Campaign as APICampaign } from '../../data-multichannel/types';
|
||||
import '../../data-multichannel'; // To ensure the store is registered
|
||||
|
||||
type Channel = Pick< RegisteredChannel, 'slug' | 'title' | 'icon' >;
|
||||
|
||||
jest.mock( '@wordpress/api-fetch', () =>
|
||||
jest.fn( ( { path } ) => {
|
||||
const total = 9;
|
||||
|
||||
const params = new URLSearchParams( path.replace( /^[^?]*/, '' ) );
|
||||
const page = Number( params.get( 'page' ) );
|
||||
const perPage = Number( params.get( 'per_page' ) );
|
||||
|
||||
if ( ! Number.isInteger( page ) || ! Number.isInteger( perPage ) ) {
|
||||
return Promise.reject(
|
||||
new Response( '{"message": "invalid query"}', { status: 400 } )
|
||||
);
|
||||
}
|
||||
|
||||
const length = Math.min( perPage, total - ( page - 1 ) * perPage );
|
||||
|
||||
const campaigns: Array< APICampaign > = Array.from( { length } ).map(
|
||||
( _, index ) => {
|
||||
const id = `${ page }_${ index + 1 }`;
|
||||
return {
|
||||
id,
|
||||
channel: 'extension-foo',
|
||||
title: `Campaign ${ id }`,
|
||||
manage_url: `https://test/extension-foo?path=setup&id=${ id }`,
|
||||
cost: {
|
||||
value: ( ( page * perPage + index ) * 0.25 ).toString(),
|
||||
currency: 'USD',
|
||||
},
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
// For testing fallbacks when data fields are not available
|
||||
if ( campaigns[ 2 ] ) {
|
||||
campaigns[ 2 ].channel = 'intentional-mismatch-channel';
|
||||
campaigns[ 2 ].cost = null;
|
||||
}
|
||||
|
||||
return Promise.resolve(
|
||||
new Response( JSON.stringify( campaigns ), {
|
||||
headers: new Headers( { 'x-wp-total': total.toString() } ),
|
||||
} )
|
||||
);
|
||||
} )
|
||||
);
|
||||
|
||||
jest.mock( '../useRegisteredChannels', () => ( {
|
||||
useRegisteredChannels: jest.fn(),
|
||||
} ) );
|
||||
|
||||
function mockRegisteredChannels( ...channels: Array< Channel > ) {
|
||||
(
|
||||
useRegisteredChannels as jest.MockedFunction<
|
||||
typeof useRegisteredChannels
|
||||
>
|
||||
).mockReturnValue( {
|
||||
loading: false,
|
||||
data: channels.map( ( channel ) => ( {
|
||||
...channel,
|
||||
// The following is not relevant to this test scope
|
||||
description: '',
|
||||
isSetupCompleted: true,
|
||||
setupUrl: '',
|
||||
manageUrl: '',
|
||||
syncStatus: 'synced',
|
||||
issueType: 'none',
|
||||
issueText: '',
|
||||
} ) ),
|
||||
refetch: () => {},
|
||||
} );
|
||||
}
|
||||
|
||||
describe( 'useCampaigns', () => {
|
||||
beforeEach( () => {
|
||||
dispatch( STORE_KEY ).invalidateResolutionForStoreSelector(
|
||||
'getCampaigns'
|
||||
);
|
||||
|
||||
mockRegisteredChannels( {
|
||||
slug: 'extension-foo',
|
||||
title: 'Extension Foo',
|
||||
icon: 'https://test/foo.png',
|
||||
} );
|
||||
} );
|
||||
|
||||
it( 'should return correct data', async () => {
|
||||
const { result } = renderHook( () => useCampaigns() );
|
||||
|
||||
await waitFor( () => expect( result.current.loading ).toBe( false ) );
|
||||
expect( result.current.error ).toBeUndefined();
|
||||
|
||||
// Campaign matched with a channel
|
||||
expect( result.current.data?.[ 0 ] ).toEqual( {
|
||||
id: 'extension-foo|1_1',
|
||||
title: 'Campaign 1_1',
|
||||
description: '',
|
||||
cost: 'USD 1.25',
|
||||
manageUrl: 'https://test/extension-foo?path=setup&id=1_1',
|
||||
icon: 'https://test/foo.png',
|
||||
channelName: 'Extension Foo',
|
||||
channelSlug: 'extension-foo',
|
||||
} );
|
||||
|
||||
// Campaign didn't match any channel
|
||||
expect( result.current.data?.[ 2 ] ).toEqual( {
|
||||
id: 'intentional-mismatch-channel|1_3',
|
||||
title: 'Campaign 1_3',
|
||||
description: '',
|
||||
cost: '',
|
||||
manageUrl: 'https://test/extension-foo?path=setup&id=1_3',
|
||||
icon: '',
|
||||
channelName: '',
|
||||
channelSlug: 'intentional-mismatch-channel',
|
||||
} );
|
||||
} );
|
||||
|
||||
it( 'should handle error', async () => {
|
||||
const { result } = renderHook( () => useCampaigns( 1.5 ) );
|
||||
|
||||
await waitFor( () => expect( result.current.loading ).toBe( false ) );
|
||||
expect( result.current.data ).toBeUndefined();
|
||||
expect( result.current.error ).toEqual( { message: 'invalid query' } );
|
||||
} );
|
||||
|
||||
it( 'should handle pagination according to the page and perPage arguments', async () => {
|
||||
// Initial page
|
||||
const { result, rerender } = renderHook<
|
||||
{ page: number; perPage: number },
|
||||
ReturnType< typeof useCampaigns >
|
||||
>( ( { page, perPage } ) => useCampaigns( page, perPage ), {
|
||||
initialProps: { page: 1, perPage: 5 },
|
||||
} );
|
||||
|
||||
await waitFor( () => expect( result.current.loading ).toBe( false ) );
|
||||
expect( result.current.meta ).toEqual( { total: 9 } );
|
||||
expect( result.current.data ).toHaveLength( 5 );
|
||||
expect( result.current.data?.[ 0 ].id ).toEqual( 'extension-foo|1_1' );
|
||||
expect( result.current.data?.[ 4 ].id ).toEqual( 'extension-foo|1_5' );
|
||||
|
||||
// Change page
|
||||
rerender( { page: 2, perPage: 5 } );
|
||||
|
||||
await waitFor( () => expect( result.current.loading ).toBe( false ) );
|
||||
expect( result.current.data ).toHaveLength( 4 );
|
||||
expect( result.current.data?.[ 0 ].id ).toEqual( 'extension-foo|2_1' );
|
||||
expect( result.current.data?.[ 1 ].id ).toEqual( 'extension-foo|2_2' );
|
||||
|
||||
// Change page to a page that doesn't exist
|
||||
rerender( { page: 3, perPage: 5 } );
|
||||
|
||||
await waitFor( () => expect( result.current.loading ).toBe( false ) );
|
||||
expect( result.current.data ).toEqual( [] );
|
||||
|
||||
// Change perPage
|
||||
rerender( { page: 3, perPage: 4 } );
|
||||
|
||||
await waitFor( () => expect( result.current.loading ).toBe( false ) );
|
||||
expect( result.current.meta ).toEqual( { total: 9 } );
|
||||
expect( result.current.data ).toHaveLength( 1 );
|
||||
expect( result.current.data?.[ 0 ].id ).toEqual( 'extension-foo|3_1' );
|
||||
} );
|
||||
|
||||
it( 'should update data accordingly once the registered channels are updated', async () => {
|
||||
const { result, rerender } = renderHook( () => useCampaigns() );
|
||||
|
||||
await waitFor( () => expect( result.current.loading ).toBe( false ) );
|
||||
expect( result.current.data?.[ 0 ] ).toMatchObject( {
|
||||
id: 'extension-foo|1_1',
|
||||
channelName: 'Extension Foo',
|
||||
icon: 'https://test/foo.png',
|
||||
} );
|
||||
|
||||
// Update registered channels
|
||||
mockRegisteredChannels( {
|
||||
slug: 'extension-foo',
|
||||
title: 'Extension Bar',
|
||||
icon: 'https://test/bar.png',
|
||||
} );
|
||||
|
||||
rerender();
|
||||
|
||||
expect( result.current.data?.[ 0 ] ).toMatchObject( {
|
||||
id: 'extension-foo|1_1',
|
||||
channelName: 'Extension Bar',
|
||||
icon: 'https://test/bar.png',
|
||||
} );
|
||||
} );
|
||||
|
||||
it( 'should be able to use different arguments for different instances at the same time', async () => {
|
||||
const { result: resultA } = renderHook( () => useCampaigns( 1, 2 ) );
|
||||
const { result: resultB } = renderHook( () => useCampaigns( 2, 2 ) );
|
||||
const { result: resultC } = renderHook( () => useCampaigns( 2, 4 ) );
|
||||
|
||||
await waitFor( () => expect( resultA.current.loading ).toBe( false ) );
|
||||
await waitFor( () => expect( resultB.current.loading ).toBe( false ) );
|
||||
await waitFor( () => expect( resultC.current.loading ).toBe( false ) );
|
||||
|
||||
expect( resultA.current.data ).toHaveLength( 2 );
|
||||
expect( resultA.current.data?.[ 0 ].id ).toEqual( 'extension-foo|1_1' );
|
||||
expect( resultA.current.data?.[ 1 ].id ).toEqual( 'extension-foo|1_2' );
|
||||
|
||||
expect( resultB.current.data ).toHaveLength( 2 );
|
||||
expect( resultB.current.data?.[ 0 ].id ).toEqual( 'extension-foo|2_1' );
|
||||
expect( resultB.current.data?.[ 1 ].id ).toEqual( 'extension-foo|2_2' );
|
||||
|
||||
expect( resultC.current.data ).toHaveLength( 4 );
|
||||
expect( resultC.current.data?.[ 0 ].id ).toEqual( 'extension-foo|2_1' );
|
||||
expect( resultC.current.data?.[ 3 ].id ).toEqual( 'extension-foo|2_4' );
|
||||
} );
|
||||
} );
|
|
@ -9,7 +9,7 @@ import { useSelect } from '@wordpress/data';
|
|||
import { Campaign } from '~/marketing/types';
|
||||
import { STORE_KEY } from '~/marketing/data-multichannel/constants';
|
||||
import {
|
||||
CampaignsState,
|
||||
CampaignsPagination,
|
||||
Campaign as APICampaign,
|
||||
ApiFetchError,
|
||||
} from '~/marketing/data-multichannel/types';
|
||||
|
@ -36,7 +36,7 @@ export const useCampaigns = ( page = 1, perPage = 5 ): UseCampaignsType => {
|
|||
return useSelect(
|
||||
( select ) => {
|
||||
const { hasFinishedResolution, getCampaigns } = select( STORE_KEY );
|
||||
const campaignsState = getCampaigns< CampaignsState >(
|
||||
const { campaignsPage, meta } = getCampaigns< CampaignsPagination >(
|
||||
page,
|
||||
perPage
|
||||
);
|
||||
|
@ -62,25 +62,16 @@ export const useCampaigns = ( page = 1, perPage = 5 ): UseCampaignsType => {
|
|||
};
|
||||
};
|
||||
|
||||
const error =
|
||||
campaignsState.pages && campaignsState.pages[ page ]?.error;
|
||||
|
||||
const data =
|
||||
campaignsState.pages &&
|
||||
campaignsState.pages[ page ]?.data?.map( convert );
|
||||
|
||||
return {
|
||||
loading: ! hasFinishedResolution( 'getCampaigns', [
|
||||
page,
|
||||
perPage,
|
||||
] ),
|
||||
data,
|
||||
error,
|
||||
meta: {
|
||||
total: campaignsState.total,
|
||||
},
|
||||
data: campaignsPage?.data?.map( convert ),
|
||||
error: campaignsPage?.error,
|
||||
meta,
|
||||
};
|
||||
},
|
||||
[ page, perPage ]
|
||||
[ page, perPage, channels ]
|
||||
);
|
||||
};
|
||||
|
|
|
@ -140,7 +140,6 @@ export const PricingSaleField: React.FC< PricingListFieldProps > = ( {
|
|||
<span>
|
||||
{ formatDate(
|
||||
timeFormat,
|
||||
// @ts-expect-error TODO - fix this type error with moment
|
||||
moment().startOf( 'day' )
|
||||
) }
|
||||
</span>
|
||||
|
@ -149,7 +148,6 @@ export const PricingSaleField: React.FC< PricingListFieldProps > = ( {
|
|||
<span>
|
||||
{ formatDate(
|
||||
timeFormat,
|
||||
// @ts-expect-error TODO - fix this type error with moment
|
||||
moment().endOf( 'day' )
|
||||
) }
|
||||
</span>
|
||||
|
|
|
@ -33,7 +33,7 @@ const CustomizeStoreHeader = ( {
|
|||
<h1>{ __( 'Start customizing your store', 'woocommerce' ) }</h1>
|
||||
<p>
|
||||
{ __(
|
||||
'Use our built-in AI tools to effortlessly design your store and generate content, or choose a pre-built theme and customize it to fit your brand.',
|
||||
'Quickly create a beautiful looking store using our built-in store designer, or select a pre-built theme and customize it to fit your brand.',
|
||||
'woocommerce'
|
||||
) }
|
||||
</p>
|
||||
|
|
|
@ -8,7 +8,6 @@ export const RegionPicker = ( { options, initialValues } ) => {
|
|||
const [ selected, setSelected ] = useState( initialValues );
|
||||
const onChange = ( value ) => {
|
||||
document.body.dispatchEvent(
|
||||
/* global CustomEvent */
|
||||
new CustomEvent( 'wc_region_picker_update', { detail: value } )
|
||||
);
|
||||
setSelected( value );
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
"@automattic/interpolate-components": "^1.2.0",
|
||||
"@automattic/components": "^2.0.1",
|
||||
"@react-spring/web": "^9.4.3",
|
||||
"@types/wordpress__blocks": "^11.0.7",
|
||||
"@types/wordpress__blocks": "11.0.7",
|
||||
"@woocommerce/api": "^0.2.0",
|
||||
"@wordpress/a11y": "wp-6.0",
|
||||
"@wordpress/api-fetch": "wp-6.0",
|
||||
|
@ -100,7 +100,7 @@
|
|||
"qs": "^6.10.3",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-router-dom": "^6.3.0",
|
||||
"react-router-dom": "~6.3.0",
|
||||
"react-transition-group": "^4.4.2",
|
||||
"react-visibility-sensor": "^5.1.1",
|
||||
"redux": "^4.1.2",
|
||||
|
@ -121,11 +121,11 @@
|
|||
"@babel/runtime": "^7.17.2",
|
||||
"@octokit/core": "^3.5.1",
|
||||
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.10",
|
||||
"@testing-library/dom": "^8.11.3",
|
||||
"@testing-library/jest-dom": "^5.16.2",
|
||||
"@testing-library/react": "^12.1.3",
|
||||
"@testing-library/react-hooks": "^7.0.2",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"@testing-library/dom": "8.11.3",
|
||||
"@testing-library/jest-dom": "5.16.2",
|
||||
"@testing-library/react": "12.1.3",
|
||||
"@testing-library/react-hooks": "7.0.2",
|
||||
"@testing-library/user-event": "13.5.0",
|
||||
"@types/cookie": "^0.4.1",
|
||||
"@types/dompurify": "^2.3.3",
|
||||
"@types/expect-puppeteer": "^4.4.7",
|
||||
|
@ -139,12 +139,12 @@
|
|||
"@types/testing-library__jest-dom": "^5.14.3",
|
||||
"@types/tinymce": "^4.6.5",
|
||||
"@types/wordpress__components": "^19.10.3",
|
||||
"@types/wordpress__compose": "^4.0.1",
|
||||
"@types/wordpress__data": "^6.0.0",
|
||||
"@types/wordpress__data-controls": "^2.2.0",
|
||||
"@types/wordpress__media-utils": "^3.0.0",
|
||||
"@types/wordpress__notices": "^3.3.0",
|
||||
"@types/wordpress__plugins": "^3.0.0",
|
||||
"@types/wordpress__compose": "4.0.1",
|
||||
"@types/wordpress__data": "6.0.0",
|
||||
"@types/wordpress__data-controls": "~2.2.0",
|
||||
"@types/wordpress__media-utils": "3.0.0",
|
||||
"@types/wordpress__notices": "3.3.0",
|
||||
"@types/wordpress__plugins": "3.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.54.0",
|
||||
"@typescript-eslint/parser": "^5.54.0",
|
||||
"@woocommerce/admin-e2e-tests": "workspace:*",
|
||||
|
@ -182,7 +182,7 @@
|
|||
"@xstate/test": "0.5.1",
|
||||
"autoprefixer": "^10.4.2",
|
||||
"await-exec": "^0.1.2",
|
||||
"babel-jest": "^27.5.1",
|
||||
"babel-jest": "~27.5.1",
|
||||
"babel-loader": "^8.2.3",
|
||||
"babel-plugin-transform-class-properties": "^6.24.1",
|
||||
"babel-plugin-transform-es2015-template-literals": "^6.22.0",
|
||||
|
@ -201,9 +201,9 @@
|
|||
"eslint-plugin-xstate": "^1.1.0",
|
||||
"expose-loader": "^3.1.0",
|
||||
"fork-ts-checker-webpack-plugin": "^8.0.0",
|
||||
"jest": "^27.5.1",
|
||||
"jest-environment-jsdom": "~27.5.0",
|
||||
"jest-environment-node": "^27.5.1",
|
||||
"jest": "~27.5.1",
|
||||
"jest-environment-jsdom": "~27.5.1",
|
||||
"jest-environment-node": "~27.5.1",
|
||||
"md5": "^2.3.0",
|
||||
"merge-config": "^2.0.0",
|
||||
"mini-css-extract-plugin": "^2.6.0",
|
||||
|
@ -228,7 +228,7 @@
|
|||
"sass-loader": "^10.2.1",
|
||||
"style-loader": "^0.23.1",
|
||||
"stylelint": "^14.5.3",
|
||||
"ts-jest": "^27.1.3",
|
||||
"ts-jest": "~29.1.1",
|
||||
"typescript": "^5.1.6",
|
||||
"url-loader": "^1.1.2",
|
||||
"webpack": "^5.70.0",
|
||||
|
|
|
@ -1 +1 @@
|
|||
jQuery(function(i){const e={init(){i("#wp-admin-bar-show-version-info").on("click",this.showModal)},showModal(e){e.preventDefault(),0<i(".wc-backbone-modal-beta-tester-version-info").length||i(this).WCBackboneModal({template:"wc-beta-tester-version-info",variable:{version:wc_beta_tester_version_info_params.version,description:wc_beta_tester_version_info_params.description}})}};e.init()});
|
||||
jQuery(function(i){({init(){i("#wp-admin-bar-show-version-info").on("click",this.showModal)},showModal(e){e.preventDefault(),0<i(".wc-backbone-modal-beta-tester-version-info").length||i(this).WCBackboneModal({template:"wc-beta-tester-version-info",variable:{version:wc_beta_tester_version_info_params.version,description:wc_beta_tester_version_info_params.description}})}}).init()});
|
||||
|
|
|
@ -1 +1 @@
|
|||
jQuery(function(n){const i={init(){instance=this,instance.new_version=void 0,n("#wcbt-modal-version-switch-confirm").on("click",this.showConfirmVersionSwitchModal),n("input[type=radio][name=wcbt_switch_to_version]").change(function(){n(this).is(":checked")&&(instance.new_version=n(this).val())}).trigger("change")},showConfirmVersionSwitchModal(i){i.preventDefault(),instance.new_version?(n(this).WCBackboneModal({template:"wcbt-version-switch-confirm",variable:{new_version:instance.new_version}}),n("#wcbt-submit-version-switch").on("click",instance.submitSwitchVersionForm)):alert(wc_beta_tester_version_picker_params.i18n_pick_version)},submitSwitchVersionForm(i){i.preventDefault(),n("form[name=wcbt-select-version]").get(0).submit()}};i.init()});
|
||||
jQuery(function(e){({init(){(instance=this).new_version=void 0,e("#wcbt-modal-version-switch-confirm").on("click",this.showConfirmVersionSwitchModal),e("input[type=radio][name=wcbt_switch_to_version]").change(function(){e(this).is(":checked")&&(instance.new_version=e(this).val())}).trigger("change")},showConfirmVersionSwitchModal(i){i.preventDefault(),instance.new_version?(e(this).WCBackboneModal({template:"wcbt-version-switch-confirm",variable:{new_version:instance.new_version}}),e("#wcbt-submit-version-switch").on("click",instance.submitSwitchVersionForm)):alert(wc_beta_tester_version_picker_params.i18n_pick_version)},submitSwitchVersionForm(i){i.preventDefault(),e("form[name=wcbt-select-version]").get(0).submit()}}).init()});
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
"@types/react": "^17.0.2",
|
||||
"@types/react-dom": "^17.0.2",
|
||||
"@types/wordpress__components": "^19.10.3",
|
||||
"@types/wordpress__plugins": "^3.0.0",
|
||||
"@types/wordpress__plugins": "3.0.0",
|
||||
"@woocommerce/dependency-extraction-webpack-plugin": "workspace:*",
|
||||
"@woocommerce/eslint-plugin": "workspace:*",
|
||||
"@wordpress/env": "^8.2.0",
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<rect width="32" height="32" rx="16" fill="#8E9196" />
|
||||
<mask
|
||||
id="bacs0"
|
||||
mask-type="alpha"
|
||||
style="mask-type:alpha"
|
||||
maskUnits="userSpaceOnUse"
|
||||
x="8"
|
||||
y="8"
|
||||
|
@ -27,7 +27,7 @@
|
|||
</g>
|
||||
<mask
|
||||
id="bacs1"
|
||||
mask-type="alpha"
|
||||
style="mask-type:alpha"
|
||||
maskUnits="userSpaceOnUse"
|
||||
x="39"
|
||||
y="10"
|
||||
|
@ -52,7 +52,7 @@
|
|||
<rect x="64" width="32" height="32" rx="16" fill="#8E9196" />
|
||||
<mask
|
||||
id="bacs2"
|
||||
mask-type="alpha"
|
||||
style="mask-type:alpha"
|
||||
maskUnits="userSpaceOnUse"
|
||||
x="72"
|
||||
y="8"
|
||||
|
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
|
@ -8,7 +8,7 @@
|
|||
<rect width="32" height="32" rx="16" fill="#8E9196" />
|
||||
<mask
|
||||
id="cod-mask-0"
|
||||
mask-type="alpha"
|
||||
style="mask-type:alpha"
|
||||
maskUnits="userSpaceOnUse"
|
||||
x="7"
|
||||
y="10"
|
||||
|
@ -27,7 +27,7 @@
|
|||
</g>
|
||||
<mask
|
||||
id="cod-mask-1"
|
||||
mask-type="alpha"
|
||||
style="mask-type:alpha"
|
||||
maskUnits="userSpaceOnUse"
|
||||
x="39"
|
||||
y="10"
|
||||
|
@ -52,7 +52,7 @@
|
|||
<rect x="64" width="32" height="32" rx="16" fill="#8E9196" />
|
||||
<mask
|
||||
id="cod-mask-2"
|
||||
mask-type="alpha"
|
||||
style="mask-type:alpha"
|
||||
maskUnits="userSpaceOnUse"
|
||||
x="76"
|
||||
y="9"
|
||||
|
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
|
@ -268,16 +268,16 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "v5.4.31",
|
||||
"version": "v5.4.32",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/console.git",
|
||||
"reference": "11ac5f154e0e5c4c77af83ad11ead9165280b92a"
|
||||
"reference": "c70df1ffaf23a8d340bded3cfab1b86752ad6ed7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/11ac5f154e0e5c4c77af83ad11ead9165280b92a",
|
||||
"reference": "11ac5f154e0e5c4c77af83ad11ead9165280b92a",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/c70df1ffaf23a8d340bded3cfab1b86752ad6ed7",
|
||||
"reference": "c70df1ffaf23a8d340bded3cfab1b86752ad6ed7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -347,7 +347,7 @@
|
|||
"terminal"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/console/tree/v5.4.31"
|
||||
"source": "https://github.com/symfony/console/tree/v5.4.32"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -363,7 +363,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-10-31T07:58:33+00:00"
|
||||
"time": "2023-11-18T18:23:04+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/deprecation-contracts",
|
||||
|
@ -1072,16 +1072,16 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/string",
|
||||
"version": "v5.4.31",
|
||||
"version": "v5.4.32",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/string.git",
|
||||
"reference": "2765096c03f39ddf54f6af532166e42aaa05b24b"
|
||||
"reference": "91bf4453d65d8231688a04376c3a40efe0770f04"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/string/zipball/2765096c03f39ddf54f6af532166e42aaa05b24b",
|
||||
"reference": "2765096c03f39ddf54f6af532166e42aaa05b24b",
|
||||
"url": "https://api.github.com/repos/symfony/string/zipball/91bf4453d65d8231688a04376c3a40efe0770f04",
|
||||
"reference": "91bf4453d65d8231688a04376c3a40efe0770f04",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1138,7 +1138,7 @@
|
|||
"utf8"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/string/tree/v5.4.31"
|
||||
"source": "https://github.com/symfony/string/tree/v5.4.32"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -1154,7 +1154,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-11-09T08:19:44+00:00"
|
||||
"time": "2023-11-26T13:43:46+00:00"
|
||||
}
|
||||
],
|
||||
"aliases": [],
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
Significance: patch
|
||||
Type: tweak
|
||||
|
||||
Update pattern assembler thumbnail shadow
|
|
@ -1,4 +0,0 @@
|
|||
Significance: patch
|
||||
Type: fix
|
||||
|
||||
Fix save button is still disabled after updating logo settings
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue