User:Samwilson/CreateNewEntity.js

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
function CreateNewEntityDialog( searchTerm, $textarea ) {
    this.searchTerm = searchTerm;
    this.$entityInput = $textarea;
    CreateNewEntityDialog.super.call( this, {} );
}

OO.inheritClass( CreateNewEntityDialog, OO.ui.ProcessDialog );

CreateNewEntityDialog.static.name = 'user-samwilson-createnewentity-dialog';

CreateNewEntityDialog.static.title = 'Create a new item';

CreateNewEntityDialog.static.size = 'large';

CreateNewEntityDialog.static.actions = [
    { label: 'Create', flags: 'primary', action: 'save' },
    { label: 'Cancel', flags: 'safe' }
];

CreateNewEntityDialog.prototype.initialize = function () {
    CreateNewEntityDialog.super.prototype.initialize.apply( this, arguments );
    const panel = new OO.ui.PanelLayout( { padded: true, expanded: false } );

    // Label input.
    this.labelInput = new OO.ui.TextInputWidget( {
        value: this.searchTerm
    } );
    const labelField = new OO.ui.FieldLayout( this.labelInput, {
        label: 'Label:',
        align: 'left'
    } );

    // Description input.
    this.descInput = new OO.ui.TextInputWidget();
    const descField = new OO.ui.FieldLayout( this.descInput, {
        label: 'Description:',
        align: 'left'
    } );

    panel.$element.append( labelField.$element, descField.$element );
    this.$body.append( panel.$element );
};
CreateNewEntityDialog.prototype.getActionProcess = function ( action ) {
    var dialog = this;
    if ( action === 'save' ) {
        return CreateNewEntityDialog.super.prototype.getActionProcess.call( this, action )
            .first( function () {
                dialog.pushPending();
                // Save the new item.
                const apiParams = {
                    "action": "wbeditentity",
                    "new": "item",
                    "data": JSON.stringify( {
                        "labels": { "en": { "language": "en", "value": dialog.labelInput.getValue() } },
                        "descriptions": { "en": { "language": "en", "value": dialog.descInput.getValue() } }
                    } )
                };
                ( new mw.Api() )
                    .postWithEditToken( apiParams )
                    .done( function ( res ) {
                        dialog.$entityInput.val( res.entity.id );
                        dialog.$entityInput.trigger( 'eachchange' );
                        dialog.close();
                    } );
            } );
    } else {
        return new OO.ui.Process( function () {
            dialog.close();
        } );
    }
};

( function ( $, mw ) {

    let createItemLink = null;

	function log( msg ) {
		console.log( 'User:Samwilson/CreateNewEntity.js -- ' + msg );
	}

    function onEntitySelectorSearch( data, addPromise ) {
        if ( !data.term || data.options.type !== 'item' ) {
        	log( 'No search term, or not searching for an item.' );
        	console.log(data);
            return;
        }
        if ( !createItemLink ) {
        	log( 'Adding new-item link to the search menu.' );
            createItemLink = new $.ui.ooMenu.CustomItem( 'Create new item' );
            data.options.menu.option( 'customItems' ).unshift( createItemLink );
        }
        createItemLink.setVisibility( true );
        createItemLink.setAction( function () {
            const windowManager = new OO.ui.getWindowManager();
            var dialog = new CreateNewEntityDialog( data.term, data.element );
            windowManager.addWindows( [ dialog ] );
            windowManager.openWindow( dialog );
        } );
    }

    $( function () {
    	log( 'Add search hook handler.' );
        mw.hook( 'wikibase.entityselector.search' ).add( onEntitySelectorSearch );
    } );

}( jQuery, mediaWiki ) );