Hide the buttons on the tag page (#20148)
* feat: step 1 - add the buttons to the html template * refactor: renamed the class to be prepended with js- * feat: add the js-tag-card class to the entire tag-card div * feat: add the relevant data elements and tag-id to the tag-card div * feat: add the required data elements for the top level js-tag-card * feat: use @tag instead of tag * refactor: rename the tag pack file * refactor: rename the Tag file component * feat: add a snackzone so that the snackbar can be added there * feat: remove the follow-actions-button and the hide-actions-button from the tag pages so that it doesn't conflict with the 'followButtons' pack whne we need to add it * spec: update the specs for tags * chore: follow-action-button renamed to follow-tag-button and hide-action-button to hide-tag-button * refactor: js-classes * chore: add some comments --------- Co-authored-by: Ben Halpern <bendhalpern@gmail.com>
This commit is contained in:
parent
484821fe5e
commit
ae9d1b5ace
5 changed files with 87 additions and 20 deletions
|
|
@ -4,10 +4,18 @@ import { getUserDataAndCsrfToken } from '@utilities/getUserDataAndCsrfToken';
|
|||
|
||||
/* global showLoginModal */
|
||||
|
||||
// This Pack file has some dependencies for it to function accurately:
|
||||
// Copy and paste the FOllow and Hide button snippets from a tag card.
|
||||
// An example can be found in app/views/tags/index.html.erb
|
||||
// The tag card needs to contain a class .js-tag-card elements,
|
||||
// with data attributes for the tag-id and name.
|
||||
// The follow button and the hide button need to contain classes
|
||||
// js-follow-tag-button and/or js-hide-tag-button respectively.
|
||||
|
||||
function renderPage(currentUser) {
|
||||
import('../tags/Tag')
|
||||
import('../tags/TagButtonContainer')
|
||||
.then(({ Tag }) => {
|
||||
const tagCards = document.getElementsByClassName('tag-card');
|
||||
const tagCards = document.getElementsByClassName('js-tag-card');
|
||||
|
||||
const followedTags = JSON.parse(currentUser.followed_tags);
|
||||
Array.from(tagCards).forEach((element) => {
|
||||
|
|
@ -46,11 +54,11 @@ function listenForButtonClicks() {
|
|||
function handleButtonClick({ target }) {
|
||||
let trigger;
|
||||
|
||||
if (target.classList.contains('follow-action-button')) {
|
||||
if (target.classList.contains('js-follow-tag-button')) {
|
||||
trigger = 'follow_button';
|
||||
}
|
||||
|
||||
if (target.classList.contains('hide-action-button')) {
|
||||
if (target.classList.contains('js-hide-tag-button')) {
|
||||
trigger = 'hide_button';
|
||||
}
|
||||
|
||||
|
|
@ -64,8 +72,9 @@ function handleButtonClick({ target }) {
|
|||
}
|
||||
|
||||
function loadSnackbar() {
|
||||
const root = document.getElementsByClassName('tags-index');
|
||||
if (root.length > 0) {
|
||||
const snackZone = document.getElementById('snack-zone');
|
||||
|
||||
if (snackZone) {
|
||||
render(<Snackbar lifespan="1" />, document.getElementById('snack-zone'));
|
||||
}
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
<% expiry_minutes = params[:timeframe].blank? || params[:timeframe] == "latest" ? 4 : 20 %>
|
||||
<% flag = true %>
|
||||
<% cache("tag-stories-index-#{params}-#{flag}-#{@tag.updated_at}-#{user_signed_in?}", expires_in: expiry_minutes.minutes) do %>
|
||||
<div class="crayons-layout">
|
||||
<div data-tag-id="<%= @tag.id %>" data-tag-name="<%= @tag.name %>" id="tag-<%= @tag.id %>" class="crayons-layout js-tag-card">
|
||||
<header class="crayons-card branded-4 p-4 l:p-6 spec__tag-header" style="border-top-color: <%= @tag.bg_color_hex %> ">
|
||||
<div class="flex">
|
||||
<% if @tag.badge_id && @tag.badge %>
|
||||
|
|
@ -21,12 +21,20 @@
|
|||
<% end %>
|
||||
</h1>
|
||||
<% if @tag %>
|
||||
<button
|
||||
id="user-follow-butt"
|
||||
class="crayons-btn follow-action-button"
|
||||
data-info='<%= DataInfo.to_json(object: @tag, class_name: "Tag", name: @tag.pretty_name || @tag.name) %>'>
|
||||
<%= t("views.stories.follow") %>
|
||||
</button>
|
||||
<div id="tag-buttons-<%= @tag.id %>" class="mt-auto flex items-end justify-between">
|
||||
<div class="flex gap-2">
|
||||
<button
|
||||
class="c-btn c-btn--primary js-follow-tag-button"
|
||||
aria-label="<%= t("views.tags.aria_labels.follow", tag_name: @tag.name) %>">
|
||||
<%= t("views.tags.follow") %>
|
||||
</button>
|
||||
<button
|
||||
class="c-btn js-hide-tag-button"
|
||||
aria-label="<%= t("views.tags.aria_labels.hide", tag_name: @tag.name) %>">
|
||||
<%= t("views.tags.hide") %>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<% if @tag && @tag.short_summary.present? %>
|
||||
|
|
@ -130,5 +138,5 @@
|
|||
<%= render "stories/tagged_articles/sidebar_additional" %>
|
||||
</div>
|
||||
|
||||
<%= javascript_packs_with_chunks_tag "storiesList", "followButtons", "feedPreviewCards", "hideBookmarkButtons", "drawerSliders", "localizeArticleDates", defer: true %>
|
||||
<%= javascript_packs_with_chunks_tag "storiesList", "followButtons", "tagFollows", "feedPreviewCards", "hideBookmarkButtons", "drawerSliders", "localizeArticleDates", defer: true %>
|
||||
<% end %>
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@
|
|||
<% else %>
|
||||
<div class="grid gap-3 m:gap-4 l:gap-4 m:grid-cols-2 l:grid-cols-4 px-3 m:px-0 pb-3" data-follow-button-container="true">
|
||||
<% @tags.includes([:badge]).each do |tag| %>
|
||||
<div data-tag-id="<%= tag.id %>" data-tag-name="<%= tag.name %>" id="tag-<%= tag.id %>" class="tag-card crayons-card p-3 pt-2 m:p-5 m:pt-4 relative flex flex-col">
|
||||
<div data-tag-id="<%= tag.id %>" data-tag-name="<%= tag.name %>" id="tag-<%= tag.id %>" class="js-tag-card tag-card crayons-card p-3 pt-2 m:p-5 m:pt-4 relative flex flex-col">
|
||||
<div>
|
||||
<div class="mb-1 flex items-center justify-between">
|
||||
<h4 class="-ml-2">
|
||||
|
|
@ -68,12 +68,12 @@
|
|||
<div id="tag-buttons-<%= tag.id %>" class="mt-auto flex items-end justify-between">
|
||||
<div class="flex gap-2">
|
||||
<button
|
||||
class="c-btn c-btn--primary follow-action-button"
|
||||
class="c-btn c-btn--primary js-follow-tag-button"
|
||||
aria-label="<%= t("views.tags.aria_labels.follow", tag_name: tag.name) %>">
|
||||
<%= t("views.tags.follow") %>
|
||||
</button>
|
||||
<button
|
||||
class="c-btn hide-action-button"
|
||||
class="c-btn js-hide-tag-button"
|
||||
aria-label="<%= t("views.tags.aria_labels.hide", tag_name: tag.name) %>">
|
||||
<%= t("views.tags.hide") %>
|
||||
</button>
|
||||
|
|
@ -89,4 +89,4 @@
|
|||
<% end %>
|
||||
</main>
|
||||
|
||||
<%= javascript_packs_with_chunks_tag "TagsIndex", defer: true %>
|
||||
<%= javascript_packs_with_chunks_tag "tagFollows", defer: true %>
|
||||
|
|
|
|||
|
|
@ -103,12 +103,11 @@ describe('Follow tag', () => {
|
|||
cy.get('@user').then((user) => {
|
||||
cy.loginAndVisit(user, '/t/tag1').then(() => {
|
||||
cy.findByRole('heading', { name: '# tag1' });
|
||||
cy.get('[data-follow-clicks-initialized]');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('follows and unfollows a tag from the tag feed page', () => {
|
||||
it('follows and unfollows a tag', () => {
|
||||
cy.intercept('/follows').as('followsRequest');
|
||||
cy.findByRole('button', { name: 'Follow tag: tag1' }).as('followButton');
|
||||
|
||||
|
|
@ -116,11 +115,62 @@ describe('Follow tag', () => {
|
|||
cy.wait('@followsRequest');
|
||||
|
||||
cy.get('@followButton').should('have.text', 'Following');
|
||||
cy.get('@followButton').should('have.attr', 'aria-pressed', 'true');
|
||||
|
||||
cy.findByTestId('snackbar').within(() => {
|
||||
cy.findByRole('alert').should('have.text', 'You have followed tag1.');
|
||||
});
|
||||
|
||||
cy.get('@followButton').click();
|
||||
cy.wait('@followsRequest');
|
||||
|
||||
cy.get('@followButton').should('have.text', 'Follow');
|
||||
cy.get('@followButton').should('have.attr', 'aria-pressed', 'false');
|
||||
|
||||
cy.findByTestId('snackbar').within(() => {
|
||||
cy.findByRole('alert').should('have.text', 'You have unfollowed tag1.');
|
||||
});
|
||||
});
|
||||
|
||||
it('hides and unhides a tag', () => {
|
||||
cy.intercept('/follows').as('followsRequest');
|
||||
cy.findByRole('button', { name: 'Follow tag: tag1' }).as(
|
||||
'toBeHiddenFollowButton',
|
||||
);
|
||||
cy.findByRole('button', { name: 'Hide tag: tag1' }).as('hideButton');
|
||||
|
||||
cy.get('@hideButton').click();
|
||||
cy.wait('@followsRequest');
|
||||
|
||||
// clicking on 'Hide' should change it to an 'Unhide'
|
||||
// and remove the Follow button
|
||||
cy.get('@hideButton').should('have.text', 'Unhide');
|
||||
cy.get('@toBeHiddenFollowButton').should('not.exist');
|
||||
cy.findByTestId('snackbar').within(() => {
|
||||
cy.findByRole('alert').should('have.text', 'You have hidden tag1.');
|
||||
});
|
||||
|
||||
// clicking on 'Unhide' should change it back to 'Hide'
|
||||
// and show a 'Follow' button
|
||||
cy.get('@hideButton').click();
|
||||
cy.wait('@followsRequest');
|
||||
|
||||
cy.get('@hideButton').should('have.text', 'Hide');
|
||||
cy.get('@toBeHiddenFollowButton').should('not.exist');
|
||||
|
||||
cy.findByRole('button', { name: 'Follow tag: tag1' }).as(
|
||||
'toBeShownFollowButton',
|
||||
);
|
||||
cy.get('@toBeShownFollowButton').should('exist');
|
||||
cy.get('@toBeShownFollowButton').should('have.text', 'Follow');
|
||||
cy.get('@toBeShownFollowButton').should(
|
||||
'have.attr',
|
||||
'aria-pressed',
|
||||
'false',
|
||||
);
|
||||
cy.findByTestId('snackbar').within(() => {
|
||||
cy.findByRole('alert').should('have.text', 'You have unhidden tag1.');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue