Merge pull request #32755 from woocommerce/refactor/woo-data-types

Make `@woocommerce/data` tidy
This commit is contained in:
Chi-Hsuan Huang 2022-04-28 19:19:30 +08:00 committed by GitHub
commit eb21a4dc8c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 248 additions and 273 deletions

View File

@ -3,6 +3,70 @@
*/
import '@wordpress/core-data';
// Export store names
export { SETTINGS_STORE_NAME } from './settings';
export { PLUGINS_STORE_NAME } from './plugins';
export { ONBOARDING_STORE_NAME } from './onboarding';
export { USER_STORE_NAME } from './user';
export { REVIEWS_STORE_NAME } from './reviews';
export { NOTES_STORE_NAME } from './notes';
export { REPORTS_STORE_NAME } from './reports';
export { COUNTRIES_STORE_NAME } from './countries';
export { NAVIGATION_STORE_NAME } from './navigation';
export { OPTIONS_STORE_NAME } from './options';
export { ITEMS_STORE_NAME } from './items';
export { PAYMENT_GATEWAYS_STORE_NAME } from './payment-gateways';
// Export hooks
export { withSettingsHydration } from './settings/with-settings-hydration';
export { withOnboardingHydration } from './onboarding/with-onboarding-hydration';
export { withCurrentUserHydration } from './user/with-current-user-hydration';
export { withNavigationHydration } from './navigation/with-navigation-hydration';
export { withPluginsHydration } from './plugins/with-plugins-hydration';
export {
withOptionsHydration,
useOptionsHydration,
} from './options/with-options-hydration';
export { useSettings } from './settings/use-settings';
export { useUserPreferences } from './user/use-user-preferences';
export { useUser } from './user/use-user';
// Export utils
export { getVisibleTasks } from './onboarding/utils';
export { getLeaderboard, searchItemsByString } from './items/utils';
export {
getFilterQuery,
getSummaryNumbers,
getReportTableData,
getReportTableQuery,
getReportChartData,
getTooltipValueFormat,
} from './reports/utils';
// Export constants
export { pluginNames } from './plugins/constants';
export { EXPORT_STORE_NAME } from './export';
export { IMPORT_STORE_NAME } from './import';
export {
MAX_PER_PAGE,
QUERY_DEFAULTS,
NAMESPACE,
WC_ADMIN_NAMESPACE,
WCS_NAMESPACE,
SECOND,
MINUTE,
HOUR,
DAY,
WEEK,
MONTH,
} from './constants';
// Export types
export * from './types';
export * from './countries/types';
export * from './onboarding/types';
export * from './plugins/types';
/**
* Internal dependencies
*/
@ -18,82 +82,6 @@ import type { REPORTS_STORE_NAME } from './reports';
import type { ITEMS_STORE_NAME } from './items';
import type { COUNTRIES_STORE_NAME } from './countries';
import type { PAYMENT_GATEWAYS_STORE_NAME } from './payment-gateways';
import { OnboardingSelectors } from './onboarding/selectors';
import { PaymentSelectors } from './payment-gateways/selectors';
import { WPDataSelectors } from './types';
import { PluginSelectors } from './plugins/selectors';
export * from './types';
export { SETTINGS_STORE_NAME } from './settings';
export { withSettingsHydration } from './settings/with-settings-hydration';
export { useSettings } from './settings/use-settings';
export { PLUGINS_STORE_NAME } from './plugins';
export type { Plugin } from './plugins/types';
export type { InstallPluginsResponse } from './plugins/actions';
export { ActionDispatchers as PluginsStoreActions } from './plugins/actions';
export { pluginNames } from './plugins/constants';
export { withPluginsHydration } from './plugins/with-plugins-hydration';
export { ONBOARDING_STORE_NAME } from './onboarding';
export { withOnboardingHydration } from './onboarding/with-onboarding-hydration';
export { getVisibleTasks } from './onboarding/utils';
export type { TaskType, TaskListType } from './onboarding/types';
export type { Extension, ExtensionList } from './onboarding/selectors';
export { USER_STORE_NAME } from './user';
export { withCurrentUserHydration } from './user/with-current-user-hydration';
export { useUser } from './user/use-user';
export { useUserPreferences } from './user/use-user-preferences';
export { OPTIONS_STORE_NAME } from './options';
export {
withOptionsHydration,
useOptionsHydration,
} from './options/with-options-hydration';
export { REVIEWS_STORE_NAME } from './reviews';
export { NOTES_STORE_NAME } from './notes';
export { REPORTS_STORE_NAME } from './reports';
export { ITEMS_STORE_NAME } from './items';
export { getLeaderboard, searchItemsByString } from './items/utils';
export { COUNTRIES_STORE_NAME } from './countries';
export { NAVIGATION_STORE_NAME } from './navigation';
export { withNavigationHydration } from './navigation/with-navigation-hydration';
export { PAYMENT_GATEWAYS_STORE_NAME } from './payment-gateways';
export {
getFilterQuery,
getSummaryNumbers,
getReportTableData,
getReportTableQuery,
getReportChartData,
getTooltipValueFormat,
} from './reports/utils';
export {
MAX_PER_PAGE,
QUERY_DEFAULTS,
NAMESPACE,
WC_ADMIN_NAMESPACE,
WCS_NAMESPACE,
SECOND,
MINUTE,
HOUR,
DAY,
WEEK,
MONTH,
} from './constants';
export { EXPORT_STORE_NAME } from './export';
export { IMPORT_STORE_NAME } from './import';
export type WCDataStoreName =
| typeof REVIEWS_STORE_NAME
@ -109,6 +97,14 @@ export type WCDataStoreName =
| typeof COUNTRIES_STORE_NAME
| typeof PAYMENT_GATEWAYS_STORE_NAME;
/**
* Internal dependencies
*/
import { WPDataSelectors } from './types';
import { PaymentSelectors } from './payment-gateways/selectors';
import { PluginSelectors } from './plugins/selectors';
import { OnboardingSelectors } from './onboarding/selectors';
// As we add types to all the package selectors we can fill out these unknown types with real ones. See one
// of the already typed selectors for an example of how you can do this.
export type WCSelectorType< T > = T extends typeof REVIEWS_STORE_NAME
@ -140,6 +136,6 @@ export type WCSelectorType< T > = T extends typeof REVIEWS_STORE_NAME
export interface WCDataSelector {
< T extends WCDataStoreName >( storeName: T ): WCSelectorType< T >;
}
export * from './onboarding/selectors';
export * from './onboarding/types';
export * from './countries/types';
// Other exports
export { ActionDispatchers as PluginsStoreActions } from './plugins/actions';

View File

@ -6,7 +6,14 @@ import createSelector from 'rememo';
/**
* Internal dependencies
*/
import { TaskType, TaskListType } from './types';
import {
TaskType,
TaskListType,
OnboardingState,
ExtensionList,
ProfileItemsState,
Product,
} from './types';
import { WPDataSelectors } from '../types';
import { Plugin } from '../plugins/types';
@ -22,8 +29,6 @@ export const getProfileItems = (
return state.profileItems || {};
};
const EMPTY_ARRAY: Product[] = [];
export const getTaskLists = createSelector(
( state: OnboardingState ): TaskListType[] => {
return Object.values( state.taskLists );
@ -88,10 +93,9 @@ export const getEmailPrefill = ( state: OnboardingState ): string => {
};
export const getProductTypes = ( state: OnboardingState ): Product[] => {
return state.productTypes || EMPTY_ARRAY;
return state.productTypes || [];
};
// Types
export type OnboardingSelectors = {
getProfileItems: () => ReturnType< typeof getProfileItems >;
getPaymentGatewaySuggestions: () => ReturnType<
@ -106,104 +110,3 @@ export type OnboardingSelectors = {
getTaskList: ( id: string ) => ReturnType< typeof getTaskList >;
getFreeExtensions: () => ReturnType< typeof getFreeExtensions >;
} & WPDataSelectors;
export type OnboardingState = {
freeExtensions: ExtensionList[];
profileItems: ProfileItemsState;
taskLists: Record< string, TaskListType >;
paymentMethods: Plugin[];
productTypes: Product[];
emailPrefill: string;
// TODO clarify what the error record's type is
errors: Record< string, unknown >;
requesting: Record< string, boolean >;
};
export type Industry = {
slug: string;
};
export type ProductCount = '0' | '1-10' | '11-100' | '101 - 1000' | '1000+';
export type ProductTypeSlug =
| 'physical'
| 'bookings'
| 'download'
| 'memberships'
| 'product-add-ons'
| 'product-bundles'
| 'subscriptions';
export type OtherPlatformSlug =
| 'shopify'
| 'bigcommerce'
| 'wix'
| 'amazon'
| 'ebay'
| 'etsy'
| 'squarespace'
| 'other';
export type RevenueTypeSlug =
| 'none'
| 'rather-not-say'
| 'up-to-2500'
| '2500-10000'
| '10000-50000'
| '50000-250000'
| 'more-than-250000';
export type ProfileItemsState = {
business_extensions: [ ] | null;
completed: boolean | null;
industry: Industry[] | null;
number_employees: string | null;
other_platform: OtherPlatformSlug | null;
other_platform_name: string | null;
product_count: ProductCount | null;
product_types: ProductTypeSlug[] | null;
revenue: RevenueTypeSlug | null;
selling_venues: string | null;
setup_client: boolean | null;
skipped: boolean | null;
theme: string | null;
wccom_connected: boolean | null;
is_agree_marketing: boolean | null;
store_email: string | null;
};
export type FieldLocale = {
locale: string;
label: string;
};
export type MethodFields = {
name: string;
option?: string;
label?: string;
locales?: FieldLocale[];
type?: string;
value?: string;
};
export type Product = {
default?: boolean;
label: string;
product?: number;
};
export type ExtensionList = {
key: string;
title: string;
plugins: Extension[];
};
export type Extension = {
description: string;
key: string;
image_url: string;
manage_url: string;
name: string;
is_built_by_wc: boolean;
is_visible: boolean;
};

View File

@ -1,3 +1,8 @@
/**
* Internal dependencies
*/
import { Plugin } from '../plugins/types';
export type TaskType = {
actionLabel?: string;
actionUrl?: string;
@ -51,3 +56,103 @@ export type TaskListType = {
isCollapsible?: boolean;
isExpandable?: boolean;
};
export type OnboardingState = {
freeExtensions: ExtensionList[];
profileItems: ProfileItemsState;
taskLists: Record< string, TaskListType >;
paymentMethods: Plugin[];
productTypes: Product[];
emailPrefill: string;
// TODO clarify what the error record's type is
errors: Record< string, unknown >;
requesting: Record< string, boolean >;
};
export type Industry = {
slug: string;
};
export type ProductCount = '0' | '1-10' | '11-100' | '101 - 1000' | '1000+';
export type ProductTypeSlug =
| 'physical'
| 'bookings'
| 'download'
| 'memberships'
| 'product-add-ons'
| 'product-bundles'
| 'subscriptions';
export type OtherPlatformSlug =
| 'shopify'
| 'bigcommerce'
| 'wix'
| 'amazon'
| 'ebay'
| 'etsy'
| 'squarespace'
| 'other';
export type RevenueTypeSlug =
| 'none'
| 'rather-not-say'
| 'up-to-2500'
| '2500-10000'
| '10000-50000'
| '50000-250000'
| 'more-than-250000';
export type ProfileItemsState = {
business_extensions: [ ] | null;
completed: boolean | null;
industry: Industry[] | null;
number_employees: string | null;
other_platform: OtherPlatformSlug | null;
other_platform_name: string | null;
product_count: ProductCount | null;
product_types: ProductTypeSlug[] | null;
revenue: RevenueTypeSlug | null;
selling_venues: string | null;
setup_client: boolean | null;
skipped: boolean | null;
theme: string | null;
wccom_connected: boolean | null;
is_agree_marketing: boolean | null;
store_email: string | null;
};
export type FieldLocale = {
locale: string;
label: string;
};
export type MethodFields = {
name: string;
option?: string;
label?: string;
locales?: FieldLocale[];
type?: string;
value?: string;
};
export type Product = {
default?: boolean;
label: string;
product?: number;
};
export type ExtensionList = {
key: string;
title: string;
plugins: Extension[];
};
export type Extension = {
description: string;
key: string;
image_url: string;
manage_url: string;
name: string;
is_built_by_wc: boolean;
};

View File

@ -13,7 +13,7 @@ import { controls } from '@wordpress/data';
/**
* Internal dependencies
*/
import { pluginNames, STORE_NAME } from './constants';
import { STORE_NAME } from './constants';
import { ACTION_TYPES as TYPES } from './action-types';
import { WC_ADMIN_NAMESPACE } from '../constants';
import { WPError } from '../types';
@ -22,6 +22,8 @@ import {
PluginNames,
SelectorKeysWithActions,
RecommendedTypes,
InstallPluginsResponse,
ActivatePluginsResponse,
} from './types';
// Can be removed in WP 5.9, wp.data is supported in >5.7.
@ -30,63 +32,12 @@ const dispatch =
const resolveSelect =
controls && controls.resolveSelect ? controls.resolveSelect : select;
type PluginsResponse< PluginData > = {
data: PluginData;
errors: WPError< PluginNames >;
success: boolean;
message: string;
} & Response;
export type InstallPluginsResponse = PluginsResponse< {
installed: string[];
results: Record< string, boolean >;
install_time?: Record< string, number >;
} >;
type ActivatePluginsResponse = PluginsResponse< {
activated: string[];
active: string[];
} >;
function isWPError(
error: WPError< PluginNames > | Error | string
): error is WPError< PluginNames > {
return ( error as WPError ).errors !== undefined;
}
class PluginError extends Error {
constructor( message: string, public data: unknown ) {
super( message );
}
}
function formatErrors(
response: WPError< PluginNames > | Error | string
): string {
if ( isWPError( response ) ) {
// Replace the slug with a plugin name if a constant exists.
( Object.keys( response.errors ) as PluginNames[] ).forEach(
( plugin ) => {
response.errors[ plugin ] = response.errors[ plugin ].map(
( pluginError ) => {
return pluginNames[ plugin ]
? pluginError.replace(
`\`${ plugin }\``,
pluginNames[ plugin ]
)
: pluginError;
}
);
}
);
} else if ( typeof response === 'string' ) {
return response;
} else {
return response.message;
}
return '';
}
const formatErrorMessage = (
pluginErrors: Record< PluginNames, string[] >,
actionType = 'install'
@ -170,6 +121,43 @@ export function updateJetpackConnectUrl(
};
}
export const createErrorNotice = (
errorMessage: string
): {
type: 'CREATE_NOTICE';
[ key: string ]: unknown;
} => {
return dispatch( 'core/notices', 'createNotice', 'error', errorMessage );
};
export function setPaypalOnboardingStatus(
status: Partial< PaypalOnboardingStatus >
): {
type: TYPES.SET_PAYPAL_ONBOARDING_STATUS;
paypalOnboardingStatus: Partial< PaypalOnboardingStatus >;
} {
return {
type: TYPES.SET_PAYPAL_ONBOARDING_STATUS as const,
paypalOnboardingStatus: status,
};
}
export function setRecommendedPlugins(
type: string,
plugins: Plugin[]
): {
type: TYPES.SET_RECOMMENDED_PLUGINS;
recommendedType: string;
plugins: Plugin[];
} {
return {
type: TYPES.SET_RECOMMENDED_PLUGINS as const,
recommendedType: type,
plugins,
};
}
// Action Creator Generators
export function* installPlugins( plugins: string[] ) {
yield setIsRequesting( 'installPlugins', true );
@ -258,15 +246,6 @@ export function* installAndActivatePlugins( plugins: string[] ) {
}
}
export const createErrorNotice = (
errorMessage: string
): {
type: 'CREATE_NOTICE';
[ key: string ]: unknown;
} => {
return dispatch( 'core/notices', 'createNotice', 'error', errorMessage );
};
export function* connectToJetpack(
getAdminLink: ( endpoint: string ) => string
) {
@ -335,33 +314,6 @@ export function* connectToJetpackWithFailureRedirect(
}
}
export function setPaypalOnboardingStatus(
status: Partial< PaypalOnboardingStatus >
): {
type: TYPES.SET_PAYPAL_ONBOARDING_STATUS;
paypalOnboardingStatus: Partial< PaypalOnboardingStatus >;
} {
return {
type: TYPES.SET_PAYPAL_ONBOARDING_STATUS as const,
paypalOnboardingStatus: status,
};
}
export function setRecommendedPlugins(
type: string,
plugins: Plugin[]
): {
type: TYPES.SET_RECOMMENDED_PLUGINS;
recommendedType: string;
plugins: Plugin[];
} {
return {
type: TYPES.SET_RECOMMENDED_PLUGINS as const,
recommendedType: type,
plugins,
};
}
const SUPPORTED_TYPES = [ 'payments' ];
export function* dismissRecommendedPlugins( type: RecommendedTypes ) {
if ( ! SUPPORTED_TYPES.includes( type ) ) {

View File

@ -2,6 +2,7 @@
* Internal dependencies
*/
import { pluginNames } from './constants';
import { WPError } from '../types';
export type RecommendedTypes = 'payments';
@ -61,3 +62,21 @@ export type PaypalOnboardingStatus = {
onboarded: boolean;
};
};
type PluginsResponse< PluginData > = {
data: PluginData;
errors: WPError< PluginNames >;
success: boolean;
message: string;
} & Response;
export type InstallPluginsResponse = PluginsResponse< {
installed: string[];
results: Record< string, boolean >;
install_time?: Record< string, number >;
} >;
export type ActivatePluginsResponse = PluginsResponse< {
activated: string[];
active: string[];
} >;