Skip to content

Commit

Permalink
feat(search): ✨ add search history to initial state
Browse files Browse the repository at this point in the history
  • Loading branch information
alistair3149 committed Aug 24, 2023
1 parent bd41516 commit f6d3fc9
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 41 deletions.
51 changes: 51 additions & 0 deletions resources/skins.citizen.search/presult.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
const config = require( './config.json' );
const typeaheadItem = require( './typeaheadItem.js' )();
const searchHistory = require( './searchHistory.js' )( config );

function presult() {
return {
elements: undefined,
addSearchHistory: function ( fragment ) {
const historyData = searchHistory.get();
if ( historyData?.length > 0 ) {
historyData.forEach( ( result, index ) => {
const data = {
icon: 'history',
id: `citizen-typeahead-history-${index}`,
// TODO: Add option to prepend the result to input field
link: `${config.wgScriptPath}/index.php?title=Special:Search&fulltext=1&search=${result}`,
type: 'history',
size: 'sm',
desc: result
};
fragment.append( typeaheadItem.get( data ) );
} );
}
return fragment;
},
render: function ( typeaheadEl ) {
const fragment = document.createDocumentFragment();
this.addSearchHistory( fragment );

if ( fragment.childNodes.length === 0 ) {
const data = {
icon: 'articlesSearch',
type: 'placeholder',
size: 'lg',
title: mw.message( 'searchsuggest-search' ).text(),
desc: mw.message( 'citizen-search-empty-desc' ).text()
};
fragment.append( typeaheadItem.get( data ) );
}

typeaheadEl.prepend( fragment );
this.set( typeaheadEl );
},
set: function ( typeaheadEl ) {
this.elements = typeaheadEl.querySelectorAll( '.citizen-typeahead__item-history' );
}
};
}

/** @module presult */
module.exports = presult;
11 changes: 9 additions & 2 deletions resources/skins.citizen.search/searchHistory.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,13 @@ function searchHistory( config ) {
/* TODO: Should probably create a separate config */
limit: config.wgCitizenMaxSearchResults,
get: function () {
// IDK why this.data keeps returning an empty array without init
this.init();
return this.data;
},
set: function ( arr ) {
this.data = arr;
},
add: function ( query ) {
if ( typeof query === 'string' ) {
let history = this.data;
Expand All @@ -16,14 +21,16 @@ function searchHistory( config ) {
if ( history.length > this.limit ) {
history.splice( this.limit );
}
this.data = history;
this.set( history );
/* NOTE: Should we set an expiry? This data only exists locally though */
mw.storage.set( 'skin-citizen-search-history', JSON.stringify( this.data ) );
}
},
init: function () {
const storedData = mw.storage.get( 'skin-citizen-search-history' );
this.data = storedData ? JSON.parse( storedData ) : [];
if ( storedData ) {
this.set( JSON.parse( storedData ) );
}
}
};
}
Expand Down
10 changes: 0 additions & 10 deletions resources/skins.citizen.search/templates/typeahead.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,6 @@
}}

<ol id="searchform-suggestions" class="citizen-typeahead" role="listbox">
{{! Empty state }}
<li class="citizen-typeahead__item-placeholder citizen-typeahead__item-lg">
<div class="citizen-typeahead__content">
<div class="citizen-typeahead__thumbnail citizen-ui-icon articlesSearch mw-ui-icon-wikimedia-articlesSearch"></div>
<div class="citizen-typeahead__text">
<div class="citizen-typeahead__title">{{msg-searchsuggest-search}}</div>
<div class="citizen-typeahead__description">{{msg-citizen-search-empty-desc}}</div>
</div>
</div>
</li>
{{! Template }}
<template id="citizen-typeahead-template">
<li role="option" class="citizen-typeahead__item">
Expand Down
58 changes: 29 additions & 29 deletions resources/skins.citizen.search/typeahead.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
const
PREFIX = 'citizen-typeahead',
SEARCH_LOADING_CLASS = 'citizen-loading',
ITEM_CLASS = `${PREFIX}__item`,
HIDDEN_CLASS = `${ITEM_CLASS}--hidden`;
SEARCH_LOADING_CLASS = 'citizen-loading';

// Config object from getCitizenSearchResourceLoaderConfig()
const config = require( './config.json' );

const typeaheadItem = require( './typeaheadItem.js' )();
const presult = require( './presult.js' )();
const searchClient = require( './searchClient.js' )( config );
const searchHistory = require( './searchHistory.js' )( config );
const searchQuery = require( './searchQuery.js' )();
Expand Down Expand Up @@ -146,8 +145,22 @@ const typeahead = {
},
set: function () {
this.elements = typeahead.element.querySelectorAll( '.citizen-typeahead__item' );
this.bindMouseHoverEvent();
this.setMax( this.elements.length );
// If there is no placeholder element, then there are selectable items
if ( !typeahead.element.querySelector( '.citizen-typeahead__item-placeholder' ) ) {
this.bindMouseHoverEvent();
this.setMax( this.elements.length );
}
},
clear: function () {
if ( !this.elements ) {
return;
}
this.elements.forEach( ( element ) => {
if ( !element.classList.contains( 'citizen-typeahead__item-tool' ) ) {
element.remove();
}
} );
this.elements = undefined;
}
},
suggestions: {
Expand All @@ -162,9 +175,6 @@ const typeahead = {
return;
}

this.elements.forEach( ( suggestion ) => {
suggestion.remove();
} );
this.set();
typeahead.input.element.setAttribute( 'aria-activedescendant', '' );
typeahead.items.clearIndex();
Expand Down Expand Up @@ -264,12 +274,11 @@ const typeahead = {
/**
* Fetch suggestions from API and render the suggetions in HTML
*
* @param {HTMLElement} placeholder
*/
function getSuggestions( placeholder ) {
function getSuggestions() {
const renderSuggestions = ( results ) => {
const fragment = document.createDocumentFragment();
if ( results.length > 0 ) {
const fragment = document.createDocumentFragment();
/**
* Return the redirect title with search query highlight
*
Expand Down Expand Up @@ -340,20 +349,19 @@ function getSuggestions( placeholder ) {
}
fragment.append( typeaheadItem.get( data ) );
} );
// Hide placeholder
placeholder.classList.add( HIDDEN_CLASS );
typeahead.element.prepend( fragment );
} else {
// Update placeholder with no result content
typeaheadItem.update( placeholder, {
const data = {
icon: 'articleNotFound',
type: 'placeholder',
size: 'lg',
title: mw.message( 'citizen-search-noresults-title', searchQuery.valueHtml ).text(),
desc: mw.message( 'citizen-search-noresults-desc' ).text()
} );
placeholder.classList.remove( HIDDEN_CLASS );
};
fragment.append( typeaheadItem.get( data ) );
}
typeahead.items.clear();
typeahead.element.prepend( fragment );
typeahead.suggestions.set();
// In case if somehow typeahead.suggestions.clear() didn't clear the loading animation
typeahead.form.element.classList.remove( SEARCH_LOADING_CLASS );
Expand Down Expand Up @@ -392,8 +400,6 @@ function getSuggestions( placeholder ) {
*
*/
function updateTypeaheadItems() {
const placeholder = typeahead.element.querySelector( `.${ITEM_CLASS}-placeholder` );

/**
* Get a list of tools for the typeahead footer
*/
Expand Down Expand Up @@ -455,17 +461,11 @@ function updateTypeaheadItems() {

getTools();
if ( searchQuery.isValid ) {
getSuggestions( placeholder );
getSuggestions();

} else {
typeahead.suggestions.clear();
// Update placeholder with no query content
typeaheadItem.update( placeholder, {
icon: 'articlesSearch',
title: mw.message( 'searchsuggest-search' ).text(),
desc: mw.message( 'citizen-search-empty-desc' ).text()
}
);
placeholder.classList.remove( HIDDEN_CLASS );
presult.render( typeahead.element );
typeahead.items.clear();
typeahead.items.set();
}
}
Expand Down
1 change: 1 addition & 0 deletions skin.json
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@
"resources/skins.citizen.search/typeahead.js",
"resources/skins.citizen.search/typeaheadItem.js",
"resources/skins.citizen.search/fetch.js",
"resources/skins.citizen.search/presult.js",
"resources/skins.citizen.search/searchClient.js",
"resources/skins.citizen.search/searchHistory.js",
"resources/skins.citizen.search/searchQuery.js",
Expand Down

0 comments on commit f6d3fc9

Please sign in to comment.