-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
TMS-1052: Favorite programs #182
Changes from 3 commits
008df90
8abaa5d
802afe6
133996d
9541fb0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,280 @@ | ||||||
/* eslint-disable no-console */ | ||||||
/** | ||||||
* Load more functionality for koulutusnosto-component. | ||||||
*/ | ||||||
|
||||||
// Use jQuery as $ within this file scope. | ||||||
const $ = jQuery; | ||||||
|
||||||
/** | ||||||
* Class LoadMore | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Väärä kommentti |
||||||
*/ | ||||||
export default class FavoritePrograms { | ||||||
docReady() { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Näille parille metodille vois heittää docblock-kommentin vielä |
||||||
// Bail if browser does not support localStorage. | ||||||
if ( typeof Storage === 'undefined' ) { | ||||||
return; | ||||||
} | ||||||
|
||||||
this.cache(); | ||||||
this.favorites = this.parseFavorites(); | ||||||
|
||||||
if ( ! this.hasFavorites() ) { | ||||||
this.showNoResults(); | ||||||
} | ||||||
|
||||||
// Init functionalities common to all templates. | ||||||
this.initCommon(); | ||||||
|
||||||
// Init functionalities for favorite-listing. | ||||||
this.initFavorites(); | ||||||
|
||||||
// Favorite popup functionalities | ||||||
this.favoritePopup(); | ||||||
} | ||||||
|
||||||
cache() { | ||||||
this.classes = { | ||||||
hasFavorites: 'has-favorites', | ||||||
isFavorite: 'is-favorite', | ||||||
hide: 'is-hidden', | ||||||
}; | ||||||
|
||||||
this.selectors = { | ||||||
button: '.js-toggle-favorite', | ||||||
}; | ||||||
this.storageKey = 'tredu-program-favorites'; | ||||||
this.closeFavorites = $( '#js-favorites-close' ); | ||||||
this.openFavorites = $( '#js-favorites-open' ); | ||||||
this.favoritesContainer = $( '#js-favorites-container' ); | ||||||
this.favoritePrograms = $( '#js-favorite-programs' ); | ||||||
this.favoritesContent = $( '#js-favorites-content' ); | ||||||
this.favoritesNoResults = $( '#js-favorites-no-results' ); | ||||||
} | ||||||
|
||||||
/** | ||||||
* Initialize functionalities common for all templates. | ||||||
*/ | ||||||
initCommon() { | ||||||
this.favoriteButtons = $( this.selectors.button ); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Kaikki luokan variablejen asetukset kannattaisi olla tossa |
||||||
|
||||||
if ( this.favoriteButtons.length > 0 ) { | ||||||
this.populateFavorites(); | ||||||
} | ||||||
} | ||||||
|
||||||
/** | ||||||
* Initialize functionalities for favorites listing. | ||||||
*/ | ||||||
initFavorites() { | ||||||
// Fetch favorites according to localStorage. | ||||||
if ( this.favorites.length !== 0 ) { | ||||||
dp( 'ProgramFavorites/FavoritePrograms', { | ||||||
partial: 'header-favorites-item', | ||||||
tidy: true, | ||||||
data: true, | ||||||
args: { | ||||||
ids: this.favorites, | ||||||
}, | ||||||
} ).then( ( response ) => { | ||||||
if ( ! response.success ) { | ||||||
this.showNoResults(); | ||||||
return; | ||||||
} | ||||||
|
||||||
// Set favorites content. | ||||||
this.favoritePrograms.html( response.success ); | ||||||
|
||||||
// Show the container. | ||||||
this.favoritePrograms.removeClass( this.classes.hide ); | ||||||
} ).catch( ( error ) => { | ||||||
console.log( error ); | ||||||
this.showNoResults(); | ||||||
} ); | ||||||
} | ||||||
|
||||||
// Update favorites when favorite-button clicked | ||||||
if ( this.favoritesContainer.length > 0 ) { | ||||||
this.favoriteButtons.on( 'click', ( e ) => { | ||||||
e.stopPropagation(); | ||||||
this.toggleFavorite( e.currentTarget ); | ||||||
this.loadFavorites(); | ||||||
} ); | ||||||
|
||||||
$( document ).on( 'click', '.js-remove-favorite', ( e ) => { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Voisiko tällä classilla tehdä myös jonkun There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Piti toteuttaa tälleen, koska |
||||||
e.stopPropagation(); | ||||||
this.removeFavorite( e.currentTarget ); | ||||||
this.loadFavorites(); | ||||||
} ); | ||||||
} | ||||||
} | ||||||
|
||||||
/** | ||||||
* Update favorite popup button attributes. | ||||||
*/ | ||||||
favoritePopup() { | ||||||
this.closeFavorites.on( 'click', ( e ) => { | ||||||
e.stopPropagation(); | ||||||
this.openFavorites.attr( 'aria-expanded', 'false' ); | ||||||
this.openFavorites.removeClass( 'is-active' ); | ||||||
} ); | ||||||
} | ||||||
|
||||||
/** | ||||||
* Parse favorite programs from localStorage. | ||||||
* | ||||||
* @return {Array} The localStorage values or an empty array. | ||||||
*/ | ||||||
parseFavorites() { | ||||||
const favorites = localStorage.getItem( this.storageKey ); | ||||||
|
||||||
if ( ! favorites ) { | ||||||
return []; | ||||||
} | ||||||
|
||||||
return JSON.parse( favorites ); | ||||||
} | ||||||
|
||||||
/** | ||||||
* Save passed favorites to localStorage. | ||||||
* | ||||||
* @param {Array} favorites The favorites as array | ||||||
*/ | ||||||
saveFavorites( favorites = [] ) { | ||||||
localStorage.setItem( this.storageKey, JSON.stringify( favorites ) ); | ||||||
} | ||||||
|
||||||
/** | ||||||
* Populate favorites from localStorage. | ||||||
* | ||||||
* @return {void} | ||||||
*/ | ||||||
populateFavorites() { | ||||||
// Loop over the favorite buttons and update their favorite-status. | ||||||
for ( const item of this.favoriteButtons ) { | ||||||
const programId = $( item ).data( 'program-id' ); | ||||||
|
||||||
if ( this.favorites.includes( programId ) ) { | ||||||
$( item ).addClass( this.classes.isFavorite ); | ||||||
$( item ).attr( 'aria-pressed', 'true' ); | ||||||
$( item ).find( '.text-favorite-active' ).removeClass( this.classes.hide ); | ||||||
$( item ).find( '.text-favorite-inactive' ).addClass( this.classes.hide ); | ||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
/** | ||||||
* Check if there are favorites in the localStorage. | ||||||
* | ||||||
* @return {boolean} True if favorites exist. | ||||||
*/ | ||||||
hasFavorites() { | ||||||
return this.favorites.length > 0; | ||||||
} | ||||||
|
||||||
/** | ||||||
* Changes favorite-status of the selected favorite. | ||||||
* | ||||||
* @param {Object} selectedItem The button element to be toggled. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
* @return {void} | ||||||
*/ | ||||||
toggleFavorite( selectedItem ) { | ||||||
const programId = $( selectedItem ).data( 'program-id' ); | ||||||
|
||||||
// Add or remove program ID from localStorage. | ||||||
if ( this.favorites.includes( programId ) ) { | ||||||
this.favorites = this.favorites.filter( ( fav ) => fav !== programId ); | ||||||
$( selectedItem ).removeClass( this.classes.isFavorite ); | ||||||
$( selectedItem ).find( '.text-favorite-active' ).addClass( this.classes.hide ); | ||||||
$( selectedItem ).find( '.text-favorite-inactive' ).removeClass( this.classes.hide ); | ||||||
$( selectedItem ).attr( 'aria-pressed', 'false' ); | ||||||
} | ||||||
else { | ||||||
this.favorites.push( programId ); | ||||||
$( selectedItem ).addClass( this.classes.isFavorite ); | ||||||
$( selectedItem ).find( '.text-favorite-active' ).removeClass( this.classes.hide ); | ||||||
$( selectedItem ).find( '.text-favorite-inactive' ).addClass( this.classes.hide ); | ||||||
$( selectedItem ).attr( 'aria-pressed', 'true' ); | ||||||
} | ||||||
|
||||||
// Save to localStorage. | ||||||
this.saveFavorites( this.favorites ); | ||||||
} | ||||||
|
||||||
/** | ||||||
* Remove favorite. | ||||||
* | ||||||
* @param {Object} selectedItem The button element to be toggled. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
* @return {void} | ||||||
*/ | ||||||
removeFavorite( selectedItem ) { | ||||||
const programId = $( selectedItem ).data( 'program-id' ); | ||||||
|
||||||
// Remove program ID from localStorage. | ||||||
if ( this.favorites.includes( programId ) ) { | ||||||
this.favorites = this.favorites.filter( ( fav ) => fav !== programId ); | ||||||
this.toggleFavoriteButton = $( '.js-toggle-favorite[data-program-id="' + programId + '"]' ); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Pitäiskö tässä tsekata, että elementti varmasti löytyy, koska on aika monimutkainen selector? Tässä voisi varmaan vetää returnin, jos elementtiä ei ole olemassa, muuten tulee consoleen virheitä. |
||||||
|
||||||
// Remove toggle-buttons attributes and texts | ||||||
this.toggleFavoriteButton.removeClass( this.classes.isFavorite ); | ||||||
this.toggleFavoriteButton.attr( 'aria-pressed', 'false' ); | ||||||
this.toggleFavoriteButton.find( '.text-favorite-active' ).addClass( this.classes.hide ); | ||||||
this.toggleFavoriteButton.find( '.text-favorite-inactive' ).removeClass( this.classes.hide ); | ||||||
} | ||||||
|
||||||
// Save to localStorage. | ||||||
this.saveFavorites( this.favorites ); | ||||||
} | ||||||
|
||||||
/** | ||||||
* Show "no results" content. | ||||||
*/ | ||||||
showNoResults() { | ||||||
this.favoritesContent.addClass( this.classes.hide ); | ||||||
this.favoritesNoResults.removeClass( this.classes.hide ); | ||||||
} | ||||||
|
||||||
/** | ||||||
* Hide "no results" content. | ||||||
*/ | ||||||
hideNoResults() { | ||||||
this.favoritesContent.removeClass( this.classes.hide ); | ||||||
this.favoritesNoResults.addClass( this.classes.hide ); | ||||||
} | ||||||
|
||||||
/** | ||||||
* Load and show the favorite programs. | ||||||
* | ||||||
* @return {void} | ||||||
*/ | ||||||
loadFavorites() { | ||||||
// Fetch favorites according to localStorage. | ||||||
dp( 'ProgramFavorites/FavoritePrograms', { | ||||||
partial: 'header-favorites-item', | ||||||
tidy: true, | ||||||
data: true, | ||||||
args: { | ||||||
ids: this.favorites, | ||||||
}, | ||||||
} ).then( ( response ) => { | ||||||
if ( ! response.success ) { | ||||||
this.showNoResults(); | ||||||
} | ||||||
else { | ||||||
this.hideNoResults(); | ||||||
} | ||||||
|
||||||
// Set favorites content. | ||||||
this.favoritePrograms.html( response.success ); | ||||||
|
||||||
// Refresh favorite buttons and add event listeners. | ||||||
this.initCommon(); | ||||||
|
||||||
// Show the container. | ||||||
this.favoritePrograms.removeClass( this.classes.hide ); | ||||||
} ).catch( () => { | ||||||
this.showNoResults(); | ||||||
} ); | ||||||
} | ||||||
|
||||||
} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,45 @@ | ||||||
#js-favorites-open { | ||||||
flex: 1 0 auto; | ||||||
width: 2.375rem; | ||||||
height: 2.375rem; | ||||||
|
||||||
svg { | ||||||
margin: 0 !important; | ||||||
} | ||||||
|
||||||
@include from($tablet) { | ||||||
width: rem(50px); | ||||||
height: rem(50px); | ||||||
} | ||||||
} | ||||||
|
||||||
#js-favorites-container { | ||||||
ul { | ||||||
list-style: none; | ||||||
padding: 0; | ||||||
|
||||||
li { | ||||||
&:not(:last-of-type) { | ||||||
border-bottom: 2px solid $primary; | ||||||
} | ||||||
|
||||||
.button-container { | ||||||
display: flex; | ||||||
gap: 2rem; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Olihan täällä noi spacing-muuttujat? |
||||||
|
||||||
.button.js-remove-favorite { | ||||||
padding: 0; | ||||||
background-color: transparent; | ||||||
border-color: transparent; | ||||||
|
||||||
svg.icon { | ||||||
margin-left: .25rem !important; | ||||||
margin-right: 0 !important; | ||||||
height: 1.25rem; | ||||||
width: 1.25rem; | ||||||
} | ||||||
} | ||||||
} | ||||||
} | ||||||
} | ||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Väärä kommentti