A feature tab to toggle features
This commit is contained in:
parent
83392f2526
commit
46cba23313
|
@ -36,3 +36,4 @@ require( 'tools/delete-all-products.php');
|
|||
require( 'tools/disable-wc-email.php' );
|
||||
require( 'tools/trigger-update-callbacks.php' );
|
||||
require( 'tracks/tracks-debug-log.php' );
|
||||
require( 'features/features.php' );
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
<?php
|
||||
use Automattic\WooCommerce\Admin\Features\Features;
|
||||
|
||||
const OPTION_NAME_PREFIX = 'wc_admin_helper_feature_values';
|
||||
|
||||
register_woocommerce_admin_test_helper_rest_route(
|
||||
'/features/(?P<feature_name>[a-z0-9_\-]+)/toggle',
|
||||
'toggle_feature',
|
||||
array(
|
||||
'methods' => 'POST',
|
||||
)
|
||||
);
|
||||
|
||||
register_woocommerce_admin_test_helper_rest_route(
|
||||
'/features',
|
||||
'get_features',
|
||||
array(
|
||||
'methods' => 'GET',
|
||||
)
|
||||
);
|
||||
|
||||
register_woocommerce_admin_test_helper_rest_route(
|
||||
'/features/reset',
|
||||
'reset_features',
|
||||
array(
|
||||
'methods' => 'POST',
|
||||
)
|
||||
);
|
||||
|
||||
function toggle_feature( $request ) {
|
||||
$features = get_features();
|
||||
$custom_feature_values = get_option( OPTION_NAME_PREFIX, array() );
|
||||
$feature_name = $request->get_param( 'feature_name' );
|
||||
|
||||
if ( ! isset( $features[$feature_name ]) ) {
|
||||
return new WP_REST_Response( $features, 204 );
|
||||
}
|
||||
|
||||
if ( isset( $custom_feature_values[$feature_name] ) ) {
|
||||
unset( $custom_feature_values[$feature_name] );
|
||||
} else {
|
||||
$custom_feature_values[$feature_name] = ! $features[ $feature_name ];
|
||||
}
|
||||
|
||||
update_option(OPTION_NAME_PREFIX, $custom_feature_values );
|
||||
return new WP_REST_Response( get_features(), 200 );
|
||||
}
|
||||
|
||||
function reset_features() {
|
||||
delete_option( OPTION_NAME_PREFIX );
|
||||
return new WP_REST_Response( get_features(), 200 );
|
||||
}
|
||||
|
||||
function get_features() {
|
||||
if ( function_exists( 'wc_admin_get_feature_config' ) ) {
|
||||
return apply_filters( 'woocommerce_admin_get_feature_config', wc_admin_get_feature_config() );
|
||||
}
|
||||
return array();
|
||||
}
|
10
plugin.php
10
plugin.php
|
@ -14,3 +14,13 @@ add_action( 'admin_menu', function() {
|
|||
add_action( 'wp_loaded', function() {
|
||||
require( 'api/api.php' );
|
||||
} );
|
||||
|
||||
add_filter( 'woocommerce_admin_get_feature_config', function( $feature_config ) {
|
||||
$custom_feature_values = get_option( 'wc_admin_helper_feature_values', array() );
|
||||
foreach ( $custom_feature_values as $feature => $value ) {
|
||||
if ( isset( $feature_config[$feature] ) ) {
|
||||
$feature_config[$feature] = $value;
|
||||
}
|
||||
}
|
||||
return $feature_config;
|
||||
} );
|
|
@ -11,6 +11,7 @@ import { AdminNotes } from '../admin-notes';
|
|||
import { default as Tools } from '../tools';
|
||||
import { default as Options } from '../options';
|
||||
import { default as Experiments } from '../experiments';
|
||||
import { default as Features } from '../features';
|
||||
|
||||
const tabs = applyFilters('woocommerce_admin_test_helper_tabs', [
|
||||
{
|
||||
|
@ -33,6 +34,11 @@ const tabs = applyFilters('woocommerce_admin_test_helper_tabs', [
|
|||
title: 'Experiments',
|
||||
content: <Experiments />,
|
||||
},
|
||||
{
|
||||
name: 'features',
|
||||
title: 'Features',
|
||||
content: <Features />,
|
||||
},
|
||||
]);
|
||||
|
||||
export function App() {
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
const TYPES = {
|
||||
TOGGLE_FEATURE: 'TOGGLE_FEATURE',
|
||||
SET_FEATURES: 'SET_FEATURES',
|
||||
SET_MODIFIED_FEATURES: 'SET_MODIFIED_FEATURES',
|
||||
};
|
||||
|
||||
export default TYPES;
|
|
@ -0,0 +1,51 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { apiFetch } from '@wordpress/data-controls';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import TYPES from './action-types';
|
||||
import { API_NAMESPACE } from './constants';
|
||||
|
||||
export function* resetModifiedFeatures() {
|
||||
try {
|
||||
const response = yield apiFetch({
|
||||
path: `${API_NAMESPACE}/features/reset`,
|
||||
method: 'POST',
|
||||
});
|
||||
|
||||
yield setModifiedFeatures([]);
|
||||
yield setFeatures(response);
|
||||
} catch (error) {
|
||||
throw new Error();
|
||||
}
|
||||
}
|
||||
|
||||
export function* toggleFeature(featureName) {
|
||||
try {
|
||||
const response = yield apiFetch({
|
||||
method: 'POST',
|
||||
path: API_NAMESPACE + '/features/' + featureName + '/toggle',
|
||||
headers: { 'content-type': 'application/json' },
|
||||
});
|
||||
return yield setFeatures(response);
|
||||
} catch (error) {
|
||||
throw new Error();
|
||||
}
|
||||
}
|
||||
|
||||
export function setFeatures(features) {
|
||||
return {
|
||||
type: TYPES.SET_FEATURES,
|
||||
features,
|
||||
};
|
||||
}
|
||||
|
||||
export function setModifiedFeatures(modifiedFeatures) {
|
||||
return {
|
||||
type: TYPES.SET_MODIFIED_FEATURES,
|
||||
modifiedFeatures,
|
||||
};
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
export const STORE_KEY = 'wc-admin-helper/features';
|
||||
export const OPTION_NAME_PREFIX = 'wc_admin_helper_feature_values';
|
||||
export const API_NAMESPACE = '/wc-admin-test-helper';
|
|
@ -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,28 @@
|
|||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import TYPES from './action-types';
|
||||
|
||||
const DEFAULT_STATE = {
|
||||
features: {},
|
||||
modifiedFeatures: [],
|
||||
};
|
||||
|
||||
const reducer = (state = DEFAULT_STATE, action) => {
|
||||
switch (action.type) {
|
||||
case TYPES.SET_MODIFIED_FEATURES:
|
||||
return {
|
||||
...state,
|
||||
modifiedFeatures: action.modifiedFeatures,
|
||||
};
|
||||
case TYPES.SET_FEATURES:
|
||||
return {
|
||||
...state,
|
||||
features: action.features,
|
||||
};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
||||
export default reducer;
|
|
@ -0,0 +1,34 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { apiFetch } from '@wordpress/data-controls';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { setFeatures, setModifiedFeatures } from './actions';
|
||||
import { API_NAMESPACE, OPTION_NAME_PREFIX } from './constants';
|
||||
|
||||
export function* getModifiedFeatures() {
|
||||
try {
|
||||
const response = yield apiFetch({
|
||||
path: `${API_NAMESPACE}/options?search=` + OPTION_NAME_PREFIX,
|
||||
});
|
||||
|
||||
yield setModifiedFeatures(Object.keys(response));
|
||||
} catch (error) {
|
||||
throw new Error();
|
||||
}
|
||||
}
|
||||
|
||||
export function* getFeatures() {
|
||||
try {
|
||||
const response = yield apiFetch({
|
||||
path: `${API_NAMESPACE}/features`,
|
||||
});
|
||||
|
||||
yield setFeatures(response);
|
||||
} catch (error) {
|
||||
throw new Error();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
export function getFeatures(state) {
|
||||
return state.features;
|
||||
}
|
||||
|
||||
export function getModifiedFeatures(state) {
|
||||
return state.modifiedFeatures;
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { useDispatch, useSelect } from '@wordpress/data';
|
||||
import { Button } from '@wordpress/components';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { STORE_KEY } from './data/constants';
|
||||
import './data';
|
||||
|
||||
function Features() {
|
||||
const { features = {}, modifiedFeatures = [] } = useSelect((select) => {
|
||||
const { getFeatures, getModifiedFeatures } = select(STORE_KEY);
|
||||
return {
|
||||
features: getFeatures(),
|
||||
modifiedFeatures: getModifiedFeatures(),
|
||||
};
|
||||
});
|
||||
|
||||
const { toggleFeature, resetModifiedFeatures } = useDispatch(STORE_KEY);
|
||||
|
||||
return (
|
||||
<div id="wc-admin-test-helper-features">
|
||||
<h2>Features</h2>
|
||||
<Button
|
||||
disabled={modifiedFeatures.length === 0}
|
||||
onClick={() => resetModifiedFeatures()}
|
||||
>
|
||||
Reset to defaults
|
||||
</Button>
|
||||
<table className="features wp-list-table striped table-view-list widefat">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Feature Name</th>
|
||||
<th>Enabled?</th>
|
||||
<th>Toggle</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{Object.keys(features).map((feature_name) => {
|
||||
return (
|
||||
<tr key={feature_name}>
|
||||
<td className="feature-name">{feature_name}</td>
|
||||
<td>{features[feature_name].toString()}</td>
|
||||
<td>
|
||||
<Button
|
||||
onClick={() => {
|
||||
toggleFeature(feature_name);
|
||||
}}
|
||||
isPrimary
|
||||
>
|
||||
Toggle
|
||||
</Button>
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Features;
|
Loading…
Reference in New Issue