33 * You can obtain one at http://mozilla.org/MPL/2.0/. */
44
55import { actionCreators as ac , actionTypes as at } from "common/Actions.mjs" ;
6+ import { WIDGET_REGISTRY } from "common/WidgetsRegistry.mjs" ;
67import { connect } from "react-redux" ;
78import React from "react" ;
89
@@ -24,6 +25,14 @@ const PREF_UNIFIED_ADS_ENDPOINT = "unifiedAds.endpoint";
2425const PREF_ALLOWED_ENDPOINTS = "discoverystream.endpoints" ;
2526const PREF_OHTTP_CONFIG = "discoverystream.ohttp.configURL" ;
2627const PREF_OHTTP_RELAY = "discoverystream.ohttp.relayURL" ;
28+ const PREF_WIDGETS_SYSTEM_ENABLED = "widgets.system.enabled" ;
29+
30+ // Turn a camelCase widget id into a human-readable label, e.g.
31+ // "pictureOfTheDay" -> "Picture Of The Day".
32+ function widgetLabel ( id ) {
33+ const spaced = id . replace ( / ( [ A - Z ] ) / g, " $1" ) ;
34+ return spaced . charAt ( 0 ) . toUpperCase ( ) + spaced . slice ( 1 ) ;
35+ }
2736
2837const Row = props => (
2938 < tr className = "message-item" { ...props } >
@@ -115,6 +124,9 @@ export class DiscoveryStreamAdminUI extends React.PureComponent {
115124 this . handleDebugOverrideChange = this . handleDebugOverrideChange . bind ( this ) ;
116125 this . handleResetAllOverrides = this . handleResetAllOverrides . bind ( this ) ;
117126 this . handleSectionsToggle = this . handleSectionsToggle . bind ( this ) ;
127+ this . handleWidgetsSystemToggle = this . handleWidgetsSystemToggle . bind ( this ) ;
128+ this . handleWidgetToggle = this . handleWidgetToggle . bind ( this ) ;
129+ this . handleWidgetsToggleAll = this . handleWidgetsToggleAll . bind ( this ) ;
118130 this . toggleIABBanners = this . toggleIABBanners . bind ( this ) ;
119131 this . handleAllizomToggle = this . handleAllizomToggle . bind ( this ) ;
120132 this . sendConversionEvent = this . sendConversionEvent . bind ( this ) ;
@@ -403,6 +415,34 @@ export class DiscoveryStreamAdminUI extends React.PureComponent {
403415 ) ;
404416 }
405417
418+ handleWidgetsSystemToggle ( e ) {
419+ this . props . dispatch (
420+ ac . SetPref ( PREF_WIDGETS_SYSTEM_ENABLED , e . target . pressed )
421+ ) ;
422+ }
423+
424+ handleWidgetToggle ( e ) {
425+ // e.target.id is the widget's systemEnabledPref (widgets.system.<name>.enabled)
426+ this . props . dispatch ( ac . SetPref ( e . target . id , e . target . pressed ) ) ;
427+ }
428+
429+ handleWidgetsToggleAll ( ) {
430+ const value = ! this . areAllWidgetsEnabled ( ) ;
431+ const values = { [ PREF_WIDGETS_SYSTEM_ENABLED ] : value } ;
432+ for ( const widget of WIDGET_REGISTRY ) {
433+ values [ widget . systemEnabledPref ] = value ;
434+ }
435+ this . props . dispatch ( ac . SetMultiplePrefs ( values ) ) ;
436+ }
437+
438+ areAllWidgetsEnabled ( ) {
439+ const { otherPrefs } = this . props ;
440+ return Boolean (
441+ otherPrefs [ PREF_WIDGETS_SYSTEM_ENABLED ] &&
442+ WIDGET_REGISTRY . every ( widget => otherPrefs [ widget . systemEnabledPref ] )
443+ ) ;
444+ }
445+
406446 sendConversionEvent ( ) {
407447 const detail = {
408448 partnerId : "295BEEF7-1E3B-4128-B8F8-858E12AA660B" ,
@@ -809,6 +849,13 @@ export class DiscoveryStreamAdminUI extends React.PureComponent {
809849 </ Row >
810850 </ tbody >
811851 </ table >
852+ < button
853+ className = "button"
854+ style = { { marginBlockStart : "var(--space-large)" } }
855+ onClick = { this . sendConversionEvent }
856+ >
857+ Send conversion event
858+ </ button >
812859 < h4 > Spoc data</ h4 >
813860 < table >
814861 < tbody > { spocsData . map ( spoc => this . renderStoryData ( spoc ) ) } </ tbody >
@@ -893,6 +940,9 @@ export class DiscoveryStreamAdminUI extends React.PureComponent {
893940 const leaderboardPressed =
894941 leaderboardEnabled && spocPlacements . includes ( "newtab_leaderboard" ) ;
895942
943+ const widgetsSystemEnabled =
944+ this . props . otherPrefs [ PREF_WIDGETS_SYSTEM_ENABLED ] ;
945+
896946 return (
897947 < div >
898948 < button className = "button" onClick = { this . refreshCache } >
@@ -955,9 +1005,34 @@ export class DiscoveryStreamAdminUI extends React.PureComponent {
9551005 />
9561006 </ div >
9571007 </ details >
958- < button className = "button" onClick = { this . sendConversionEvent } >
959- Send conversion event
960- </ button >
1008+ < details className = "details-section" >
1009+ < summary > Widgets</ summary >
1010+ < div className = "toggle-wrapper" >
1011+ < moz-toggle
1012+ id = "widgets-system-enabled"
1013+ pressed = { widgetsSystemEnabled || null }
1014+ ontoggle = { this . handleWidgetsSystemToggle }
1015+ label = "Enable widget system"
1016+ />
1017+ </ div >
1018+ < button className = "button" onClick = { this . handleWidgetsToggleAll } >
1019+ { this . areAllWidgetsEnabled ( ) ? "Disable all" : "Enable all" }
1020+ </ button >
1021+ < hr />
1022+ { WIDGET_REGISTRY . map ( widget => (
1023+ < div className = "toggle-wrapper" key = { widget . id } >
1024+ < moz-toggle
1025+ id = { widget . systemEnabledPref }
1026+ pressed = {
1027+ this . props . otherPrefs [ widget . systemEnabledPref ] || null
1028+ }
1029+ disabled = { ! widgetsSystemEnabled || null }
1030+ ontoggle = { this . handleWidgetToggle }
1031+ label = { widgetLabel ( widget . id ) }
1032+ />
1033+ </ div >
1034+ ) ) }
1035+ </ details >
9611036 < h3 > Layout</ h3 >
9621037 { layout . map ( ( row , rowIndex ) => (
9631038 < div key = { `row-${ rowIndex } ` } >
0 commit comments