Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.
       🚧 True to our name, we’re still a work in progress. 🚧
   
       You’re welcome to explore, but account registration is currently invite-only as we finalize the setup. 
       Join our forum or follow Mastodon for updates. 
       Full Wiki launch coming soon!
   

MediaWiki:Gadget-tutorials.js: Difference between revisions

MediaWiki interface page
m Removed protection from "MediaWiki:Gadget-tutorials.js"
(No difference)

Revision as of 05:07, 14 March 2026

/* =============================================================================
   Gadget-tutorials.js — collapse/expand + per-section search + hub metadata
   ============================================================================= */
( function () {
    if ( mw.config.get( 'wgPageName' ) !== 'Tutorials' ) return;

    $( function () {
        $( '.tutorial-section' ).each( function () {
            var $section = $( this );
            var $header  = $section.find( '.tutorial-section-header' );
            var $grid    = $section.find( '.tutorial-section-grid' );
            var $count   = $section.find( '.tutorial-section-count' );
            var $wrap    = $section.find( '.tutorial-section-search-wrap' );
            var $cards   = $grid.find( '.tutorial-card-wrap' );
            var total    = $cards.length;

            $count.text( total + ( total === 1 ? ' tutorial' : ' tutorials' ) );

            // Per-section search
            var $search = $( '<input>' ).attr( {
                type        : 'text',
                placeholder : 'Filter...',
                'class'     : 'tutorial-section-search'
            } );
            $wrap.append( $search );

            $search.on( 'input', function ( e ) {
                e.stopPropagation();
                var q = $( this ).val().toLowerCase().trim();
                var visible = 0;
                $cards.each( function () {
                    var $c  = $( this );
                    var hay = [
                        $c.data( 'title' )      || '',
                        $c.data( 'tags' )        || '',
                        $c.data( 'difficulty' ) || ''
                    ].join( ' ' ).toLowerCase();
                    var show = !q || hay.indexOf( q ) !== -1;
                    $c.toggle( show );
                    if ( show ) visible++;
                } );
                $count.text( ( q ? visible + ' / ' : '' ) + total + ( total === 1 ? ' tutorial' : ' tutorials' ) );
                $section.find( '.tutorial-section-empty' ).toggle( visible === 0 && total > 0 );
            } );

            $search.on( 'click', function ( e ) { e.stopPropagation(); } );

            $header.on( 'click', function ( e ) {
                if ( $( e.target ).closest( '.tutorial-section-more, .tutorial-section-search-wrap' ).length ) return;
                var isOpen = $section.hasClass( 'is-open' );
                $( '.tutorial-section.is-open' ).each( function () {
                    $( this ).find( '.tutorial-section-grid' ).slideUp( 180 );
                    $( this ).removeClass( 'is-open' );
                } );
                if ( !isOpen ) {
                    $grid.slideDown( 180 );
                    $section.addClass( 'is-open' );
                }
            } );
        } );

        // Hub metadata
        mw.loader.using( 'mediawiki.api' ).then( function () {
            var api = new mw.Api();
            api.get( {
                action  : 'query',
                list    : 'categorymembers',
                cmtitle : 'Category:Tutorials',
                cmsort  : 'timestamp',
                cmdir   : 'desc',
                cmlimit : 1,
                cmtype  : 'page',
                cmprop  : 'ids|title|timestamp',
                format  : 'json'
            } ).done( function ( data ) {
                var members = data.query && data.query.categorymembers;
                if ( !members || !members.length ) return;
                var name = members[0].title.replace( /^.*\//, '' );
                var date = members[0].timestamp
                    ? new Date( members[0].timestamp ).toLocaleDateString( 'en-GB', { day: 'numeric', month: 'short', year: 'numeric' } )
                    : '—';
                var str = name + ' — ' + date;
                $( '#hub-meta-last-submission' ).text( str );
                $( '#hub-meta-last-edit' ).text( str );
            } );
        } );

    } );
}() );