mirror of
https://github.com/IT4Change/Ocelot-Social.git
synced 2026-03-22 18:25:29 +00:00
fix(webapp): fix search + search e2e (#9376)
This commit is contained in:
parent
237798b0f0
commit
83df85001d
6
.github/workflows/test-e2e.yml
vendored
6
.github/workflows/test-e2e.yml
vendored
@ -233,6 +233,12 @@ jobs:
|
||||
timeout 120 bash -c 'until curl -sf http://localhost:3000 > /dev/null 2>&1; do sleep 5; done'
|
||||
echo "Webapp is ready."
|
||||
|
||||
- name: Initialize database
|
||||
run: docker compose -f docker-compose.yml -f docker-compose.test.yml exec -T backend yarn db:migrate init
|
||||
|
||||
- name: Migrate database
|
||||
run: docker compose -f docker-compose.yml -f docker-compose.test.yml exec -T backend yarn db:migrate up
|
||||
|
||||
- name: Full stack tests | run tests
|
||||
id: e2e-tests
|
||||
run: yarn run cypress:run --spec "cypress/e2e/${{ matrix.feature }}"
|
||||
|
||||
@ -230,6 +230,55 @@ Factory.define('post')
|
||||
return post
|
||||
})
|
||||
|
||||
Factory.define('group')
|
||||
.option('ownerId', null)
|
||||
.option('owner', ['ownerId'], (ownerId) => {
|
||||
if (ownerId) return neode.find('User', ownerId)
|
||||
return Factory.build('user')
|
||||
})
|
||||
.attrs({
|
||||
id: uuid,
|
||||
name: faker.company.name,
|
||||
about: faker.lorem.sentence,
|
||||
description: faker.lorem.paragraphs,
|
||||
groupType: 'public',
|
||||
actionRadius: 'regional',
|
||||
deleted: false,
|
||||
disabled: false,
|
||||
})
|
||||
.attr('slug', ['slug', 'name'], (slug, name) => {
|
||||
return slug || slugify(name, { lower: true })
|
||||
})
|
||||
.attr(
|
||||
'descriptionExcerpt',
|
||||
['descriptionExcerpt', 'description'],
|
||||
(descriptionExcerpt, description) => {
|
||||
return descriptionExcerpt || description
|
||||
},
|
||||
)
|
||||
.after(async (buildObject, options) => {
|
||||
const [group, owner] = await Promise.all([neode.create('Group', buildObject), options.owner])
|
||||
const session = driver.session()
|
||||
try {
|
||||
await session.writeTransaction((txc) =>
|
||||
txc.run(
|
||||
`
|
||||
MATCH (owner:User {id: $ownerId}), (group:Group {id: $groupId})
|
||||
MERGE (owner)-[:CREATED]->(group)
|
||||
MERGE (owner)-[membership:MEMBER_OF]->(group)
|
||||
SET membership.createdAt = toString(datetime()),
|
||||
membership.updatedAt = toString(datetime()),
|
||||
membership.role = 'owner'
|
||||
`,
|
||||
{ ownerId: owner.get('id'), groupId: buildObject.id },
|
||||
),
|
||||
)
|
||||
} finally {
|
||||
await session.close()
|
||||
}
|
||||
return group
|
||||
})
|
||||
|
||||
Factory.define('comment')
|
||||
.option('postId', null)
|
||||
.option('post', ['postId'], (postId) => {
|
||||
|
||||
@ -19,7 +19,7 @@ async function setupNodeEvents(on, config) {
|
||||
webpackPreprocessor({
|
||||
webpackOptions: {
|
||||
mode: 'development',
|
||||
devtool: 'source-map',
|
||||
devtool: 'eval-source-map',
|
||||
resolve: {
|
||||
extensions: ['.js', '.json'],
|
||||
fallback: {
|
||||
|
||||
67
cypress/e2e/Search.Results.feature
Normal file
67
cypress/e2e/Search.Results.feature
Normal file
@ -0,0 +1,67 @@
|
||||
Feature: Search Results Page
|
||||
As a user
|
||||
I would like to see search results for posts, users, groups, and hashtags
|
||||
In order to find specific content on the platform
|
||||
|
||||
Background:
|
||||
Given the following "users" are in the database:
|
||||
| slug | email | password | id | name | termsAndConditionsAgreedVersion |
|
||||
| narrator | narrator@example.org | 1234 | narrator | Nathan Narrator | 0.0.4 |
|
||||
| jenny | jenny@example.org | 1234 | jenny-id | Jenny Rostock | 0.0.4 |
|
||||
| finduser | finduser@example.org | 1234 | finduser | Find me user | 0.0.4 |
|
||||
And the following "tags" are in the database:
|
||||
| id |
|
||||
| find-me-tag |
|
||||
And the following "posts" are in the database:
|
||||
| id | title | content | authorId | tagIds |
|
||||
| p1 | Find me post one | This is the first result | narrator | find-me-tag |
|
||||
| p2 | Find me post two | This is the second result | narrator | find-me-tag |
|
||||
And the following "groups" are in the database:
|
||||
| id | name | slug | about | description | ownerId |
|
||||
| group-1 | Discoverable club | discoverable-club | A group to be found | This is a detailed description for the test group so it has enough characters to pass the minimum length of one hundred | narrator |
|
||||
And I am logged in as "narrator"
|
||||
|
||||
Scenario: Post results are displayed
|
||||
When I navigate to page "/search/search-results?search=Find"
|
||||
Then I should see the "Post" tab as active
|
||||
And I should see 2 post results
|
||||
|
||||
Scenario: User results are displayed
|
||||
When I navigate to page "/search/search-results?search=Jenny"
|
||||
Then I should see the "User" tab as active
|
||||
And I should see 1 user results
|
||||
|
||||
Scenario: Group results are displayed
|
||||
When I navigate to page "/search/search-results?search=Discoverable club"
|
||||
Then I should see the "Group" tab as active
|
||||
And I should see 1 group results
|
||||
|
||||
Scenario: Hashtag results are displayed
|
||||
When I navigate to page "/search/search-results?search=find-me-tag"
|
||||
Then I should see the "Hashtag" tab as active
|
||||
And I should see 1 hashtag results
|
||||
|
||||
Scenario: Switching tabs hides previous results
|
||||
When I navigate to page "/search/search-results?search=Find"
|
||||
And I click on the "User" tab
|
||||
Then I should not see post results
|
||||
|
||||
Scenario: Pagination for many posts
|
||||
Given the following "posts" are in the database:
|
||||
| id | title | content | authorId |
|
||||
| p3 | Find me post 3 | Some content 3 | narrator |
|
||||
| p4 | Find me post 4 | Some content 4 | narrator |
|
||||
| p5 | Find me post 5 | Some content 5 | narrator |
|
||||
| p6 | Find me post 6 | Some content 6 | narrator |
|
||||
| p7 | Find me post 7 | Some content 7 | narrator |
|
||||
| p8 | Find me post 8 | Some content 8 | narrator |
|
||||
| p9 | Find me post 9 | Some content 9 | narrator |
|
||||
| p10 | Find me post 10 | Some content 10 | narrator |
|
||||
| p11 | Find me post 11 | Some content 11 | narrator |
|
||||
| p12 | Find me post 12 | Some content 12 | narrator |
|
||||
| p13 | Find me post 13 | Some content 13 | narrator |
|
||||
When I navigate to page "/search/search-results?search=Find"
|
||||
Then I should see pagination buttons
|
||||
And I should see page "Page 1 / 2"
|
||||
When I click on the next page button
|
||||
Then I should see page "Page 2 / 2"
|
||||
@ -0,0 +1,5 @@
|
||||
import { defineStep } from '@badeball/cypress-cucumber-preprocessor'
|
||||
|
||||
defineStep('I click on the next page button', () => {
|
||||
cy.get('[data-test="next-button"]').first().click()
|
||||
})
|
||||
@ -0,0 +1,6 @@
|
||||
import { defineStep } from '@badeball/cypress-cucumber-preprocessor'
|
||||
|
||||
defineStep('I click on the {string} tab', (type) => {
|
||||
cy.get(`[data-test="${type}-tab"]`).should('not.have.class', '--disabled')
|
||||
cy.get(`[data-test="${type}-tab-click"]`).click()
|
||||
})
|
||||
@ -0,0 +1,5 @@
|
||||
import { defineStep } from '@badeball/cypress-cucumber-preprocessor'
|
||||
|
||||
defineStep('I should not see post results', () => {
|
||||
cy.get('.post-teaser').should('not.exist')
|
||||
})
|
||||
@ -0,0 +1,7 @@
|
||||
import { defineStep } from '@badeball/cypress-cucumber-preprocessor'
|
||||
|
||||
defineStep('I should see page {string}', (page) => {
|
||||
cy.get('.pagination-pageCount').first().invoke('text').then((text) => {
|
||||
expect(text.replace(/\s+/g, ' ').trim()).to.contain(page)
|
||||
})
|
||||
})
|
||||
@ -0,0 +1,6 @@
|
||||
import { defineStep } from '@badeball/cypress-cucumber-preprocessor'
|
||||
|
||||
defineStep('I should see pagination buttons', () => {
|
||||
cy.get('[data-test="previous-button"]').should('exist')
|
||||
cy.get('[data-test="next-button"]').should('exist')
|
||||
})
|
||||
@ -0,0 +1,5 @@
|
||||
import { defineStep } from '@badeball/cypress-cucumber-preprocessor'
|
||||
|
||||
defineStep('I should see the {string} tab as active', (type) => {
|
||||
cy.get(`[data-test="${type}-tab"]`).should('have.class', '--active')
|
||||
})
|
||||
@ -0,0 +1,5 @@
|
||||
import { defineStep } from '@badeball/cypress-cucumber-preprocessor'
|
||||
|
||||
defineStep('I should see {int} group results', (count) => {
|
||||
cy.get('.group-teaser').should('have.length', count)
|
||||
})
|
||||
@ -0,0 +1,5 @@
|
||||
import { defineStep } from '@badeball/cypress-cucumber-preprocessor'
|
||||
|
||||
defineStep('I should see {int} hashtag results', (count) => {
|
||||
cy.get('.hc-hashtag').should('have.length', count)
|
||||
})
|
||||
@ -0,0 +1,5 @@
|
||||
import { defineStep } from '@badeball/cypress-cucumber-preprocessor'
|
||||
|
||||
defineStep('I should see {int} post results', (count) => {
|
||||
cy.get('.post-teaser').should('have.length', count)
|
||||
})
|
||||
@ -0,0 +1,5 @@
|
||||
import { defineStep } from '@badeball/cypress-cucumber-preprocessor'
|
||||
|
||||
defineStep('I should see {int} user results', (count) => {
|
||||
cy.get('.user-teaser').should('have.length', count)
|
||||
})
|
||||
@ -32,6 +32,15 @@ defineStep('the following {string} are in the database:', (table,data) => {
|
||||
cy.factory().build('tag', entry, entry)
|
||||
})
|
||||
break
|
||||
case 'groups':
|
||||
data.hashes().forEach( entry => {
|
||||
cy.factory().build('group', {
|
||||
...entry,
|
||||
deleted: Boolean(entry.deleted),
|
||||
disabled: Boolean(entry.disabled),
|
||||
}, entry)
|
||||
})
|
||||
break
|
||||
case 'donations':
|
||||
data.hashes().forEach( entry => {
|
||||
cy.factory().build('donations', entry, entry)
|
||||
|
||||
@ -1,121 +1,110 @@
|
||||
<template>
|
||||
<div id="search-results" class="search-results">
|
||||
<div class="search-results__content">
|
||||
<masonry-grid>
|
||||
<!-- search text -->
|
||||
<div class="grid-total-search-results" style="grid-row-end: span 1; grid-column: 1 / -1">
|
||||
<div class="ds-mb-xxx-small ds-mt-xxx-small ds-space-centered">
|
||||
<p class="ds-text total-search-results">
|
||||
{{ $t('search.for') }}
|
||||
<strong>{{ '"' + (search || '') + '"' }}</strong>
|
||||
</p>
|
||||
<!-- search text -->
|
||||
<div class="grid-total-search-results">
|
||||
<div class="ds-mb-xxx-small ds-mt-xxx-small ds-space-centered">
|
||||
<p class="ds-text total-search-results">
|
||||
{{ $t('search.for') }}
|
||||
<strong>{{ '"' + (search || '') + '"' }}</strong>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- tabs -->
|
||||
<tab-navigation :tabs="tabOptions" :activeTab="activeTab" @switch-tab="switchTab" />
|
||||
|
||||
<!-- search results -->
|
||||
<div v-if="!(!activeResourceCount || searchCount === 0)" class="search-results-body">
|
||||
<!-- pagination buttons -->
|
||||
<div v-if="activeResourceCount > pageSize" class="search-results-pagination">
|
||||
<pagination-buttons
|
||||
:hasNext="hasNext"
|
||||
:showPageCounter="true"
|
||||
:hasPrevious="hasPrevious"
|
||||
:activePage="activePage"
|
||||
:activeResourceCount="activeResourceCount"
|
||||
:key="'Top'"
|
||||
:pageSize="pageSize"
|
||||
@back="previousResults"
|
||||
@next="nextResults"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- posts -->
|
||||
<masonry-grid v-if="activeTab === 'Post'">
|
||||
<masonry-grid-item
|
||||
v-for="post in activeResources"
|
||||
:key="post.id"
|
||||
:imageAspectRatio="post.image && post.image.aspectRatio"
|
||||
>
|
||||
<post-teaser
|
||||
:post="post"
|
||||
:width="{ base: '100%', md: '100%', xl: '50%' }"
|
||||
:showGroupPinned="true"
|
||||
@removePostFromList="posts = removePostFromList(post, posts)"
|
||||
@pinPost="pinPost(post, refetchPostList)"
|
||||
@unpinPost="unpinPost(post, refetchPostList)"
|
||||
@pinGroupPost="pinGroupPost(post, refetchPostList)"
|
||||
@unpinGroupPost="unpinGroupPost(post, refetchPostList)"
|
||||
@pushPost="pushPost(post, refetchPostList)"
|
||||
@unpushPost="unpushPost(post, refetchPostList)"
|
||||
@toggleObservePost="
|
||||
(postId, value) => toggleObservePost(postId, value, refetchPostList)
|
||||
"
|
||||
/>
|
||||
</masonry-grid-item>
|
||||
</masonry-grid>
|
||||
<!-- users -->
|
||||
<div v-if="activeTab === 'User'" class="search-results-list">
|
||||
<div v-for="user in activeResources" :key="user.id" class="search-results-list__item">
|
||||
<os-card>
|
||||
<user-teaser :user="user" />
|
||||
</os-card>
|
||||
</div>
|
||||
</div>
|
||||
<!-- groups -->
|
||||
<div v-if="activeTab === 'Group'" class="search-results-list">
|
||||
<div v-for="group in activeResources" :key="group.id" class="search-results-list__item">
|
||||
<group-teaser :group="{ ...group, name: group.groupName }" />
|
||||
</div>
|
||||
</div>
|
||||
<!-- hashtags -->
|
||||
<div v-if="activeTab === 'Hashtag'" class="search-results-list">
|
||||
<div
|
||||
v-for="hashtag in activeResources"
|
||||
:key="hashtag.id"
|
||||
class="search-results-list__item"
|
||||
>
|
||||
<os-card>
|
||||
<hc-hashtag :id="hashtag.id" />
|
||||
</os-card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- tabs -->
|
||||
<tab-navigation :tabs="tabOptions" :activeTab="activeTab" @switch-tab="switchTab" />
|
||||
|
||||
<!-- search results -->
|
||||
|
||||
<template v-if="!(!activeResourceCount || searchCount === 0)">
|
||||
<!-- pagination buttons -->
|
||||
<div
|
||||
v-if="activeResourceCount > pageSize"
|
||||
style="grid-row-end: span 2; grid-column: 1 / -1"
|
||||
>
|
||||
<div class="ds-mb-large ds-space-centered">
|
||||
<pagination-buttons
|
||||
:hasNext="hasNext"
|
||||
:showPageCounter="true"
|
||||
:hasPrevious="hasPrevious"
|
||||
:activePage="activePage"
|
||||
:activeResourceCount="activeResourceCount"
|
||||
:key="'Top'"
|
||||
:pageSize="pageSize"
|
||||
@back="previousResults"
|
||||
@next="nextResults"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- posts -->
|
||||
<template v-if="activeTab === 'Post'">
|
||||
<masonry-grid-item
|
||||
v-for="post in activeResources"
|
||||
:key="post.id"
|
||||
:imageAspectRatio="post.image && post.image.aspectRatio"
|
||||
>
|
||||
<post-teaser
|
||||
:post="post"
|
||||
:width="{ base: '100%', md: '100%', xl: '50%' }"
|
||||
:showGroupPinned="true"
|
||||
@removePostFromList="posts = removePostFromList(post, posts)"
|
||||
@pinPost="pinPost(post, refetchPostList)"
|
||||
@unpinPost="unpinPost(post, refetchPostList)"
|
||||
@pinGroupPost="pinGroupPost(post, refetchPostList)"
|
||||
@unpinGroupPost="unpinGroupPost(post, refetchPostList)"
|
||||
@pushPost="pushPost(post, refetchPostList)"
|
||||
@unpushPost="unpushPost(post, refetchPostList)"
|
||||
@toggleObservePost="
|
||||
(postId, value) => toggleObservePost(postId, value, refetchPostList)
|
||||
"
|
||||
/>
|
||||
</masonry-grid-item>
|
||||
</template>
|
||||
<!-- users -->
|
||||
<template v-if="activeTab === 'User'">
|
||||
<div v-for="user in activeResources" :key="user.id" style="grid-row-end: span 2">
|
||||
<os-card>
|
||||
<user-teaser :user="user" />
|
||||
</os-card>
|
||||
</div>
|
||||
</template>
|
||||
<!-- groups -->
|
||||
<template v-if="activeTab === 'Group'">
|
||||
<div v-for="group in activeResources" :key="group.id" style="grid-row-end: span 2">
|
||||
<os-card class="group-teaser-card-wrapper">
|
||||
<group-teaser :group="{ ...group, name: group.groupName }" />
|
||||
</os-card>
|
||||
</div>
|
||||
</template>
|
||||
<!-- hashtags -->
|
||||
<template v-if="activeTab === 'Hashtag'">
|
||||
<div v-for="hashtag in activeResources" :key="hashtag.id" style="grid-row-end: span 2">
|
||||
<os-card>
|
||||
<hc-hashtag :id="hashtag.id" />
|
||||
</os-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- pagination buttons -->
|
||||
<div
|
||||
v-if="activeResourceCount > pageSize"
|
||||
style="grid-row-end: span 2; grid-column: 1 / -1"
|
||||
>
|
||||
<div class="ds-mb-large ds-space-centered">
|
||||
<pagination-buttons
|
||||
:hasNext="hasNext"
|
||||
:hasPrevious="hasPrevious"
|
||||
:activePage="activePage"
|
||||
:showPageCounter="true"
|
||||
:activeResourceCount="activeResourceCount"
|
||||
:key="'Bottom'"
|
||||
:pageSize="pageSize"
|
||||
:srollTo="'#search-results'"
|
||||
@back="previousResults"
|
||||
@next="nextResults"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- no results -->
|
||||
<div v-else style="grid-row-end: span 7; grid-column: 1 / -1">
|
||||
<div class="ds-mb-large ds-space-centered">
|
||||
<hc-empty icon="tasks" :message="$t('search.no-results', { search })" />
|
||||
</div>
|
||||
<!-- pagination buttons -->
|
||||
<div v-if="activeResourceCount > pageSize" class="search-results-pagination">
|
||||
<pagination-buttons
|
||||
:hasNext="hasNext"
|
||||
:hasPrevious="hasPrevious"
|
||||
:activePage="activePage"
|
||||
:showPageCounter="true"
|
||||
:activeResourceCount="activeResourceCount"
|
||||
:key="'Bottom'"
|
||||
:pageSize="pageSize"
|
||||
:srollTo="'#search-results'"
|
||||
@back="previousResults"
|
||||
@next="nextResults"
|
||||
/>
|
||||
</div>
|
||||
</masonry-grid>
|
||||
</div>
|
||||
|
||||
<!-- no results -->
|
||||
<div v-else class="search-results-empty">
|
||||
<div class="ds-space-centered">
|
||||
<hc-empty icon="tasks" :message="$t('search.no-results', { search })" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -474,4 +463,34 @@ export default {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.search-results-empty {
|
||||
padding-top: $space-small;
|
||||
|
||||
@media (max-width: 810px) {
|
||||
padding-top: $space-x-small;
|
||||
}
|
||||
}
|
||||
|
||||
.search-results-pagination {
|
||||
padding-top: $space-small;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
@media (max-width: 810px) {
|
||||
padding-top: $space-x-small;
|
||||
}
|
||||
}
|
||||
|
||||
.search-results-list {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
|
||||
gap: $space-small;
|
||||
padding-top: $space-small;
|
||||
|
||||
@media (max-width: 810px) {
|
||||
gap: $space-x-small;
|
||||
padding-top: $space-x-small;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="tab-navigation" :style="{ gridRowEnd: 'span ' + tabs.length, gridColumn: '1 / -1' }">
|
||||
<div class="tab-navigation">
|
||||
<os-card class="ds-tab-nav">
|
||||
<ul class="Tabs">
|
||||
<li
|
||||
|
||||
@ -71,7 +71,7 @@ export const searchPosts = gql`
|
||||
`
|
||||
|
||||
export const searchGroups = (i18n) => {
|
||||
const lang = i18n ? i18n.locale().toUpperCase() : 'EN'
|
||||
const lang = i18n ? i18n.locale() : 'en'
|
||||
return gql`
|
||||
${imageUrls}
|
||||
|
||||
@ -103,7 +103,7 @@ export const searchGroups = (i18n) => {
|
||||
}
|
||||
locationName
|
||||
location {
|
||||
name: name${lang}
|
||||
name(lang: "${lang}")
|
||||
}
|
||||
myRole
|
||||
}
|
||||
|
||||
@ -59,6 +59,7 @@ describe('PostIndex', () => {
|
||||
push: jest.fn(),
|
||||
},
|
||||
push: jest.fn(),
|
||||
replace: jest.fn(),
|
||||
},
|
||||
$toast: {
|
||||
success: jest.fn(),
|
||||
|
||||
@ -1,5 +1,10 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- hashtag filter -->
|
||||
<div v-if="hashtag" class="hashtag-filter-bar">
|
||||
<hashtags-filter :hashtag="hashtag" @clearSearch="clearSearch" />
|
||||
</div>
|
||||
|
||||
<!-- feed top row: filter (left) + create post (right) -->
|
||||
<div class="feed-top-row">
|
||||
<div
|
||||
@ -101,14 +106,11 @@
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="hashtag || showDonations"
|
||||
v-if="showDonations"
|
||||
class="newsfeed-controls"
|
||||
:class="{ 'newsfeed-controls--no-filter': !SHOW_CONTENT_FILTER_MASONRY_GRID }"
|
||||
>
|
||||
<div v-if="hashtag">
|
||||
<hashtags-filter :hashtag="hashtag" @clearSearch="clearSearch" />
|
||||
</div>
|
||||
<div v-if="showDonations" class="top-info-bar donation-desktop-only">
|
||||
<div class="top-info-bar donation-desktop-only">
|
||||
<donation-info :goal="goal" :progress="progress" />
|
||||
</div>
|
||||
</div>
|
||||
@ -116,7 +118,7 @@
|
||||
<masonry-grid
|
||||
:single-column="singleColumn"
|
||||
:class="[
|
||||
!hashtag && !showDonations ? 'grid-margin-top' : '',
|
||||
!showDonations ? 'grid-margin-top' : '',
|
||||
!isMobile && !singleColumn && posts.length <= 2 ? 'grid-column-helper' : '',
|
||||
]"
|
||||
>
|
||||
@ -253,8 +255,11 @@ export default {
|
||||
return this.$route.query && this.$route.query.categoryId ? this.$route.query.categoryId : null
|
||||
},
|
||||
},
|
||||
watchQuery: ['hashtag'],
|
||||
watch: {
|
||||
'$route.query.hashtag'(value) {
|
||||
this.hashtag = value || null
|
||||
this.resetPostList()
|
||||
},
|
||||
postsFilter() {
|
||||
this.resetPostList()
|
||||
},
|
||||
@ -317,8 +322,10 @@ export default {
|
||||
this.prevScrollpos = currentScrollPos
|
||||
},
|
||||
clearSearch() {
|
||||
this.$router.push({ path: '/' })
|
||||
this.hashtag = null
|
||||
const query = { ...this.$route.query }
|
||||
delete query.hashtag
|
||||
this.$router.replace({ query })
|
||||
},
|
||||
href(post) {
|
||||
return this.$router.resolve({
|
||||
@ -390,6 +397,11 @@ export default {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.hashtag-filter-bar {
|
||||
margin-top: -$space-x-small;
|
||||
margin-bottom: $space-small;
|
||||
}
|
||||
|
||||
.feed-top-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@ -419,6 +431,10 @@ export default {
|
||||
transition: top 0.3s ease !important;
|
||||
}
|
||||
|
||||
.hashtag-filter-bar + .feed-top-row .post-add-button {
|
||||
top: 146px !important;
|
||||
}
|
||||
|
||||
.main-navigation:has(.hide-navbar) ~ .ds-container .post-add-button {
|
||||
top: 20px !important;
|
||||
}
|
||||
@ -519,6 +535,10 @@ export default {
|
||||
top: 67px !important;
|
||||
}
|
||||
|
||||
.hashtag-filter-bar + .feed-top-row .post-add-button {
|
||||
top: 125px !important;
|
||||
}
|
||||
|
||||
.newsfeed-controls {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
@ -452,7 +452,6 @@ exports[`ProfileSlug given an authenticated user given another profile user and
|
||||
>
|
||||
<div
|
||||
class="tab-navigation ds-mb-large"
|
||||
style="grid-row-end: span 3; grid-column: 1 / -1;"
|
||||
>
|
||||
<div
|
||||
class="ds-tab-nav os-card relative rounded-[5px] break-words bg-white shadow-[0px_12px_26px_-4px_rgba(0,0,0,0.1)] p-6 ds-tab-nav"
|
||||
@ -1187,7 +1186,6 @@ exports[`ProfileSlug given an authenticated user given another profile user and
|
||||
>
|
||||
<div
|
||||
class="tab-navigation ds-mb-large"
|
||||
style="grid-row-end: span 3; grid-column: 1 / -1;"
|
||||
>
|
||||
<div
|
||||
class="ds-tab-nav os-card relative rounded-[5px] break-words bg-white shadow-[0px_12px_26px_-4px_rgba(0,0,0,0.1)] p-6 ds-tab-nav"
|
||||
@ -1743,7 +1741,6 @@ exports[`ProfileSlug given an authenticated user given the logged in user as pro
|
||||
>
|
||||
<div
|
||||
class="tab-navigation ds-mb-large"
|
||||
style="grid-row-end: span 3; grid-column: 1 / -1;"
|
||||
>
|
||||
<div
|
||||
class="ds-tab-nav os-card relative rounded-[5px] break-words bg-white shadow-[0px_12px_26px_-4px_rgba(0,0,0,0.1)] p-6 ds-tab-nav"
|
||||
@ -2377,7 +2374,6 @@ exports[`ProfileSlug given an authenticated user given the logged in user as pro
|
||||
>
|
||||
<div
|
||||
class="tab-navigation ds-mb-large"
|
||||
style="grid-row-end: span 3; grid-column: 1 / -1;"
|
||||
>
|
||||
<div
|
||||
class="ds-tab-nav os-card relative rounded-[5px] break-words bg-white shadow-[0px_12px_26px_-4px_rgba(0,0,0,0.1)] p-6 ds-tab-nav"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user