Merge pull request #33153 from woocommerce/dev/33132-migrate-woo-onboarding-to-ts

Migrate `@woocmmerce/onboarding` to TS
This commit is contained in:
Chi-Hsuan Huang 2022-05-23 18:33:00 +08:00 committed by GitHub
commit c83dedd849
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 104 additions and 27 deletions

View File

@ -0,0 +1,4 @@
Significance: patch
Type: dev
Migrate @woocommerce/onboarding to TS

View File

@ -28,8 +28,8 @@
"@automattic/interpolate-components": "^1.2.0",
"@woocommerce/components": "workspace:*",
"@woocommerce/experimental": "workspace:*",
"@woocommerce/tracks": "workspace:*",
"@woocommerce/explat": "workspace:*",
"@woocommerce/tracks": "workspace:*",
"@wordpress/components": "^19.5.0",
"@wordpress/element": "^4.1.1",
"@wordpress/i18n": "^4.3.1",
@ -38,6 +38,7 @@
},
"devDependencies": {
"@babel/core": "^7.17.5",
"@types/wordpress__data": "^6.0.0",
"@woocommerce/eslint-plugin": "workspace:*",
"@woocommerce/style-build": "workspace:*",
"@wordpress/browserslist-config": "^4.1.1",

View File

@ -4,7 +4,13 @@
import { __ } from '@wordpress/i18n';
import { createElement } from '@wordpress/element';
export const RecommendedRibbon = ( { isLocalPartner = false } ) => {
type RecommendedRibbonProps = {
isLocalPartner?: boolean;
};
export const RecommendedRibbon: React.VFC< RecommendedRibbonProps > = ( {
isLocalPartner = false,
} ) => {
const text = isLocalPartner
? __( 'Local Partner', 'woocommerce' )
: __( 'Recommended', 'woocommerce' );

View File

@ -6,7 +6,7 @@ import NoticeOutlineIcon from 'gridicons/dist/notice-outline';
import { __ } from '@wordpress/i18n';
import { Text } from '@woocommerce/experimental';
export const SetupRequired = () => {
export const SetupRequired: React.VFC = () => {
return (
<span className="woocommerce-task-payment__setup_required">
<NoticeOutlineIcon />

View File

@ -19,7 +19,7 @@ import Discover from '../images/cards/discover.js';
import JCB from '../images/cards/jcb.js';
import UnionPay from '../images/cards/unionpay.js';
export const WCPayAcceptedMethods = () => (
export const WCPayAcceptedMethods: React.VFC = () => (
<>
<Text as="h3" variant="label" weight="600" size="12" lineHeight="16px">
{ __( 'Accepted payment methods', 'woocommerce' ) }

View File

@ -13,7 +13,12 @@ import { __ } from '@wordpress/i18n';
import { WCPayAcceptedMethods } from '../WCPayAcceptedMethods';
import WCPayLogo from '../../images/wcpay-logo';
export const WCPayCardHeader = ( {
type WCPayCardHeaderProps = {
logoWidth?: number;
logoHeight?: number;
};
export const WCPayCardHeader: React.FC< WCPayCardHeaderProps > = ( {
logoWidth = 196,
logoHeight = 41,
children,
@ -24,7 +29,13 @@ export const WCPayCardHeader = ( {
</CardHeader>
);
export const WCPayCardBody = ( {
type WCPayCardBodyProps = {
description: string;
heading: string;
onLinkClick?: () => void;
};
export const WCPayCardBody: React.VFC< WCPayCardBodyProps > = ( {
description,
heading,
onLinkClick = () => {},
@ -54,10 +65,10 @@ export const WCPayCardBody = ( {
</CardBody>
);
export const WCPayCardFooter = ( { children } ) => (
export const WCPayCardFooter: React.FC = ( { children } ) => (
<CardFooter>{ children }</CardFooter>
);
export const WCPayCard = ( { children } ) => {
export const WCPayCard: React.FC = ( { children } ) => {
return <Card className="woocommerce-task-payment-wcpay">{ children }</Card>;
};

View File

@ -11,16 +11,16 @@ import { Slot, Fill } from '@wordpress/components';
* @param {string} taskId Task id.
* @param {string} variant The variant of the task.
*/
export const trackView = async ( taskId, variant ) => {
const activePlugins = wp.data
export const trackView = async ( taskId: string, variant?: string ) => {
const activePlugins: string[] = wp.data
.select( 'wc/admin/plugins' )
.getActivePlugins();
const installedPlugins = wp.data
const installedPlugins: string[] = wp.data
.select( 'wc/admin/plugins' )
.getInstalledPlugins();
const isJetpackConnected = wp.data
const isJetpackConnected: boolean = wp.data
.select( 'wc/admin/plugins' )
.isJetpackConnected();
@ -35,18 +35,29 @@ export const trackView = async ( taskId, variant ) => {
} );
};
let experimentalVariant;
let experimentalVariant: string | undefined;
type WooOnboardingTaskProps = {
id: string;
variant?: string;
};
type WooOnboardingTaskSlotProps = Slot.Props & {
id: string;
};
/**
* A Fill for adding Onboarding tasks.
*
* @slotFill WooOnboardingTask
* @scope woocommerce-tasks
* @param {Object} props React props.
* @param {string} props.variant The variant of the task.
* @param {Object} props.children React component children
* @param {string} props.id Task id.
* @param {Object} props React props.
* @param {string} [props.variant] The variant of the task.
* @param {Object} props.children React component children
* @param {string} props.id Task id.
*/
const WooOnboardingTask = ( { id, variant, ...props } ) => {
const WooOnboardingTask: React.FC< WooOnboardingTaskProps > & {
Slot: React.VFC< WooOnboardingTaskSlotProps >;
} = ( { id, variant, ...props } ) => {
useEffect( () => {
if ( id === 'products' ) {
experimentalVariant = variant;
@ -58,7 +69,7 @@ const WooOnboardingTask = ( { id, variant, ...props } ) => {
// We need this here just in case the experiment assignment takes awhile to load, so that we don't fire trackView with a blank experimentalVariant
// Remove all of the code in this file related to experiments and variants when the product task experiment concludes and never speak of the existence of this code to anyone
const pollForExperimentalVariant = ( id, count ) => {
const pollForExperimentalVariant = ( id: string, count: number ) => {
if ( count > 20 ) {
trackView( id, 'experiment_timed_out' ); // if we can't fetch experiment after 4 seconds, give up
} else if ( experimentalVariant ) {

View File

@ -4,6 +4,10 @@
import { createElement } from '@wordpress/element';
import { Slot, Fill } from '@wordpress/components';
type WooOnboardingTaskListItemProps = {
id: string;
};
/**
* A Fill for adding Onboarding Task List items.
*
@ -12,7 +16,9 @@ import { Slot, Fill } from '@wordpress/components';
* @param {Object} props React props.
* @param {string} props.id Task id.
*/
export const WooOnboardingTaskListItem = ( { id, ...props } ) => (
export const WooOnboardingTaskListItem: React.FC< WooOnboardingTaskListItemProps > & {
Slot: React.VFC< Slot.Props & { id: string } >;
} = ( { id, ...props } ) => (
<Fill name={ 'woocommerce_onboarding_task_list_item_' + id } { ...props } />
);

View File

@ -4,6 +4,10 @@
import { createElement } from '@wordpress/element';
import { Slot, Fill } from '@wordpress/components';
type WooPaymentGatewayConfigureProps = {
id: string;
};
/**
* WooCommerce Payment Gateway configuration
*
@ -12,7 +16,9 @@ import { Slot, Fill } from '@wordpress/components';
* @param {Object} props React props.
* @param {string} props.id gateway id.
*/
export const WooPaymentGatewayConfigure = ( { id, ...props } ) => (
export const WooPaymentGatewayConfigure: React.FC< WooPaymentGatewayConfigureProps > & {
Slot: React.VFC< Slot.Props & { id: string } >;
} = ( { id, ...props } ) => (
<Fill name={ 'woocommerce_payment_gateway_configure_' + id } { ...props } />
);

View File

@ -4,6 +4,9 @@
import { createElement } from '@wordpress/element';
import { Slot, Fill } from '@wordpress/components';
type WooPaymentGatewaySetupProps = {
id: string;
};
/**
* WooCommerce Payment Gateway setup.
*
@ -12,7 +15,9 @@ import { Slot, Fill } from '@wordpress/components';
* @param {Object} props React props.
* @param {string} props.id Setup id.
*/
export const WooPaymentGatewaySetup = ( { id, ...props } ) => (
export const WooPaymentGatewaySetup: React.FC< WooPaymentGatewaySetupProps > & {
Slot: React.VFC< Slot.Props & { id: string } >;
} = ( { id, ...props } ) => (
<Fill name={ 'woocommerce_payment_gateway_setup_' + id } { ...props } />
);

View File

@ -0,0 +1,10 @@
import wpData from '@wordpress/data';
declare global {
const wp: {
data: typeof wpData
};
}
/*~ If your module exports nothing, you'll need this line. Otherwise, delete it */
export {};

View File

@ -0,0 +1,7 @@
declare module 'gridicons/dist/*' {
const value: React.ElementType< {
size?: 12 | 18 | 24 | 36 | 48 | 54 | 72;
onClick?: ( event: MouseEvent | KeyboardEvent ) => void;
} >;
export default value;
}

View File

@ -50,7 +50,6 @@ const DeprecatedWooOnboardingTaskFills = () => {
return (
<>
{ deprecatedTasks.map( ( task ) => (
// @ts-expect-error WooOnboardingTask is still a pure JS file
<WooOnboardingTask id={ task.id } key={ task.id }>
{ () => task.container }
</WooOnboardingTask>

View File

@ -225,7 +225,6 @@ registerPlugin( 'wc-admin-onboarding-task-marketing', {
// @ts-expect-error @types/wordpress__plugins need to be updated
scope: 'woocommerce-tasks',
render: () => (
// @ts-expect-error WooOnboardingTask is still a pure JS file
<WooOnboardingTask id="marketing">
{ ( { onComplete }: MarketingProps ) => {
return <Marketing onComplete={ onComplete } />;

View File

@ -265,7 +265,6 @@ registerPlugin( 'wc-admin-onboarding-task-tax', {
// @ts-expect-error @types/wordpress__plugins need to be updated
scope: 'woocommerce-tasks',
render: () => (
// @ts-expect-error WooOnboardingTask is still a pure JS file
<WooOnboardingTask id="tax">
{ ( { onComplete, query, task }: TaxProps ) => (
<Tax onComplete={ onComplete } query={ query } task={ task } />

View File

@ -19,7 +19,13 @@ export type TaskProps = {
};
export const Task: React.FC< TaskProps > = ( { query, task } ) => {
const id = query.task;
const id = query.task || '';
if ( ! id ) {
// eslint-disable-next-line no-console
console.warn( 'No task id provided' );
// eslint-enable-next-line no-console
}
const {
invalidateResolutionForStoreSelector,
optimisticallyCompleteTask,

View File

@ -0,0 +1,4 @@
Significance: patch
Type: dev
Fix onboarding task type errors after migrating woo.onboarding to TS

View File

@ -1059,6 +1059,7 @@ importers:
specifiers:
'@automattic/interpolate-components': ^1.2.0
'@babel/core': ^7.17.5
'@types/wordpress__data': ^6.0.0
'@woocommerce/components': workspace:*
'@woocommerce/eslint-plugin': workspace:*
'@woocommerce/experimental': workspace:*
@ -1095,6 +1096,7 @@ importers:
gridicons: 3.4.0
devDependencies:
'@babel/core': 7.17.8
'@types/wordpress__data': 6.0.0
'@woocommerce/eslint-plugin': link:../eslint-plugin
'@woocommerce/style-build': link:../style-build
'@wordpress/browserslist-config': 4.1.2
@ -13711,6 +13713,7 @@ packages:
re-resizable: 4.11.0
transitivePeerDependencies:
- react
- react-dom
dev: true
/@types/wordpress__compose/4.0.1:
@ -18577,7 +18580,7 @@ packages:
dev: true
/buffer-crc32/0.2.13:
resolution: {integrity: sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=}
resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==}
/buffer-fill/1.0.0:
resolution: {integrity: sha1-+PeLdniYiO858gXNY39o5wISKyw=}