Merge pull request #10 from woocommerce/update/add-loading-state
Add loading and fix bug where the same keyword does not work
This commit is contained in:
commit
abddff5034
|
@ -1,5 +1,6 @@
|
|||
const TYPES = {
|
||||
SET_OPTIONS: 'SET_OPTIONS',
|
||||
SET_IS_LOADING: 'SET_IS_LOADING',
|
||||
DELETE_OPTION_BY_ID: 'DELETE_OPTION_BY_ID',
|
||||
};
|
||||
|
||||
|
|
|
@ -21,6 +21,13 @@ export function setOptions( options ) {
|
|||
};
|
||||
}
|
||||
|
||||
export function setLoadingState( isLoading ) {
|
||||
return {
|
||||
type: TYPES.SET_IS_LOADING,
|
||||
isLoading,
|
||||
};
|
||||
}
|
||||
|
||||
export function* deleteOptionById( optionId ) {
|
||||
try {
|
||||
yield apiFetch( {
|
||||
|
|
|
@ -5,16 +5,22 @@ import TYPES from './action-types';
|
|||
|
||||
const DEFAULT_STATE = {
|
||||
options: [],
|
||||
isLoading: true,
|
||||
};
|
||||
|
||||
const reducer = ( state = DEFAULT_STATE, action ) => {
|
||||
switch ( action.type ) {
|
||||
case TYPES.SET_IS_LOADING:
|
||||
return {
|
||||
...state,
|
||||
isLoading: action.isLoading,
|
||||
};
|
||||
case TYPES.SET_OPTIONS:
|
||||
return {
|
||||
...state,
|
||||
options: action.options,
|
||||
isLoading: false,
|
||||
};
|
||||
|
||||
case TYPES.DELETE_OPTION_BY_ID:
|
||||
return {
|
||||
...state,
|
||||
|
|
|
@ -7,7 +7,7 @@ import { apiFetch } from '@wordpress/data-controls';
|
|||
* Internal dependencies
|
||||
*/
|
||||
import { API_NAMESPACE } from './constants';
|
||||
import { setOptions } from './actions';
|
||||
import { setLoadingState, setOptions } from './actions';
|
||||
|
||||
export function* getOptions( search ) {
|
||||
let path = `${ API_NAMESPACE }/options?`;
|
||||
|
@ -15,6 +15,8 @@ export function* getOptions( search ) {
|
|||
path += `search=${ search }`;
|
||||
}
|
||||
|
||||
yield setLoadingState( true );
|
||||
|
||||
try {
|
||||
const response = yield apiFetch( {
|
||||
path,
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
export function getOptions( state ) {
|
||||
return state.options;
|
||||
}
|
||||
|
||||
export function isLoading( state ) {
|
||||
return state.isLoading;
|
||||
}
|
||||
|
|
|
@ -14,7 +14,8 @@ function Options( {
|
|||
options,
|
||||
getOptions,
|
||||
deleteOptionById,
|
||||
invalidateResolutionForStoreSelector,
|
||||
isLoading,
|
||||
invalidateResolution,
|
||||
} ) {
|
||||
const deleteOption = function ( optionId ) {
|
||||
// eslint-disable-next-line no-alert
|
||||
|
@ -23,7 +24,27 @@ function Options( {
|
|||
}
|
||||
};
|
||||
|
||||
const renderLoading = function () {
|
||||
return (
|
||||
<tr>
|
||||
<td colSpan="4" align="center">
|
||||
Loading...
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
};
|
||||
|
||||
const renderTableData = function () {
|
||||
if ( options.length === 0 ) {
|
||||
return (
|
||||
<tr>
|
||||
<td colSpan="4" align="center">
|
||||
No Options Found
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
|
||||
return options.map( ( option ) => {
|
||||
// eslint-disable-next-line camelcase
|
||||
const { option_id, option_name, autoload } = option;
|
||||
|
@ -53,14 +74,13 @@ function Options( {
|
|||
|
||||
const searchOption = function ( event ) {
|
||||
event.preventDefault();
|
||||
let keyword = event.target.search.value;
|
||||
if ( keyword === '' ) {
|
||||
keyword = undefined;
|
||||
}
|
||||
getOptions( keyword );
|
||||
const keyword = event.target.search.value;
|
||||
|
||||
// force invlidation of the cached selector resolvers
|
||||
invalidateResolutionForStoreSelector( 'getOptions' );
|
||||
// Invalidate resolution of the same selector + arg
|
||||
// so that entering the same keyword always works
|
||||
invalidateResolution( STORE_KEY, 'getOptions', [ keyword ] );
|
||||
|
||||
getOptions( keyword );
|
||||
};
|
||||
|
||||
return (
|
||||
|
@ -100,7 +120,9 @@ function Options( {
|
|||
</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>{ renderTableData() }</tbody>
|
||||
<tbody>
|
||||
{ isLoading ? renderLoading() : renderTableData() }
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
);
|
||||
|
@ -108,15 +130,15 @@ function Options( {
|
|||
|
||||
export default compose(
|
||||
withSelect( ( select ) => {
|
||||
const { getOptions } = select( STORE_KEY );
|
||||
const { getOptions, isLoading } = select( STORE_KEY );
|
||||
const options = getOptions();
|
||||
return { options, getOptions };
|
||||
|
||||
return { options, getOptions, isLoading: isLoading() };
|
||||
} ),
|
||||
withDispatch( ( dispatch ) => {
|
||||
const {
|
||||
deleteOptionById,
|
||||
invalidateResolutionForStoreSelector,
|
||||
} = dispatch( STORE_KEY );
|
||||
return { deleteOptionById, invalidateResolutionForStoreSelector };
|
||||
const { deleteOptionById } = dispatch( STORE_KEY );
|
||||
const { invalidateResolution } = dispatch( 'core/data' );
|
||||
|
||||
return { deleteOptionById, invalidateResolution };
|
||||
} )
|
||||
)( Options );
|
||||
|
|
Loading…
Reference in New Issue