Skip to content
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

[Search page] Add search input and filters #22

Merged
merged 21 commits into from
Feb 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
fc010d4
feat(search-form): add a search-form with basic UI
tkohr Feb 20, 2024
fbd8415
feat(search-filters): add filter component
tkohr Feb 20, 2024
8246701
feat(search-filters): extend components for dropdown
tkohr Feb 21, 2024
952bb53
feat(dropdown-select): display selected counter and arrow
tkohr Feb 21, 2024
a6d8a99
chore(package.json): update gn-ui
tkohr Feb 22, 2024
6127e7b
type(dropdown-select): remove workarounds for gn-ui typing issues
tkohr Feb 22, 2024
4a057cf
feat(results-list-grid): add show more button
tkohr Feb 23, 2024
2c1b9f3
feat(results-list): display content ghost on grid list as well
tkohr Feb 23, 2024
6d9e2bf
feat(search-form): rework layout
tkohr Feb 23, 2024
ed3293f
feat(search-page): ajust result hits and spacings to mel design
tkohr Feb 23, 2024
fbb2f47
refactor(search-page): move template around grid to search-results
tkohr Feb 23, 2024
e6fd7dc
feat(search-results): add spinning loader to show more button
tkohr Feb 23, 2024
951f87f
refactor(search-page): use control flow syntax
tkohr Feb 23, 2024
b540d1a
refactor(filter-dropdown): rename components extended from gn-ui with…
tkohr Feb 23, 2024
8687a72
test(search-results): fix e2e tests
tkohr Feb 23, 2024
11cb654
chore(i18n): run `npm run i18n:extract` after rebase
tkohr Feb 27, 2024
2e96f58
feat(search-form): use mel fuzzy-search.component
tkohr Feb 27, 2024
521388f
refactor(style): use mel-title-line class
tkohr Feb 27, 2024
b33f1cb
fix(content-ghost): change condition to isLoading
tkohr Feb 27, 2024
3f1a049
test(e2e): add and restructure tests
tkohr Feb 27, 2024
c763763
review: address comments
tkohr Feb 28, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 37 additions & 24 deletions apps/datahub-e2e/src/e2e/home.cy.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
describe('datahub-e2e', () => {
describe('home', () => {
beforeEach(() => cy.visit('/home'))

it('should display the title', () => {
cy.get('.mel-page-title').should('be.visible')
})
it('should display the search bar and placeholder', () => {
cy.get('mel-datahub-fuzzy-search').should('be.visible')
cy.get('mel-datahub-autocomplete').should('have.length.gt', 0)
describe('home header search', () => {
it('should display the title', () => {
cy.get('.mel-page-title').should('be.visible')
})
it('should display the search bar and placeholder', () => {
cy.get('mel-datahub-fuzzy-search').should('be.visible')
cy.get('mel-datahub-autocomplete').should('have.length.gt', 0)
})
it('should navigate to search and display results when executing a search', () => {
cy.get('mel-datahub-fuzzy-search').type('test{enter}')
cy.url().should('include', 'search')
cy.get('mel-datahub-results-card-search').should('have.length.gt', 0)
})
})
it('should display results card last created', () => {
cy.get('mel-datahub-results-card-last-created').should('be.visible')
cy.get('mel-datahub-results-card-last-created').should('have.length.gt', 0)
cy.get('mel-datahub-results-card-last-created').as('lastCreatedCard')

cy.get('@lastCreatedCard').find('h1').should('be.visible')
cy.get('@lastCreatedCard').find('.mel-badge-button').should('be.visible')
})
describe('home header carousel', () => {
it('should display results card last created', () => {
cy.get('mel-datahub-results-card-last-created').should('be.visible')
cy.get('mel-datahub-results-card-last-created').should(
'have.length.gt',
0
)
cy.get('mel-datahub-results-card-last-created').as('lastCreatedCard')

describe('interactions with dataset', () => {
beforeEach(() => {
cy.get('mel-datahub-results-card-last-created').first().as('firstResult')
})
it('should open the dataset page in the same application on click', () => {
cy.get('@firstResult').click()
cy.url().should('include', 'dataset')
cy.get('mel-datahub-dataset-page').should('be.visible')
cy.get('@lastCreatedCard').find('h1').should('be.visible')
cy.get('@lastCreatedCard').find('.mel-badge-button').should('be.visible')
})
})
describe('custom carousel', () => {
it('should display a carousel that loops through last created cards', () => {
cy.get('mel-datahub-custom-carousel').find(
'mel-datahub-results-card-last-created'
Expand All @@ -45,7 +45,20 @@ describe('datahub-e2e', () => {
)
.should('be.visible')
})
describe('interactions with dataset', () => {
beforeEach(() => {
cy.get('mel-datahub-results-card-last-created')
.first()
.as('firstResult')
})
it('should open the dataset page in the same application on click', () => {
cy.get('@firstResult').click()
cy.url().should('include', 'dataset')
cy.get('mel-datahub-dataset-page').should('be.visible')
})
})
})

describe('footer', () => {
beforeEach(() => {
cy.get('mel-datahub-footer').as('footer')
Expand Down
209 changes: 152 additions & 57 deletions apps/datahub-e2e/src/e2e/search.cy.ts
Original file line number Diff line number Diff line change
@@ -1,85 +1,180 @@
describe('datahub-e2e', () => {
describe('search', () => {
beforeEach(() => cy.visit('/search'))

it('should display the title', () => {
cy.get('.mel-page-title').should('be.visible')
})
it('should display the number of result hits', () => {
cy.get('gn-ui-results-hits-number').should('contain', 14)
})
it('should display the footer', () => {
cy.get('mel-datahub-footer').should('be.visible')
})
it('should display the result hits in search card', () => {
cy.get('mel-datahub-results-card-search').should('have.length', 14)
})

// If not logged in or no favorites exists
it('should display record results in last created cards inside a carousel', () => {
cy.get('mel-datahub-custom-carousel')
.find('mel-datahub-results-card-last-created')
.eq(0)
.find('h1')
.should(
'have.text',
' Metadata for E2E testing purpose. (this title is too long and should be cut, this title is too long and should be cut, this title is too long and should be cut, this title is too long and should be cut, this title is too long and should be cut) '
)

cy.get('mel-datahub-results-card-last-created')
.find('h1')
.should('be.visible')

cy.get('mel-datahub-results-card-last-created')
.find('.mel-badge-button')
.should('be.visible')
})

describe('interactions with dataset', () => {
beforeEach(() => {
cy.get('mel-datahub-results-card-last-created').first().as('firstResult')
describe('search page defaults', () => {
it('should display the title', () => {
cy.get('.mel-page-title').should('be.visible')
})
it('should display the number of result hits', () => {
cy.get('[data-cy="searchResults"]').should('contain', 14)
})
it('should open the dataset page in the same application on click', () => {
cy.get('@firstResult').click()
cy.url().should('include', 'dataset')
cy.get('mel-datahub-dataset-page').should('be.visible')
it('should display the footer', () => {
cy.get('mel-datahub-footer').should('be.visible')
})
it('should display the result hits in search card', () => {
cy.get('mel-datahub-results-card-search').should('have.length', 14)
})
})

// If logged in and favorites exist
describe('User logged in', () => {
beforeEach(() => {
cy.login()
cy.visit('/search')
cy.get('mel-datahub-heart-toggle').first().click()
})
it('should display record results in favorite cards inside a carousel', () => {
describe('search header carousel', () => {
// If not logged in or no favorites exists
it('should display record results in last created cards inside a carousel', () => {
cy.get('mel-datahub-custom-carousel')
.find('mel-datahub-results-card-favorite')
.eq(0)
.find('mel-datahub-results-card-last-created')
.first()
.find('h1')
.should(
'have.text',
' Metadata for E2E testing purpose. (this title is too long and should be cut, this title is too long and should be cut, this title is too long and should be cut, this title is too long and should be cut, this title is too long and should be cut) '
)

cy.get('mel-datahub-results-card-favorite')
.find('.mel-badge-button')
cy.get('mel-datahub-results-card-last-created')
.find('h1')
.should('be.visible')

cy.get('mel-datahub-results-card-favorite')
.find('mel-datahub-metadata-quality')
cy.get('mel-datahub-results-card-last-created')
.find('.mel-badge-button')
.should('be.visible')
})

describe('interactions with dataset', () => {
beforeEach(() => {
cy.get('mel-datahub-results-card-favorite').first().as('firstResult')
cy.get('mel-datahub-results-card-last-created')
.first()
.as('firstResult')
})
it('should open the dataset page in the same application on click', () => {
cy.get('@firstResult').find('h1').click()
cy.get('@firstResult').click()
cy.url().should('include', 'dataset')
cy.get('mel-datahub-dataset-page').should('be.visible')
})
})

// If logged in and favorites exist
describe('User logged in', () => {
beforeEach(() => {
cy.login()
cy.visit('/search')
cy.get('mel-datahub-heart-toggle').first().click()
})
it('should display record results in favorite cards inside a carousel', () => {
cy.get('mel-datahub-custom-carousel')
.find('mel-datahub-results-card-favorite')
.first()
.find('h1')
.should(
'have.text',
' Metadata for E2E testing purpose. (this title is too long and should be cut, this title is too long and should be cut, this title is too long and should be cut, this title is too long and should be cut, this title is too long and should be cut) '
)

cy.get('mel-datahub-results-card-favorite')
.find('.mel-badge-button')
.should('be.visible')

cy.get('mel-datahub-results-card-favorite')
.find('mel-datahub-metadata-quality')
.should('be.visible')
})

describe('interactions with dataset', () => {
beforeEach(() => {
cy.get('mel-datahub-results-card-favorite').first().as('firstResult')
})
it('should open the dataset page in the same application on click', () => {
cy.get('@firstResult').find('h1').click()
cy.url().should('include', 'dataset')
cy.get('mel-datahub-dataset-page').should('be.visible')
})
})
})
})

describe('search form and results', () => {
const getFilterOptions = () => {
cy.get('[id^=dropdown-multiselect-] label').as('options')
}

beforeEach(() => {
cy.get('mel-datahub-filter-dropdown').as('filters')
cy.get('mel-datahub-results-card-search').as('result-cards')
})

it('should display the search form', () => {
cy.get('mel-datahub-search-form').should('be.visible')
})
it('should display the search filters', () => {
cy.get('mel-datahub-search-filters').should('be.visible')
})
it('should display the search results', () => {
cy.get('mel-datahub-search-results').should('be.visible')
})
it('should display the search results in a grid', () => {
cy.get('mel-datahub-results-list-grid').should('be.visible')
})
it('should filter the results when selecting a filter value (topic)', () => {
cy.get('@filters').first().click()
getFilterOptions()
cy.get('@options').first().click()
cy.get('@result-cards').should('have.length', 2)
cy.get('@result-cards')
.first()
.find('h1')
.should('have.text', ' Alpenkonvention ')
cy.get('@result-cards')
.eq(1)
.find('h1')
.should(
'have.text',
' Patrimoine - Biens classés et zones de protection - Série '
)
})
it('should filter the results when selecting multiple filter values (producer)', () => {
cy.get('@filters').eq(1).click()
getFilterOptions()
cy.get('@options').first().click()
cy.get('@options').eq(1).click()
cy.get('@options').eq(2).click()
cy.get('mel-datahub-results-card-search').should('have.length', 3)
})
it('should filter the results when executing a search', () => {
cy.get('mel-datahub-autocomplete input').type('velo')
cy.get('mel-datahub-autocomplete .material-symbols-outlined')
.contains('search')
.click()
cy.get('@result-cards').should('have.length', 1)
cy.get('@result-cards')
.first()
.find('h1')
.should('have.text', ' Accroches vélos MEL ')
})
it('should combine search input and filters (producer)', () => {
cy.get('mel-datahub-autocomplete input').type('test')
cy.get('mel-datahub-autocomplete .material-symbols-outlined')
.contains('search')
.click()
cy.get('@result-cards').should('have.length', 3)
cy.get('@filters').eq(1).click()
getFilterOptions()
cy.get('@options').eq(12).click()
cy.get('@result-cards').should('have.length', 1)
cy.get('@result-cards')
.first()
.find('h1')
.should('have.text', ' Accroches vélos MEL ')
})
it('should combine search input and filters and display a message if no results found', () => {
cy.get('mel-datahub-autocomplete input').type('test')
cy.get('mel-datahub-autocomplete .material-symbols-outlined')
.contains('search')
.click()
cy.get('@result-cards').should('have.length', 3)
cy.get('@filters').eq(1).click()
getFilterOptions()
cy.get('@options').eq(10).click()
cy.get('[data-cy=searchResults]').should(
'have.text',
' Aucune correspondance. '
)
})
})
})
14 changes: 14 additions & 0 deletions apps/datahub/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
ThemeService,
TRANSLATE_DEFAULT_CONFIG,
UiElementsModule,
UiInputsModule,
UiLayoutModule,
UiWidgetsModule,
} from 'geonetwork-ui'
Expand Down Expand Up @@ -60,6 +61,12 @@ import { MelFuzzySearchComponent } from './common/fuzzy-search/fuzzy-search.comp
import { MelAutocompleteComponent } from './common/autocomplete/autocomplete.component'
import { ReactiveFormsModule } from '@angular/forms'
import { MatAutocompleteModule } from '@angular/material/autocomplete'
import { SearchFormComponent } from './search/search-form/search-form.component'
import { SearchFiltersComponent } from './search/search-filters/search-filters.component'
import { MelFilterDropdownComponent } from './search/search-filters/filter-dropdown/filter-dropdown.component'
import { MelDropdownMultiselectComponent } from './search/search-filters/dropdown-multiselect/dropdown-multiselect.component'
import { OverlayModule } from '@angular/cdk/overlay'
import { FormsModule } from '@angular/forms'

@NgModule({
declarations: [
Expand Down Expand Up @@ -91,19 +98,26 @@ import { MatAutocompleteModule } from '@angular/material/autocomplete'
DatasetInformationComponent,
MelFuzzySearchComponent,
MelAutocompleteComponent,
SearchFormComponent,
SearchFiltersComponent,
MelFilterDropdownComponent,
MelDropdownMultiselectComponent,
],
imports: [
BrowserModule,
BrowserAnimationsModule,
UiWidgetsModule,
UiElementsModule,
UiLayoutModule,
UiInputsModule,
FeatureSearchModule,
FeatureCatalogModule,
FeatureRecordModule,
MatAutocompleteModule,
MatIconModule,
MatTabsModule,
OverlayModule,
FormsModule,
TranslateModule.forRoot({
...TRANSLATE_DEFAULT_CONFIG,
loader: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<gn-ui-content-ghost
ghostClass="h-[212px]"
class="container"
[showContent]="resultsReady"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for cleaning this up! I don't know why I implemented it with overrides...

[showContent]="(searchFacade.isLoading$ | async) === false"
>
<mel-datahub-custom-carousel
containerClass="gap-4 pt-4 pb-6"
Expand Down
Loading
Loading