Making WordPress.org

Changeset 11537


Ignore:
Timestamp:
02/10/2022 01:13:59 AM (2 years ago)
Author:
dd32
Message:

Trac: Suggest the correct component when a reporter leaves it as 'General'.

This only matches based on words contained within the Component labels, it would be nice to extend this so that we can have other matching words.

See #6078.

Location:
sites/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • sites/trunk/trac.wordpress.org/templates/site.html

    r11504 r11537  
    55
    66<?python
    7     scripts_version = '157'
     7    scripts_version = '158'
    88    project_slug = req.environ['HTTP_HOST'].split(':')[0].split('.')[0]
    99    wporg_endpoint = 'https://make.wordpress.org/' + project_slug + '/'
  • sites/trunk/wordpress.org/public_html/style/trac/wp-trac.js

    r11534 r11537  
    135135            wpTrac.linkGutenbergIssues();
    136136            wpTrac.githubPRs.init();
     137            wpTrac.suggestNotGeneral.init();
    137138
    138139            if ( ! $body.hasClass( 'plugins' ) ) {
     
    143144                }
    144145            }
     146        },
     147
     148        isNewTicket: function() {
     149            return (
     150                window.location.pathname === '/newticket' ||
     151                $( 'form[action*="/newticket"]' ).length > 0
     152            );
    145153        },
    146154
     
    397405                // Rudimentary save alerts for new tickets (summary/description) and comments.
    398406                window.onbeforeunload = function() {
    399                     if ( window.location.pathname === '/newticket' ) {
     407                    if ( wpTrac.isNewTicket() ) {
    400408                        if ( ! $( '#field-description' ).val() && ! $( '#field-summary' ).val() ) {
    401409                            return;
     
    731739
    732740            // Prevent changing to the component if need be.
    733             if ( window.location.pathname !== '/newticket' ) {
     741            if ( ! wpTrac.isNewTicket() ) {
    734742                for ( var c in bugTrackerLocations ) {
    735743                    if ( ! bugTrackerLocations[c].prevent_changing_to ) {
     
    18491857        }()),
    18501858
     1859        suggestNotGeneral: ( function() {
     1860            var enabled = true,
     1861                skipWords = [ 'and', 'any', 'all', 'the', 'for', 'get', 'plugins', 'general' ],
     1862                componentWords = {},
     1863                noticeDiv;
     1864
     1865            function init() {
     1866                // Only on new ticket creations.
     1867                if ( ! wpTrac.isNewTicket() ) {
     1868                    return;
     1869                }
     1870
     1871                // Only if we have a 'General' option.
     1872                if ( ! $( '#field-component option[value="General"]' ).length ) {
     1873                    return;
     1874                }
     1875
     1876                // bbPress Trac.. has a set of components that I wish everyone had.
     1877                if ( $( 'body.bbpress' ).length ) {
     1878                    skipWords.push( 'api' );
     1879                    skipWords.push( 'component' );
     1880                    skipWords.push( 'tools' );
     1881                    skipWords.push( 'appearance' );
     1882                }
     1883
     1884                generateComponentWords();
     1885
     1886                $( '#field-description,#field-summary,#field-component' ).on( 'blur', maybeSuggest );
     1887
     1888                // Disable once the user hits the component option.
     1889                $( '#field-component' ).on( 'change', function() {
     1890                    // If they selected 'General', keep nagging.
     1891                    enabled = $(this).find( 'option[value="General"]').prop('selected');
     1892
     1893                    if ( ! enabled && noticeDiv ) {
     1894                        noticeDiv.remove();
     1895                        noticeDiv = false;
     1896                    }
     1897                } );
     1898            }
     1899
     1900            function maybeSuggest() {
     1901                var matchText = $( '#field-summary' ).val().toLowerCase() + ' ' + $( '#field-description' ).val().toLowerCase(),
     1902                    matchingWords = [],
     1903                    matchingComponents = [];
     1904
     1905                if ( ! enabled || ! matchText.length ) {
     1906                    return;
     1907                }
     1908
     1909                for ( const [word, components] of Object.entries( componentWords ) ) {
     1910                    if ( matchText.includes( word ) ) {
     1911                        matchingWords.push( word );
     1912                    }
     1913                }
     1914
     1915                // Longest match first.
     1916                matchingWords.sort( (a,b) => a.length > b.length ? -1 : 1 );
     1917
     1918                matchingWords.forEach( (word) => {
     1919                    componentWords[ word ].forEach( (component) => {
     1920                        if ( -1 == matchingComponents.indexOf( component ) ) {
     1921                            matchingComponents.push( component );
     1922                        }
     1923                    });
     1924                } );
     1925
     1926                if ( ! noticeDiv ) {
     1927                    noticeDiv = $( '<div id="componentSuggest"/>' ).insertBefore( $( '.buttons').first() );
     1928                }
     1929                noticeDiv.html( getNoticeHTML( matchingComponents ) );
     1930            }
     1931
     1932            function getNoticeHTML( matchingComponents ) {
     1933                var hasMatches = matchingComponents.length > 0,
     1934                    template = $(
     1935                        '<div class="wp-notice"><p><strong>Have you selected the right component?</strong></p>' +
     1936                        "<p>You've not yet selected a component. " +
     1937                            'Please check the "Component" option above' +
     1938                            ( hasMatches ? ' or select from one of the following:' :  '.' ) +
     1939                        '</p>' +
     1940                        '</div>'
     1941                    ),
     1942                    ulList;
     1943
     1944                if ( hasMatches ) {
     1945                    template.append( $('<ul/>' ) );
     1946                    ulList = template.find('ul');
     1947
     1948                    ulList.on( 'click', 'a', function(e) {
     1949                        e.preventDefault();
     1950                        const component = $(this).text();
     1951
     1952                        $( `#field-component option[value="${component}"]` ).prop( 'selected', 'selected' ).change();
     1953                    } );
     1954
     1955                    matchingComponents.forEach( (component) => {
     1956                        ulList.append( $( `<li><a href="#">${component}</a></li>` ) );
     1957                    } );
     1958                }
     1959
     1960                return template;
     1961            }
     1962
     1963            function generateComponentWords() {
     1964                $( '#field-component option' ).each( function() {
     1965                    const component = $(this).val(),
     1966                        words = component.split( /[^A-Za-z0-9\.']+/ )
     1967
     1968                    // Never suggest General..
     1969                    if ( 'General' === component ) {
     1970                        return;
     1971                    }
     1972
     1973                    if ( words.length > 1 ) {
     1974                        words.push( component );
     1975                    }
     1976
     1977                    // If it's a plural, add the non-plural form.
     1978                    words.forEach( (word) => {
     1979                        if ( 's' === word.substr( -1 ) ) {
     1980                            words.push( word.substr( 0, word.length - 1 ) );
     1981                        }
     1982                    } );
     1983
     1984                    words.forEach( (word) => {
     1985                        if ( ! word ) return;
     1986
     1987                        word = word.toLowerCase();
     1988
     1989                        if ( component != word && -1 !== skipWords.indexOf( word ) ) return;
     1990
     1991                        if ( ! ( word in componentWords ) ) {
     1992                            componentWords[ word ] = [];
     1993                        }
     1994
     1995                        componentWords[ word ].push( component );
     1996                    } );
     1997                } );
     1998
     1999                return componentWords;
     2000            }
     2001
     2002            return {
     2003                init: init
     2004            }
     2005
     2006        }() ),
     2007
    18512008        patchTracFor122Changes: function() {
     2009            // TODO: This needs to be removed, the Trac assets on s.w.org are probably outdated and need updating.
    18522010            console.log( "wp-trac: Applying compat patches for Trac 1.2.2" );
    18532011            // From Trac 1.2.2 threaded_comments.js:
Note: See TracChangeset for help on using the changeset viewer.