Merge pull request #37 from woocommerce/add/rest-api-filter
Add REST API Filters to modify API responses
This commit is contained in:
commit
27fea8b434
|
@ -37,3 +37,5 @@ require( 'tools/disable-wc-email.php' );
|
||||||
require( 'tools/trigger-update-callbacks.php' );
|
require( 'tools/trigger-update-callbacks.php' );
|
||||||
require( 'tracks/tracks-debug-log.php' );
|
require( 'tracks/tracks-debug-log.php' );
|
||||||
require( 'features/features.php' );
|
require( 'features/features.php' );
|
||||||
|
require( 'rest-api-filters/rest-api-filters.php' );
|
||||||
|
require( 'rest-api-filters/hook.php' );
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$filters = get_option(WCA_Test_Helper_Rest_Api_Filters::WC_ADMIN_TEST_HELPER_REST_API_FILTER_OPTION, [] );
|
||||||
|
|
||||||
|
function array_dot_set( &$array, $key, $value ) {
|
||||||
|
if ( is_null( $key ) ) {
|
||||||
|
return $array = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
$keys = explode('.', $key);
|
||||||
|
|
||||||
|
while ( count($keys) > 1 ) {
|
||||||
|
$key = array_shift($keys);
|
||||||
|
if (! isset($array[$key]) || ! is_array($array[$key]) ) {
|
||||||
|
$array[$key] = [];
|
||||||
|
}
|
||||||
|
$array = &$array[$key];
|
||||||
|
}
|
||||||
|
|
||||||
|
$array[ array_shift($keys) ] = $value;
|
||||||
|
return $array;
|
||||||
|
}
|
||||||
|
|
||||||
|
add_filter(
|
||||||
|
'rest_request_after_callbacks',
|
||||||
|
function ( $response, array $handler, \WP_REST_Request $request ) use ( $filters ) {
|
||||||
|
if (! $response instanceof \WP_REST_Response ) {
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
$route = $request->get_route();
|
||||||
|
$filters = array_filter(
|
||||||
|
$filters, function ( $filter ) use ( $request, $route ) {
|
||||||
|
if ($filter['enabled'] && $filter['endpoint'] == $route ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
$data = $response->get_data();
|
||||||
|
|
||||||
|
foreach ( $filters as $filter ) {
|
||||||
|
array_dot_set($data, $filter['dot_notation'], $filter['replacement']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$response->set_data($data);
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
},
|
||||||
|
10,
|
||||||
|
3
|
||||||
|
);
|
|
@ -0,0 +1,109 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
register_woocommerce_admin_test_helper_rest_route(
|
||||||
|
'/rest-api-filters',
|
||||||
|
[ WCA_Test_Helper_Rest_Api_Filters::class, 'create' ],
|
||||||
|
array(
|
||||||
|
'methods' => 'POST',
|
||||||
|
'args' => array(
|
||||||
|
'endpoint' => array(
|
||||||
|
'description' => 'Rest API endpoint.',
|
||||||
|
'type' => 'string',
|
||||||
|
'required' => true,
|
||||||
|
'sanitize_callback' => 'sanitize_text_field',
|
||||||
|
),
|
||||||
|
'dot_notation' => array(
|
||||||
|
'description' => 'Dot notation of the target field.',
|
||||||
|
'type' => 'string',
|
||||||
|
'required' => true,
|
||||||
|
'sanitize_callback' => 'sanitize_text_field',
|
||||||
|
),
|
||||||
|
'replacement' => array(
|
||||||
|
'description' => 'Replacement value for the target field.',
|
||||||
|
'type' => 'string',
|
||||||
|
'required' => true,
|
||||||
|
'sanitize_callback' => 'sanitize_text_field',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
register_woocommerce_admin_test_helper_rest_route(
|
||||||
|
'/rest-api-filters',
|
||||||
|
[ WCA_Test_Helper_Rest_Api_Filters::class, 'delete' ],
|
||||||
|
array(
|
||||||
|
'methods' => 'DELETE',
|
||||||
|
'args' => array(
|
||||||
|
'index' => array(
|
||||||
|
'description' => 'Rest API endpoint.',
|
||||||
|
'type' => 'integer',
|
||||||
|
'required' => true,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
register_woocommerce_admin_test_helper_rest_route(
|
||||||
|
'/rest-api-filters/(?P<index>\d+)/toggle',
|
||||||
|
[ WCA_Test_Helper_Rest_Api_Filters::class, 'toggle' ],
|
||||||
|
array(
|
||||||
|
'methods' => 'POST',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
class WCA_Test_Helper_Rest_Api_Filters {
|
||||||
|
const WC_ADMIN_TEST_HELPER_REST_API_FILTER_OPTION = 'wc-admin-test-helper-rest-api-filters';
|
||||||
|
|
||||||
|
public static function create( $request ) {
|
||||||
|
$endpoint = $request->get_param('endpoint');
|
||||||
|
$dot_notation = $request->get_param('dot_notation');
|
||||||
|
$replacement = $request->get_param('replacement');
|
||||||
|
|
||||||
|
self::update(
|
||||||
|
function ( $filters ) use (
|
||||||
|
$endpoint,
|
||||||
|
$dot_notation,
|
||||||
|
$replacement
|
||||||
|
) {
|
||||||
|
$filters[] = array(
|
||||||
|
'endpoint' => $endpoint,
|
||||||
|
'dot_notation' => $dot_notation,
|
||||||
|
'replacement' => filter_var( $replacement, FILTER_VALIDATE_BOOLEAN ),
|
||||||
|
'enabled' => true,
|
||||||
|
);
|
||||||
|
return $filters;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return new WP_REST_RESPONSE(null, 204);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function update( callable $callback ) {
|
||||||
|
$filters = get_option(self::WC_ADMIN_TEST_HELPER_REST_API_FILTER_OPTION, array());
|
||||||
|
$filters = $callback( $filters );
|
||||||
|
return update_option(self::WC_ADMIN_TEST_HELPER_REST_API_FILTER_OPTION, $filters);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function delete( $request ) {
|
||||||
|
self::update(
|
||||||
|
function ( $filters ) use ( $request ) {
|
||||||
|
array_splice($filters, $request->get_param('index'), 1);
|
||||||
|
return $filters;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return new WP_REST_RESPONSE(null, 204);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function toggle( $request ) {
|
||||||
|
self::update(
|
||||||
|
function ( $filters ) use ( $request ) {
|
||||||
|
$index = $request->get_param('index');
|
||||||
|
$filters[$index]['enabled'] = !$filters[$index]['enabled'];
|
||||||
|
return $filters;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return new WP_REST_RESPONSE(null, 204);
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,8 +12,9 @@ import { default as Tools } from '../tools';
|
||||||
import { default as Options } from '../options';
|
import { default as Options } from '../options';
|
||||||
import { default as Experiments } from '../experiments';
|
import { default as Experiments } from '../experiments';
|
||||||
import { default as Features } from '../features';
|
import { default as Features } from '../features';
|
||||||
|
import { default as RestAPIFilters } from '../rest-api-filters';
|
||||||
|
|
||||||
const tabs = applyFilters('woocommerce_admin_test_helper_tabs', [
|
const tabs = applyFilters( 'woocommerce_admin_test_helper_tabs', [
|
||||||
{
|
{
|
||||||
name: 'options',
|
name: 'options',
|
||||||
title: 'Options',
|
title: 'Options',
|
||||||
|
@ -39,7 +40,12 @@ const tabs = applyFilters('woocommerce_admin_test_helper_tabs', [
|
||||||
title: 'Features',
|
title: 'Features',
|
||||||
content: <Features />,
|
content: <Features />,
|
||||||
},
|
},
|
||||||
]);
|
{
|
||||||
|
name: 'rest-api-filters',
|
||||||
|
title: 'REST API FIlters',
|
||||||
|
content: <RestAPIFilters />,
|
||||||
|
},
|
||||||
|
] );
|
||||||
|
|
||||||
export function App() {
|
export function App() {
|
||||||
return (
|
return (
|
||||||
|
@ -48,18 +54,18 @@ export function App() {
|
||||||
<TabPanel
|
<TabPanel
|
||||||
className="woocommerce-admin-test-helper__main-tab-panel"
|
className="woocommerce-admin-test-helper__main-tab-panel"
|
||||||
activeClass="active-tab"
|
activeClass="active-tab"
|
||||||
tabs={tabs}
|
tabs={ tabs }
|
||||||
initialTabName={tabs[0].name}
|
initialTabName={ tabs[ 0 ].name }
|
||||||
>
|
>
|
||||||
{(tab) => (
|
{ ( tab ) => (
|
||||||
<>
|
<>
|
||||||
{tab.content}
|
{ tab.content }
|
||||||
{applyFilters(
|
{ applyFilters(
|
||||||
`woocommerce_admin_test_helper_tab_${tab.name}`,
|
`woocommerce_admin_test_helper_tab_${ tab.name }`,
|
||||||
[]
|
[]
|
||||||
)}
|
) }
|
||||||
</>
|
</>
|
||||||
)}
|
) }
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
153
src/index.scss
153
src/index.scss
|
@ -1,76 +1,117 @@
|
||||||
|
#woocommerce-admin-test-helper-app-root {
|
||||||
|
.btn-danger {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #dc3545;
|
||||||
|
border-color: #dc3545;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #007bff;
|
||||||
|
border-color: #007bff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.woocommerce-admin-test-helper__main-tab-panel {
|
.woocommerce-admin-test-helper__main-tab-panel {
|
||||||
.active-tab {
|
.active-tab {
|
||||||
box-shadow: inset 0 1.5px #007cba;
|
box-shadow: inset 0 1.5px #007cba;
|
||||||
box-shadow: inset 0 1.5px var(--wp-admin-theme-color);
|
box-shadow: inset 0 1.5px var( --wp-admin-theme-color );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.woocommerce-admin-test-helper__action-status {
|
.woocommerce-admin-test-helper__action-status {
|
||||||
color: #007cba;
|
color: #007cba;
|
||||||
color: var(--wp-admin-theme-color);
|
color: var( --wp-admin-theme-color );
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
}
|
}
|
||||||
|
|
||||||
.woocommerce-admin-test-helper__add-notes {
|
.woocommerce-admin-test-helper__add-notes {
|
||||||
width: 410px;
|
width: 410px;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
.components-base-control__field {
|
.components-base-control__field {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
padding-top: 3px;
|
padding-top: 3px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#wc-admin-test-helper-options {
|
#wc-admin-test-helper-options {
|
||||||
div.search-box {
|
div.search-box {
|
||||||
float: right;
|
float: right;
|
||||||
margin-bottom:10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-danger {
|
.align-center {
|
||||||
color: #fff;
|
text-align: center;
|
||||||
background-color: #dc3545;
|
}
|
||||||
border-color: #dc3545;
|
|
||||||
}
|
|
||||||
|
|
||||||
.align-center {
|
.components-notice {
|
||||||
text-align: center;
|
margin: 0px 0px 10px 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.components-notice {
|
|
||||||
margin: 0px 0px 10px 0px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.wca-test-helper-option-editor {
|
.wca-test-helper-option-editor {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 300px;
|
height: 300px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.wca-test-helper-edit-btn-save {
|
.wca-test-helper-edit-btn-save {
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
#wc-admin-test-helper-tools, #wc-admin-test-helper-experiments {
|
#wc-admin-test-helper-tools,
|
||||||
table.tools, table.experiments {
|
#wc-admin-test-helper-experiments {
|
||||||
thead th {
|
table.tools,
|
||||||
text-align: center;
|
table.experiments {
|
||||||
}
|
thead th {
|
||||||
tbody td {
|
text-align: center;
|
||||||
vertical-align: middle;
|
}
|
||||||
&.command {
|
tbody td {
|
||||||
white-space: nowrap;
|
vertical-align: middle;
|
||||||
}
|
&.command {
|
||||||
.trigger-cron-job {
|
white-space: nowrap;
|
||||||
width: 40%;
|
}
|
||||||
padding-top: 4px;
|
.trigger-cron-job {
|
||||||
.components-base-control__field {
|
width: 40%;
|
||||||
margin-bottom: 0;
|
padding-top: 4px;
|
||||||
}
|
.components-base-control__field {
|
||||||
}
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.components-notice {
|
}
|
||||||
margin: 0px 0px 10px 0px;
|
}
|
||||||
}
|
.components-notice {
|
||||||
}
|
margin: 0px 0px 10px 0px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#wc-admin-test-helper-rest-api-filters {
|
||||||
|
.btn-new {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
form.rest-api-filter-new-form {
|
||||||
|
.grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: max-content max-content;
|
||||||
|
grid-gap: 5px;
|
||||||
|
input[type='text'] {
|
||||||
|
width: 350px;
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
label:after {
|
||||||
|
content: ':';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-new {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #007bff;
|
||||||
|
border-color: #007bff;
|
||||||
|
float: right;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
const TYPES = {
|
||||||
|
SET_FILTERS: 'SET_FILTERS',
|
||||||
|
SET_IS_LOADING: 'SET_IS_LOADING',
|
||||||
|
DELETE_FILTER: 'DELETE_FILTER',
|
||||||
|
SAVE_FILTER: 'SAVE_FILTER',
|
||||||
|
TOGGLE_FILTER: 'TOGGLE_FILTER',
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TYPES;
|
|
@ -0,0 +1,93 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import { apiFetch } from '@wordpress/data-controls';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import TYPES from './action-types';
|
||||||
|
import { API_NAMESPACE } from './constants';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the state
|
||||||
|
*
|
||||||
|
* @param {Array} filter
|
||||||
|
* @param filters
|
||||||
|
*/
|
||||||
|
export function setFilters( filters ) {
|
||||||
|
return {
|
||||||
|
type: TYPES.SET_FILTERS,
|
||||||
|
filters,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setLoadingState( isLoading ) {
|
||||||
|
return {
|
||||||
|
type: TYPES.SET_IS_LOADING,
|
||||||
|
isLoading,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function* toggleFilter( index ) {
|
||||||
|
try {
|
||||||
|
yield apiFetch( {
|
||||||
|
method: 'POST',
|
||||||
|
path: `${ API_NAMESPACE }/rest-api-filters/${ index }/toggle`,
|
||||||
|
headers: { 'content-type': 'application/json' },
|
||||||
|
} );
|
||||||
|
yield {
|
||||||
|
type: TYPES.TOGGLE_FILTER,
|
||||||
|
index,
|
||||||
|
};
|
||||||
|
} catch {
|
||||||
|
throw new Error();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function* deleteFilter( index ) {
|
||||||
|
try {
|
||||||
|
yield apiFetch( {
|
||||||
|
method: 'DELETE',
|
||||||
|
path: `${ API_NAMESPACE }/rest-api-filters/`,
|
||||||
|
headers: { 'content-type': 'application/json' },
|
||||||
|
body: JSON.stringify( {
|
||||||
|
index,
|
||||||
|
} ),
|
||||||
|
} );
|
||||||
|
|
||||||
|
yield {
|
||||||
|
type: TYPES.DELETE_FILTER,
|
||||||
|
index,
|
||||||
|
};
|
||||||
|
} catch {
|
||||||
|
throw new Error();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function* saveFilter( endpoint, dotNotation, replacement ) {
|
||||||
|
try {
|
||||||
|
yield apiFetch( {
|
||||||
|
method: 'POST',
|
||||||
|
path: API_NAMESPACE + '/rest-api-filters',
|
||||||
|
headers: { 'content-type': 'application/json' },
|
||||||
|
body: JSON.stringify( {
|
||||||
|
endpoint,
|
||||||
|
dot_notation: dotNotation,
|
||||||
|
replacement,
|
||||||
|
} ),
|
||||||
|
} );
|
||||||
|
|
||||||
|
yield {
|
||||||
|
type: TYPES.SAVE_FILTER,
|
||||||
|
filter: {
|
||||||
|
endpoint,
|
||||||
|
dot_notation: dotNotation,
|
||||||
|
replacement,
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
} catch {
|
||||||
|
throw new Error();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
export const STORE_KEY = 'wc-admin-helper/rest-api-filters';
|
||||||
|
export const API_NAMESPACE = '/wc-admin-test-helper';
|
||||||
|
|
||||||
|
// Option name where we're going to save the filters.
|
||||||
|
export const FILTERS_OPTION_NAME = 'wc-admin-test-helper-rest-api-filters';
|
|
@ -0,0 +1,22 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import { registerStore } from '@wordpress/data';
|
||||||
|
import { controls } from '@wordpress/data-controls';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import * as actions from './actions';
|
||||||
|
import * as resolvers from './resolvers';
|
||||||
|
import * as selectors from './selectors';
|
||||||
|
import reducer from './reducer';
|
||||||
|
import { STORE_KEY } from './constants';
|
||||||
|
|
||||||
|
export default registerStore( STORE_KEY, {
|
||||||
|
actions,
|
||||||
|
selectors,
|
||||||
|
resolvers,
|
||||||
|
controls,
|
||||||
|
reducer,
|
||||||
|
} );
|
|
@ -0,0 +1,55 @@
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import TYPES from './action-types';
|
||||||
|
|
||||||
|
const DEFAULT_STATE = {
|
||||||
|
filters: [],
|
||||||
|
isLoading: true,
|
||||||
|
notice: {
|
||||||
|
status: 'success',
|
||||||
|
message: '',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const reducer = ( state = DEFAULT_STATE, action ) => {
|
||||||
|
switch ( action.type ) {
|
||||||
|
case TYPES.TOGGLE_FILTER:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
filters: state.filters.map( ( filter, index ) => {
|
||||||
|
if ( index === action.index ) {
|
||||||
|
filter.enabled = ! filter.enabled;
|
||||||
|
}
|
||||||
|
return filter;
|
||||||
|
} ),
|
||||||
|
};
|
||||||
|
case TYPES.SET_IS_LOADING:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
isLoading: action.isLoading,
|
||||||
|
};
|
||||||
|
case TYPES.SET_FILTERS:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
filters: action.filters,
|
||||||
|
isLoading: false,
|
||||||
|
};
|
||||||
|
case TYPES.DELETE_FILTER:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
filters: state.filters.filter(
|
||||||
|
( item, index ) => index !== action.index
|
||||||
|
),
|
||||||
|
};
|
||||||
|
case TYPES.SAVE_FILTER:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
filters: [ ...state.filters, action.filter ],
|
||||||
|
};
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default reducer;
|
|
@ -0,0 +1,29 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import { apiFetch } from '@wordpress/data-controls';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import { FILTERS_OPTION_NAME } from './constants';
|
||||||
|
import { setLoadingState, setFilters } from './actions';
|
||||||
|
|
||||||
|
export function* getFilters() {
|
||||||
|
const path = '/wc-admin/options?options=' + FILTERS_OPTION_NAME;
|
||||||
|
|
||||||
|
yield setLoadingState( true );
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = yield apiFetch( {
|
||||||
|
path,
|
||||||
|
} );
|
||||||
|
if ( response[ FILTERS_OPTION_NAME ] === false ) {
|
||||||
|
yield setFilters( [] );
|
||||||
|
} else {
|
||||||
|
yield setFilters( response[ FILTERS_OPTION_NAME ] );
|
||||||
|
}
|
||||||
|
} catch ( error ) {
|
||||||
|
throw new Error();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
export function getFilters( state ) {
|
||||||
|
return state.filters;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isLoading( state ) {
|
||||||
|
return state.isLoading;
|
||||||
|
}
|
|
@ -0,0 +1,182 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import { withDispatch, withSelect } from '@wordpress/data';
|
||||||
|
import { compose } from '@wordpress/compose';
|
||||||
|
import { Modal } from '@wordpress/components';
|
||||||
|
import { useState } from '@wordpress/element';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import { STORE_KEY } from './data/constants';
|
||||||
|
import './data';
|
||||||
|
|
||||||
|
function RestAPIFilters( {
|
||||||
|
filters,
|
||||||
|
deleteFilter,
|
||||||
|
isLoading,
|
||||||
|
saveFilter,
|
||||||
|
toggleFilter,
|
||||||
|
} ) {
|
||||||
|
const [ isNewModalOpen, setNewModalOpen ] = useState( false );
|
||||||
|
|
||||||
|
const submitAddForm = ( e ) => {
|
||||||
|
e.preventDefault();
|
||||||
|
saveFilter(
|
||||||
|
e.target.endpoint.value,
|
||||||
|
e.target.dotNotation.value,
|
||||||
|
e.target.replacement.value
|
||||||
|
);
|
||||||
|
setNewModalOpen( false );
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderLoading = () => {
|
||||||
|
return (
|
||||||
|
<tr>
|
||||||
|
<td colSpan="6" align="center">
|
||||||
|
Loading...
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderTableData = () => {
|
||||||
|
if ( filters.length === 0 ) {
|
||||||
|
return (
|
||||||
|
<tr>
|
||||||
|
<td colSpan="7" align="center">
|
||||||
|
No Filters Found
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return filters.map( ( filter, index ) => {
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
|
const {
|
||||||
|
endpoint,
|
||||||
|
dot_notation: dotNotation,
|
||||||
|
replacement,
|
||||||
|
enabled,
|
||||||
|
} = filter;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<tr key={ index }>
|
||||||
|
<td>{ index + 1 }</td>
|
||||||
|
<td>{ endpoint }</td>
|
||||||
|
<td key={ 'optionValue' }>{ dotNotation }</td>
|
||||||
|
<td className="align-center">{ replacement + '' }</td>
|
||||||
|
<td className="align-center">{ enabled + '' }</td>
|
||||||
|
<td className="align-center">
|
||||||
|
<button
|
||||||
|
className="button btn-primary"
|
||||||
|
onClick={ () => toggleFilter( index ) }
|
||||||
|
>
|
||||||
|
Toggle
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
<td className="align-center">
|
||||||
|
<button
|
||||||
|
className="button btn-danger"
|
||||||
|
onClick={ () => deleteFilter( index ) }
|
||||||
|
>
|
||||||
|
Delete
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
);
|
||||||
|
} );
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{ isNewModalOpen && (
|
||||||
|
<Modal
|
||||||
|
title={ 'New Filter' }
|
||||||
|
onRequestClose={ () => {
|
||||||
|
setNewModalOpen( false );
|
||||||
|
} }
|
||||||
|
>
|
||||||
|
<form
|
||||||
|
className="rest-api-filter-new-form"
|
||||||
|
onSubmit={ submitAddForm }
|
||||||
|
>
|
||||||
|
<div className="grid">
|
||||||
|
<label htmlFor="endpoint">Endpoint</label>
|
||||||
|
<input type="text" name="endpoint" autoFocus />
|
||||||
|
<label htmlFor="jsonPath">Dot Notation</label>
|
||||||
|
<input type="text" name="dotNotation" />
|
||||||
|
<label htmlFor="replacement">Replacement </label>
|
||||||
|
<input type="text" name="replacement" />
|
||||||
|
</div>
|
||||||
|
<input
|
||||||
|
type="submit"
|
||||||
|
value="Create New Filter"
|
||||||
|
className="button btn-new"
|
||||||
|
/>
|
||||||
|
</form>
|
||||||
|
</Modal>
|
||||||
|
) }
|
||||||
|
<div id="wc-admin-test-helper-rest-api-filters">
|
||||||
|
<input
|
||||||
|
type="button"
|
||||||
|
className="button btn-primary btn-new"
|
||||||
|
value="New Filter"
|
||||||
|
onClick={ () => setNewModalOpen( true ) }
|
||||||
|
/>
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<table className="wp-list-table striped table-view-list widefat">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td className="manage-column column-thumb">I.D</td>
|
||||||
|
<td className="manage-column column-thumb">
|
||||||
|
Endpoint
|
||||||
|
</td>
|
||||||
|
<td className="manage-column column-thumb">
|
||||||
|
Dot Notation
|
||||||
|
</td>
|
||||||
|
<td className="manage-column column-thumb align-center">
|
||||||
|
Replacement
|
||||||
|
</td>
|
||||||
|
<td className="manage-column column-thumb align-center">
|
||||||
|
Enabled
|
||||||
|
</td>
|
||||||
|
<td className="manage-column column-thumb align-center">
|
||||||
|
Toggle
|
||||||
|
</td>
|
||||||
|
<td className="manage-column column-thumb align-center"></td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{ isLoading ? renderLoading() : renderTableData() }
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default compose(
|
||||||
|
withSelect( ( select ) => {
|
||||||
|
const { getFilters, isLoading } = select( STORE_KEY );
|
||||||
|
const filters = getFilters();
|
||||||
|
|
||||||
|
return {
|
||||||
|
filters,
|
||||||
|
isLoading: isLoading(),
|
||||||
|
};
|
||||||
|
} ),
|
||||||
|
withDispatch( ( dispatch ) => {
|
||||||
|
const { saveFilter, deleteFilter, toggleFilter } = dispatch(
|
||||||
|
STORE_KEY
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
saveFilter,
|
||||||
|
deleteFilter,
|
||||||
|
toggleFilter,
|
||||||
|
};
|
||||||
|
} )
|
||||||
|
)( RestAPIFilters );
|
Loading…
Reference in New Issue