diff --git a/bootstrap.php b/bootstrap.php index 962ac77f1..f76b29e29 100644 --- a/bootstrap.php +++ b/bootstrap.php @@ -12,6 +12,7 @@ use NewfoldLabs\WP\ModuleLoader\Container; use NewfoldLabs\WP\ModuleLoader\Plugin; use NewfoldLabs\WP\Context\Context; +use NewfoldLabs\WP\Module\Features\Features; use function NewfoldLabs\WP\ModuleLoader\container as setContainer; use function NewfoldLabs\WP\Context\setContext; use function NewfoldLabs\WP\Context\getContext; @@ -199,3 +200,6 @@ function () { if ( is_admin() ) { new Admin(); } + +// Instantiate the Features singleton +Features::getInstance(); diff --git a/composer.json b/composer.json index cc2b3dade..ce7442043 100644 --- a/composer.json +++ b/composer.json @@ -70,28 +70,30 @@ "roave/security-advisories": "dev-latest", "newfold-labs/wp-php-standards": "^1.2.3", "wp-cli/i18n-command": "^2.6.1", - "wp-phpunit/wp-phpunit": "^6.5.2" + "wp-phpunit/wp-phpunit": "^6.5.3" }, "require": { "newfold-labs/wp-module-activation": "^1.0.2", + "newfold-labs/wp-module-atomic": "^1.2.0", "newfold-labs/wp-module-coming-soon": "^1.2.3", - "newfold-labs/wp-module-context": "^1.0.0", + "newfold-labs/wp-module-context": "^1.0.1", "newfold-labs/wp-module-data": "^2.5.0", "newfold-labs/wp-module-deactivation": "^1.1.2", "newfold-labs/wp-module-ecommerce": "^1.3.31", + "newfold-labs/wp-module-features": "^1.4.1", "newfold-labs/wp-module-global-ctb": "^1.0.11", - "newfold-labs/wp-module-facebook": "^1.0.6", - "newfold-labs/wp-module-help-center": "^1.0.25", + "newfold-labs/wp-module-facebook": "^1.0.7", + "newfold-labs/wp-module-help-center": "^2.0.0", "newfold-labs/wp-module-loader": "^1.0.10", "newfold-labs/wp-module-marketplace": "^2.2.4", "newfold-labs/wp-module-notifications": "^1.3.0", "newfold-labs/wp-module-onboarding": "^2.3.2", - "newfold-labs/wp-module-patterns": "^1.0.0", - "newfold-labs/wp-module-performance": "^1.4.1", + "newfold-labs/wp-module-patterns": "2.0.0 as 1.9.9", + "newfold-labs/wp-module-performance": "2.0.0 as 1.9.9", "newfold-labs/wp-module-runtime": "^1.0.11", "newfold-labs/wp-module-secure-passwords": "^1.1.1", "newfold-labs/wp-module-sso": "^1.0.5", - "newfold-labs/wp-module-staging": "^1.3.3", + "newfold-labs/wp-module-staging": "^2.0.0", "wp-forge/wp-update-handler": "^1.0.2", "wp-forge/wp-upgrade-handler": "^1.0" } diff --git a/composer.lock b/composer.lock index 2d4ebfb60..b6569b0c3 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "58534e07ba922d999682c7939a7f3f71", + "content-hash": "dbf95386853f10764034496007450852", "packages": [ { "name": "doctrine/inflector", @@ -341,6 +341,59 @@ }, "time": "2024-05-20T17:10:20+00:00" }, + { + "name": "newfold-labs/wp-module-atomic", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/newfold-labs/wp-module-atomic.git", + "reference": "d18b3839f65b6c3fab9fbad52d632be5f1ee321f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/newfold-labs/wp-module-atomic/zipball/d18b3839f65b6c3fab9fbad52d632be5f1ee321f", + "reference": "d18b3839f65b6c3fab9fbad52d632be5f1ee321f", + "shasum": "" + }, + "require": { + "newfold-labs/wp-module-context": "^1.0" + }, + "require-dev": { + "newfold-labs/wp-php-standards": "^1.2.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "NewfoldLabs\\WP\\Module\\Atomic\\": "includes" + }, + "files": [ + "bootstrap.php" + ] + }, + "scripts": { + "fix": [ + "vendor/bin/phpcbf . --standard=phpcs.xml" + ], + "lint": [ + "vendor/bin/phpcs . --standard=phpcs.xml -s" + ] + }, + "license": [ + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "Evan Mullins", + "homepage": "https://evanmullins.com" + } + ], + "description": "A module to customize a brand plugin for wp cloud environments.", + "support": { + "source": "https://github.com/newfold-labs/wp-module-atomic/tree/1.2.0", + "issues": "https://github.com/newfold-labs/wp-module-atomic/issues" + }, + "time": "2024-05-28T20:14:15+00:00" + }, { "name": "newfold-labs/wp-module-coming-soon", "version": "1.2.3", @@ -451,19 +504,20 @@ }, { "name": "newfold-labs/wp-module-data", - "version": "2.5.0", + "version": "2.5.1", "source": { "type": "git", "url": "https://github.com/newfold-labs/wp-module-data.git", - "reference": "42bdfdece373e194b405f6b9a9e2a9e07154dfb9" + "reference": "b9cb6839f891ee05b77b98ca2f961fc8dfac5112" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/newfold-labs/wp-module-data/zipball/42bdfdece373e194b405f6b9a9e2a9e07154dfb9", - "reference": "42bdfdece373e194b405f6b9a9e2a9e07154dfb9", + "url": "https://api.github.com/repos/newfold-labs/wp-module-data/zipball/b9cb6839f891ee05b77b98ca2f961fc8dfac5112", + "reference": "b9cb6839f891ee05b77b98ca2f961fc8dfac5112", "shasum": "" }, "require": { + "ext-json": "*", "newfold-labs/wp-module-loader": "^1.0", "wp-forge/helpers": "^2.0", "wp-forge/wp-query-builder": "^1.0", @@ -493,6 +547,9 @@ "fix": [ "vendor/bin/phpcbf . --standard=phpcs.xml" ], + "cs-changes": [ + "updated_files=$( git status | grep '\\(new file\\|modified\\):\\s.*.php$' | cut -c14- | awk '{ printf(\"%s \", $0) }' ); echo \"\\nChecking\"$(git status | grep '\\(new file\\|modified\\):\\s.*.php$' | tail -n+2 | wc -l)\" files\"; phpcbf $(echo $updated_files); phpcs $(echo $updated_files);" + ], "lint": [ "vendor/bin/phpcs . --standard=phpcs.xml -s" ] @@ -502,10 +559,10 @@ ], "description": "Newfold Data Module", "support": { - "source": "https://github.com/newfold-labs/wp-module-data/tree/2.5.0", + "source": "https://github.com/newfold-labs/wp-module-data/tree/2.5.1", "issues": "https://github.com/newfold-labs/wp-module-data/issues" }, - "time": "2024-05-15T00:31:16+00:00" + "time": "2024-05-28T14:16:02+00:00" }, { "name": "newfold-labs/wp-module-deactivation", @@ -669,6 +726,63 @@ }, "time": "2024-05-03T10:09:41+00:00" }, + { + "name": "newfold-labs/wp-module-features", + "version": "1.4.1", + "source": { + "type": "git", + "url": "https://github.com/newfold-labs/wp-module-features.git", + "reference": "d22ca49d2235ac7797fa6ad315ceaf7edec9bd31" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/newfold-labs/wp-module-features/zipball/d22ca49d2235ac7797fa6ad315ceaf7edec9bd31", + "reference": "d22ca49d2235ac7797fa6ad315ceaf7edec9bd31", + "shasum": "" + }, + "require": { + "wp-forge/wp-options": "^1.1.1" + }, + "require-dev": { + "newfold-labs/wp-php-standards": "^1.2.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "NewfoldLabs\\WP\\Module\\Features\\": "includes" + }, + "files": [ + "includes/functions.php" + ] + }, + "scripts": { + "fix": [ + "vendor/bin/phpcbf . --standard=phpcs.xml" + ], + "lint": [ + "vendor/bin/phpcs . --standard=phpcs.xml -s" + ] + }, + "license": [ + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "Micah Wood", + "homepage": "https://wpscholar.com" + }, + { + "name": "Evan Mullins", + "homepage": "https://evanmullins.com" + } + ], + "description": "A module for providing an interface for features.", + "support": { + "source": "https://github.com/newfold-labs/wp-module-features/tree/1.4.1", + "issues": "https://github.com/newfold-labs/wp-module-features/issues" + }, + "time": "2024-05-28T18:01:46+00:00" + }, { "name": "newfold-labs/wp-module-global-ctb", "version": "1.0.11", @@ -721,21 +835,22 @@ }, { "name": "newfold-labs/wp-module-help-center", - "version": "1.0.25", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/newfold-labs/wp-module-help-center.git", - "reference": "6ec172715dcc43103b790878be4ac38e4223ce13" + "reference": "da9d0d08d5067285c7d36d31b8db58434af2184e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/newfold-labs/wp-module-help-center/zipball/6ec172715dcc43103b790878be4ac38e4223ce13", - "reference": "6ec172715dcc43103b790878be4ac38e4223ce13", + "url": "https://api.github.com/repos/newfold-labs/wp-module-help-center/zipball/da9d0d08d5067285c7d36d31b8db58434af2184e", + "reference": "da9d0d08d5067285c7d36d31b8db58434af2184e", "shasum": "" }, "require": { - "newfold-labs/wp-module-ai": "^1.1.7", - "newfold-labs/wp-module-data": "^2.3.4" + "newfold-labs/wp-module-ai": "^1.1.9", + "newfold-labs/wp-module-data": "^2.5.0", + "newfold-labs/wp-module-features": "^1.4.1" }, "require-dev": { "newfold-labs/wp-php-standards": "@stable" @@ -760,10 +875,10 @@ ], "description": "HelpCenter", "support": { - "source": "https://github.com/newfold-labs/wp-module-help-center/tree/1.0.25", + "source": "https://github.com/newfold-labs/wp-module-help-center/tree/2.0.0", "issues": "https://github.com/newfold-labs/wp-module-help-center/issues" }, - "time": "2024-04-26T13:58:31+00:00" + "time": "2024-05-29T14:37:29+00:00" }, { "name": "newfold-labs/wp-module-install-checker", @@ -1163,20 +1278,24 @@ }, { "name": "newfold-labs/wp-module-patterns", - "version": "1.0.0", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/newfold-labs/wp-module-patterns.git", - "reference": "3f41c4cc25b27f1e488a9cc2ffd82f5bc953128a" + "reference": "89c05ae08ebffe28521c876eb839a7bc9b60d02a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/newfold-labs/wp-module-patterns/zipball/3f41c4cc25b27f1e488a9cc2ffd82f5bc953128a", - "reference": "3f41c4cc25b27f1e488a9cc2ffd82f5bc953128a", + "url": "https://api.github.com/repos/newfold-labs/wp-module-patterns/zipball/89c05ae08ebffe28521c876eb839a7bc9b60d02a", + "reference": "89c05ae08ebffe28521c876eb839a7bc9b60d02a", "shasum": "" }, + "require": { + "newfold-labs/wp-module-data": "^2.5.1", + "newfold-labs/wp-module-features": "^1.4" + }, "require-dev": { - "newfold-labs/wp-php-standards": "^1.2" + "newfold-labs/wp-php-standards": "^1.2.2" }, "type": "library", "autoload": { @@ -1206,30 +1325,34 @@ ], "description": "WordPress Cloud Patterns", "support": { - "source": "https://github.com/newfold-labs/wp-module-patterns/tree/1.0.0", + "source": "https://github.com/newfold-labs/wp-module-patterns/tree/2.0.0", "issues": "https://github.com/newfold-labs/wp-module-patterns/issues" }, - "time": "2024-05-01T20:37:14+00:00" + "time": "2024-05-29T16:10:58+00:00" }, { "name": "newfold-labs/wp-module-performance", - "version": "1.4.1", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/newfold-labs/wp-module-performance.git", - "reference": "5e4c87d404788c61ea55e3c62e29e5df48c36340" + "reference": "91021b0f90e8a778fc7b96e71d1d4b25c1eebdfb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/newfold-labs/wp-module-performance/zipball/5e4c87d404788c61ea55e3c62e29e5df48c36340", - "reference": "5e4c87d404788c61ea55e3c62e29e5df48c36340", + "url": "https://api.github.com/repos/newfold-labs/wp-module-performance/zipball/91021b0f90e8a778fc7b96e71d1d4b25c1eebdfb", + "reference": "91021b0f90e8a778fc7b96e71d1d4b25c1eebdfb", "shasum": "" }, "require": { "newfold-labs/wp-module-context": "^1.0", - "wp-forge/collection": "^1.0", + "newfold-labs/wp-module-features": "^1.3", + "wp-forge/collection": "^1.0.2", "wp-forge/wp-htaccess-manager": "^1.0", - "wpscholar/url": "^1.2" + "wpscholar/url": "^1.2.2" + }, + "require-dev": { + "newfold-labs/wp-php-standards": "^1.2.3" }, "type": "library", "autoload": { @@ -1237,6 +1360,7 @@ "NewfoldLabs\\WP\\Module\\Performance\\": "includes" }, "files": [ + "includes/PerformanceFeature.php", "includes/functions.php", "bootstrap.php" ] @@ -1252,10 +1376,10 @@ ], "description": "A module for managing caching functionality.", "support": { - "source": "https://github.com/newfold-labs/wp-module-performance/tree/1.4.1", + "source": "https://github.com/newfold-labs/wp-module-performance/tree/2.0.0", "issues": "https://github.com/newfold-labs/wp-module-performance/issues" }, - "time": "2024-04-22T22:30:42+00:00" + "time": "2024-05-29T15:57:11+00:00" }, { "name": "newfold-labs/wp-module-runtime", @@ -1405,23 +1529,24 @@ }, { "name": "newfold-labs/wp-module-staging", - "version": "1.3.3", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/newfold-labs/wp-module-staging.git", - "reference": "c464472e3a5886d9639563262e776b33f8135398" + "reference": "dae822eec83521f6538844877ee98e637004514d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/newfold-labs/wp-module-staging/zipball/c464472e3a5886d9639563262e776b33f8135398", - "reference": "c464472e3a5886d9639563262e776b33f8135398", + "url": "https://api.github.com/repos/newfold-labs/wp-module-staging/zipball/dae822eec83521f6538844877ee98e637004514d", + "reference": "dae822eec83521f6538844877ee98e637004514d", "shasum": "" }, "require": { - "newfold-labs/wp-module-context": "^1.0" + "newfold-labs/wp-module-context": "^1.0", + "newfold-labs/wp-module-features": "^1.3.0" }, "require-dev": { - "newfold-labs/wp-php-standards": "^1.2" + "newfold-labs/wp-php-standards": "^1.2.2" }, "type": "library", "autoload": { @@ -1451,10 +1576,10 @@ ], "description": "Newfold module for staging functionality in brand plugins", "support": { - "source": "https://github.com/newfold-labs/wp-module-staging/tree/1.3.3", + "source": "https://github.com/newfold-labs/wp-module-staging/tree/2.0.0", "issues": "https://github.com/newfold-labs/wp-module-staging/issues" }, - "time": "2024-04-10T20:37:51+00:00" + "time": "2024-05-29T14:18:17+00:00" }, { "name": "wp-cli/wp-config-transformer", @@ -4062,7 +4187,20 @@ "time": "2024-05-07T16:46:52+00:00" } ], - "aliases": [], + "aliases": [ + { + "package": "newfold-labs/wp-module-patterns", + "version": "2.0.0.0", + "alias": "1.9.9", + "alias_normalized": "1.9.9.0" + }, + { + "package": "newfold-labs/wp-module-performance", + "version": "2.0.0.0", + "alias": "1.9.9", + "alias_normalized": "1.9.9.0" + } + ], "minimum-stability": "stable", "stability-flags": { "roave/security-advisories": 20 diff --git a/inc/Admin.php b/inc/Admin.php index 0b9e50ce2..4a63d288c 100644 --- a/inc/Admin.php +++ b/inc/Admin.php @@ -8,6 +8,7 @@ namespace Bluehost; use function NewfoldLabs\WP\Context\getContext; +use function NewfoldLabs\WP\Module\Features\isEnabled; /** * \Bluehost\Admin @@ -63,43 +64,37 @@ public static function add_to_runtime( $sdk ) { public static function subpages() { global $bluehost_module_container; - $home = array( + $home = array( 'bluehost#/home' => __( 'Home', 'wp-plugin-bluehost' ), ); - $pagesAndPosts = array( + $pagesAndPosts = array( 'bluehost#/pages-and-posts' => __( 'Pages & Posts', 'wp-plugin-bluehost' ), ); - $store = array( + $store = array( 'bluehost#/store' => __( 'Store', 'wp-plugin-bluehost' ), ); - $marketplace = array( + $marketplace = array( 'bluehost#/marketplace' => __( 'Marketplace', 'wp-plugin-bluehost' ), ); - $performance = array( - 'bluehost#/performance' => __( 'Performance', 'wp-plugin-bluehost' ), - ); + // add performance if enabled + $performance = isEnabled( 'performance' ) + ? array( + 'bluehost#/performance' => __( 'Performance', 'wp-plugin-bluehost' ), + ) + : array(); $settings = array( 'bluehost#/settings' => __( 'Settings', 'wp-plugin-bluehost' ), ); - $staging = array( - 'bluehost#/staging' => __( 'Staging', 'wp-plugin-bluehost' ), - ); - $help = array( + // add staging if enabled + $staging = isEnabled( 'staging' ) + ? array( + 'bluehost#/staging' => __( 'Staging', 'wp-plugin-bluehost' ), + ) + : array(); + $help = array( 'bluehost#/help' => __( 'Help', 'wp-plugin-bluehost' ), ); - // wp-cloud adjustments - if ( 'atomic' === getContext( 'platform' ) ) { - return array_merge( - $home, - $pagesAndPosts, - $store, - $marketplace, - $settings, - $help - ); - } - return array_merge( $home, $pagesAndPosts, @@ -208,7 +203,7 @@ public static function assets( $hook ) { \wp_register_script( 'bluehost-script', BLUEHOST_BUILD_URL . '/index.js', - array_merge( $asset['dependencies'], array( 'nfd-runtime' ) ), + array_merge( $asset['dependencies'], array( 'newfold-features', 'nfd-runtime' ) ), $asset['version'], true ); diff --git a/phpcs.xml b/phpcs.xml index 6c5fe9342..e1fe85a4b 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -2,7 +2,7 @@ - + /assets /build diff --git a/src/app/data/routes.js b/src/app/data/routes.js index 6826209fa..aa04a7f89 100644 --- a/src/app/data/routes.js +++ b/src/app/data/routes.js @@ -17,6 +17,7 @@ import Performance from '../pages/performance'; import Settings from '../pages/settings'; import Staging from '../pages/staging'; import Help from '../pages/help'; +import Admin from '../pages/admin'; import { getMarketplaceSubnavRoutes } from '@modules/wp-module-marketplace/components/marketplaceSubnav'; import { ReactComponent as HelpIcon } from '../components/icons/HelpIcon.svg'; import PagesAndPosts from '../pages/pages-and-posts'; @@ -133,7 +134,7 @@ export const routes = [ title: __( 'Performance', 'wp-plugin-bluehost' ), Component: Performance, Icon: BoltIcon, - condition: 'atomic' !== window.NewfoldRuntime.context.platform, + condition: await window.NewfoldFeatures.isEnabled( 'performance' ), }, { name: '/settings', @@ -147,7 +148,7 @@ export const routes = [ title: __( 'Staging', 'wp-plugin-bluehost' ), Component: Staging, Icon: WrenchScrewdriverIcon, - condition: 'atomic' !== window.NewfoldRuntime.context.platform, + condition: await window.NewfoldFeatures.isEnabled( 'staging' ), }, { name: '/help', @@ -159,6 +160,12 @@ export const routes = [ ? HelpCenterAI : false, }, + { + name: '/admin', + title: __( 'Admin', 'wp-plugin-bluehost' ), + Component: Admin, + condition: true, + }, ]; export const topRoutes = _filter( routes, ( route ) => diff --git a/src/app/data/store.js b/src/app/data/store.js index 64def0fe8..f3d70399a 100644 --- a/src/app/data/store.js +++ b/src/app/data/store.js @@ -37,7 +37,12 @@ export const AppStoreProvider = ( { children } ) => { if ( false === booted ) { bluehostApiFetchSettings() .then( ( settings ) => { - setStore( { ...store, ...settings } ); + setStore( { + ...store, + ...settings, + features: window.NewfoldFeatures.features, + toggleableFeatures: window.NewfoldFeatures.togglable, + } ); setBooted( true ); } ) .catch( ( error ) => { diff --git a/src/app/pages/admin/index.js b/src/app/pages/admin/index.js new file mode 100644 index 000000000..4f0e2dcd2 --- /dev/null +++ b/src/app/pages/admin/index.js @@ -0,0 +1,44 @@ +import classNames from 'classnames'; +import HelpCenterSettings from '../settings/helpCenterSettings'; +import WonderBlocksSettings from '../settings/wonderBlocksSettings'; +import StagingFeatureSettings from '../settings/stagingFeatureSettings'; +import PerformanceFeatureSettings from '../settings/performanceFeatureSettings'; +import { Container, Page } from '@newfold/ui-component-library'; + +const Admin = () => { + return ( + + + + + + + +
+ +
+ +
+ +
+
+
+
+ ); +}; + +export default Admin; diff --git a/src/app/pages/settings/helpCenterSettings.js b/src/app/pages/settings/helpCenterSettings.js new file mode 100644 index 000000000..56fa6a6ae --- /dev/null +++ b/src/app/pages/settings/helpCenterSettings.js @@ -0,0 +1,104 @@ +import { useState } from '@wordpress/element'; +import { useUpdateEffect } from 'react-use'; +import { Alert, ToggleField } from '@newfold/ui-component-library'; +import AppStore from '../../data/store'; +import { featureToggle, updateUI } from '../../util/helpers'; +import { useNotification } from 'App/components/notifications'; + +const HelpCenterSettings = ( { forceShow = false } ) => { + const { store, setStore } = useContext( AppStore ); + const [ helpCenter, setHelpCenter ] = useState( store.features.helpCenter ); + const [ helpCenterLocked, setHelpCenterLocked ] = useState( + ! store.toggleableFeatures.helpCenter + ); + const [ isError, setError ] = useState( false ); + const notify = useNotification(); + + const getHelpCenterNoticeTitle = () => { + return helpCenter + ? __( 'Help Center Enabled', 'wp-plugin-bluehost' ) + : __( 'Help Center Disabled', 'wp-plugin-bluehost' ); + }; + const getHelpCenterNoticeText = () => { + return helpCenter + ? __( + 'Reload the page to access the Help Center.', + 'wp-plugin-bluehost' + ) + : __( + 'The Help Center will no longer display.', + 'wp-plugin-bluehost' + ); + }; + + const toggleHelpCenter = () => { + featureToggle( 'helpCenter', ( response ) => { + // console.log( response ); + if ( response.success ) { + setHelpCenter( ! helpCenter ); + } else { + setHelpCenterLocked( true ); + setError( true ); + notifyError(); + } + } ); + }; + + const notifyError = () => { + notify.push( 'feature-toggle-notice', { + title: __( 'Sorry, that is not allowed.', 'wp-plugin-bluehost' ), + description: __( + 'This feature cannot currently be modified.', + 'wp-plugin-bluehost' + ), + variant: 'error', + } ); + }; + + const notifySuccess = ( renderTitle, renderDescription ) => { + notify.push( 'feature-toggle-notice', { + title: renderTitle(), + description: renderDescription(), + variant: 'success', + autoDismiss: 5000, + } ); + }; + + useUpdateEffect( () => { + setStore( { + ...store, + helpCenter, + } ); + notifySuccess( getHelpCenterNoticeTitle, getHelpCenterNoticeText ); + updateUI( '#wp-admin-bar-help-center', helpCenter ); + }, [ helpCenter ] ); + + return ( +
+ { ( ! helpCenterLocked || forceShow ) && ( + + ) } + + { isError && ( + + { __( + 'Oops! Something went wrong. Please try again.', + 'wp-plugin-bluehost' + ) } + + ) } +
+ ); +}; + +export default HelpCenterSettings; diff --git a/src/app/pages/settings/index.js b/src/app/pages/settings/index.js index fb07099b9..ce7a5ce57 100644 --- a/src/app/pages/settings/index.js +++ b/src/app/pages/settings/index.js @@ -1,10 +1,12 @@ import classNames from 'classnames'; import { Container, Page } from '@newfold/ui-component-library'; import useContainerBlockIsTarget from 'App/util/hooks/useContainerBlockTarget'; -import AutomaticUpdates from './automaticUpdates'; -import CommentSettings from './commentSettings'; import ComingSoon from './comingSoon'; +import AutomaticUpdates from './automaticUpdates'; +import HelpCenterSettings from './helpCenterSettings'; +import WonderBlocksSettings from './wonderBlocksSettings'; import ContentSettings from './contentSettings'; +import CommentSettings from './commentSettings'; import SocialMediaAccounts from './socialMediaAccounts'; const Settings = () => { @@ -39,6 +41,18 @@ const Settings = () => { + + + +
+ +
+ { + const { store, setStore } = useContext( AppStore ); + const [ performance, setPerformance ] = useState( + store.features.performance + ); + const [ performanceLocked, setPerformanceLocked ] = useState( + ! store.toggleableFeatures.performance + ); + const [ isError, setError ] = useState( false ); + const notify = useNotification(); + + const getPerformanceNoticeTitle = () => { + return performance + ? __( 'Performance Enabled', 'wp-plugin-bluehost' ) + : __( 'Performance Disabled', 'wp-plugin-bluehost' ); + }; + + const getPerformanceNoticeText = () => { + return performance + ? __( + 'You need to reload the page to manage Performance.', + 'wp-plugin-bluehost' + ) + : __( 'Performance will no longer display.', 'wp-plugin-bluehost' ); + }; + + const togglePerformance = () => { + featureToggle( 'performance', ( response ) => { + if ( response.success ) { + setPerformance( ! performance ); + } else { + setPerformanceLocked( true ); + setError( true ); + notifyError(); + } + } ); + }; + + const notifySuccess = ( renderTitle, renderDescription ) => { + notify.push( 'feature-toggle-notice', { + title: renderTitle(), + description: renderDescription(), + variant: 'success', + autoDismiss: 5000, + } ); + }; + + const notifyError = () => { + notify.push( 'feature-toggle-notice', { + title: __( 'Sorry, that is not allowed.', 'wp-plugin-bluehost' ), + description: __( + 'This feature cannot currently be modified.', + 'wp-plugin-bluehost' + ), + variant: 'error', + } ); + }; + + useUpdateEffect( () => { + setStore( { + ...store, + performance, + } ); + notifySuccess( getPerformanceNoticeTitle, getPerformanceNoticeText ); + updateUI( '.wppbh-app-navitem-Performance', performance ); + }, [ performance ] ); + + return ( +
+ + + { isError && ( + + { __( + 'Oops! Something went wrong. Please try again.', + 'wp-plugin-bluehost' + ) } + + ) } +
+ ); +}; + +export default PerformanceFeatureSettings; diff --git a/src/app/pages/settings/stagingFeatureSettings.js b/src/app/pages/settings/stagingFeatureSettings.js new file mode 100644 index 000000000..599d17cfc --- /dev/null +++ b/src/app/pages/settings/stagingFeatureSettings.js @@ -0,0 +1,98 @@ +import { useState } from '@wordpress/element'; +import { useUpdateEffect } from 'react-use'; +import { Alert, ToggleField } from '@newfold/ui-component-library'; +import AppStore from '../../data/store'; +import { featureToggle, updateUI } from '../../util/helpers'; +import { useNotification } from 'App/components/notifications'; + +const StagingFeatureSettings = () => { + const { store, setStore } = useContext( AppStore ); + const [ staging, setStaging ] = useState( store.features.staging ); + const [ stagingLocked, setStagingLocked ] = useState( + ! store.toggleableFeatures.staging + ); + const [ isError, setError ] = useState( false ); + const notify = useNotification(); + + const getStagingNoticeTitle = () => { + return staging + ? __( 'Staging Enabled', 'wp-plugin-bluehost' ) + : __( 'Staging Disabled', 'wp-plugin-bluehost' ); + }; + const getStagingNoticeText = () => { + return staging + ? __( + 'You need to reload the page to manage Staging.', + 'wp-plugin-bluehost' + ) + : __( 'Staging will no longer display.', 'wp-plugin-bluehost' ); + }; + + const toggleStaging = () => { + featureToggle( 'staging', ( response ) => { + if ( response.success ) { + setStaging( ! staging ); + } else { + setStagingLocked( true ); + setError( true ); + notifyError(); + } + } ); + }; + + const notifyError = () => { + notify.push( 'feature-toggle-notice', { + title: __( 'Sorry, that is not allowed.', 'wp-plugin-bluehost' ), + description: __( + 'This feature cannot currently be modified.', + 'wp-plugin-bluehost' + ), + variant: 'error', + } ); + }; + + const notifySuccess = ( renderTitle, renderDescription ) => { + notify.push( 'feature-toggle-notice', { + title: renderTitle(), + description: renderDescription(), + variant: 'success', + autoDismiss: 5000, + } ); + }; + + useUpdateEffect( () => { + setStore( { + ...store, + staging, + } ); + notifySuccess( getStagingNoticeTitle, getStagingNoticeText ); + updateUI( '.wppbh-app-navitem-Staging', staging ); + }, [ staging ] ); + + return ( +
+ + + { isError && ( + + { __( + 'Oops! Something went wrong. Please try again.', + 'wp-plugin-bluehost' + ) } + + ) } +
+ ); +}; + +export default StagingFeatureSettings; diff --git a/src/app/pages/settings/wonderBlocksSettings.js b/src/app/pages/settings/wonderBlocksSettings.js new file mode 100644 index 000000000..f1b489be0 --- /dev/null +++ b/src/app/pages/settings/wonderBlocksSettings.js @@ -0,0 +1,103 @@ +import { useState } from '@wordpress/element'; +import { useUpdateEffect } from 'react-use'; +import { Alert, ToggleField } from '@newfold/ui-component-library'; +import AppStore from '../../data/store'; +import { featureToggle } from '../../util/helpers'; +import { useNotification } from 'App/components/notifications'; + +const WonderBlocksSettings = () => { + const { store, setStore } = useContext( AppStore ); + const [ wonderBlocks, setWonderBlocks ] = useState( + store.features.patterns + ); + const [ wonderBlocksLocked, setWonderBlocksLocked ] = useState( + ! store.toggleableFeatures.patterns + ); + const [ isError, setError ] = useState( false ); + const notify = useNotification(); + + const getWonderBlocksNoticeTitle = () => { + return wonderBlocks + ? __( 'Wonder Blocks Enabled', 'wp-plugin-bluehost' ) + : __( 'Wonder Blocks Disabled', 'wp-plugin-bluehost' ); + }; + const getWonderBlocksNoticeText = () => { + return wonderBlocks + ? __( + 'Create new content to see Wonder Blocks in action.', + 'wp-plugin-bluehost' + ) + : __( + 'Wonder Blocks will no longer display.', + 'wp-plugin-bluehost' + ); + }; + + const toggleWonderBlocks = () => { + featureToggle( 'patterns', ( response ) => { + // console.log( response ); + if ( response.success ) { + setWonderBlocks( ! wonderBlocks ); + } else { + setWonderBlocksLocked( true ); + setError( true ); + notifyError(); + } + } ); + }; + + const notifyError = () => { + notify.push( 'feature-toggle-notice', { + title: __( 'Sorry, that is not allowed.', 'wp-plugin-bluehost' ), + description: __( + 'This feature cannot currently be modified.', + 'wp-plugin-bluehost' + ), + variant: 'error', + } ); + }; + + const notifySuccess = ( renderTitle, renderDescription ) => { + notify.push( 'feature-toggle-notice', { + title: renderTitle(), + description: renderDescription(), + variant: 'success', + autoDismiss: 5000, + } ); + }; + + useUpdateEffect( () => { + setStore( { + ...store, + wonderBlocks, + } ); + notifySuccess( getWonderBlocksNoticeTitle, getWonderBlocksNoticeText ); + }, [ wonderBlocks ] ); + + return ( +
+ + + { isError && ( + + { __( + 'Oops! Something went wrong. Please try again.', + 'wp-plugin-bluehost' + ) } + + ) } +
+ ); +}; + +export default WonderBlocksSettings; diff --git a/src/app/stylesheet.scss b/src/app/stylesheet.scss index 7306fd98c..918f02f51 100644 --- a/src/app/stylesheet.scss +++ b/src/app/stylesheet.scss @@ -81,6 +81,12 @@ body.toplevel_page_bluehost { } } + +.nfd-disabled { + opacity: .5; + pointer-events: disabled; +} + .wppbh { /* color: var(--color-text); diff --git a/src/app/util/helpers.js b/src/app/util/helpers.js index 4d01f34d2..0af5e1209 100644 --- a/src/app/util/helpers.js +++ b/src/app/util/helpers.js @@ -48,14 +48,67 @@ export const bluehostSettingsApiFetch = ( data, passError, thenCallback ) => { } ); }; +/** + * Wrapper method for toggling a feature via the features API + * + * @param {string} featureName the name of the feature + * @param {Function} thenCallback method to call in promise then + * @return {Promise} Features API promise with attached then callback + */ +export const featureToggle = async ( featureName, thenCallback ) => { + if ( true === window.NewfoldFeatures.features[ featureName ] ) { + return window.NewfoldFeatures.disable( featureName ).then( + ( response ) => { + thenCallback( response ); + } + ); + } + // else + return window.NewfoldFeatures.enable( featureName ).then( ( response ) => { + thenCallback( response ); + } ); +}; + +/** + * Helper to update UI elements as features are enabled/disabled + * + * @param {string} selector css selector to find the element + * @param {boolean} enabled whether the element is now activated/deactivated + * @param {string} className the css class to add/remove - default 'nfd-disabled' + * @param {boolean} forceReload whether this update requires a forced page reload - default false + */ +export const updateUI = ( + selector, + enabled = true, + className = 'nfd-disabled', + forceReload = false +) => { + const element = document.querySelector( selector ); + if ( element ) { + if ( ! enabled ) { + element.classList.add( className ); + } else { + element.classList.remove( className ); + } + } + if ( forceReload ) { + window.location.reload(); + } +}; + /** * Wrapper method to post request to bluehost cache endpoint * * @param {Object} data object of data * @param {Function} passError setter for the error in component * @param {Function} thenCallback method to call in promise then + * @return {Promise} apiFetch promise with attached then and catch callbacks */ -export const bluehostPurgeCacheApiFetch = ( data, passError, thenCallback ) => { +export const bluehostPurgeCacheApiFetch = async ( + data, + passError, + thenCallback +) => { return apiFetch( { url: NewfoldRuntime.createApiUrl( '/bluehost/v1/caching' ), method: 'DELETE',