Migrate @woocommerce/data settings store to TS (#34184)
* Migrate wc.data.settings to TS * Correct data.settings type * Fix wc admin client type errors * Add changelog * Add changelog * Update types * Update RawSetting type
This commit is contained in:
parent
3bbee139ed
commit
af97aaf410
|
@ -0,0 +1,4 @@
|
||||||
|
Significance: patch
|
||||||
|
Type: dev
|
||||||
|
|
||||||
|
Migrate setting store to TS
|
|
@ -4,6 +4,6 @@ const TYPES = {
|
||||||
CLEAR_SETTINGS: 'CLEAR_SETTINGS',
|
CLEAR_SETTINGS: 'CLEAR_SETTINGS',
|
||||||
SET_IS_REQUESTING: 'SET_IS_REQUESTING',
|
SET_IS_REQUESTING: 'SET_IS_REQUESTING',
|
||||||
CLEAR_IS_DIRTY: 'CLEAR_IS_DIRTY',
|
CLEAR_IS_DIRTY: 'CLEAR_IS_DIRTY',
|
||||||
};
|
} as const;
|
||||||
|
|
||||||
export default TYPES;
|
export default TYPES;
|
|
@ -6,6 +6,7 @@ import { __ } from '@wordpress/i18n';
|
||||||
import { apiFetch, select } from '@wordpress/data-controls';
|
import { apiFetch, select } from '@wordpress/data-controls';
|
||||||
import { controls } from '@wordpress/data';
|
import { controls } from '@wordpress/data';
|
||||||
import { concat } from 'lodash';
|
import { concat } from 'lodash';
|
||||||
|
import { DispatchFromMap } from '@automattic/data-stores';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
|
@ -13,12 +14,17 @@ import { concat } from 'lodash';
|
||||||
import { NAMESPACE } from '../constants';
|
import { NAMESPACE } from '../constants';
|
||||||
import { STORE_NAME } from './constants';
|
import { STORE_NAME } from './constants';
|
||||||
import TYPES from './action-types';
|
import TYPES from './action-types';
|
||||||
|
import { Settings } from './types';
|
||||||
|
|
||||||
// Can be removed in WP 5.9, wp.data is supported in >5.7.
|
// Can be removed in WP 5.9, wp.data is supported in >5.7.
|
||||||
const resolveSelect =
|
const resolveSelect =
|
||||||
controls && controls.resolveSelect ? controls.resolveSelect : select;
|
controls && controls.resolveSelect ? controls.resolveSelect : select;
|
||||||
|
|
||||||
export function updateSettingsForGroup( group, data, time = new Date() ) {
|
export function updateSettingsForGroup(
|
||||||
|
group: string,
|
||||||
|
data: Settings,
|
||||||
|
time = new Date()
|
||||||
|
) {
|
||||||
return {
|
return {
|
||||||
type: TYPES.UPDATE_SETTINGS_FOR_GROUP,
|
type: TYPES.UPDATE_SETTINGS_FOR_GROUP,
|
||||||
group,
|
group,
|
||||||
|
@ -27,7 +33,12 @@ export function updateSettingsForGroup( group, data, time = new Date() ) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function updateErrorForGroup( group, data, error, time = new Date() ) {
|
export function updateErrorForGroup(
|
||||||
|
group: string,
|
||||||
|
data: Settings | null,
|
||||||
|
error: unknown,
|
||||||
|
time = new Date()
|
||||||
|
) {
|
||||||
return {
|
return {
|
||||||
type: TYPES.UPDATE_ERROR_FOR_GROUP,
|
type: TYPES.UPDATE_ERROR_FOR_GROUP,
|
||||||
group,
|
group,
|
||||||
|
@ -37,7 +48,7 @@ export function updateErrorForGroup( group, data, error, time = new Date() ) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setIsRequesting( group, isRequesting ) {
|
export function setIsRequesting( group: string, isRequesting: boolean ) {
|
||||||
return {
|
return {
|
||||||
type: TYPES.SET_IS_REQUESTING,
|
type: TYPES.SET_IS_REQUESTING,
|
||||||
group,
|
group,
|
||||||
|
@ -45,25 +56,23 @@ export function setIsRequesting( group, isRequesting ) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function clearIsDirty( group ) {
|
export function clearIsDirty( group: string ) {
|
||||||
return {
|
return {
|
||||||
type: TYPES.CLEAR_IS_DIRTY,
|
type: TYPES.CLEAR_IS_DIRTY,
|
||||||
group,
|
group,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// allows updating and persisting immediately in one action.
|
|
||||||
export function* updateAndPersistSettingsForGroup( group, data ) {
|
|
||||||
yield updateSettingsForGroup( group, data );
|
|
||||||
yield* persistSettingsForGroup( group );
|
|
||||||
}
|
|
||||||
|
|
||||||
// this would replace setSettingsForGroup
|
// this would replace setSettingsForGroup
|
||||||
export function* persistSettingsForGroup( group ) {
|
export function* persistSettingsForGroup( group: string ) {
|
||||||
// first dispatch the is persisting action
|
// first dispatch the is persisting action
|
||||||
yield setIsRequesting( group, true );
|
yield setIsRequesting( group, true );
|
||||||
// get all dirty keys with select control
|
// get all dirty keys with select control
|
||||||
const dirtyKeys = yield resolveSelect( STORE_NAME, 'getDirtyKeys', group );
|
const dirtyKeys: string[] = yield resolveSelect(
|
||||||
|
STORE_NAME,
|
||||||
|
'getDirtyKeys',
|
||||||
|
group
|
||||||
|
);
|
||||||
// if there is nothing dirty, bail
|
// if there is nothing dirty, bail
|
||||||
if ( dirtyKeys.length === 0 ) {
|
if ( dirtyKeys.length === 0 ) {
|
||||||
yield setIsRequesting( group, false );
|
yield setIsRequesting( group, false );
|
||||||
|
@ -71,22 +80,27 @@ export function* persistSettingsForGroup( group ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// get data slice for keys
|
// get data slice for keys
|
||||||
const dirtyData = yield resolveSelect(
|
const dirtyData: {
|
||||||
|
[ key: string ]: Record< string, unknown >;
|
||||||
|
} = yield resolveSelect(
|
||||||
STORE_NAME,
|
STORE_NAME,
|
||||||
'getSettingsForGroup',
|
'getSettingsForGroup',
|
||||||
group,
|
group,
|
||||||
dirtyKeys
|
dirtyKeys
|
||||||
);
|
);
|
||||||
const url = `${ NAMESPACE }/settings/${ group }/batch`;
|
const url = `${ NAMESPACE }/settings/${ group }/batch`;
|
||||||
|
const update = dirtyKeys.reduce< Array< { id: string; value: unknown } > >(
|
||||||
|
( updates, key ) => {
|
||||||
|
const u = Object.keys( dirtyData[ key ] ).map( ( k ) => {
|
||||||
|
return { id: k, value: dirtyData[ key ][ k ] };
|
||||||
|
} );
|
||||||
|
|
||||||
const update = dirtyKeys.reduce( ( updates, key ) => {
|
return concat( updates, u );
|
||||||
const u = Object.keys( dirtyData[ key ] ).map( ( k ) => {
|
},
|
||||||
return { id: k, value: dirtyData[ key ][ k ] };
|
[]
|
||||||
} );
|
);
|
||||||
return concat( updates, u );
|
|
||||||
}, [] );
|
|
||||||
try {
|
try {
|
||||||
const results = yield apiFetch( {
|
const results: unknown = yield apiFetch( {
|
||||||
path: url,
|
path: url,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
data: { update },
|
data: { update },
|
||||||
|
@ -112,8 +126,30 @@ export function* persistSettingsForGroup( group ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// allows updating and persisting immediately in one action.
|
||||||
|
export function* updateAndPersistSettingsForGroup(
|
||||||
|
group: string,
|
||||||
|
data: Settings
|
||||||
|
) {
|
||||||
|
yield updateSettingsForGroup( group, data );
|
||||||
|
yield* persistSettingsForGroup( group );
|
||||||
|
}
|
||||||
|
|
||||||
export function clearSettings() {
|
export function clearSettings() {
|
||||||
return {
|
return {
|
||||||
type: TYPES.CLEAR_SETTINGS,
|
type: TYPES.CLEAR_SETTINGS,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type Actions = ReturnType<
|
||||||
|
| typeof updateSettingsForGroup
|
||||||
|
| typeof updateErrorForGroup
|
||||||
|
| typeof setIsRequesting
|
||||||
|
| typeof clearIsDirty
|
||||||
|
| typeof clearSettings
|
||||||
|
>;
|
||||||
|
|
||||||
|
export type ActionDispatchers = DispatchFromMap< {
|
||||||
|
createProduct: typeof persistSettingsForGroup;
|
||||||
|
updateProduct: typeof updateAndPersistSettingsForGroup;
|
||||||
|
} >;
|
|
@ -1 +1 @@
|
||||||
export const STORE_NAME = 'wc/admin/settings';
|
export const STORE_NAME = 'wc/admin/settings' as const;
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
/**
|
|
||||||
* External dependencies
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { registerStore } from '@wordpress/data';
|
|
||||||
import { controls } from '@wordpress/data-controls';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal dependencies
|
|
||||||
*/
|
|
||||||
import { STORE_NAME } from './constants';
|
|
||||||
import * as selectors from './selectors';
|
|
||||||
import * as actions from './actions';
|
|
||||||
import * as resolvers from './resolvers';
|
|
||||||
import reducer from './reducer';
|
|
||||||
|
|
||||||
registerStore( STORE_NAME, {
|
|
||||||
reducer,
|
|
||||||
actions,
|
|
||||||
controls,
|
|
||||||
selectors,
|
|
||||||
resolvers,
|
|
||||||
} );
|
|
||||||
|
|
||||||
export const SETTINGS_STORE_NAME = STORE_NAME;
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { registerStore } from '@wordpress/data';
|
||||||
|
import { controls } from '@wordpress/data-controls';
|
||||||
|
import { Reducer } from 'redux';
|
||||||
|
import { SelectFromMap, DispatchFromMap } from '@automattic/data-stores';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import { WPDataSelectors } from '../types';
|
||||||
|
import { STORE_NAME } from './constants';
|
||||||
|
import * as selectors from './selectors';
|
||||||
|
import * as actions from './actions';
|
||||||
|
import * as resolvers from './resolvers';
|
||||||
|
import reducer, { State } from './reducer';
|
||||||
|
import { SettingsState } from './types';
|
||||||
|
export * from './types';
|
||||||
|
export type { State };
|
||||||
|
|
||||||
|
registerStore< State >( STORE_NAME, {
|
||||||
|
reducer: reducer as Reducer< SettingsState >,
|
||||||
|
actions,
|
||||||
|
controls,
|
||||||
|
selectors,
|
||||||
|
resolvers,
|
||||||
|
} );
|
||||||
|
|
||||||
|
export const SETTINGS_STORE_NAME = STORE_NAME;
|
||||||
|
|
||||||
|
declare module '@wordpress/data' {
|
||||||
|
function dispatch(
|
||||||
|
key: typeof STORE_NAME
|
||||||
|
): DispatchFromMap< typeof actions >;
|
||||||
|
function select(
|
||||||
|
key: typeof STORE_NAME
|
||||||
|
): SelectFromMap< typeof selectors > & WPDataSelectors;
|
||||||
|
}
|
|
@ -2,16 +2,31 @@
|
||||||
* External dependencies
|
* External dependencies
|
||||||
*/
|
*/
|
||||||
import { union } from 'lodash';
|
import { union } from 'lodash';
|
||||||
|
import { Reducer } from 'redux';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
import TYPES from './action-types';
|
import TYPES from './action-types';
|
||||||
import { getResourceName } from '../utils';
|
import { getResourceName } from '../utils';
|
||||||
|
import { Actions } from './actions';
|
||||||
|
import { Settings, SettingsState } from './types';
|
||||||
|
|
||||||
const updateGroupDataInNewState = (
|
const updateGroupDataInNewState = (
|
||||||
newState,
|
newState: SettingsState,
|
||||||
{ group, groupIds, data, time, error }
|
{
|
||||||
|
group,
|
||||||
|
groupIds,
|
||||||
|
data,
|
||||||
|
time,
|
||||||
|
error,
|
||||||
|
}: {
|
||||||
|
group: string;
|
||||||
|
groupIds: string[];
|
||||||
|
data: Settings;
|
||||||
|
time: Date;
|
||||||
|
error: unknown;
|
||||||
|
}
|
||||||
) => {
|
) => {
|
||||||
groupIds.forEach( ( id ) => {
|
groupIds.forEach( ( id ) => {
|
||||||
newState[ getResourceName( group, id ) ] = {
|
newState[ getResourceName( group, id ) ] = {
|
||||||
|
@ -23,33 +38,35 @@ const updateGroupDataInNewState = (
|
||||||
return newState;
|
return newState;
|
||||||
};
|
};
|
||||||
|
|
||||||
const receiveSettings = (
|
const reducer: Reducer< SettingsState, Actions > = ( state = {}, action ) => {
|
||||||
state = {},
|
|
||||||
{ type, group, data, error, time, isRequesting }
|
|
||||||
) => {
|
|
||||||
const newState = {};
|
const newState = {};
|
||||||
switch ( type ) {
|
switch ( action.type ) {
|
||||||
case TYPES.SET_IS_REQUESTING:
|
case TYPES.SET_IS_REQUESTING:
|
||||||
state = {
|
state = {
|
||||||
...state,
|
...state,
|
||||||
[ group ]: {
|
[ action.group ]: {
|
||||||
...state[ group ],
|
...state[ action.group ],
|
||||||
isRequesting,
|
isRequesting: action.isRequesting,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case TYPES.CLEAR_IS_DIRTY:
|
case TYPES.CLEAR_IS_DIRTY:
|
||||||
state = {
|
state = {
|
||||||
...state,
|
...state,
|
||||||
[ group ]: {
|
[ action.group ]: {
|
||||||
...state[ group ],
|
...state[ action.group ],
|
||||||
dirty: [],
|
dirty: [],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case TYPES.UPDATE_SETTINGS_FOR_GROUP:
|
case TYPES.UPDATE_SETTINGS_FOR_GROUP:
|
||||||
case TYPES.UPDATE_ERROR_FOR_GROUP:
|
case TYPES.UPDATE_ERROR_FOR_GROUP:
|
||||||
|
const { data, group, time } = action;
|
||||||
const groupIds = data ? Object.keys( data ) : [];
|
const groupIds = data ? Object.keys( data ) : [];
|
||||||
|
const error =
|
||||||
|
action.type === TYPES.UPDATE_ERROR_FOR_GROUP
|
||||||
|
? action.error
|
||||||
|
: null;
|
||||||
if ( data === null ) {
|
if ( data === null ) {
|
||||||
state = {
|
state = {
|
||||||
...state,
|
...state,
|
||||||
|
@ -60,12 +77,15 @@ const receiveSettings = (
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
|
const stateGroup = state[ group ];
|
||||||
state = {
|
state = {
|
||||||
...state,
|
...state,
|
||||||
[ group ]: {
|
[ group ]: {
|
||||||
data:
|
data:
|
||||||
state[ group ] && state[ group ].data
|
stateGroup &&
|
||||||
? [ ...state[ group ].data, ...groupIds ]
|
stateGroup.data &&
|
||||||
|
Array.isArray( stateGroup.data )
|
||||||
|
? [ ...stateGroup.data, ...groupIds ]
|
||||||
: groupIds,
|
: groupIds,
|
||||||
error,
|
error,
|
||||||
lastReceived: time,
|
lastReceived: time,
|
||||||
|
@ -91,4 +111,5 @@ const receiveSettings = (
|
||||||
return state;
|
return state;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default receiveSettings;
|
export type State = ReturnType< typeof reducer >;
|
||||||
|
export default reducer;
|
|
@ -1,48 +0,0 @@
|
||||||
/**
|
|
||||||
* External dependencies
|
|
||||||
*/
|
|
||||||
import {
|
|
||||||
apiFetch,
|
|
||||||
dispatch as depreciatedDispatch,
|
|
||||||
} from '@wordpress/data-controls';
|
|
||||||
import { controls } from '@wordpress/data';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal dependencies
|
|
||||||
*/
|
|
||||||
import { NAMESPACE } from '../constants';
|
|
||||||
import { STORE_NAME } from './constants';
|
|
||||||
import { updateSettingsForGroup, updateErrorForGroup } from './actions';
|
|
||||||
|
|
||||||
// Can be removed in WP 5.9.
|
|
||||||
const dispatch =
|
|
||||||
controls && controls.dispatch ? controls.dispatch : depreciatedDispatch;
|
|
||||||
|
|
||||||
function settingsToSettingsResource( settings ) {
|
|
||||||
return settings.reduce( ( resource, setting ) => {
|
|
||||||
resource[ setting.id ] = setting.value;
|
|
||||||
return resource;
|
|
||||||
}, {} );
|
|
||||||
}
|
|
||||||
|
|
||||||
export function* getSettings( group ) {
|
|
||||||
yield dispatch( STORE_NAME, 'setIsRequesting', group, true );
|
|
||||||
|
|
||||||
try {
|
|
||||||
const url = NAMESPACE + '/settings/' + group;
|
|
||||||
const results = yield apiFetch( {
|
|
||||||
path: url,
|
|
||||||
method: 'GET',
|
|
||||||
} );
|
|
||||||
|
|
||||||
const resource = settingsToSettingsResource( results );
|
|
||||||
|
|
||||||
return updateSettingsForGroup( group, { [ group ]: resource } );
|
|
||||||
} catch ( error ) {
|
|
||||||
return updateErrorForGroup( group, null, error.message );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function* getSettingsForGroup( group ) {
|
|
||||||
return getSettings( group );
|
|
||||||
}
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import {
|
||||||
|
apiFetch,
|
||||||
|
dispatch as depreciatedDispatch,
|
||||||
|
} from '@wordpress/data-controls';
|
||||||
|
import { controls } from '@wordpress/data';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import { NAMESPACE } from '../constants';
|
||||||
|
import { STORE_NAME } from './constants';
|
||||||
|
import { updateSettingsForGroup, updateErrorForGroup } from './actions';
|
||||||
|
import { isRestApiError } from '../types';
|
||||||
|
|
||||||
|
// Can be removed in WP 5.9.
|
||||||
|
const dispatch =
|
||||||
|
controls && controls.dispatch ? controls.dispatch : depreciatedDispatch;
|
||||||
|
|
||||||
|
// [class-wc-rest-setting-options-controller.php](https://github.com/woocommerce/woocommerce/blob/28926968bdcd2b504e16761a483388f85ee0c151/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-setting-options-controller.php#L158-L248)
|
||||||
|
type RawSetting = {
|
||||||
|
id: string;
|
||||||
|
group_id: string;
|
||||||
|
label: string;
|
||||||
|
description: string;
|
||||||
|
tip?: string;
|
||||||
|
type:
|
||||||
|
| 'text'
|
||||||
|
| 'email'
|
||||||
|
| 'number'
|
||||||
|
| 'color'
|
||||||
|
| 'password'
|
||||||
|
| 'textarea'
|
||||||
|
| 'select'
|
||||||
|
| 'multiselect'
|
||||||
|
| 'radio'
|
||||||
|
| 'image_width'
|
||||||
|
| 'checkbox';
|
||||||
|
default: unknown;
|
||||||
|
value: unknown;
|
||||||
|
options: {
|
||||||
|
[ key: string ]: string;
|
||||||
|
};
|
||||||
|
placeholder?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
function settingsToSettingsResource( settings: RawSetting[] ) {
|
||||||
|
return settings.reduce< {
|
||||||
|
[ id: string ]: unknown;
|
||||||
|
} >( ( resource, setting ) => {
|
||||||
|
resource[ setting.id ] = setting.value;
|
||||||
|
return resource;
|
||||||
|
}, {} );
|
||||||
|
}
|
||||||
|
|
||||||
|
export function* getSettings( group: string ) {
|
||||||
|
yield dispatch( STORE_NAME, 'setIsRequesting', group, true );
|
||||||
|
try {
|
||||||
|
const url = NAMESPACE + '/settings/' + group;
|
||||||
|
const results: RawSetting[] = yield apiFetch( {
|
||||||
|
path: url,
|
||||||
|
method: 'GET',
|
||||||
|
} );
|
||||||
|
const resource = settingsToSettingsResource( results );
|
||||||
|
return updateSettingsForGroup( group, { [ group ]: resource } );
|
||||||
|
} catch ( error ) {
|
||||||
|
if ( error instanceof Error || isRestApiError( error ) ) {
|
||||||
|
return updateErrorForGroup( group, null, error.message );
|
||||||
|
}
|
||||||
|
throw `Unexpected error ${ error }`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function* getSettingsForGroup( group: string ) {
|
||||||
|
return getSettings( group );
|
||||||
|
}
|
|
@ -2,8 +2,9 @@
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
import { getResourceName, getResourcePrefix } from '../utils';
|
import { getResourceName, getResourcePrefix } from '../utils';
|
||||||
|
import { SettingsState, Settings } from './types';
|
||||||
|
|
||||||
export const getSettingsGroupNames = ( state ) => {
|
export const getSettingsGroupNames = ( state: SettingsState ) => {
|
||||||
const groupNames = new Set(
|
const groupNames = new Set(
|
||||||
Object.keys( state ).map( ( resourceName ) => {
|
Object.keys( state ).map( ( resourceName ) => {
|
||||||
return getResourcePrefix( resourceName );
|
return getResourcePrefix( resourceName );
|
||||||
|
@ -12,10 +13,10 @@ export const getSettingsGroupNames = ( state ) => {
|
||||||
return [ ...groupNames ];
|
return [ ...groupNames ];
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getSettings = ( state, group ) => {
|
export const getSettings = ( state: SettingsState, group: string ) => {
|
||||||
const settings = {};
|
const settings: Settings = {};
|
||||||
const settingIds = ( state[ group ] && state[ group ].data ) || [];
|
const settingIds = ( state[ group ] && state[ group ].data ) || [];
|
||||||
if ( settingIds.length === 0 ) {
|
if ( ! Array.isArray( settingIds ) || settingIds.length === 0 ) {
|
||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
settingIds.forEach( ( id ) => {
|
settingIds.forEach( ( id ) => {
|
||||||
|
@ -24,11 +25,15 @@ export const getSettings = ( state, group ) => {
|
||||||
return settings;
|
return settings;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getDirtyKeys = ( state, group ) => {
|
export const getDirtyKeys = ( state: SettingsState, group: string ) => {
|
||||||
return state[ group ].dirty || [];
|
return state[ group ].dirty || [];
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getIsDirty = ( state, group, keys = [] ) => {
|
export const getIsDirty = (
|
||||||
|
state: SettingsState,
|
||||||
|
group: string,
|
||||||
|
keys: string[] = []
|
||||||
|
) => {
|
||||||
const dirtyMap = getDirtyKeys( state, group );
|
const dirtyMap = getDirtyKeys( state, group );
|
||||||
// if empty array bail
|
// if empty array bail
|
||||||
if ( dirtyMap.length === 0 ) {
|
if ( dirtyMap.length === 0 ) {
|
||||||
|
@ -39,15 +44,22 @@ export const getIsDirty = ( state, group, keys = [] ) => {
|
||||||
return keys.some( ( key ) => dirtyMap.includes( key ) );
|
return keys.some( ( key ) => dirtyMap.includes( key ) );
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getSettingsForGroup = ( state, group, keys ) => {
|
export const getSettingsForGroup = (
|
||||||
|
state: SettingsState,
|
||||||
|
group: string,
|
||||||
|
keys: string[]
|
||||||
|
) => {
|
||||||
const allSettings = getSettings( state, group );
|
const allSettings = getSettings( state, group );
|
||||||
return keys.reduce( ( accumulator, key ) => {
|
return keys.reduce< Settings >( ( accumulator, key ) => {
|
||||||
accumulator[ key ] = allSettings[ key ] || {};
|
accumulator[ key ] = allSettings[ key ] || {};
|
||||||
return accumulator;
|
return accumulator;
|
||||||
}, {} );
|
}, {} );
|
||||||
};
|
};
|
||||||
|
|
||||||
export const isUpdateSettingsRequesting = ( state, group ) => {
|
export const isUpdateSettingsRequesting = (
|
||||||
|
state: SettingsState,
|
||||||
|
group: string
|
||||||
|
) => {
|
||||||
return state[ group ] && Boolean( state[ group ].isRequesting );
|
return state[ group ] && Boolean( state[ group ].isRequesting );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -70,11 +82,12 @@ export const isUpdateSettingsRequesting = ( state, group ) => {
|
||||||
* name.
|
* name.
|
||||||
*/
|
*/
|
||||||
export function getSetting(
|
export function getSetting(
|
||||||
state,
|
state: SettingsState,
|
||||||
group,
|
group: string,
|
||||||
name,
|
name: string,
|
||||||
fallback = false,
|
fallback = false,
|
||||||
filter = ( val ) => val
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars -- _fallback in default filter is unused.
|
||||||
|
filter = ( val: unknown, _fallback: unknown | boolean ) => val
|
||||||
) {
|
) {
|
||||||
const resourceName = getResourceName( group, name );
|
const resourceName = getResourceName( group, name );
|
||||||
const value =
|
const value =
|
||||||
|
@ -82,15 +95,22 @@ export function getSetting(
|
||||||
return filter( value, fallback );
|
return filter( value, fallback );
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getLastSettingsErrorForGroup = ( state, group ) => {
|
export const getLastSettingsErrorForGroup = (
|
||||||
|
state: SettingsState,
|
||||||
|
group: string
|
||||||
|
) => {
|
||||||
const settingsIds = state[ group ].data;
|
const settingsIds = state[ group ].data;
|
||||||
if ( settingsIds.length === 0 ) {
|
if ( ! Array.isArray( settingsIds ) || settingsIds.length === 0 ) {
|
||||||
return state[ group ].error;
|
return state[ group ].error;
|
||||||
}
|
}
|
||||||
return [ ...settingsIds ].pop().error;
|
return [ ...settingsIds ].pop().error;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getSettingsError = ( state, group, id ) => {
|
export const getSettingsError = (
|
||||||
|
state: SettingsState,
|
||||||
|
group: string,
|
||||||
|
id: string
|
||||||
|
) => {
|
||||||
if ( ! id ) {
|
if ( ! id ) {
|
||||||
return ( state[ group ] && state[ group ].error ) || false;
|
return ( state[ group ] && state[ group ].error ) || false;
|
||||||
}
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
export type Settings = {
|
||||||
|
[ key: string ]: unknown;
|
||||||
|
} & {
|
||||||
|
general?: {
|
||||||
|
[ key: string ]: string;
|
||||||
|
};
|
||||||
|
tax?: {
|
||||||
|
[ key: string ]: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export type SettingsState = {
|
||||||
|
[ key: string ]: {
|
||||||
|
data?: unknown;
|
||||||
|
lastReceived?: Date;
|
||||||
|
error?: unknown;
|
||||||
|
isRequesting?: boolean;
|
||||||
|
dirty?: string[];
|
||||||
|
};
|
||||||
|
};
|
|
@ -9,7 +9,7 @@ import { useCallback } from '@wordpress/element';
|
||||||
*/
|
*/
|
||||||
import { STORE_NAME } from './constants';
|
import { STORE_NAME } from './constants';
|
||||||
|
|
||||||
export const useSettings = ( group, settingsKeys = [] ) => {
|
export const useSettings = ( group: string, settingsKeys: string[] = [] ) => {
|
||||||
const { requestedSettings, settingsError, isRequesting, isDirty } =
|
const { requestedSettings, settingsError, isRequesting, isDirty } =
|
||||||
useSelect(
|
useSelect(
|
||||||
( select ) => {
|
( select ) => {
|
|
@ -2,20 +2,22 @@
|
||||||
* External dependencies
|
* External dependencies
|
||||||
*/
|
*/
|
||||||
import { createHigherOrderComponent } from '@wordpress/compose';
|
import { createHigherOrderComponent } from '@wordpress/compose';
|
||||||
import { useSelect } from '@wordpress/data';
|
import { useSelect, select as wpSelect } from '@wordpress/data';
|
||||||
import { createElement, useRef } from '@wordpress/element';
|
import { createElement, useRef } from '@wordpress/element';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
import { STORE_NAME } from './constants';
|
import { STORE_NAME } from './constants';
|
||||||
|
import { Settings } from './types';
|
||||||
|
|
||||||
export const withSettingsHydration = ( group, settings ) =>
|
export const withSettingsHydration = ( group: string, settings: Settings ) =>
|
||||||
createHigherOrderComponent(
|
createHigherOrderComponent< Record< string, unknown > >(
|
||||||
( OriginalComponent ) => ( props ) => {
|
( OriginalComponent ) => ( props ) => {
|
||||||
const settingsRef = useRef( settings );
|
const settingsRef = useRef( settings );
|
||||||
|
|
||||||
useSelect( ( select, registry ) => {
|
// @ts-expect-error registry is not defined in the wp.data typings
|
||||||
|
useSelect( ( select: typeof wpSelect, registry ) => {
|
||||||
if ( ! settingsRef.current ) {
|
if ( ! settingsRef.current ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
|
@ -12,7 +12,7 @@ import { fetchWithHeaders } from './controls';
|
||||||
|
|
||||||
export function getResourceName(
|
export function getResourceName(
|
||||||
prefix: string,
|
prefix: string,
|
||||||
identifier: Record< string, unknown >
|
identifier: Record< string, unknown > | string
|
||||||
) {
|
) {
|
||||||
const identifierString = JSON.stringify(
|
const identifierString = JSON.stringify(
|
||||||
identifier,
|
identifier,
|
||||||
|
|
|
@ -25,11 +25,7 @@ const ShippingRecommendations: React.FC = () => {
|
||||||
isJetpackConnected,
|
isJetpackConnected,
|
||||||
isSellingDigitalProductsOnly,
|
isSellingDigitalProductsOnly,
|
||||||
} = useSelect( ( select ) => {
|
} = useSelect( ( select ) => {
|
||||||
const settings = select( SETTINGS_STORE_NAME ).getSettings< {
|
const settings = select( SETTINGS_STORE_NAME ).getSettings( 'general' );
|
||||||
general?: {
|
|
||||||
woocommerce_default_country: string;
|
|
||||||
};
|
|
||||||
} >( 'general' );
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
getActivePlugins,
|
getActivePlugins,
|
||||||
|
|
|
@ -64,9 +64,7 @@ export const Products = () => {
|
||||||
|
|
||||||
const { isStoreInUS } = useSelect( ( select ) => {
|
const { isStoreInUS } = useSelect( ( select ) => {
|
||||||
const { getSettings } = select( SETTINGS_STORE_NAME );
|
const { getSettings } = select( SETTINGS_STORE_NAME );
|
||||||
const { general: settings = {} } = getSettings< {
|
const { general: settings = {} } = getSettings( 'general' );
|
||||||
general?: { [ key: string ]: unknown };
|
|
||||||
} >( 'general' );
|
|
||||||
|
|
||||||
const country =
|
const country =
|
||||||
typeof settings.woocommerce_default_country === 'string'
|
typeof settings.woocommerce_default_country === 'string'
|
||||||
|
|
|
@ -10,7 +10,7 @@ import { useSelect, useDispatch } from '@wordpress/data';
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
import { getCountryCode } from '~/dashboard/utils';
|
import { getCountryCode } from '~/dashboard/utils';
|
||||||
import { hasCompleteAddress, SettingsSelector } from '../../tax/utils';
|
import { hasCompleteAddress } from '../../tax/utils';
|
||||||
import { default as StoreLocationForm } from '~/tasks/fills/steps/location';
|
import { default as StoreLocationForm } from '~/tasks/fills/steps/location';
|
||||||
|
|
||||||
export const StoreLocation: React.FC< {
|
export const StoreLocation: React.FC< {
|
||||||
|
@ -21,9 +21,8 @@ export const StoreLocation: React.FC< {
|
||||||
const { updateAndPersistSettingsForGroup } =
|
const { updateAndPersistSettingsForGroup } =
|
||||||
useDispatch( SETTINGS_STORE_NAME );
|
useDispatch( SETTINGS_STORE_NAME );
|
||||||
const { generalSettings, isResolving } = useSelect( ( select ) => {
|
const { generalSettings, isResolving } = useSelect( ( select ) => {
|
||||||
const { getSettings, hasFinishedResolution } = select(
|
const { getSettings, hasFinishedResolution } =
|
||||||
SETTINGS_STORE_NAME
|
select( SETTINGS_STORE_NAME );
|
||||||
) as SettingsSelector;
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
generalSettings: getSettings( 'general' )?.general,
|
generalSettings: getSettings( 'general' )?.general,
|
||||||
|
@ -34,7 +33,7 @@ export const StoreLocation: React.FC< {
|
||||||
} );
|
} );
|
||||||
|
|
||||||
useEffect( () => {
|
useEffect( () => {
|
||||||
if ( isResolving || ! hasCompleteAddress( generalSettings ) ) {
|
if ( isResolving || ! hasCompleteAddress( generalSettings || {} ) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
onLocationComplete();
|
onLocationComplete();
|
||||||
|
|
|
@ -14,15 +14,12 @@ import { compose } from '@wordpress/compose';
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
import { SettingsSelector } from '../tax/utils';
|
|
||||||
import { ShippingRecommendation } from './shipping-recommendation';
|
import { ShippingRecommendation } from './shipping-recommendation';
|
||||||
import { TaskProps } from './types';
|
import { TaskProps } from './types';
|
||||||
|
|
||||||
const ShippingRecommendationWrapper = compose(
|
const ShippingRecommendationWrapper = compose(
|
||||||
withSelect( ( select ) => {
|
withSelect( ( select ) => {
|
||||||
const { getSettings } = select(
|
const { getSettings } = select( SETTINGS_STORE_NAME );
|
||||||
SETTINGS_STORE_NAME
|
|
||||||
) as SettingsSelector;
|
|
||||||
const { hasFinishedResolution } = select( OPTIONS_STORE_NAME );
|
const { hasFinishedResolution } = select( OPTIONS_STORE_NAME );
|
||||||
const { getActivePlugins } = select( PLUGINS_STORE_NAME );
|
const { getActivePlugins } = select( PLUGINS_STORE_NAME );
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ import { useSelect, useDispatch } from '@wordpress/data';
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
import { getCountryCode } from '~/dashboard/utils';
|
import { getCountryCode } from '~/dashboard/utils';
|
||||||
import { hasCompleteAddress, SettingsSelector } from '../utils';
|
import { hasCompleteAddress } from '../utils';
|
||||||
import { default as StoreLocationForm } from '~/tasks/fills/steps/location';
|
import { default as StoreLocationForm } from '~/tasks/fills/steps/location';
|
||||||
|
|
||||||
export const StoreLocation: React.FC< {
|
export const StoreLocation: React.FC< {
|
||||||
|
@ -21,9 +21,8 @@ export const StoreLocation: React.FC< {
|
||||||
const { updateAndPersistSettingsForGroup } =
|
const { updateAndPersistSettingsForGroup } =
|
||||||
useDispatch( SETTINGS_STORE_NAME );
|
useDispatch( SETTINGS_STORE_NAME );
|
||||||
const { generalSettings, isResolving } = useSelect( ( select ) => {
|
const { generalSettings, isResolving } = useSelect( ( select ) => {
|
||||||
const { getSettings, hasFinishedResolution } = select(
|
const { getSettings, hasFinishedResolution } =
|
||||||
SETTINGS_STORE_NAME
|
select( SETTINGS_STORE_NAME );
|
||||||
) as SettingsSelector;
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
generalSettings: getSettings( 'general' )?.general,
|
generalSettings: getSettings( 'general' )?.general,
|
||||||
|
@ -34,7 +33,7 @@ export const StoreLocation: React.FC< {
|
||||||
} );
|
} );
|
||||||
|
|
||||||
useEffect( () => {
|
useEffect( () => {
|
||||||
if ( isResolving || ! hasCompleteAddress( generalSettings ) ) {
|
if ( isResolving || ! hasCompleteAddress( generalSettings || {} ) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
nextStep();
|
nextStep();
|
||||||
|
|
|
@ -24,11 +24,7 @@ import { WooOnboardingTask } from '@woocommerce/onboarding';
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
import {
|
import { redirectToTaxSettings, supportsAvalara } from './utils';
|
||||||
redirectToTaxSettings,
|
|
||||||
SettingsSelector,
|
|
||||||
supportsAvalara,
|
|
||||||
} from './utils';
|
|
||||||
import { Card as AvalaraCard } from './avalara/card';
|
import { Card as AvalaraCard } from './avalara/card';
|
||||||
import { Card as WooCommerceTaxCard } from './woocommerce-tax/card';
|
import { Card as WooCommerceTaxCard } from './woocommerce-tax/card';
|
||||||
import { createNoticesFromResponse } from '../../../lib/notices';
|
import { createNoticesFromResponse } from '../../../lib/notices';
|
||||||
|
@ -59,10 +55,8 @@ const Tax: React.FC< TaxProps > = ( { onComplete, query, task } ) => {
|
||||||
useDispatch( SETTINGS_STORE_NAME );
|
useDispatch( SETTINGS_STORE_NAME );
|
||||||
const { generalSettings, isResolving, taxSettings } = useSelect(
|
const { generalSettings, isResolving, taxSettings } = useSelect(
|
||||||
( select ) => {
|
( select ) => {
|
||||||
const { getSettings, hasFinishedResolution } = select(
|
const { getSettings, hasFinishedResolution } =
|
||||||
SETTINGS_STORE_NAME
|
select( SETTINGS_STORE_NAME );
|
||||||
) as SettingsSelector;
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
generalSettings: getSettings( 'general' ).general,
|
generalSettings: getSettings( 'general' ).general,
|
||||||
isResolving: ! hasFinishedResolution( 'getSettings', [
|
isResolving: ! hasFinishedResolution( 'getSettings', [
|
||||||
|
@ -75,7 +69,7 @@ const Tax: React.FC< TaxProps > = ( { onComplete, query, task } ) => {
|
||||||
|
|
||||||
const onManual = useCallback( async () => {
|
const onManual = useCallback( async () => {
|
||||||
setIsPending( true );
|
setIsPending( true );
|
||||||
if ( generalSettings.woocommerce_calc_taxes !== 'yes' ) {
|
if ( generalSettings?.woocommerce_calc_taxes !== 'yes' ) {
|
||||||
updateAndPersistSettingsForGroup( 'tax', {
|
updateAndPersistSettingsForGroup( 'tax', {
|
||||||
tax: {
|
tax: {
|
||||||
...taxSettings,
|
...taxSettings,
|
||||||
|
@ -88,7 +82,6 @@ const Tax: React.FC< TaxProps > = ( { onComplete, query, task } ) => {
|
||||||
woocommerce_calc_taxes: 'yes',
|
woocommerce_calc_taxes: 'yes',
|
||||||
},
|
},
|
||||||
} )
|
} )
|
||||||
// @ts-expect-error updateAndPersistSettingsForGroup returns a Promise, but it is not typed in source.
|
|
||||||
.then( () => redirectToTaxSettings() )
|
.then( () => redirectToTaxSettings() )
|
||||||
.catch( ( error: unknown ) => {
|
.catch( ( error: unknown ) => {
|
||||||
setIsPending( false );
|
setIsPending( false );
|
||||||
|
|
|
@ -12,15 +12,13 @@ import { useSelect } from '@wordpress/data';
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
import { SettingsSelector, TaxChildProps } from '../utils';
|
import { TaxChildProps } from '../utils';
|
||||||
|
|
||||||
export const Configure: React.FC<
|
export const Configure: React.FC<
|
||||||
Pick< TaxChildProps, 'isPending' | 'onManual' >
|
Pick< TaxChildProps, 'isPending' | 'onManual' >
|
||||||
> = ( { isPending, onManual } ) => {
|
> = ( { isPending, onManual } ) => {
|
||||||
const { generalSettings } = useSelect( ( select ) => {
|
const { generalSettings } = useSelect( ( select ) => {
|
||||||
const { getSettings } = select(
|
const { getSettings } = select( SETTINGS_STORE_NAME );
|
||||||
SETTINGS_STORE_NAME
|
|
||||||
) as SettingsSelector;
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
generalSettings: getSettings( 'general' )?.general,
|
generalSettings: getSettings( 'general' )?.general,
|
||||||
|
@ -41,7 +39,7 @@ export const Configure: React.FC<
|
||||||
{ __( 'Configure', 'woocommerce' ) }
|
{ __( 'Configure', 'woocommerce' ) }
|
||||||
</Button>
|
</Button>
|
||||||
<p>
|
<p>
|
||||||
{ generalSettings.woocommerce_calc_taxes !== 'yes' &&
|
{ generalSettings?.woocommerce_calc_taxes !== 'yes' &&
|
||||||
interpolateComponents( {
|
interpolateComponents( {
|
||||||
mixedString: __(
|
mixedString: __(
|
||||||
/*eslint-disable max-len*/
|
/*eslint-disable max-len*/
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* External dependencies
|
* External dependencies
|
||||||
*/
|
*/
|
||||||
import { getAdminLink } from '@woocommerce/settings';
|
import { getAdminLink } from '@woocommerce/settings';
|
||||||
import { WPDataSelectors, TaskType } from '@woocommerce/data';
|
import { TaskType } from '@woocommerce/data';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Plugins required to automate taxes.
|
* Plugins required to automate taxes.
|
||||||
|
@ -17,11 +17,9 @@ export const AUTOMATION_PLUGINS = [ 'jetpack', 'woocommerce-services' ];
|
||||||
* @param {Object} generalSettings.woocommerce_default_country Store default country.
|
* @param {Object} generalSettings.woocommerce_default_country Store default country.
|
||||||
* @param {Object} generalSettings.woocommerce_store_postcode Store postal code.
|
* @param {Object} generalSettings.woocommerce_store_postcode Store postal code.
|
||||||
*/
|
*/
|
||||||
export const hasCompleteAddress = ( generalSettings: {
|
export const hasCompleteAddress = (
|
||||||
woocommerce_store_address?: string;
|
generalSettings: Record< string, string >
|
||||||
woocommerce_default_country?: string;
|
): boolean => {
|
||||||
woocommerce_store_postcode?: string;
|
|
||||||
} ): boolean => {
|
|
||||||
const {
|
const {
|
||||||
woocommerce_store_address: storeAddress,
|
woocommerce_store_address: storeAddress,
|
||||||
woocommerce_default_country: defaultCountry,
|
woocommerce_default_country: defaultCountry,
|
||||||
|
@ -39,22 +37,6 @@ export const redirectToTaxSettings = (): void => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Types for settings selectors.
|
|
||||||
*/
|
|
||||||
export type SettingsSelector = WPDataSelectors & {
|
|
||||||
getSettings: ( type: string ) => {
|
|
||||||
general: {
|
|
||||||
woocommerce_default_country?: string;
|
|
||||||
woocommerce_calc_taxes?: string;
|
|
||||||
};
|
|
||||||
tax: { [ key: string ]: string };
|
|
||||||
};
|
|
||||||
getOption: ( type: string ) => {
|
|
||||||
tos_accepted?: boolean;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Types for child tax components.
|
* Types for child tax components.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -13,7 +13,6 @@ import { PLUGINS_STORE_NAME, SETTINGS_STORE_NAME } from '@woocommerce/data';
|
||||||
import {
|
import {
|
||||||
AUTOMATION_PLUGINS,
|
AUTOMATION_PLUGINS,
|
||||||
hasCompleteAddress,
|
hasCompleteAddress,
|
||||||
SettingsSelector,
|
|
||||||
TaxChildProps,
|
TaxChildProps,
|
||||||
} from '../utils';
|
} from '../utils';
|
||||||
import { AutomatedTaxes } from './automated-taxes';
|
import { AutomatedTaxes } from './automated-taxes';
|
||||||
|
@ -31,9 +30,7 @@ export const WooCommerceTax: React.FC< TaxChildProps > = ( {
|
||||||
isResolving,
|
isResolving,
|
||||||
pluginsToActivate,
|
pluginsToActivate,
|
||||||
} = useSelect( ( select ) => {
|
} = useSelect( ( select ) => {
|
||||||
const { getSettings } = select(
|
const { getSettings } = select( SETTINGS_STORE_NAME );
|
||||||
SETTINGS_STORE_NAME
|
|
||||||
) as SettingsSelector;
|
|
||||||
const { getActivePlugins, hasFinishedResolution } =
|
const { getActivePlugins, hasFinishedResolution } =
|
||||||
select( PLUGINS_STORE_NAME );
|
select( PLUGINS_STORE_NAME );
|
||||||
const activePlugins = getActivePlugins();
|
const activePlugins = getActivePlugins();
|
||||||
|
@ -55,7 +52,7 @@ export const WooCommerceTax: React.FC< TaxChildProps > = ( {
|
||||||
|
|
||||||
const canAutomateTaxes = () => {
|
const canAutomateTaxes = () => {
|
||||||
return (
|
return (
|
||||||
hasCompleteAddress( generalSettings ) &&
|
hasCompleteAddress( generalSettings || {} ) &&
|
||||||
! pluginsToActivate.length &&
|
! pluginsToActivate.length &&
|
||||||
isJetpackConnected
|
isJetpackConnected
|
||||||
);
|
);
|
||||||
|
|
|
@ -15,7 +15,7 @@ import { useSelect } from '@wordpress/data';
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
import { AUTOMATION_PLUGINS, SettingsSelector } from '../utils';
|
import { AUTOMATION_PLUGINS } from '../utils';
|
||||||
import { Connect } from './connect';
|
import { Connect } from './connect';
|
||||||
import { Plugins } from './plugins';
|
import { Plugins } from './plugins';
|
||||||
import { StoreLocation } from '../components/store-location';
|
import { StoreLocation } from '../components/store-location';
|
||||||
|
@ -48,9 +48,7 @@ export const Setup: React.FC< SetupProps > = ( {
|
||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
const { activePlugins, isResolving } = useSelect( ( select ) => {
|
const { activePlugins, isResolving } = useSelect( ( select ) => {
|
||||||
const { getSettings } = select(
|
const { getSettings } = select( SETTINGS_STORE_NAME );
|
||||||
SETTINGS_STORE_NAME
|
|
||||||
) as SettingsSelector;
|
|
||||||
const { hasFinishedResolution } = select( OPTIONS_STORE_NAME );
|
const { hasFinishedResolution } = select( OPTIONS_STORE_NAME );
|
||||||
const { getActivePlugins } = select( PLUGINS_STORE_NAME );
|
const { getActivePlugins } = select( PLUGINS_STORE_NAME );
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
Significance: patch
|
||||||
|
Type: dev
|
||||||
|
|
||||||
|
Fix typescript errors for setting selector
|
Loading…
Reference in New Issue