mediawiki-extensions-Popups/resources/ext.popups/settingsDialog.js
joakin efb7b3d872 Wire up saving enabled/disabled in settings dialog
The save action has been implemented, and it is listened to by the
canonical enabled state in the previews reducer, and by the settings
reducer to perform UI changes.

The enabled state of the application has been kept in the preview
reducer as the canonical source of truth. See supporting changes for
documentation about the decision.

Actions:
* Introduce new action SETTINGS_CHANGE with the enabled status
* Trigger that action when clicking Save in the settings dialog

Reducers:
* Listen to SETTINGS_CHANGE in the preview reducer to update enabled
  status
* On the settings reducer
  * Handle the SETTINGS_CHANGE action
  * Add showHelp flag to determine if the help should be showing

Change listeners:
* Switch to compare past vs present changes in the implementation
* Handle showing and hiding the help

Supporting changes:
* On the rendered settings dialog:
  * Change #hide to actually just hide and remove legacy if statement
  * Add #toggleHelp method to show or hide the help dialog
* Add doc/adr/0003-keep-enabled-state-only-in-preview-reducer.md to
  support the decision of making the saveSettings action creator return
  a Redux.Thunk and keeping the enabled state just in the preview
  reducer.
  * Add NB to actions#saveSettings explaining and linking to the
    document

Follow commits soon:
* Persist the settings change to local storage when it changes, and
  unify with the preview change listener

Change-Id: I80dc5f29fbe6286f2e3e3b50d909894bc5041ccd
2016-12-14 14:35:59 +00:00

168 lines
4.1 KiB
JavaScript

( function ( mw, $ ) {
/**
* Creates a render function that will create the settings dialog and return
* a set of methods to operate on it
*/
mw.popups.createSettingsDialogRenderer = function () {
/**
* Cached settings dialog
*
* @type {jQuery}
*/
var $dialog,
/**
* Cached settings overlay
*
* @type {jQuery}
*/
$overlay;
/**
* Renders the relevant form and labels in the settings dialog
*/
return function ( boundActions ) {
if ( !$dialog ) {
$dialog = createSettingsDialog();
$overlay = $( '<div>' ).addClass( 'mwe-popups-overlay' );
// Setup event bindings
$dialog.find( '.save' ).click( function () {
// Find the selected value (simple|advanced|off)
var selected = getSelectedSetting( $dialog ),
// Only simple means enabled, advanced is disabled in favor of
// NavPops and off means disabled.
enabled = selected === 'simple';
boundActions.saveSettings( enabled );
} );
$dialog.find( '.close, .okay' ).click( boundActions.hideSettings );
}
return {
/**
* Append the dialog and overlay to a DOM element
* @param {HTMLElement} el
*/
appendTo: function ( el ) {
$overlay.appendTo( el );
$dialog.appendTo( el );
},
/**
* Show the settings element and position it correctly
*/
show: function () {
var h = $( window ).height(),
w = $( window ).width();
$overlay.show();
// FIXME: Should recalc on browser resize
$dialog
.show()
.css( 'left', ( w - $dialog.outerWidth( true ) ) / 2 )
.css( 'top', ( h - $dialog.outerHeight( true ) ) / 2 );
},
/**
* Hide the settings dialog.
*/
hide: function () {
$overlay.hide();
$dialog.hide();
},
/**
* Toggle the help dialog on or off
*/
toggleHelp: function ( visible ) {
toggleHelp( $dialog, visible );
}
};
};
};
/**
* Create the settings dialog
*
* @return {jQuery} settings dialog
*/
function createSettingsDialog() {
var $el,
path = mw.config.get( 'wgExtensionAssetsPath' ) + '/Popups/resources/ext.popups/images/',
choices = [
{
id: 'simple',
name: mw.msg( 'popups-settings-option-simple' ),
description: mw.msg( 'popups-settings-option-simple-description' ),
image: path + 'hovercard.svg',
isChecked: true
},
{
id: 'advanced',
name: mw.msg( 'popups-settings-option-advanced' ),
description: mw.msg( 'popups-settings-option-advanced-description' ),
image: path + 'navpop.svg'
},
{
id: 'off',
name: mw.msg( 'popups-settings-option-off' )
}
];
// Check if NavigationPopups is enabled
/*global pg: false*/
if ( typeof pg === 'undefined' || pg.fn.disablePopups === undefined ) {
// remove the advanced option
choices.splice( 1, 1 );
}
// render the template
$el = mw.template.get( 'ext.popups', 'settings.mustache' ).render( {
heading: mw.msg( 'popups-settings-title' ),
closeLabel: mw.msg( 'popups-settings-cancel' ),
saveLabel: mw.msg( 'popups-settings-save' ),
helpText: mw.msg( 'popups-settings-help' ),
okLabel: mw.msg( 'popups-settings-help-ok' ),
descriptionText: mw.msg( 'popups-settings-description' ),
choices: choices
} );
return $el;
}
/**
* Get the selected value on the radio button
*
* @param {jQuery.Object} $el the element to extract the setting from
*/
function getSelectedSetting( $el ) {
return $el.find(
'input[name=mwe-popups-setting]:checked, #mwe-popups-settings'
).val();
}
/**
* Toggles the visibility between a form and the help
* @param {jQuery.Object} $el element that contains form and help
* @param {Boolean} visible if the help should be visible, or the form
*/
function toggleHelp( $el, visible ) {
var formSelectors = '#mwe-popups-settings-form, #mwe-popups-settings .save',
helpSelectors = '#mwe-popups-settings-help, #mwe-popups-settings .okay';
if ( visible ) {
$( formSelectors ).hide();
$( helpSelectors ).show();
} else {
$( formSelectors ).show();
$( helpSelectors ).hide();
}
}
} )( mediaWiki, jQuery );