Allow different maps to be edited separately

Seperate different maps of maps-object into different panels that
contains text-area to edit the map, delete button to delete the map, and
can be navigated through using a side-bar, that also have "Add new map"
button at the top to add a new map.

Bug: T258820
Change-Id: Ib53a73203f6010b3fd8a5cd78c74c904be2340f2
This commit is contained in:
Khatean 2020-08-07 20:27:18 +02:00 committed by adham-khatean
parent b1436601e4
commit 76cf63dad2
8 changed files with 458 additions and 47 deletions

View file

@ -75,6 +75,8 @@
"widgets/ParamImportWidget.js",
"widgets/LanguageResultWidget.js",
"widgets/LanguageSearchWidget.js",
"widgets/GroupWidget.js",
"widgets/ItemWidget.js",
"Dialog.js",
"init.js"
],
@ -113,6 +115,7 @@
"templatedata-exists-on-related-page",
"templatedata-modal-button-add-language",
"templatedata-modal-button-addparam",
"templatedata-modal-button-addmap",
"templatedata-modal-button-apply",
"templatedata-modal-button-back",
"templatedata-modal-button-cancel",
@ -121,6 +124,7 @@
"templatedata-modal-button-done",
"templatedata-modal-button-importParams",
"templatedata-modal-button-map",
"templatedata-modal-button-removemap",
"templatedata-modal-button-restoreparam",
"templatedata-modal-button-saveparam",
"templatedata-modal-confirmcancel",
@ -135,9 +139,11 @@
"templatedata-modal-format-placeholder",
"templatedata-modal-json-error-replace",
"templatedata-modal-notice-import-numparams",
"templatedata-modal-placeholder-add-new-map-input",
"templatedata-modal-placeholder-paramkey",
"templatedata-modal-search-input-placeholder",
"templatedata-modal-placeholder-mapinfo",
"templatedata-modal-placeholder-prompt-map-name",
"templatedata-modal-table-param-actions",
"templatedata-modal-table-param-aliases",
"templatedata-modal-table-param-autovalue",

View file

@ -58,6 +58,7 @@
"templatedata-invalid-value": "Invalid value for property \"$1\".",
"templatedata-modal-button-add-language": "Add language",
"templatedata-modal-button-addparam": "Add parameter",
"templatedata-modal-button-addmap": "Add new map",
"templatedata-modal-button-apply": "Apply",
"templatedata-modal-button-back": "Back",
"templatedata-modal-button-cancel": "Cancel",
@ -66,6 +67,7 @@
"templatedata-modal-button-done": "Done",
"templatedata-modal-button-map": "Edit maps",
"templatedata-modal-button-importParams": "Import parameters",
"templatedata-modal-button-removemap": "Remove map",
"templatedata-modal-button-restoreparam": "Restore parameter",
"templatedata-modal-button-saveparam": "Save",
"templatedata-modal-confirmcancel": "Are you sure you want to discard your changes?",
@ -80,8 +82,10 @@
"templatedata-modal-format-placeholder": "Template parameter format string",
"templatedata-modal-json-error-replace": "Replace",
"templatedata-modal-notice-import-numparams": "$1 new {{PLURAL:$1|parameter was|parameters were}} imported: $2",
"templatedata-modal-placeholder-add-new-map-input": "Adding new map..",
"templatedata-modal-placeholder-paramkey": "Parameter name",
"templatedata-modal-placeholder-mapinfo": "This template has no maps object",
"templatedata-modal-placeholder-prompt-map-name": "Enter map name",
"templatedata-modal-search-input-placeholder": "Search by language name or code",
"templatedata-modal-table-param-actions": "Actions",
"templatedata-modal-table-param-aliases": "Aliases (comma separated)",

View file

@ -69,6 +69,7 @@
"templatedata-invalid-value": "Error message when a property that cannot contain free-form text has an invalid value.\n* $1 - name of property. e.g. \"params.1.type\"",
"templatedata-modal-button-add-language": "Label for the button to add a language in the edit dialog.\n{{Identical|Add language}}",
"templatedata-modal-button-addparam": "Button to add a parameter.\n{{Identical|Add parameter}}",
"templatedata-modal-button-addmap": "Button to add a map on maps panel.",
"templatedata-modal-button-apply": "Label of the apply button.\n{{Identical|Apply}}",
"templatedata-modal-button-back": "Label for the button to go back in the templatedata edit dialog.\n{{Identical|Back}}",
"templatedata-modal-button-cancel": "Label of the cancel button.\n{{Identical|Cancel}}",
@ -77,6 +78,7 @@
"templatedata-modal-button-done": "Label of the done button.\n{{Identical|Done}}",
"templatedata-modal-button-map": "Label of the Edit maps button",
"templatedata-modal-button-importParams": "Label of the import button",
"templatedata-modal-button-removemap": "Label of the remove map button",
"templatedata-modal-button-restoreparam": "Label for the button to restore a previously deleted parameter in the edit dialog.",
"templatedata-modal-button-saveparam": "Label for the button to save parameter details in the templatedata edit dialog.\n{{Identical|Save}}",
"templatedata-modal-confirmcancel": "Prompt shown to the user when they attempt to cancel the templatedata edit dialog after making changes.",
@ -91,8 +93,10 @@
"templatedata-modal-format-placeholder": "Placeholder text describing the format string entry widget",
"templatedata-modal-json-error-replace": "Label for the button in the error message, agreeing to replace the existing faulty TemplateData string with a new one.\n{{Identical|Replace}}",
"templatedata-modal-notice-import-numparams": "Message that appears in the TemplateData generator GUI showing how many new parameters were imported into the GUI from an existing template.\n\nParameters:\n* $1 - number of parameters\n* $2 - list of parameters that were imported",
"templatedata-modal-placeholder-add-new-map-input": "Placeholder for the input that contains map info while a new map is being added through the GUI.",
"templatedata-modal-placeholder-paramkey": "Placeholder for the input that contains new parameter name in the add parameter panel in the edit dialog.",
"templatedata-modal-placeholder-mapinfo": "Placeholder for the input that contains map information",
"templatedata-modal-placeholder-prompt-map-name": "Placeholder for new map name prompter.",
"templatedata-modal-search-input-placeholder": "Placeholder text for language search panel.",
"templatedata-modal-table-param-actions": "Label for a parameter property input: Parameter actions in the table\n{{Identical|Action}}",
"templatedata-modal-table-param-aliases": "Label for a parameter property input: Aliases of the parameter, instruct the user to separate aliases with commas.",

View file

@ -28,10 +28,53 @@
white-space: nowrap;
}
.mw-tempateData-maps-panel-button {
.mw-templateData-maps-panel-button {
margin-bottom: 0.5em;
}
.mw-tempateData-template-maps-input {
padding-bottom: 1em;
.mw-templateData-template-map-list-menu-panel {
border-right: 1px solid #c8ccd1;
}
.mw-templateData-template-remove-map-button {
margin-bottom: 0.8em;
}
.mw-templateData-template-add-map-button-panel,
.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-top > .oo-ui-menuLayout-menu {
height: fit-content;
text-align: center;
box-shadow: 0 5px 16px -8px #0000001f;
}
.mw-templateData-template-map-group {
height: available;
}
.tdg-templateDataDialog-editMapsPanel .oo-ui-menuLayout > .oo-ui-menuLayout-content {
top: 4.3em;
}
.tdg-templateDataDialog-addingNewMap .oo-ui-menuLayout > .oo-ui-menuLayout-content {
top: 6.6em;
}
.tdg-templateDataDialog-mapsListPanel {
height: available;
}
.mw-templateData-template-map-item {
padding: 0.5em 0 0.5em 0.3em;
border: 1px solid #fff;
border-radius: 2px;
width: 100%;
}
.mw-templateData-template-map-item:hover {
background-color: #eaecf0;
}
.mw-templateData-template-map-item-highlighted,
.mw-templateData-template-map-item-highlighted:hover {
background-color: #eaf3ff;
}

View file

@ -13,8 +13,8 @@ mw.TemplateData.Model = function mwTemplateDataModel() {
// Properties
this.params = {};
this.description = {};
this.originalMaps = {};
this.maps = {};
this.originalMaps = undefined;
this.maps = undefined;
this.paramOrder = [];
this.format = null;
this.paramOrderChanged = false;
@ -273,7 +273,9 @@ mw.TemplateData.Model.static.newFromObject = function ( tdObject, paramsInSource
}
// maps
model.setMapInfo( tdObject.maps );
if ( tdObject.maps ) {
model.setMapInfo( tdObject.maps );
}
model.setTemplateDescription( tdObject.description );
@ -538,14 +540,16 @@ mw.TemplateData.Model.prototype.getTemplateDescription = function ( language ) {
* @fires change
*/
mw.TemplateData.Model.prototype.setMapInfo = function ( map ) {
if ( !this.constructor.static.compare( this.maps, map ) ) {
if ( this.mapsChanged === false ) {
this.originalMaps = map;
this.mapsChanged = true;
if ( map !== undefined ) {
if ( !this.constructor.static.compare( this.maps, map ) ) {
if ( this.mapsChanged === false ) {
this.originalMaps = OO.copy( map );
this.mapsChanged = true;
}
this.maps = map;
this.emit( 'change-map', map );
this.emit( 'change' );
}
this.maps = map;
this.emit( 'change-map', map );
this.emit( 'change' );
}
};
@ -958,10 +962,10 @@ mw.TemplateData.Model.prototype.outputTemplateData = function () {
}
// Template maps
if ( this.maps !== undefined ) {
result.maps = this.maps;
} else {
if ( this.maps === undefined || Object.keys( this.maps ).length === 0 ) {
delete result.maps;
} else {
result.maps = this.maps;
}
// Param order

View file

@ -19,6 +19,8 @@ mw.TemplateData.Dialog = function mwTemplateDataDialog( config ) {
this.propInputs = {};
this.propFieldLayout = {};
this.isSetup = false;
this.highlightedMap = null;
this.mapsCache = undefined;
// Initialize
this.$element.addClass( 'tdg-templateDataDialog' );
@ -87,7 +89,8 @@ mw.TemplateData.Dialog.static.actions = [
* @chainable
*/
mw.TemplateData.Dialog.prototype.initialize = function () {
var templateParamsFieldset, addParamFieldlayout, languageActionFieldLayout, templateFormatFieldSet, mapsActionFieldLayout, templateMapsFieldSet;
var templateParamsFieldset, addParamFieldlayout, languageActionFieldLayout, templateFormatFieldSet, mapsActionFieldLayout,
mapsListMenuLayout, mapsListPanel, addNewMapButtonPanel, mapsContentPanel, templateMapsMenuLayout;
// Parent method
mw.TemplateData.Dialog.super.prototype.initialize.call( this );
@ -127,19 +130,71 @@ mw.TemplateData.Dialog.prototype.initialize = function () {
// Maps panel
this.templateMapsInput = new OO.ui.MultilineTextInputWidget( {
classes: [ 'mw-tempateData-template-maps-input' ],
classes: [ 'mw-templateData-template-maps-input' ],
autosize: true,
rows: 5,
maxRows: 200,
placeholder: mw.msg( 'templatedata-modal-placeholder-mapinfo' )
rows: this.getBodyHeight() / 22.5,
maxRows: this.getBodyHeight() / 22.5,
placeholder: mw.msg( 'templatedata-modal-placeholder-mapinfo' ),
scrollable: true
} );
this.removeMapButton = new OO.ui.ButtonWidget( {
classes: [ 'mw-templateData-template-remove-map-button' ],
label: mw.msg( 'templatedata-modal-button-removemap' ),
icon: 'trash',
flags: [ 'destructive' ]
} );
this.addNewMapButton = new OO.ui.ButtonWidget( {
classes: [ 'mw-templateData-template-add-map-button' ],
label: mw.msg( 'templatedata-modal-button-addmap' ),
icon: 'add',
framed: false,
flags: [ 'progressive' ]
} );
this.newMapNameInput = new OO.ui.TextInputWidget( {
value: '',
placeholder: mw.msg( 'templatedata-modal-placeholder-prompt-map-name' ),
classes: [ 'mw-templateData-template-map-prompter' ]
} );
this.cancelAddMapButton = new OO.ui.ButtonWidget( {
label: mw.msg( 'templatedata-modal-button-cancel' ),
framed: false,
flags: [ 'destructive' ]
} );
this.saveAddMapButton = new OO.ui.ButtonWidget( {
label: mw.msg( 'templatedata-modal-button-done' ),
framed: false,
flags: [ 'primary', 'progressive' ]
} );
this.mapsGroup = new mw.TemplateData.GroupWidget( {
classes: [ 'mw-templateData-template-map-group' ],
orientation: 'vertical'
} );
addNewMapButtonPanel = new OO.ui.PanelLayout( {
classes: [ 'mw-templateData-template-add-map-button-panel' ],
padded: true,
expanded: true
} );
mapsListPanel = new OO.ui.PanelLayout( {
padded: true,
expanded: true,
scrollable: true
} );
mapsListMenuLayout = new OO.ui.MenuLayout( {
classes: [ 'mw-templateData-template-map-list-menu-panel' ],
menuPosition: 'top',
padded: true,
expanded: true,
contentPanel: mapsListPanel,
menuPanel: addNewMapButtonPanel
} );
mapsContentPanel = new OO.ui.PanelLayout( {
padded: true,
expanded: true
} );
templateMapsMenuLayout = new OO.ui.MenuLayout( {
contentPanel: mapsContentPanel,
menuPanel: mapsListMenuLayout
} );
templateMapsFieldSet = new OO.ui.FieldsetLayout(
this.templateMapsInput,
{
align: 'top',
label: mw.msg( 'templatedata-modal-title-map' )
}
);
// Param list panel (main)
this.languageDropdownWidget = new OO.ui.DropdownWidget();
@ -165,7 +220,7 @@ mw.TemplateData.Dialog.prototype.initialize = function () {
// Add Maps panel button
this.mapsPanelButton = new OO.ui.ButtonWidget( {
label: mw.msg( 'templatedata-modal-button-map' ),
classes: [ 'mw-tempateData-maps-panel-button' ]
classes: [ 'mw-templateData-maps-panel-button' ]
} );
mapsActionFieldLayout = new OO.ui.ActionFieldLayout(
this.mapsPanelButton,
@ -256,10 +311,29 @@ mw.TemplateData.Dialog.prototype.initialize = function () {
.append( addParamFieldlayout.$element );
// Maps panel
mapsListPanel.$element
.addClass( 'tdg-templateDataDialog-mapsListPanel' )
.append( this.mapsGroup.$element );
this.newMapNameInput.$element.hide();
this.cancelAddMapButton.$element.hide();
this.saveAddMapButton.$element.hide();
addNewMapButtonPanel.$element
.addClass( 'tdg-templateDataDialog-addNewMapButtonPanel' )
.append(
this.addNewMapButton.$element,
this.newMapNameInput.$element,
this.cancelAddMapButton.$element,
this.saveAddMapButton.$element
);
mapsContentPanel.$element
.addClass( 'tdg-templateDataDialog-mapsContentPanel' )
.append(
this.removeMapButton.$element,
this.templateMapsInput.$element
);
this.editMapsPanel.$element
.addClass( 'tdg-templateDataDialog-editMapsPanel' )
.append( templateMapsFieldSet.$element );
.append( templateMapsMenuLayout.$element );
this.panels.addItems( [
this.listParamsPanel,
this.editParamPanel,
@ -287,6 +361,12 @@ mw.TemplateData.Dialog.prototype.initialize = function () {
this.languagePanelButton.connect( this, { click: 'onLanguagePanelButton' } );
this.languageDropdownWidget.getMenu().connect( this, { select: 'onLanguageDropdownWidgetSelect' } );
this.mapsPanelButton.connect( this, { click: 'onMapsPanelButton' } );
this.addNewMapButton.connect( this, { click: 'onAddNewMapClick' } );
this.cancelAddMapButton.connect( this, { click: 'onCancelAddingMap' } );
this.saveAddMapButton.connect( this, { click: 'onEmbedNewMap' } );
this.newMapNameInput.connect( this, { enter: 'onEmbedNewMap' } );
this.mapsGroup.connect( this, { editItem: 'onHighlightMapElement' } );
this.removeMapButton.connect( this, { click: 'onMapItemRemove' } );
this.templateMapsInput.connect( this, { change: 'onMapInfoChange' } );
this.paramSelect.connect( this, {
choose: 'onParamSelectChoose',
@ -316,7 +396,9 @@ mw.TemplateData.Dialog.prototype.onModelChangeDescription = function ( descripti
* @param {string} map New description
*/
mw.TemplateData.Dialog.prototype.onModelChangeMapInfo = function ( map ) {
this.templateMapsInput.setValue( JSON.stringify( map, null, 4 ) );
map = map === undefined ? {} : map;
this.mapsCache = OO.copy( map );
this.templateMapsInput.setValue( this.stringifyObject( map[ this.highlightedMap.label ] ) );
};
/**
@ -402,27 +484,205 @@ mw.TemplateData.Dialog.prototype.onDescriptionInputChange = function ( value ) {
}
};
/**
* Create items for the returned maps and add them to the maps group
*
* @param {Object} mapsObject object
*/
mw.TemplateData.Dialog.prototype.populateMapsItems = function ( mapsObject ) {
var mapKeysList,
items = [];
mapsObject = mapsObject === undefined ? {} : mapsObject;
mapKeysList = Object.keys( mapsObject );
if ( mapKeysList.length > 0 ) {
mapKeysList.forEach( function ( mapKey ) {
items.push( new mw.TemplateData.ItemWidget( {
label: mapKey,
classes: [ 'mw-templateData-template-map-item' ]
} ) );
} );
}
this.mapsGroup.clearItems();
this.mapsGroup.addItems( items );
// Maps is not empty anymore
this.updateActions();
};
/**
* Respond to edit maps input change event
*
* @param {string} value map info value
*/
mw.TemplateData.Dialog.prototype.onMapInfoChange = function ( value ) {
var mapValue;
// Update map Info
if ( this.model.getMapInfo() !== value ) {
// Disable Done button in case of invalid JSON
try {
// This parsing method keeps only the last key/value pair if duplicate keys are defined, and does not throw an error.
// Our model will be updated with a valid maps object, but the user may lose their input if it has duplicate key.
this.mapValue = JSON.parse( value );
this.actions.setAbilities( { done: true } );
} catch ( err ) {
// Otherwise disable the done button
this.actions.setAbilities( { done: false } );
this.model.maps = this.model.getMapInfo() === undefined ? {} : this.model.getMapInfo();
if ( this.highlightedMap !== null ) {
if ( this.model.getMapInfo()[ this.highlightedMap.label ] !== value ) {
// Disable Done button in case of invalid JSON
try {
// This parsing method keeps only the last key/value pair if duplicate keys are defined, and does not throw an error.
// Our model will be updated with a valid maps object, but the user may lose their input if it has duplicate key.
mapValue = JSON.parse( value );
this.mapsCache[ this.highlightedMap.label ] = mapValue;
this.actions.setAbilities( { done: true } );
} catch ( err ) {
// Otherwise disable the done button if maps object is populated
this.actions.setAbilities( { done: false } );
} finally {
if ( this.mapsGroup.items.length === 0 ) {
this.actions.setAbilities( { done: true } );
this.removeMapButton.setDisabled( true );
}
}
}
}
};
/**
* Handle click event for Add new map button
*/
mw.TemplateData.Dialog.prototype.onAddNewMapClick = function () {
// Add new text input in maps elements to prompt the map name
this.newMapNameInput.$element.show();
this.cancelAddMapButton.$element.show();
this.saveAddMapButton.$element.show();
this.addNewMapButton.$element.hide();
this.newMapNameInput.setValue( '' );
this.newMapNameInput.focus();
// Text-area show "adding a new map.." message in templateMapsInput and disable the input.
this.templateMapsInput.setDisabled( true );
this.templateMapsInput.setValue( mw.msg( 'templatedata-modal-placeholder-add-new-map-input' ) );
// Disable the removing functionality for maps
this.removeMapButton.setDisabled( true );
// move the list panel down as add new map expanded
this.editMapsPanel.$element.addClass( 'tdg-templateDataDialog-addingNewMap' );
};
/**
* Handle clicking cancel button (for add new map panel)
*
* @param {mw.TemplateData.ItemWidget} highlightNext item to be highlighted after adding a new map canceled/done
*/
mw.TemplateData.Dialog.prototype.onCancelAddingMap = function ( highlightNext ) {
// Remove the text-area input, cancel button, and show add new map button
this.newMapNameInput.$element.hide();
this.cancelAddMapButton.$element.hide();
this.saveAddMapButton.$element.hide();
this.addNewMapButton.$element.show();
// move the list panel up back as add new map shrank
this.editMapsPanel.$element.removeClass( 'tdg-templateDataDialog-addingNewMap' );
this.removeMapButton.setDisabled( false );
this.onHighlightMapElement( highlightNext );
};
/**
* Handle clicking Enter event for promptMapName
*
* @param {jQuery.Event} response response from Enter action on promptMapName
*/
mw.TemplateData.Dialog.prototype.onEmbedNewMap = function ( response ) {
var newlyAddedMap,
mapNameValue;
if ( response !== undefined ) {
mapNameValue = response.target.value;
} else {
mapNameValue = this.newMapNameInput.getValue();
}
this.mapsCache = this.mapsCache === undefined ? {} : this.mapsCache;
// Create a new empty map in maps object
this.mapsCache[ mapNameValue ] = {};
newlyAddedMap = new mw.TemplateData.ItemWidget( {
label: mapNameValue,
classes: [ 'mw-templateData-template-map-item' ]
} );
// Add the new map item and highlight it
if ( mapNameValue.length !== 0 ) {
this.mapsGroup.addItems( newlyAddedMap, 0 );
} else {
delete this.mapsCache[ mapNameValue ];
}
this.onCancelAddingMap( newlyAddedMap );
this.onHighlightMapElement();
};
/**
* Handle click event for the remove button
*/
mw.TemplateData.Dialog.prototype.onMapItemRemove = function () {
// Remove the highlighted item
this.mapsGroup.removeItems( [ this.highlightedMap ] );
// Remove the highlighted map from maps object
delete this.mapsCache[ this.highlightedMap.label ];
// Highlight another item, or show the search panel if the maps group is now empty
this.onHighlightMapElement();
};
/**
* Respond to edits on elements of maps list
*
* @param {mw.TemplateData.ItemWidget} item currently highlighted item
*/
mw.TemplateData.Dialog.prototype.onHighlightMapElement = function ( item ) {
var currentMapInfo;
// Cancel the process of adding a map, Cannot call onCancelAddingMap because these two functions
// cannot be called recursively
// Remove the text-area input, cancel button, and show add new map button
this.newMapNameInput.$element.hide();
this.cancelAddMapButton.$element.hide();
this.saveAddMapButton.$element.hide();
this.addNewMapButton.$element.show();
// move the list panel up back as add new map shrank
this.editMapsPanel.$element.removeClass( 'tdg-templateDataDialog-addingNewMap' );
this.removeMapButton.setDisabled( $.isEmptyObject( this.mapsCache ) );
// Un-highlight previous item
if ( this.highlightedMap ) {
this.highlightedMap.toggleHighlighted( false );
}
// Highlight new item.
// If no item was given, highlight the first item in the group.
item = item || this.mapsGroup.items[ 0 ];
if ( !item ) {
this.templateMapsInput.setDisabled( true );
this.templateMapsInput.setValue( '' );
} else {
this.templateMapsInput.setDisabled( false );
item.toggleHighlighted( true );
this.highlightedMap = item;
// Scroll item into view in menu
OO.ui.Element.static.scrollIntoView( item.$element[ 0 ] );
// Populate the mapsContentPanel
this.mapsCache = this.mapsCache === undefined ? {} : this.mapsCache;
currentMapInfo = this.mapsCache[ this.highlightedMap.label ];
this.templateMapsInput.setValue( this.stringifyObject( currentMapInfo ) );
}
};
/**
* Stringify objects in the dialog with space of 4, mainly maps objects
*
* @param {Object} object maps object
*/
mw.TemplateData.Dialog.prototype.stringifyObject = function ( object ) {
return JSON.stringify( object, null, 4 );
};
/**
* Respond to add language button click
*/
@ -1121,13 +1381,23 @@ mw.TemplateData.Dialog.prototype.getSetupProcess = function ( data ) {
* after initialization of the model.
*/
mw.TemplateData.Dialog.prototype.setupDetailsFromModel = function () {
var format;
var format,
firstMapItem;
// Set up description
this.descriptionInput.setValue( this.model.getTemplateDescription( this.language ) );
// set up maps
this.templateMapsInput.setValue( JSON.stringify( this.model.getMapInfo(), null, 4 ) );
this.populateMapsItems( this.model.getMapInfo() );
this.mapsCache = OO.copy( this.model.getMapInfo() );
this.onHighlightMapElement();
if ( this.model.getMapInfo() !== undefined ) {
firstMapItem = Object.keys( this.model.getMapInfo() )[ 0 ];
this.templateMapsInput.setValue( this.stringifyObject( this.model.getMapInfo()[ firstMapItem ] ) );
} else {
this.templateMapsInput.setValue( '' );
this.templateMapsInput.setDisabled( true );
}
// Set up format
format = this.model.getTemplateFormat();
@ -1231,8 +1501,8 @@ mw.TemplateData.Dialog.prototype.getActionProcess = function ( action ) {
if ( action === 'done' ) {
return new OO.ui.Process( function () {
// setMapInfo with the value and keep the done button active
this.model.setMapInfo( this.mapValue );
this.model.originalMaps = this.mapValue;
this.model.setMapInfo( this.mapsCache );
this.model.originalMaps = OO.copy( this.mapsCache );
this.switchPanels( 'listParams' );
}, this );
}
@ -1248,8 +1518,10 @@ mw.TemplateData.Dialog.prototype.getActionProcess = function ( action ) {
}
if ( action === 'cancel' ) {
return new OO.ui.Process( function () {
this.templateMapsInput.setValue( JSON.stringify( this.model.originalMaps, null, 4 ) );
this.mapsCache = OO.copy( this.model.getOriginalMapsInfo() );
this.model.restoreOriginalMaps();
this.populateMapsItems( this.mapsCache );
this.onCancelAddingMap();
this.switchPanels( 'listParams' );
}, this );
}

View file

@ -0,0 +1,26 @@
/**
* Group widget containing items
*
* @class
* @param {Object} [config] Configuration options
*/
mw.TemplateData.GroupWidget = function mwTemplateDataGroupWidget( config ) {
// Configuration initialization
config = config || {};
// Parent constructor
mw.TemplateData.GroupWidget.super.call( this, config );
// Mixin constructors
OO.ui.mixin.GroupElement.call( this, $.extend( {
$group: this.$element
}, config ) );
// Events
this.aggregate( {
edit: 'editItem'
} );
};
/* Inheritance */
OO.inheritClass( mw.TemplateData.GroupWidget, OO.ui.Widget );
OO.mixinClass( mw.TemplateData.GroupWidget, OO.ui.mixin.GroupElement );

View file

@ -0,0 +1,52 @@
/**
* Item widget contained by the Group widget
*
* @class
* @extends OO.ui.Widget
* @mixins OO.ui.mixin.IconElement
* @mixins OO.ui.mixin.LabelElement
* @param {Object} [config] Configuration options
*/
mw.TemplateData.ItemWidget = function mwTemplateDataItemWidget( config ) {
// Configuration initialization
config = config || {};
// Parent constructor
mw.TemplateData.ItemWidget.super.call( this, config );
// Mixin constructors
OO.ui.mixin.IconElement.call( this, config );
OO.ui.mixin.LabelElement.call( this, config );
// Initialization
this.$element
.addClass( 'mw-TemplateData-itemWidget' )
.append( this.$icon, this.$label );
this.$element.on( {
click: this.onItemClick.bind( this )
} );
this.highlighted = false;
};
/* Inheritance */
OO.inheritClass( mw.TemplateData.ItemWidget, OO.ui.Widget );
OO.mixinClass( mw.TemplateData.ItemWidget, OO.ui.mixin.IconElement );
OO.mixinClass( mw.TemplateData.ItemWidget, OO.ui.mixin.LabelElement );
/* Event handlers */
/**
* Handle clicking on an item (map name on the side-bar)
*/
mw.TemplateData.ItemWidget.prototype.onItemClick = function () {
this.emit( 'edit', this );
};
/**
* Toggle highlighted class
*
* @param {boolean} highlighted The item is highlighted
*/
mw.TemplateData.ItemWidget.prototype.toggleHighlighted = function ( highlighted ) {
highlighted = highlighted !== undefined ? highlighted : !this.highlighted;
this.$element.toggleClass( 'mw-templateData-template-map-item-highlighted', !!highlighted );
};