From 76317910a819ca96f4472ee24db900ca9efd1974 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germ=C3=A1n=20Saracca?= Date: Mon, 9 Dec 2024 11:29:33 -0300 Subject: [PATCH 01/28] chore: use js-dataverse pr version --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 42ddaf1e7..7321e4c61 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.1.0", "dependencies": { "@faker-js/faker": "7.6.0", - "@iqss/dataverse-client-javascript": "2.0.0-alpha.4", + "@iqss/dataverse-client-javascript": "2.0.0-pr230.f6c393a", "@iqss/dataverse-design-system": "*", "@istanbuljs/nyc-config-typescript": "1.0.2", "@tanstack/react-table": "8.9.2", @@ -3674,9 +3674,9 @@ }, "node_modules/@iqss/dataverse-client-javascript": { "name": "@IQSS/dataverse-client-javascript", - "version": "2.0.0-alpha.4", - "resolved": "https://npm.pkg.github.com/download/@IQSS/dataverse-client-javascript/2.0.0-alpha.4/10ab7e0ed2a31a09b1b32d27521b96f84ef50f4f", - "integrity": "sha512-SJdkBIks+yjJxEVw8G7sf4YY2Bujl+8vOD+fZqt2qhIGmyPSlj9ld0APnYyoVX6lI8lGsREHZzYYjzeAmYfxhw==", + "version": "2.0.0-pr230.f6c393a", + "resolved": "https://npm.pkg.github.com/download/@IQSS/dataverse-client-javascript/2.0.0-pr230.f6c393a/a633f85ea3c6998d0b3cdc0a23fdacc419377a9c", + "integrity": "sha512-xg5PqgXzhxw31YOe7FTrAW92CqDgFczsCUp0rCJeJ2AW2UjYHLRpR1OTvCMvfwnC6Nz/HGemoHbIcVc8lxj7gA==", "license": "MIT", "dependencies": { "@types/node": "^18.15.11", diff --git a/package.json b/package.json index db411a652..cb85a5c63 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ }, "dependencies": { "@faker-js/faker": "7.6.0", - "@iqss/dataverse-client-javascript": "2.0.0-alpha.4", + "@iqss/dataverse-client-javascript": "2.0.0-pr230.f6c393a", "@iqss/dataverse-design-system": "*", "@istanbuljs/nyc-config-typescript": "1.0.2", "@tanstack/react-table": "8.9.2", From 1c3e03328415b8121e82f3a18d24bd8045a390f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germ=C3=A1n=20Saracca?= Date: Mon, 9 Dec 2024 11:40:39 -0300 Subject: [PATCH 02/28] feat: move types query param to specific get collection items enum --- .../domain/models/CollectionItemSubset.ts | 15 ++++++++++ .../models/CollectionSearchCriteria.tsx | 28 +++++++++++++++++-- .../models/GetCollectionItemsQueryParams.ts | 19 +++++++++++++ .../CollectionJSDataverseRepository.ts | 1 + src/sections/Route.enum.ts | 1 - src/sections/collection/CollectionHelper.ts | 3 +- .../CollectionItemsPanel.tsx | 5 ++-- .../homepage/search-input/SearchInput.tsx | 3 +- .../collection/CollectionHelper.spec.tsx | 5 ++-- .../collection/CollectionItemsPanel.spec.ts | 13 +++++---- .../e2e/sections/homepage/Homepage.spec.tsx | 3 +- 11 files changed, 79 insertions(+), 17 deletions(-) create mode 100644 src/collection/domain/models/GetCollectionItemsQueryParams.ts diff --git a/src/collection/domain/models/CollectionItemSubset.ts b/src/collection/domain/models/CollectionItemSubset.ts index 3fbc3b0b7..4c466f530 100644 --- a/src/collection/domain/models/CollectionItemSubset.ts +++ b/src/collection/domain/models/CollectionItemSubset.ts @@ -4,6 +4,7 @@ import { FileItemTypePreview } from '../../../files/domain/models/FileItemTypePr export interface CollectionItemSubset { items: CollectionItem[] + facets: CollectionItemsFacet[] totalItemCount: number } @@ -11,3 +12,17 @@ export type CollectionItem = | CollectionItemTypePreview | DatasetItemTypePreview | FileItemTypePreview + +export interface CollectionItemsFacet { + [key: string]: CollectionItemsFacetValue +} + +interface CollectionItemsFacetValue { + friendly: string + labels: CollectionItemsFacetLabel[] +} + +interface CollectionItemsFacetLabel { + name: string + count: number +} diff --git a/src/collection/domain/models/CollectionSearchCriteria.tsx b/src/collection/domain/models/CollectionSearchCriteria.tsx index 247439c7d..63ac15933 100644 --- a/src/collection/domain/models/CollectionSearchCriteria.tsx +++ b/src/collection/domain/models/CollectionSearchCriteria.tsx @@ -1,17 +1,39 @@ import { type CollectionItemType } from './CollectionItemType' +import { FilterQuery, OrderType, SortType } from './GetCollectionItemsQueryParams' export class CollectionSearchCriteria { constructor( public readonly searchText?: string, - public readonly itemTypes?: CollectionItemType[] + public readonly itemTypes?: CollectionItemType[], + public readonly sort?: SortType, + public readonly order?: OrderType, + public readonly filterQueries?: FilterQuery[] ) {} withSearchText(searchText: string | undefined): CollectionSearchCriteria { - return new CollectionSearchCriteria(searchText, this.itemTypes) + return new CollectionSearchCriteria(searchText, this.itemTypes, this.sort, this.order) } withItemTypes(itemTypes: CollectionItemType[] | undefined): CollectionSearchCriteria { - return new CollectionSearchCriteria(this.searchText, itemTypes) + return new CollectionSearchCriteria(this.searchText, itemTypes, this.sort, this.order) + } + + withSort(sort: SortType | undefined): CollectionSearchCriteria { + return new CollectionSearchCriteria(this.searchText, this.itemTypes, sort, this.order) + } + + withOrder(order: OrderType | undefined): CollectionSearchCriteria { + return new CollectionSearchCriteria(this.searchText, this.itemTypes, this.sort, order) + } + + withFilterQueries(filterQueries: FilterQuery[] | undefined): CollectionSearchCriteria { + return new CollectionSearchCriteria( + this.searchText, + this.itemTypes, + this.sort, + this.order, + filterQueries + ) } hasSearchText(): boolean { diff --git a/src/collection/domain/models/GetCollectionItemsQueryParams.ts b/src/collection/domain/models/GetCollectionItemsQueryParams.ts new file mode 100644 index 000000000..ffd5700ab --- /dev/null +++ b/src/collection/domain/models/GetCollectionItemsQueryParams.ts @@ -0,0 +1,19 @@ +export enum GetCollectionItemsQueryParams { + SORT = 'sort', + ORDER = 'order', + START = 'start', + TYPES = 'types', + FILTER_QUERIES = 'fq' +} + +export enum SortType { + NAME = 'name', + DATE = 'date' +} + +export enum OrderType { + ASC = 'asc', + DESC = 'desc' +} + +export type FilterQuery = `${string}:${string}` diff --git a/src/collection/infrastructure/repositories/CollectionJSDataverseRepository.ts b/src/collection/infrastructure/repositories/CollectionJSDataverseRepository.ts index 996b6750a..f9ad0ce2f 100644 --- a/src/collection/infrastructure/repositories/CollectionJSDataverseRepository.ts +++ b/src/collection/infrastructure/repositories/CollectionJSDataverseRepository.ts @@ -54,6 +54,7 @@ export class CollectionJSDataverseRepository implements CollectionRepository { return { items: collectionItemsPreviewsMapped, + facets: jsCollectionItemSubset.facets, totalItemCount: jsCollectionItemSubset.totalItemCount } }) diff --git a/src/sections/Route.enum.ts b/src/sections/Route.enum.ts index 93a88ee49..ec892314a 100644 --- a/src/sections/Route.enum.ts +++ b/src/sections/Route.enum.ts @@ -25,7 +25,6 @@ export enum QueryParamKey { VERSION = 'version', PERSISTENT_ID = 'persistentId', QUERY = 'q', - COLLECTION_ITEM_TYPES = 'types', PAGE = 'page', COLLECTION_ID = 'collectionId' } diff --git a/src/sections/collection/CollectionHelper.ts b/src/sections/collection/CollectionHelper.ts index d16273f05..1fabe912e 100644 --- a/src/sections/collection/CollectionHelper.ts +++ b/src/sections/collection/CollectionHelper.ts @@ -1,3 +1,4 @@ +import { GetCollectionItemsQueryParams } from '@/collection/domain/models/GetCollectionItemsQueryParams' import { CollectionItemType } from '../../collection/domain/models/CollectionItemType' import { QueryParamKey } from '../Route.enum' @@ -11,7 +12,7 @@ export class CollectionHelper { ? decodeURIComponent(searchParams.get(QueryParamKey.QUERY) as string) : undefined - const typesParam = searchParams.get(QueryParamKey.COLLECTION_ITEM_TYPES) ?? undefined + const typesParam = searchParams.get(GetCollectionItemsQueryParams.TYPES) ?? undefined const typesQuery = typesParam ?.split(',') diff --git a/src/sections/collection/collection-items-panel/CollectionItemsPanel.tsx b/src/sections/collection/collection-items-panel/CollectionItemsPanel.tsx index 76664d5ae..d398d4372 100644 --- a/src/sections/collection/collection-items-panel/CollectionItemsPanel.tsx +++ b/src/sections/collection/collection-items-panel/CollectionItemsPanel.tsx @@ -14,6 +14,7 @@ import { FilterPanel } from './filter-panel/FilterPanel' import { ItemsList } from './items-list/ItemsList' import { SearchPanel } from './search-panel/SearchPanel' import { ItemTypeChange } from './filter-panel/type-filters/TypeFilters' +import { GetCollectionItemsQueryParams } from '@/collection/domain/models/GetCollectionItemsQueryParams' import styles from './CollectionItemsPanel.module.scss' interface CollectionItemsPanelProps { @@ -104,7 +105,7 @@ export const CollectionItemsPanel = ({ // Update the URL with the search value ,keep other querys and include all item types always setSearchParams((currentSearchParams) => ({ ...currentSearchParams, - [QueryParamKey.COLLECTION_ITEM_TYPES]: [ + [GetCollectionItemsQueryParams.TYPES]: [ CollectionItemType.COLLECTION, CollectionItemType.DATASET, CollectionItemType.FILE @@ -146,7 +147,7 @@ export const CollectionItemsPanel = ({ // Update the URL with the new item types, keep other querys and include the search value if exists setSearchParams((currentSearchParams) => ({ ...currentSearchParams, - [QueryParamKey.COLLECTION_ITEM_TYPES]: newItemsTypes.join(','), + [GetCollectionItemsQueryParams.TYPES]: newItemsTypes.join(','), ...(currentSearchCriteria.searchText && { [QueryParamKey.QUERY]: currentSearchCriteria.searchText }) diff --git a/src/sections/homepage/search-input/SearchInput.tsx b/src/sections/homepage/search-input/SearchInput.tsx index 204a09023..f87efbbda 100644 --- a/src/sections/homepage/search-input/SearchInput.tsx +++ b/src/sections/homepage/search-input/SearchInput.tsx @@ -4,6 +4,7 @@ import { Form, CloseButton } from '@iqss/dataverse-design-system' import { Search as SearchIcon } from 'react-bootstrap-icons' import { QueryParamKey, Route } from '../../Route.enum' import { CollectionItemType } from '../../../collection/domain/models/CollectionItemType' +import { GetCollectionItemsQueryParams } from '@/collection/domain/models/GetCollectionItemsQueryParams' import styles from './SearchInput.module.scss' export const SearchInput = () => { @@ -27,7 +28,7 @@ export const SearchInput = () => { const searchParams = new URLSearchParams() searchParams.set(QueryParamKey.QUERY, encodedSearchValue) searchParams.set( - QueryParamKey.COLLECTION_ITEM_TYPES, + GetCollectionItemsQueryParams.TYPES, [CollectionItemType.COLLECTION, CollectionItemType.DATASET, CollectionItemType.FILE].join(',') ) diff --git a/tests/component/sections/collection/CollectionHelper.spec.tsx b/tests/component/sections/collection/CollectionHelper.spec.tsx index 9ca99e207..1e5669607 100644 --- a/tests/component/sections/collection/CollectionHelper.spec.tsx +++ b/tests/component/sections/collection/CollectionHelper.spec.tsx @@ -1,3 +1,4 @@ +import { GetCollectionItemsQueryParams } from '@/collection/domain/models/GetCollectionItemsQueryParams' import { CollectionHelper } from '@/sections/collection/CollectionHelper' import { QueryParamKey } from '@/sections/Route.enum' import { CollectionItemType } from '@iqss/dataverse-client-javascript' @@ -12,7 +13,7 @@ describe('CollectionHelper', () => { searchParams.set(QueryParamKey.QUERY, QUERY_VALUE) searchParams.set( - QueryParamKey.COLLECTION_ITEM_TYPES, + GetCollectionItemsQueryParams.TYPES, [CollectionItemType.COLLECTION, CollectionItemType.DATASET].join(',') ) searchParams.set(QueryParamKey.PAGE, PAGE_NUMBER.toString()) @@ -41,7 +42,7 @@ describe('CollectionHelper', () => { const searchParams = new URLSearchParams({}) searchParams.set( - QueryParamKey.COLLECTION_ITEM_TYPES, + GetCollectionItemsQueryParams.TYPES, [CollectionItemType.COLLECTION, CollectionItemType.DATASET].join(',') ) const collectionQueryParams = CollectionHelper.defineCollectionQueryParams(searchParams) diff --git a/tests/e2e-integration/e2e/sections/collection/CollectionItemsPanel.spec.ts b/tests/e2e-integration/e2e/sections/collection/CollectionItemsPanel.spec.ts index 37e33b7e2..926ac40c6 100644 --- a/tests/e2e-integration/e2e/sections/collection/CollectionItemsPanel.spec.ts +++ b/tests/e2e-integration/e2e/sections/collection/CollectionItemsPanel.spec.ts @@ -1,5 +1,6 @@ import { CollectionItem } from '@/collection/domain/models/CollectionItemSubset' import { CollectionItemType } from '@/collection/domain/models/CollectionItemType' +import { GetCollectionItemsQueryParams } from '@/collection/domain/models/GetCollectionItemsQueryParams' import { QueryParamKey } from '@/sections/Route.enum' import { DatasetHelper } from '@tests/e2e-integration/shared/datasets/DatasetHelper' import { FileHelper } from '@tests/e2e-integration/shared/files/FileHelper' @@ -97,7 +98,7 @@ describe('Collection Items Panel', () => { cy.findAllByTestId('file-card').should('have.length', filesInResponse.length) const firstExpectedURL = new URLSearchParams({ - [QueryParamKey.COLLECTION_ITEM_TYPES]: [ + [GetCollectionItemsQueryParams.TYPES]: [ CollectionItemType.COLLECTION, CollectionItemType.DATASET, CollectionItemType.FILE @@ -129,7 +130,7 @@ describe('Collection Items Panel', () => { cy.findAllByTestId('file-card').should('have.length', filesInResponse.length) const secondExpectedURL = new URLSearchParams({ - [QueryParamKey.COLLECTION_ITEM_TYPES]: [ + [GetCollectionItemsQueryParams.TYPES]: [ CollectionItemType.COLLECTION, CollectionItemType.DATASET, CollectionItemType.FILE @@ -163,7 +164,7 @@ describe('Collection Items Panel', () => { cy.findAllByTestId('file-card').should('have.length', filesInResponse.length) const thirdExpectedURL = new URLSearchParams({ - [QueryParamKey.COLLECTION_ITEM_TYPES]: [ + [GetCollectionItemsQueryParams.TYPES]: [ CollectionItemType.COLLECTION, CollectionItemType.DATASET, CollectionItemType.FILE @@ -196,7 +197,7 @@ describe('Collection Items Panel', () => { cy.findAllByTestId('file-card').should('have.length', filesInResponse.length) const fourthExpectedURL = new URLSearchParams({ - [QueryParamKey.COLLECTION_ITEM_TYPES]: [ + [GetCollectionItemsQueryParams.TYPES]: [ CollectionItemType.DATASET, CollectionItemType.FILE ].join(',') @@ -227,7 +228,7 @@ describe('Collection Items Panel', () => { cy.findAllByTestId('file-card').should('have.length', filesInResponse.length) const fifthExpectedURL = new URLSearchParams({ - [QueryParamKey.COLLECTION_ITEM_TYPES]: [CollectionItemType.FILE].join(',') + [GetCollectionItemsQueryParams.TYPES]: [CollectionItemType.FILE].join(',') }).toString() cy.url().should('include', `/collections?${fifthExpectedURL}`) @@ -255,7 +256,7 @@ describe('Collection Items Panel', () => { cy.findAllByTestId('file-card').should('have.length', filesInResponse.length) const fourthExpectedURL = new URLSearchParams({ - [QueryParamKey.COLLECTION_ITEM_TYPES]: [ + [GetCollectionItemsQueryParams.TYPES]: [ CollectionItemType.DATASET, CollectionItemType.FILE ].join(',') diff --git a/tests/e2e-integration/e2e/sections/homepage/Homepage.spec.tsx b/tests/e2e-integration/e2e/sections/homepage/Homepage.spec.tsx index 09c19beab..c2c4dff73 100644 --- a/tests/e2e-integration/e2e/sections/homepage/Homepage.spec.tsx +++ b/tests/e2e-integration/e2e/sections/homepage/Homepage.spec.tsx @@ -1,3 +1,4 @@ +import { GetCollectionItemsQueryParams } from '@/collection/domain/models/GetCollectionItemsQueryParams' import { CollectionItemType } from '../../../../../src/collection/domain/models/CollectionItemType' import { QueryParamKey } from '../../../../../src/sections/Route.enum' @@ -13,7 +14,7 @@ describe('Homepage', () => { const searchParams = new URLSearchParams() searchParams.set(QueryParamKey.QUERY, encodedSearchValue) searchParams.set( - QueryParamKey.COLLECTION_ITEM_TYPES, + GetCollectionItemsQueryParams.TYPES, [CollectionItemType.COLLECTION, CollectionItemType.DATASET, CollectionItemType.FILE].join(',') ) From 61371a11c00aae59614c49d45be21657efc006b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germ=C3=A1n=20Saracca?= Date: Mon, 9 Dec 2024 13:04:34 -0300 Subject: [PATCH 03/28] chore: update to new pr js-dataverse version --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7321e4c61..713acf2d1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.1.0", "dependencies": { "@faker-js/faker": "7.6.0", - "@iqss/dataverse-client-javascript": "2.0.0-pr230.f6c393a", + "@iqss/dataverse-client-javascript": "2.0.0-pr230.1408cdd", "@iqss/dataverse-design-system": "*", "@istanbuljs/nyc-config-typescript": "1.0.2", "@tanstack/react-table": "8.9.2", @@ -3674,9 +3674,9 @@ }, "node_modules/@iqss/dataverse-client-javascript": { "name": "@IQSS/dataverse-client-javascript", - "version": "2.0.0-pr230.f6c393a", - "resolved": "https://npm.pkg.github.com/download/@IQSS/dataverse-client-javascript/2.0.0-pr230.f6c393a/a633f85ea3c6998d0b3cdc0a23fdacc419377a9c", - "integrity": "sha512-xg5PqgXzhxw31YOe7FTrAW92CqDgFczsCUp0rCJeJ2AW2UjYHLRpR1OTvCMvfwnC6Nz/HGemoHbIcVc8lxj7gA==", + "version": "2.0.0-pr230.1408cdd", + "resolved": "https://npm.pkg.github.com/download/@IQSS/dataverse-client-javascript/2.0.0-pr230.1408cdd/829436c03c3edb45ac906870dd9a0116233e3762", + "integrity": "sha512-LN+e2ZEkMcefWFkL9l+qarBzZzNT/i1WbkHzzlbzPFx9PqLBI57b3nzvLMGeK3bNdMb8BWuNMDPstlDkNwjGDg==", "license": "MIT", "dependencies": { "@types/node": "^18.15.11", diff --git a/package.json b/package.json index cb85a5c63..c9addf695 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ }, "dependencies": { "@faker-js/faker": "7.6.0", - "@iqss/dataverse-client-javascript": "2.0.0-pr230.f6c393a", + "@iqss/dataverse-client-javascript": "2.0.0-pr230.1408cdd", "@iqss/dataverse-design-system": "*", "@istanbuljs/nyc-config-typescript": "1.0.2", "@tanstack/react-table": "8.9.2", From 47700171c09c04043558e393dd6e2bf829a4691e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germ=C3=A1n=20Saracca?= Date: Tue, 10 Dec 2024 10:02:19 -0300 Subject: [PATCH 04/28] feat: types, retrieve facets etc --- .../domain/models/CollectionItemSubset.ts | 7 ++----- .../models/GetCollectionItemsQueryParams.ts | 2 +- src/sections/collection/CollectionHelper.ts | 16 ++++++++++++++-- .../useGetAccumulatedItems.tsx | 8 +++++++- .../collection/useGetCollectionQueryParams.ts | 2 ++ 5 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/collection/domain/models/CollectionItemSubset.ts b/src/collection/domain/models/CollectionItemSubset.ts index 4c466f530..85cdee9a7 100644 --- a/src/collection/domain/models/CollectionItemSubset.ts +++ b/src/collection/domain/models/CollectionItemSubset.ts @@ -14,11 +14,8 @@ export type CollectionItem = | FileItemTypePreview export interface CollectionItemsFacet { - [key: string]: CollectionItemsFacetValue -} - -interface CollectionItemsFacetValue { - friendly: string + name: string + friendlyName: string labels: CollectionItemsFacetLabel[] } diff --git a/src/collection/domain/models/GetCollectionItemsQueryParams.ts b/src/collection/domain/models/GetCollectionItemsQueryParams.ts index ffd5700ab..8f461f499 100644 --- a/src/collection/domain/models/GetCollectionItemsQueryParams.ts +++ b/src/collection/domain/models/GetCollectionItemsQueryParams.ts @@ -3,7 +3,7 @@ export enum GetCollectionItemsQueryParams { ORDER = 'order', START = 'start', TYPES = 'types', - FILTER_QUERIES = 'fq' + FILTER_QUERIES = 'fqs' } export enum SortType { diff --git a/src/sections/collection/CollectionHelper.ts b/src/sections/collection/CollectionHelper.ts index 1fabe912e..bce7ae01f 100644 --- a/src/sections/collection/CollectionHelper.ts +++ b/src/sections/collection/CollectionHelper.ts @@ -1,4 +1,7 @@ -import { GetCollectionItemsQueryParams } from '@/collection/domain/models/GetCollectionItemsQueryParams' +import { + FilterQuery, + GetCollectionItemsQueryParams +} from '@/collection/domain/models/GetCollectionItemsQueryParams' import { CollectionItemType } from '../../collection/domain/models/CollectionItemType' import { QueryParamKey } from '../Route.enum' @@ -21,6 +24,15 @@ export class CollectionHelper { Object.values(CollectionItemType).includes(type as CollectionItemType) ) as CollectionItemType[] - return { pageQuery, searchQuery, typesQuery } + const filtersParam = searchParams.get(GetCollectionItemsQueryParams.FILTER_QUERIES) ?? undefined + + const filtersQuery: FilterQuery[] | undefined = filtersParam + ? (filtersParam + ?.split(',') + .map((filterQuery) => decodeURIComponent(filterQuery)) + .filter((decodedFilter) => /^[^:]+:[^:]+$/.test(decodedFilter)) as FilterQuery[]) + : undefined + + return { pageQuery, searchQuery, typesQuery, filtersQuery } } } diff --git a/src/sections/collection/collection-items-panel/useGetAccumulatedItems.tsx b/src/sections/collection/collection-items-panel/useGetAccumulatedItems.tsx index 8179cc2a1..f2094589b 100644 --- a/src/sections/collection/collection-items-panel/useGetAccumulatedItems.tsx +++ b/src/sections/collection/collection-items-panel/useGetAccumulatedItems.tsx @@ -3,6 +3,7 @@ import { getCollectionItems } from '@/collection/domain/useCases/getCollectionIt import { CollectionRepository } from '@/collection/domain/repositories/CollectionRepository' import { CollectionItem, + CollectionItemsFacet, CollectionItemSubset } from '@/collection/domain/models/CollectionItemSubset' import { CollectionItemsPaginationInfo } from '@/collection/domain/models/CollectionItemsPaginationInfo' @@ -13,6 +14,7 @@ export const NO_COLLECTION_ITEMS = 0 type UseGetAccumulatedItemsReturnType = { isLoadingItems: boolean accumulatedItems: CollectionItem[] + facets: CollectionItemsFacet[] totalAvailable: number | undefined hasNextPage: boolean error: string | null @@ -37,6 +39,7 @@ export const useGetAccumulatedItems = ({ }: UseGetAccumulatedItemsParams): UseGetAccumulatedItemsReturnType => { const [isLoadingItems, setIsLoadingItems] = useState(false) const [accumulatedItems, setAccumulatedItems] = useState([]) + const [facets, setFacets] = useState([]) const [hasNextPage, setHasNextPage] = useState(true) const [totalAvailable, setTotalAvailable] = useState(undefined) const [error, setError] = useState(null) @@ -55,7 +58,7 @@ export const useGetAccumulatedItems = ({ setIsLoadingItems(true) try { - const { items, totalItemCount } = await loadNextItems( + const { items, facets, totalItemCount } = await loadNextItems( collectionRepository, collectionId, pagination, @@ -66,6 +69,8 @@ export const useGetAccumulatedItems = ({ setAccumulatedItems(newAccumulatedItems) + setFacets(facets) + setTotalAvailable(totalItemCount) const isNextPage = !resetAccumulated @@ -93,6 +98,7 @@ export const useGetAccumulatedItems = ({ return { isLoadingItems, accumulatedItems, + facets, totalAvailable, hasNextPage, error, diff --git a/src/sections/collection/useGetCollectionQueryParams.ts b/src/sections/collection/useGetCollectionQueryParams.ts index 292db143f..9f322ccac 100644 --- a/src/sections/collection/useGetCollectionQueryParams.ts +++ b/src/sections/collection/useGetCollectionQueryParams.ts @@ -1,11 +1,13 @@ import { useSearchParams } from 'react-router-dom' import { CollectionItemType } from '@/collection/domain/models/CollectionItemType' +import { FilterQuery } from '@/collection/domain/models/GetCollectionItemsQueryParams' import { CollectionHelper } from './CollectionHelper' export interface UseCollectionQueryParamsReturnType { pageQuery: number searchQuery?: string typesQuery?: CollectionItemType[] + filtersQuery?: FilterQuery[] } export const useGetCollectionQueryParams = (): UseCollectionQueryParamsReturnType => { From e1a4275e7c219f8667460d74917f05765caadeb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germ=C3=A1n=20Saracca?= Date: Tue, 10 Dec 2024 10:44:32 -0300 Subject: [PATCH 05/28] chore: update js-dataverse version --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 713acf2d1..09fb51eab 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.1.0", "dependencies": { "@faker-js/faker": "7.6.0", - "@iqss/dataverse-client-javascript": "2.0.0-pr230.1408cdd", + "@iqss/dataverse-client-javascript": "2.0.0-pr230.13612a8", "@iqss/dataverse-design-system": "*", "@istanbuljs/nyc-config-typescript": "1.0.2", "@tanstack/react-table": "8.9.2", @@ -3674,9 +3674,9 @@ }, "node_modules/@iqss/dataverse-client-javascript": { "name": "@IQSS/dataverse-client-javascript", - "version": "2.0.0-pr230.1408cdd", - "resolved": "https://npm.pkg.github.com/download/@IQSS/dataverse-client-javascript/2.0.0-pr230.1408cdd/829436c03c3edb45ac906870dd9a0116233e3762", - "integrity": "sha512-LN+e2ZEkMcefWFkL9l+qarBzZzNT/i1WbkHzzlbzPFx9PqLBI57b3nzvLMGeK3bNdMb8BWuNMDPstlDkNwjGDg==", + "version": "2.0.0-pr230.13612a8", + "resolved": "https://npm.pkg.github.com/download/@IQSS/dataverse-client-javascript/2.0.0-pr230.13612a8/79860d14c5222eaac6838b48f8737fb0a0e6e210", + "integrity": "sha512-qiewJpTmXd07MeLMKFlQtUnhKMOCLnv0BGZqjZOgR1vGBPKaxUMVMFKvp+c3/PJCktzHG9GwgtM5yaluxgC/Eg==", "license": "MIT", "dependencies": { "@types/node": "^18.15.11", diff --git a/package.json b/package.json index c9addf695..3eb8d77d6 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ }, "dependencies": { "@faker-js/faker": "7.6.0", - "@iqss/dataverse-client-javascript": "2.0.0-pr230.1408cdd", + "@iqss/dataverse-client-javascript": "2.0.0-pr230.13612a8", "@iqss/dataverse-design-system": "*", "@istanbuljs/nyc-config-typescript": "1.0.2", "@tanstack/react-table": "8.9.2", From c6d4f3c37a770599dc845ad3bc842aa7f496ffd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germ=C3=A1n=20Saracca?= Date: Tue, 10 Dec 2024 11:18:10 -0300 Subject: [PATCH 06/28] feat: filtering by queries working --- src/index.tsx | 18 ++-- .../CollectionItemsPanel.tsx | 68 +++++++++++++- .../filter-panel/FilterPanel.tsx | 16 ++++ .../facets-filters/FacetFilter.tsx | 89 +++++++++++++++++++ .../facets-filters/FacetsFilters.module.scss | 22 +++++ .../facets-filters/FacetsFilters.tsx | 36 ++++++++ 6 files changed, 237 insertions(+), 12 deletions(-) create mode 100644 src/sections/collection/collection-items-panel/filter-panel/facets-filters/FacetFilter.tsx create mode 100644 src/sections/collection/collection-items-panel/filter-panel/facets-filters/FacetsFilters.module.scss create mode 100644 src/sections/collection/collection-items-panel/filter-panel/facets-filters/FacetsFilters.tsx diff --git a/src/index.tsx b/src/index.tsx index a50dc685e..c8cc67b83 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -8,13 +8,13 @@ import { AppLoader } from './sections/shared/layout/app-loader/AppLoader' const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement) root.render( - - }> - - - - - - - + // + }> + + + + + + + // ) diff --git a/src/sections/collection/collection-items-panel/CollectionItemsPanel.tsx b/src/sections/collection/collection-items-panel/CollectionItemsPanel.tsx index d398d4372..ee50552c6 100644 --- a/src/sections/collection/collection-items-panel/CollectionItemsPanel.tsx +++ b/src/sections/collection/collection-items-panel/CollectionItemsPanel.tsx @@ -4,6 +4,10 @@ import { CollectionRepository } from '@/collection/domain/repositories/Collectio import { CollectionItemsPaginationInfo } from '@/collection/domain/models/CollectionItemsPaginationInfo' import { CollectionSearchCriteria } from '@/collection/domain/models/CollectionSearchCriteria' import { CollectionItemType } from '@/collection/domain/models/CollectionItemType' +import { + FilterQuery, + GetCollectionItemsQueryParams +} from '@/collection/domain/models/GetCollectionItemsQueryParams' import { useGetAccumulatedItems } from './useGetAccumulatedItems' import { UseCollectionQueryParamsReturnType } from '../useGetCollectionQueryParams' import { useLoadMoreOnPopStateEvent } from './useLoadMoreOnPopStateEvent' @@ -14,7 +18,7 @@ import { FilterPanel } from './filter-panel/FilterPanel' import { ItemsList } from './items-list/ItemsList' import { SearchPanel } from './search-panel/SearchPanel' import { ItemTypeChange } from './filter-panel/type-filters/TypeFilters' -import { GetCollectionItemsQueryParams } from '@/collection/domain/models/GetCollectionItemsQueryParams' +import { RemoveAddFacetFilter } from './filter-panel/facets-filters/FacetFilter' import styles from './CollectionItemsPanel.module.scss' interface CollectionItemsPanelProps { @@ -52,9 +56,14 @@ export const CollectionItemsPanel = ({ // This object will update every time we update a query param in the URL with the setSearchParams setter const currentSearchCriteria = new CollectionSearchCriteria( collectionQueryParams.searchQuery, - collectionQueryParams.typesQuery || [CollectionItemType.COLLECTION, CollectionItemType.DATASET] + collectionQueryParams.typesQuery || [CollectionItemType.COLLECTION, CollectionItemType.DATASET], + undefined, + undefined, + collectionQueryParams.filtersQuery ) + console.log({ currentSearchCriteria }) + const [paginationInfo, setPaginationInfo] = useState( new CollectionItemsPaginationInfo() ) @@ -63,6 +72,7 @@ export const CollectionItemsPanel = ({ const { isLoadingItems, accumulatedItems, + facets, totalAvailable, hasNextPage, error, @@ -166,13 +176,62 @@ export const CollectionItemsPanel = ({ } } + const handleFacetChange = async (filterQuery: FilterQuery, removeOrAdd: RemoveAddFacetFilter) => { + const newFilterQueries = + removeOrAdd === RemoveAddFacetFilter.ADD + ? [ + ...new Set([ + ...(currentSearchCriteria?.filterQueries ?? /* istanbul ignore next */ []), + filterQuery + ]) + ] + : (currentSearchCriteria.filterQueries ?? /* istanbul ignore next */ []).filter( + (fQuery) => fQuery !== filterQuery + ) + + // KEEP SEARCH VALUE IF EXISTS + itemsListContainerRef.current?.scrollTo({ top: 0 }) + + const resetPaginationInfo = new CollectionItemsPaginationInfo() + setPaginationInfo(resetPaginationInfo) + + // Update the URL with the new item types, keep other querys and include the search value if exists + setSearchParams((currentSearchParams) => ({ + ...currentSearchParams, + ...(newFilterQueries.length > 0 && { + [GetCollectionItemsQueryParams.FILTER_QUERIES]: newFilterQueries.join(',') + }), + ...(currentSearchCriteria.searchText && { + [QueryParamKey.QUERY]: currentSearchCriteria.searchText + }) + })) + + const newCollectionSearchCriteria = new CollectionSearchCriteria( + currentSearchCriteria.searchText, + currentSearchCriteria.itemTypes, + undefined, + undefined, + newFilterQueries + ) + + const totalItemsCount = await loadMore(resetPaginationInfo, newCollectionSearchCriteria, true) + + if (totalItemsCount !== undefined) { + const paginationInfoUpdated = resetPaginationInfo.withTotal(totalItemsCount) + setPaginationInfo(paginationInfoUpdated) + } + } + async function loadItemsOnBackAndForwardNavigation() { const searchParams = new URLSearchParams(window.location.search) const collectionQueryParams = CollectionHelper.defineCollectionQueryParams(searchParams) const newCollectionSearchCriteria = new CollectionSearchCriteria( collectionQueryParams.searchQuery, - collectionQueryParams.typesQuery + collectionQueryParams.typesQuery, + undefined, + undefined, + collectionQueryParams.filtersQuery ) const newPaginationInfo = new CollectionItemsPaginationInfo() @@ -203,6 +262,9 @@ export const CollectionItemsPanel = ({ diff --git a/src/sections/collection/collection-items-panel/filter-panel/FilterPanel.tsx b/src/sections/collection/collection-items-panel/filter-panel/FilterPanel.tsx index 64e33fca5..6d8e77204 100644 --- a/src/sections/collection/collection-items-panel/filter-panel/FilterPanel.tsx +++ b/src/sections/collection/collection-items-panel/filter-panel/FilterPanel.tsx @@ -4,17 +4,27 @@ import { Button, Offcanvas } from '@iqss/dataverse-design-system' import { FunnelFill } from 'react-bootstrap-icons' import { CollectionItemType } from '@/collection/domain/models/CollectionItemType' import { ItemTypeChange, TypeFilters } from './type-filters/TypeFilters' +import { CollectionItemsFacet } from '@/collection/domain/models/CollectionItemSubset' +import { FilterQuery } from '@/collection/domain/models/GetCollectionItemsQueryParams' +import { FacetsFilters } from './facets-filters/FacetsFilters' +import { RemoveAddFacetFilter } from './facets-filters/FacetFilter' import styles from './FilterPanel.module.scss' interface FilterPanelProps { currentItemTypes?: CollectionItemType[] onItemTypesChange: (itemTypeChange: ItemTypeChange) => void + facets: CollectionItemsFacet[] + currentFilterQueries?: FilterQuery[] + onFacetChange: (filterQuery: FilterQuery, removeOrAdd: RemoveAddFacetFilter) => void isLoadingCollectionItems: boolean } export const FilterPanel = ({ currentItemTypes, onItemTypesChange, + facets, + currentFilterQueries, + onFacetChange, isLoadingCollectionItems }: FilterPanelProps) => { const { t } = useTranslation('collection') @@ -45,6 +55,12 @@ export const FilterPanel = ({ currentItemTypes={currentItemTypes} isLoadingCollectionItems={isLoadingCollectionItems} /> + + diff --git a/src/sections/collection/collection-items-panel/filter-panel/facets-filters/FacetFilter.tsx b/src/sections/collection/collection-items-panel/filter-panel/facets-filters/FacetFilter.tsx new file mode 100644 index 000000000..1157642c9 --- /dev/null +++ b/src/sections/collection/collection-items-panel/filter-panel/facets-filters/FacetFilter.tsx @@ -0,0 +1,89 @@ +import { useState } from 'react' +import { Button, Col, Row } from '@iqss/dataverse-design-system' +import { XLg } from 'react-bootstrap-icons' +import { CollectionItemsFacet } from '@/collection/domain/models/CollectionItemSubset' +import { FilterQuery } from '@/collection/domain/models/GetCollectionItemsQueryParams' +import styles from './FacetsFilters.module.scss' + +const FACETS_PER_VIEW = 5 + +export enum RemoveAddFacetFilter { + REMOVE = 'remove', + ADD = 'add' +} + +interface FacetFilterProps { + facet: CollectionItemsFacet + facetSelectedLabels?: string[] + onFacetChange: (filterQuery: FilterQuery, removeOrAdd: RemoveAddFacetFilter) => void +} + +export const FacetFilter = ({ facet, facetSelectedLabels, onFacetChange }: FacetFilterProps) => { + const [visibleCount, setVisibleCount] = useState(FACETS_PER_VIEW) + + const handleShowMore = () => { + setVisibleCount((prev) => Math.min(prev + FACETS_PER_VIEW, facet.labels.length)) + } + + const handleShowLess = () => { + setVisibleCount((prev) => Math.max(prev - FACETS_PER_VIEW, FACETS_PER_VIEW)) + } + + const handleClickFacetLabel = (facetName: string, labelName: string) => { + const filterQuery: FilterQuery = `${facetName}:${labelName}` + const shouldRemoveOrAdd = facetSelectedLabels?.includes(labelName) + ? RemoveAddFacetFilter.REMOVE + : RemoveAddFacetFilter.ADD + + onFacetChange(filterQuery, shouldRemoveOrAdd) + } + + const showMoreButton = visibleCount < facet.labels.length + const showLessButton = visibleCount > FACETS_PER_VIEW + const showMoreLessButtons = + (showMoreButton || showLessButton) && facet.labels.length > FACETS_PER_VIEW + + // TODO:ME - Increase width of X icon + + return ( +
  • + {facet.friendlyName} +
      + {facet.labels.slice(0, visibleCount).map((label) => { + const isFacetLabelSelected = Boolean(facetSelectedLabels?.includes(label.name)) + + return ( +
    • + +
    • + ) + })} +
    + + {showMoreLessButtons && ( + + + {showLessButton && ( + + )} + + + {showMoreButton && ( + + )} + + + )} +
  • + ) +} diff --git a/src/sections/collection/collection-items-panel/filter-panel/facets-filters/FacetsFilters.module.scss b/src/sections/collection/collection-items-panel/filter-panel/facets-filters/FacetsFilters.module.scss new file mode 100644 index 000000000..966bd3326 --- /dev/null +++ b/src/sections/collection/collection-items-panel/filter-panel/facets-filters/FacetsFilters.module.scss @@ -0,0 +1,22 @@ +@import 'node_modules/@iqss/dataverse-design-system/src/lib/assets/styles/design-tokens/colors.module'; + +// TODO:ME Improve styles + +.facets-list, +.labels-list { + margin-bottom: 0; + padding-left: 0; + list-style-type: none; +} + +.facets-list { + > li { + border-bottom: solid 1px $dv-border-color; + } +} + +.labels-list { + .label-btn { + padding: 0; + } +} diff --git a/src/sections/collection/collection-items-panel/filter-panel/facets-filters/FacetsFilters.tsx b/src/sections/collection/collection-items-panel/filter-panel/facets-filters/FacetsFilters.tsx new file mode 100644 index 000000000..eff094b18 --- /dev/null +++ b/src/sections/collection/collection-items-panel/filter-panel/facets-filters/FacetsFilters.tsx @@ -0,0 +1,36 @@ +import { Stack } from '@iqss/dataverse-design-system' +import { CollectionItemsFacet } from '@/collection/domain/models/CollectionItemSubset' +import { FilterQuery } from '@/collection/domain/models/GetCollectionItemsQueryParams' +import { FacetFilter, RemoveAddFacetFilter } from './FacetFilter' +import styles from './FacetsFilters.module.scss' + +interface FacetsFiltersProps { + facets: CollectionItemsFacet[] + currentFilterQueries?: FilterQuery[] + onFacetChange: (filterQuery: FilterQuery, removeOrAdd: RemoveAddFacetFilter) => void +} + +export const FacetsFilters = ({ + facets, + currentFilterQueries, + onFacetChange +}: FacetsFiltersProps) => { + return ( + + {facets.map((facet) => { + const facetSelectedLabels = currentFilterQueries + ?.filter((query) => query.split(':')[0] === facet.name) + .map((query) => query.split(':')[1]) + + return ( + + ) + })} + + ) +} From 01b3a9c5174c1e3e3187e2816bec10d7e5b3d7ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germ=C3=A1n=20Saracca?= Date: Tue, 10 Dec 2024 15:15:51 -0300 Subject: [PATCH 07/28] feat: seleceted facets functionality --- .../CollectionItemsPanel.tsx | 47 ++++++++++++------- .../SelectedFacets.module.scss | 33 +++++++++++++ .../selected-facets/SelectedFacets.tsx | 30 ++++++++++++ 3 files changed, 93 insertions(+), 17 deletions(-) create mode 100644 src/sections/collection/collection-items-panel/selected-facets/SelectedFacets.module.scss create mode 100644 src/sections/collection/collection-items-panel/selected-facets/SelectedFacets.tsx diff --git a/src/sections/collection/collection-items-panel/CollectionItemsPanel.tsx b/src/sections/collection/collection-items-panel/CollectionItemsPanel.tsx index ee50552c6..1c460423f 100644 --- a/src/sections/collection/collection-items-panel/CollectionItemsPanel.tsx +++ b/src/sections/collection/collection-items-panel/CollectionItemsPanel.tsx @@ -19,6 +19,7 @@ import { ItemsList } from './items-list/ItemsList' import { SearchPanel } from './search-panel/SearchPanel' import { ItemTypeChange } from './filter-panel/type-filters/TypeFilters' import { RemoveAddFacetFilter } from './filter-panel/facets-filters/FacetFilter' +import { SelectedFacets } from './selected-facets/SelectedFacets' import styles from './CollectionItemsPanel.module.scss' interface CollectionItemsPanelProps { @@ -62,8 +63,6 @@ export const CollectionItemsPanel = ({ collectionQueryParams.filtersQuery ) - console.log({ currentSearchCriteria }) - const [paginationInfo, setPaginationInfo] = useState( new CollectionItemsPaginationInfo() ) @@ -243,6 +242,9 @@ export const CollectionItemsPanel = ({ } } + const showSelectedFacets = + currentSearchCriteria.filterQueries && currentSearchCriteria.filterQueries.length > 0 + useEffect(() => { setIsLoading(isLoadingItems) }, [isLoadingItems, setIsLoading]) @@ -268,21 +270,32 @@ export const CollectionItemsPanel = ({ isLoadingCollectionItems={isLoadingItems} /> - +
    + {showSelectedFacets && facets.length > 0 && ( + + handleFacetChange(filterQuery, RemoveAddFacetFilter.REMOVE) + } + selectedFilterQueries={currentSearchCriteria.filterQueries} + /> + )} + + +
    ) diff --git a/src/sections/collection/collection-items-panel/selected-facets/SelectedFacets.module.scss b/src/sections/collection/collection-items-panel/selected-facets/SelectedFacets.module.scss new file mode 100644 index 000000000..ab82d889b --- /dev/null +++ b/src/sections/collection/collection-items-panel/selected-facets/SelectedFacets.module.scss @@ -0,0 +1,33 @@ +@use 'sass:color'; +@import 'node_modules/@iqss/dataverse-design-system/src/lib/assets/styles/design-tokens/colors.module'; + +.selected-facets-container { + display: flex; + flex-wrap: wrap; + gap: 0.5rem; + margin-bottom: 0.5rem; + + .selected-facet-btn { + display: flex; + align-items: center; + padding-right: 2px; + padding-block: 2px; + color: $dv-primary-color; + font-weight: 600; + font-size: 80%; + line-height: 1; + background-color: color.adjust($dv-primary-color, $lightness: 50%); + + &:hover { + background-color: color.adjust($dv-primary-color, $lightness: 40%); + } + + &:active { + color: $dv-primary-color; + } + + svg { + min-width: fit-content; + } + } +} diff --git a/src/sections/collection/collection-items-panel/selected-facets/SelectedFacets.tsx b/src/sections/collection/collection-items-panel/selected-facets/SelectedFacets.tsx new file mode 100644 index 000000000..e8aa38788 --- /dev/null +++ b/src/sections/collection/collection-items-panel/selected-facets/SelectedFacets.tsx @@ -0,0 +1,30 @@ +import { Button } from '@iqss/dataverse-design-system' +import { X as CloseIcon } from 'react-bootstrap-icons' +import { FilterQuery } from '@/collection/domain/models/GetCollectionItemsQueryParams' +import styles from './SelectedFacets.module.scss' + +interface SelectedFacetsProps { + selectedFilterQueries: FilterQuery[] + onRemoveFacet: (filterQuery: FilterQuery) => void +} + +export const SelectedFacets = ({ selectedFilterQueries, onRemoveFacet }: SelectedFacetsProps) => { + return ( +
    + {selectedFilterQueries.map((filterQuery) => { + const [_facetName, labelName] = filterQuery.split(':') + + return ( + + ) + })} +
    + ) +} From 032a428096d468ffd5f9e6a34ed5f55fac86904a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germ=C3=A1n=20Saracca?= Date: Tue, 10 Dec 2024 16:35:20 -0300 Subject: [PATCH 08/28] feat: improve facet group list styles --- .../CollectionItemsPanel.tsx | 1 - .../facets-filters/FacetFilter.tsx | 29 ++++++++----- .../facets-filters/FacetsFilters.module.scss | 42 ++++++++++++++++--- .../facets-filters/FacetsFilters.tsx | 6 +-- .../SelectedFacets.module.scss | 1 - 5 files changed, 57 insertions(+), 22 deletions(-) diff --git a/src/sections/collection/collection-items-panel/CollectionItemsPanel.tsx b/src/sections/collection/collection-items-panel/CollectionItemsPanel.tsx index 1c460423f..12600a2b5 100644 --- a/src/sections/collection/collection-items-panel/CollectionItemsPanel.tsx +++ b/src/sections/collection/collection-items-panel/CollectionItemsPanel.tsx @@ -188,7 +188,6 @@ export const CollectionItemsPanel = ({ (fQuery) => fQuery !== filterQuery ) - // KEEP SEARCH VALUE IF EXISTS itemsListContainerRef.current?.scrollTo({ top: 0 }) const resetPaginationInfo = new CollectionItemsPaginationInfo() diff --git a/src/sections/collection/collection-items-panel/filter-panel/facets-filters/FacetFilter.tsx b/src/sections/collection/collection-items-panel/filter-panel/facets-filters/FacetFilter.tsx index 1157642c9..d5cee786b 100644 --- a/src/sections/collection/collection-items-panel/filter-panel/facets-filters/FacetFilter.tsx +++ b/src/sections/collection/collection-items-panel/filter-panel/facets-filters/FacetFilter.tsx @@ -1,6 +1,6 @@ import { useState } from 'react' import { Button, Col, Row } from '@iqss/dataverse-design-system' -import { XLg } from 'react-bootstrap-icons' +import { X as CloseIcon } from 'react-bootstrap-icons' import { CollectionItemsFacet } from '@/collection/domain/models/CollectionItemSubset' import { FilterQuery } from '@/collection/domain/models/GetCollectionItemsQueryParams' import styles from './FacetsFilters.module.scss' @@ -12,13 +12,17 @@ export enum RemoveAddFacetFilter { ADD = 'add' } -interface FacetFilterProps { +interface FacetFilterGroupProps { facet: CollectionItemsFacet facetSelectedLabels?: string[] onFacetChange: (filterQuery: FilterQuery, removeOrAdd: RemoveAddFacetFilter) => void } -export const FacetFilter = ({ facet, facetSelectedLabels, onFacetChange }: FacetFilterProps) => { +export const FacetFilterGroup = ({ + facet, + facetSelectedLabels, + onFacetChange +}: FacetFilterGroupProps) => { const [visibleCount, setVisibleCount] = useState(FACETS_PER_VIEW) const handleShowMore = () => { @@ -43,11 +47,9 @@ export const FacetFilter = ({ facet, facetSelectedLabels, onFacetChange }: Facet const showMoreLessButtons = (showMoreButton || showLessButton) && facet.labels.length > FACETS_PER_VIEW - // TODO:ME - Increase width of X icon - return ( -
  • - {facet.friendlyName} +
  • + {facet.friendlyName}
      {facet.labels.slice(0, visibleCount).map((label) => { const isFacetLabelSelected = Boolean(facetSelectedLabels?.includes(label.name)) @@ -56,10 +58,15 @@ export const FacetFilter = ({ facet, facetSelectedLabels, onFacetChange }: Facet
    • ) @@ -75,7 +82,7 @@ export const FacetFilter = ({ facet, facetSelectedLabels, onFacetChange }: Facet )} - + {showMoreButton && ( )} {showMoreButton && ( - )} diff --git a/src/sections/collection/collection-items-panel/filter-panel/facets-filters/FacetsFilters.module.scss b/src/sections/collection/collection-items-panel/filter-panel/facets-filters/FacetsFilters.module.scss index 01c458fbf..f451c1291 100644 --- a/src/sections/collection/collection-items-panel/filter-panel/facets-filters/FacetsFilters.module.scss +++ b/src/sections/collection/collection-items-panel/filter-panel/facets-filters/FacetsFilters.module.scss @@ -34,6 +34,10 @@ font-weight: 600; } + &:disabled { + color: $dv-primary-color; + } + span { text-wrap: wrap; } diff --git a/src/sections/collection/collection-items-panel/filter-panel/facets-filters/FacetsFilters.tsx b/src/sections/collection/collection-items-panel/filter-panel/facets-filters/FacetsFilters.tsx index d211e1998..f8a87645e 100644 --- a/src/sections/collection/collection-items-panel/filter-panel/facets-filters/FacetsFilters.tsx +++ b/src/sections/collection/collection-items-panel/filter-panel/facets-filters/FacetsFilters.tsx @@ -8,12 +8,14 @@ interface FacetsFiltersProps { facets: CollectionItemsFacet[] currentFilterQueries?: FilterQuery[] onFacetChange: (filterQuery: FilterQuery, removeOrAdd: RemoveAddFacetFilter) => void + isLoadingCollectionItems: boolean } export const FacetsFilters = ({ facets, currentFilterQueries, - onFacetChange + onFacetChange, + isLoadingCollectionItems }: FacetsFiltersProps) => { return ( @@ -28,6 +30,7 @@ export const FacetsFilters = ({ key={facet.name} facetSelectedLabels={facetSelectedLabels} onFacetChange={onFacetChange} + isLoadingCollectionItems={isLoadingCollectionItems} /> ) })} diff --git a/src/sections/collection/collection-items-panel/selected-facets/SelectedFacets.tsx b/src/sections/collection/collection-items-panel/selected-facets/SelectedFacets.tsx index e8aa38788..6e8ce3e3a 100644 --- a/src/sections/collection/collection-items-panel/selected-facets/SelectedFacets.tsx +++ b/src/sections/collection/collection-items-panel/selected-facets/SelectedFacets.tsx @@ -6,9 +6,14 @@ import styles from './SelectedFacets.module.scss' interface SelectedFacetsProps { selectedFilterQueries: FilterQuery[] onRemoveFacet: (filterQuery: FilterQuery) => void + isLoadingCollectionItems: boolean } -export const SelectedFacets = ({ selectedFilterQueries, onRemoveFacet }: SelectedFacetsProps) => { +export const SelectedFacets = ({ + selectedFilterQueries, + onRemoveFacet, + isLoadingCollectionItems +}: SelectedFacetsProps) => { return (
      {selectedFilterQueries.map((filterQuery) => { @@ -19,6 +24,7 @@ export const SelectedFacets = ({ selectedFilterQueries, onRemoveFacet }: Selecte size="sm" className={styles['selected-facet-btn']} onClick={() => onRemoveFacet(filterQuery)} + disabled={isLoadingCollectionItems} aria-label={`Remove ${labelName} query filter`} key={filterQuery}> {labelName} From 2612231e20f43ecc8d78f186c6d121dbd16c104b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germ=C3=A1n=20Saracca?= Date: Wed, 11 Dec 2024 12:24:39 -0300 Subject: [PATCH 11/28] feat: text align left --- .../filter-panel/facets-filters/FacetsFilters.module.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sections/collection/collection-items-panel/filter-panel/facets-filters/FacetsFilters.module.scss b/src/sections/collection/collection-items-panel/filter-panel/facets-filters/FacetsFilters.module.scss index f451c1291..5fd58c14e 100644 --- a/src/sections/collection/collection-items-panel/filter-panel/facets-filters/FacetsFilters.module.scss +++ b/src/sections/collection/collection-items-panel/filter-panel/facets-filters/FacetsFilters.module.scss @@ -27,6 +27,7 @@ button { padding: 0; + text-align: left; text-decoration: none; text-wrap: nowrap; From f028bba4e3a24e8c98c123ae7e258f059e149451 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germ=C3=A1n=20Saracca?= Date: Wed, 11 Dec 2024 16:20:11 -0300 Subject: [PATCH 12/28] feat: improve list layout --- .../CollectionItemsPanel.tsx | 12 +++++++++--- .../facets-filters/FacetsFilters.module.scss | 13 +++++++++---- .../items-list/ItemsList.module.scss | 17 +++++++++++++++-- .../items-list/ItemsList.tsx | 7 ++++--- .../selected-facets/SelectedFacets.module.scss | 1 - 5 files changed, 37 insertions(+), 13 deletions(-) diff --git a/src/sections/collection/collection-items-panel/CollectionItemsPanel.tsx b/src/sections/collection/collection-items-panel/CollectionItemsPanel.tsx index 83843ff6a..79e7bbf17 100644 --- a/src/sections/collection/collection-items-panel/CollectionItemsPanel.tsx +++ b/src/sections/collection/collection-items-panel/CollectionItemsPanel.tsx @@ -1,5 +1,6 @@ import { useEffect, useRef, useState } from 'react' import { useSearchParams } from 'react-router-dom' +import { Stack } from '@iqss/dataverse-design-system' import { CollectionRepository } from '@/collection/domain/repositories/CollectionRepository' import { CollectionItemsPaginationInfo } from '@/collection/domain/models/CollectionItemsPaginationInfo' import { CollectionSearchCriteria } from '@/collection/domain/models/CollectionSearchCriteria' @@ -43,6 +44,12 @@ interface CollectionItemsPanelProps { * Every time a load of items is triggered, the pagination info is updated and the URL is updated with the new query params so it can be shared and the user can navigate back and forward in the browser. */ +// TODO:ME - Nothing found message when no items are found +// TODO:ME - Add a remove all filters button +// TODO:ME - Maybe different button to show more facets +// TODO:ME - margin top scroll +// TODO:ME - Facet filters skeleton? + export const CollectionItemsPanel = ({ collectionId, collectionRepository, @@ -147,7 +154,6 @@ export const CollectionItemsPanel = ({ (itemType) => itemType !== type ) - // KEEP SEARCH VALUE IF EXISTS itemsListContainerRef.current?.scrollTo({ top: 0 }) const resetPaginationInfo = new CollectionItemsPaginationInfo() @@ -277,7 +283,7 @@ export const CollectionItemsPanel = ({ isLoadingCollectionItems={isLoadingItems} /> -
      + {showSelectedFacets && facets.length > 0 && ( @@ -303,7 +309,7 @@ export const CollectionItemsPanel = ({ onBottomReach={handleLoadMoreOnBottomReach} ref={itemsListContainerRef} /> -
      +
      ) diff --git a/src/sections/collection/collection-items-panel/filter-panel/facets-filters/FacetsFilters.module.scss b/src/sections/collection/collection-items-panel/filter-panel/facets-filters/FacetsFilters.module.scss index 5fd58c14e..5c4e5870d 100644 --- a/src/sections/collection/collection-items-panel/filter-panel/facets-filters/FacetsFilters.module.scss +++ b/src/sections/collection/collection-items-panel/filter-panel/facets-filters/FacetsFilters.module.scss @@ -1,7 +1,5 @@ @import 'node_modules/@iqss/dataverse-design-system/src/lib/assets/styles/design-tokens/colors.module'; -// TODO:ME Improve styles - .facets-list, .labels-list { margin-bottom: 0; @@ -10,11 +8,18 @@ } .facets-list { - padding-block: 1rem; + padding-top: 1rem; + + &:empty { + padding-top: 0; + } .facet-filter-group { padding-bottom: 0.5rem; - border-bottom: solid 1px $dv-border-color; + + &:not(:last-child) { + border-bottom: solid 1px $dv-border-color; + } .facet-name { font-weight: 600; diff --git a/src/sections/collection/collection-items-panel/items-list/ItemsList.module.scss b/src/sections/collection/collection-items-panel/items-list/ItemsList.module.scss index 253026076..151e4516b 100644 --- a/src/sections/collection/collection-items-panel/items-list/ItemsList.module.scss +++ b/src/sections/collection/collection-items-panel/items-list/ItemsList.module.scss @@ -1,4 +1,10 @@ @import 'node_modules/@iqss/dataverse-design-system/src/lib/assets/styles/design-tokens/colors.module'; +@import 'src/assets/variables'; + +.items-list-root-ref { + flex: 1; + height: 100%; +} .items-list { --inline-padding: 1rem; @@ -10,17 +16,24 @@ overflow-y: auto; border: 1px solid $dv-border-color; border-radius: 4px; + scroll-margin-top: calc(#{$header-aproximate-height} + 1rem); @media screen and (max-width: 768px) { --inline-padding: 0.5rem; } - @media screen and (min-width: 1280px) { + @media screen and (min-width: 992px) { height: 60vh; - max-height: 60vh; + min-height: 100%; + max-height: unset; + + &.only-one-or-two-items { + height: auto; + } } &.empty-or-error { + height: auto; padding-block: var(--inline-padding); } diff --git a/src/sections/collection/collection-items-panel/items-list/ItemsList.tsx b/src/sections/collection/collection-items-panel/items-list/ItemsList.tsx index 7eeee3709..d4c84a598 100644 --- a/src/sections/collection/collection-items-panel/items-list/ItemsList.tsx +++ b/src/sections/collection/collection-items-panel/items-list/ItemsList.tsx @@ -63,10 +63,11 @@ export const ItemsList = forwardRef( const showNotSentrySkeleton = isLoadingItems && isEmptyItems return ( -
      +
      } @@ -141,7 +142,7 @@ export const InitialLoadingSkeleton = () => ( data-testid="collection-items-list-infinite-scroll-skeleton-header">
      - + diff --git a/src/sections/collection/collection-items-panel/selected-facets/SelectedFacets.module.scss b/src/sections/collection/collection-items-panel/selected-facets/SelectedFacets.module.scss index 204db0219..1f89c0e09 100644 --- a/src/sections/collection/collection-items-panel/selected-facets/SelectedFacets.module.scss +++ b/src/sections/collection/collection-items-panel/selected-facets/SelectedFacets.module.scss @@ -5,7 +5,6 @@ display: flex; flex-wrap: wrap; gap: 0.5rem; - margin-bottom: 0.5rem; .selected-facet-btn { display: flex; From 8c199930ac7c80ca993e22c3763190ac2d7d709e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germ=C3=A1n=20Saracca?= Date: Wed, 11 Dec 2024 16:33:04 -0300 Subject: [PATCH 13/28] feat: show diff message when filter queries applied --- public/locales/en/collection.json | 3 ++- .../CollectionItemsPanel.tsx | 2 +- .../items-list/ItemsList.tsx | 12 ++++++++-- .../items-list/NoItemsMessage.tsx | 22 +++++++++++++++++-- 4 files changed, 33 insertions(+), 6 deletions(-) diff --git a/public/locales/en/collection.json b/public/locales/en/collection.json index f950adb7f..e022a2ca9 100644 --- a/public/locales/en/collection.json +++ b/public/locales/en/collection.json @@ -14,7 +14,8 @@ "collectionAndDataset": "collections or datasets", "collectionAndFile": "collections or files", "datasetAndFile": "datasets or files" - } + }, + "noItemsBasedOnFilterQueries": "There are no search results based on how you have narrowed your search. You can check out the <1>search guide for tips." }, "noSearchMatches": "There are no collections, datasets, or files that match your search. Please try a new search by using other or broader terms. You can also check out the search guide for tips.", "createdAlert": "You have successfully created your collection! To learn more about what you can do with your collection, check out the User Guide.", diff --git a/src/sections/collection/collection-items-panel/CollectionItemsPanel.tsx b/src/sections/collection/collection-items-panel/CollectionItemsPanel.tsx index 79e7bbf17..4c38602a4 100644 --- a/src/sections/collection/collection-items-panel/CollectionItemsPanel.tsx +++ b/src/sections/collection/collection-items-panel/CollectionItemsPanel.tsx @@ -44,7 +44,6 @@ interface CollectionItemsPanelProps { * Every time a load of items is triggered, the pagination info is updated and the URL is updated with the new query params so it can be shared and the user can navigate back and forward in the browser. */ -// TODO:ME - Nothing found message when no items are found // TODO:ME - Add a remove all filters button // TODO:ME - Maybe different button to show more facets // TODO:ME - margin top scroll @@ -305,6 +304,7 @@ export const CollectionItemsPanel = ({ isEmptyItems={isEmptyItems} hasSearchValue={currentSearchCriteria.hasSearchText()} itemsTypesSelected={currentSearchCriteria.itemTypes as CollectionItemType[]} + filterQueriesSelected={currentSearchCriteria.filterQueries ?? []} paginationInfo={paginationInfo} onBottomReach={handleLoadMoreOnBottomReach} ref={itemsListContainerRef} diff --git a/src/sections/collection/collection-items-panel/items-list/ItemsList.tsx b/src/sections/collection/collection-items-panel/items-list/ItemsList.tsx index d4c84a598..f633cfc53 100644 --- a/src/sections/collection/collection-items-panel/items-list/ItemsList.tsx +++ b/src/sections/collection/collection-items-panel/items-list/ItemsList.tsx @@ -5,6 +5,7 @@ import cn from 'classnames' import { type CollectionItem } from '@/collection/domain/models/CollectionItemSubset' import { CollectionItemsPaginationInfo } from '@/collection/domain/models/CollectionItemsPaginationInfo' import { CollectionItemType } from '@/collection/domain/models/CollectionItemType' +import { FilterQuery } from '@/collection/domain/models/GetCollectionItemsQueryParams' import { PaginationResultsInfo } from '@/sections/shared/pagination/PaginationResultsInfo' import { NO_COLLECTION_ITEMS } from '../useGetAccumulatedItems' import { ErrorItemsMessage } from './ErrorItemsMessage' @@ -28,6 +29,7 @@ interface ItemsListProps { paginationInfo: CollectionItemsPaginationInfo onBottomReach: (paginationInfo: CollectionItemsPaginationInfo) => void itemsTypesSelected: CollectionItemType[] + filterQueriesSelected: FilterQuery[] } export const ItemsList = forwardRef( @@ -44,7 +46,8 @@ export const ItemsList = forwardRef( hasSearchValue, paginationInfo, onBottomReach, - itemsTypesSelected + itemsTypesSelected, + filterQueriesSelected }: ItemsListProps, ref ) => { @@ -72,7 +75,12 @@ export const ItemsList = forwardRef( tabIndex={0} ref={ref as ForwardedRef} data-testid="items-list-scrollable-container"> - {showNoItemsMessage && } + {showNoItemsMessage && ( + + )} {showNoSearchMatchesMessage && } diff --git a/src/sections/collection/collection-items-panel/items-list/NoItemsMessage.tsx b/src/sections/collection/collection-items-panel/items-list/NoItemsMessage.tsx index 6b568040f..28cc2292e 100644 --- a/src/sections/collection/collection-items-panel/items-list/NoItemsMessage.tsx +++ b/src/sections/collection/collection-items-panel/items-list/NoItemsMessage.tsx @@ -2,13 +2,15 @@ import { Trans, useTranslation } from 'react-i18next' import { useSession } from '@/sections/session/SessionContext' import { Route } from '@/sections/Route.enum' import { CollectionItemType } from '@/collection/domain/models/CollectionItemType' +import { FilterQuery } from '@/collection/domain/models/GetCollectionItemsQueryParams' import styles from './ItemsList.module.scss' interface NoItemsMessageProps { itemsTypesSelected: CollectionItemType[] + filterQueriesSelected: FilterQuery[] } -export function NoItemsMessage({ itemsTypesSelected }: NoItemsMessageProps) { +export function NoItemsMessage({ itemsTypesSelected, filterQueriesSelected }: NoItemsMessageProps) { const { t } = useTranslation('collection') const { user } = useSession() @@ -58,7 +60,23 @@ export function NoItemsMessage({ itemsTypesSelected }: NoItemsMessageProps) { return (
      {user ? ( -

      {t('noItemsMessage.authenticated', { typeOfEmptyItems: messageKey })}

      + filterQueriesSelected.length > 0 ? ( + + ) + }} + /> + ) : ( +

      {t('noItemsMessage.authenticated', { typeOfEmptyItems: messageKey })}

      + ) ) : ( Date: Wed, 11 Dec 2024 17:05:37 -0300 Subject: [PATCH 14/28] feat: remove underline in less and more buttons --- .../CollectionItemsPanel.tsx | 5 ++--- .../filter-panel/FilterPanel.tsx | 2 +- .../{FacetFilter.tsx => FacetFilterGroup.tsx} | 4 ++-- .../facets-filters/FacetsFilters.module.scss | 16 +++++++++++----- .../facets-filters/FacetsFilters.tsx | 2 +- 5 files changed, 17 insertions(+), 12 deletions(-) rename src/sections/collection/collection-items-panel/filter-panel/facets-filters/{FacetFilter.tsx => FacetFilterGroup.tsx} (98%) diff --git a/src/sections/collection/collection-items-panel/CollectionItemsPanel.tsx b/src/sections/collection/collection-items-panel/CollectionItemsPanel.tsx index 4c38602a4..3eb9b848d 100644 --- a/src/sections/collection/collection-items-panel/CollectionItemsPanel.tsx +++ b/src/sections/collection/collection-items-panel/CollectionItemsPanel.tsx @@ -19,7 +19,7 @@ import { FilterPanel } from './filter-panel/FilterPanel' import { ItemsList } from './items-list/ItemsList' import { SearchPanel } from './search-panel/SearchPanel' import { ItemTypeChange } from './filter-panel/type-filters/TypeFilters' -import { RemoveAddFacetFilter } from './filter-panel/facets-filters/FacetFilter' +import { RemoveAddFacetFilter } from './filter-panel/facets-filters/FacetFilterGroup' import { SelectedFacets } from './selected-facets/SelectedFacets' import styles from './CollectionItemsPanel.module.scss' @@ -44,10 +44,9 @@ interface CollectionItemsPanelProps { * Every time a load of items is triggered, the pagination info is updated and the URL is updated with the new query params so it can be shared and the user can navigate back and forward in the browser. */ -// TODO:ME - Add a remove all filters button -// TODO:ME - Maybe different button to show more facets // TODO:ME - margin top scroll // TODO:ME - Facet filters skeleton? +// TODO:ME - Add locales export const CollectionItemsPanel = ({ collectionId, diff --git a/src/sections/collection/collection-items-panel/filter-panel/FilterPanel.tsx b/src/sections/collection/collection-items-panel/filter-panel/FilterPanel.tsx index 9e7a05aa1..a4b3e7de5 100644 --- a/src/sections/collection/collection-items-panel/filter-panel/FilterPanel.tsx +++ b/src/sections/collection/collection-items-panel/filter-panel/FilterPanel.tsx @@ -7,7 +7,7 @@ import { ItemTypeChange, TypeFilters } from './type-filters/TypeFilters' import { CollectionItemsFacet } from '@/collection/domain/models/CollectionItemSubset' import { FilterQuery } from '@/collection/domain/models/GetCollectionItemsQueryParams' import { FacetsFilters } from './facets-filters/FacetsFilters' -import { RemoveAddFacetFilter } from './facets-filters/FacetFilter' +import { RemoveAddFacetFilter } from './facets-filters/FacetFilterGroup' import styles from './FilterPanel.module.scss' interface FilterPanelProps { diff --git a/src/sections/collection/collection-items-panel/filter-panel/facets-filters/FacetFilter.tsx b/src/sections/collection/collection-items-panel/filter-panel/facets-filters/FacetFilterGroup.tsx similarity index 98% rename from src/sections/collection/collection-items-panel/filter-panel/facets-filters/FacetFilter.tsx rename to src/sections/collection/collection-items-panel/filter-panel/facets-filters/FacetFilterGroup.tsx index bac29a7eb..3aced5f8a 100644 --- a/src/sections/collection/collection-items-panel/filter-panel/facets-filters/FacetFilter.tsx +++ b/src/sections/collection/collection-items-panel/filter-panel/facets-filters/FacetFilterGroup.tsx @@ -77,7 +77,7 @@ export const FacetFilterGroup = ({
    {showMoreLessButtons && ( - + {showLessButton && ( )} @@ -96,7 +102,7 @@ export const FacetFilterGroup = ({ size="sm" onClick={handleShowMore} disabled={isLoadingCollectionItems}> - More... + {tShared('more')} )} diff --git a/src/sections/collection/collection-items-panel/selected-facets/SelectedFacets.tsx b/src/sections/collection/collection-items-panel/selected-facets/SelectedFacets.tsx index 6e8ce3e3a..137e0aea8 100644 --- a/src/sections/collection/collection-items-panel/selected-facets/SelectedFacets.tsx +++ b/src/sections/collection/collection-items-panel/selected-facets/SelectedFacets.tsx @@ -1,3 +1,4 @@ +import { useTranslation } from 'react-i18next' import { Button } from '@iqss/dataverse-design-system' import { X as CloseIcon } from 'react-bootstrap-icons' import { FilterQuery } from '@/collection/domain/models/GetCollectionItemsQueryParams' @@ -14,6 +15,8 @@ export const SelectedFacets = ({ onRemoveFacet, isLoadingCollectionItems }: SelectedFacetsProps) => { + const { t } = useTranslation('collection') + return (
    {selectedFilterQueries.map((filterQuery) => { @@ -25,7 +28,7 @@ export const SelectedFacets = ({ className={styles['selected-facet-btn']} onClick={() => onRemoveFacet(filterQuery)} disabled={isLoadingCollectionItems} - aria-label={`Remove ${labelName} query filter`} + aria-label={t('removeSelectedFacet', { labelName })} key={filterQuery}> {labelName} From bf2a8631a0cd7c13f3b5f63af3547b857b58a55c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germ=C3=A1n=20Saracca?= Date: Wed, 11 Dec 2024 21:52:41 -0300 Subject: [PATCH 17/28] feat: udpate js-dataverse and update search criteria --- package-lock.json | 8 ++--- package.json | 2 +- .../models/CollectionSearchCriteria.tsx | 32 ++++++++++++++++--- 3 files changed, 33 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 09fb51eab..8c70e729c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.1.0", "dependencies": { "@faker-js/faker": "7.6.0", - "@iqss/dataverse-client-javascript": "2.0.0-pr230.13612a8", + "@iqss/dataverse-client-javascript": "2.0.0-pr230.3a26dc9", "@iqss/dataverse-design-system": "*", "@istanbuljs/nyc-config-typescript": "1.0.2", "@tanstack/react-table": "8.9.2", @@ -3674,9 +3674,9 @@ }, "node_modules/@iqss/dataverse-client-javascript": { "name": "@IQSS/dataverse-client-javascript", - "version": "2.0.0-pr230.13612a8", - "resolved": "https://npm.pkg.github.com/download/@IQSS/dataverse-client-javascript/2.0.0-pr230.13612a8/79860d14c5222eaac6838b48f8737fb0a0e6e210", - "integrity": "sha512-qiewJpTmXd07MeLMKFlQtUnhKMOCLnv0BGZqjZOgR1vGBPKaxUMVMFKvp+c3/PJCktzHG9GwgtM5yaluxgC/Eg==", + "version": "2.0.0-pr230.3a26dc9", + "resolved": "https://npm.pkg.github.com/download/@IQSS/dataverse-client-javascript/2.0.0-pr230.3a26dc9/2c0e9c1f0392e8bf251f3b174954825467b73541", + "integrity": "sha512-3TVcYDw1yfY/0fZCuAImtCfy3hK3h348GC6WowoQ69vpnHN3BZ1+f+qbv3f3vEljtb6TsuCqPbvLd2oEuRf3gg==", "license": "MIT", "dependencies": { "@types/node": "^18.15.11", diff --git a/package.json b/package.json index 3eb8d77d6..d6f3f45bf 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ }, "dependencies": { "@faker-js/faker": "7.6.0", - "@iqss/dataverse-client-javascript": "2.0.0-pr230.13612a8", + "@iqss/dataverse-client-javascript": "2.0.0-pr230.3a26dc9", "@iqss/dataverse-design-system": "*", "@istanbuljs/nyc-config-typescript": "1.0.2", "@tanstack/react-table": "8.9.2", diff --git a/src/collection/domain/models/CollectionSearchCriteria.tsx b/src/collection/domain/models/CollectionSearchCriteria.tsx index 63ac15933..929d0cfa9 100644 --- a/src/collection/domain/models/CollectionSearchCriteria.tsx +++ b/src/collection/domain/models/CollectionSearchCriteria.tsx @@ -11,19 +11,43 @@ export class CollectionSearchCriteria { ) {} withSearchText(searchText: string | undefined): CollectionSearchCriteria { - return new CollectionSearchCriteria(searchText, this.itemTypes, this.sort, this.order) + return new CollectionSearchCriteria( + searchText, + this.itemTypes, + this.sort, + this.order, + this.filterQueries + ) } withItemTypes(itemTypes: CollectionItemType[] | undefined): CollectionSearchCriteria { - return new CollectionSearchCriteria(this.searchText, itemTypes, this.sort, this.order) + return new CollectionSearchCriteria( + this.searchText, + itemTypes, + this.sort, + this.order, + this.filterQueries + ) } withSort(sort: SortType | undefined): CollectionSearchCriteria { - return new CollectionSearchCriteria(this.searchText, this.itemTypes, sort, this.order) + return new CollectionSearchCriteria( + this.searchText, + this.itemTypes, + sort, + this.order, + this.filterQueries + ) } withOrder(order: OrderType | undefined): CollectionSearchCriteria { - return new CollectionSearchCriteria(this.searchText, this.itemTypes, this.sort, order) + return new CollectionSearchCriteria( + this.searchText, + this.itemTypes, + this.sort, + order, + this.filterQueries + ) } withFilterQueries(filterQueries: FilterQuery[] | undefined): CollectionSearchCriteria { From 75c6664e37e96e5f99ddd7a76bf6dd040b63f81d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germ=C3=A1n=20Saracca?= Date: Wed, 11 Dec 2024 22:56:33 -0300 Subject: [PATCH 18/28] feat: revert noItemsMessage --- public/locales/en/collection.json | 3 +-- .../items-list/ItemsList.tsx | 13 +++++------ .../items-list/NoItemsMessage.tsx | 22 ++----------------- 3 files changed, 8 insertions(+), 30 deletions(-) diff --git a/public/locales/en/collection.json b/public/locales/en/collection.json index f6c1c42fa..a687ca37b 100644 --- a/public/locales/en/collection.json +++ b/public/locales/en/collection.json @@ -14,8 +14,7 @@ "collectionAndDataset": "collections or datasets", "collectionAndFile": "collections or files", "datasetAndFile": "datasets or files" - }, - "noItemsBasedOnFilterQueries": "There are no search results based on how you have narrowed your search. You can check out the <1>search guide for tips." + } }, "noSearchMatches": "There are no collections, datasets, or files that match your search. Please try a new search by using other or broader terms. You can also check out the search guide for tips.", "createdAlert": "You have successfully created your collection! To learn more about what you can do with your collection, check out the User Guide.", diff --git a/src/sections/collection/collection-items-panel/items-list/ItemsList.tsx b/src/sections/collection/collection-items-panel/items-list/ItemsList.tsx index f633cfc53..faf9fdc19 100644 --- a/src/sections/collection/collection-items-panel/items-list/ItemsList.tsx +++ b/src/sections/collection/collection-items-panel/items-list/ItemsList.tsx @@ -59,8 +59,10 @@ export const ItemsList = forwardRef( rootMargin: '0px 0px 250px 0px' }) - const showNoItemsMessage = !isLoadingItems && isEmptyItems && !hasSearchValue - const showNoSearchMatchesMessage = !isLoadingItems && isEmptyItems && hasSearchValue + const showNoItemsMessage = + !isLoadingItems && isEmptyItems && !hasSearchValue && filterQueriesSelected.length === 0 + const showNoSearchMatchesMessage = + !isLoadingItems && isEmptyItems && (hasSearchValue || filterQueriesSelected.length > 0) const showSentrySkeleton = hasNextPage && !error && !isEmptyItems const showNotSentrySkeleton = isLoadingItems && isEmptyItems @@ -75,12 +77,7 @@ export const ItemsList = forwardRef( tabIndex={0} ref={ref as ForwardedRef} data-testid="items-list-scrollable-container"> - {showNoItemsMessage && ( - - )} + {showNoItemsMessage && } {showNoSearchMatchesMessage && } diff --git a/src/sections/collection/collection-items-panel/items-list/NoItemsMessage.tsx b/src/sections/collection/collection-items-panel/items-list/NoItemsMessage.tsx index 28cc2292e..6b568040f 100644 --- a/src/sections/collection/collection-items-panel/items-list/NoItemsMessage.tsx +++ b/src/sections/collection/collection-items-panel/items-list/NoItemsMessage.tsx @@ -2,15 +2,13 @@ import { Trans, useTranslation } from 'react-i18next' import { useSession } from '@/sections/session/SessionContext' import { Route } from '@/sections/Route.enum' import { CollectionItemType } from '@/collection/domain/models/CollectionItemType' -import { FilterQuery } from '@/collection/domain/models/GetCollectionItemsQueryParams' import styles from './ItemsList.module.scss' interface NoItemsMessageProps { itemsTypesSelected: CollectionItemType[] - filterQueriesSelected: FilterQuery[] } -export function NoItemsMessage({ itemsTypesSelected, filterQueriesSelected }: NoItemsMessageProps) { +export function NoItemsMessage({ itemsTypesSelected }: NoItemsMessageProps) { const { t } = useTranslation('collection') const { user } = useSession() @@ -60,23 +58,7 @@ export function NoItemsMessage({ itemsTypesSelected, filterQueriesSelected }: No return (
    {user ? ( - filterQueriesSelected.length > 0 ? ( - - ) - }} - /> - ) : ( -

    {t('noItemsMessage.authenticated', { typeOfEmptyItems: messageKey })}

    - ) +

    {t('noItemsMessage.authenticated', { typeOfEmptyItems: messageKey })}

    ) : ( Date: Wed, 11 Dec 2024 22:57:00 -0300 Subject: [PATCH 19/28] feat: add stories --- .../collection/CollectionMockRepository.ts | 3 ++ .../collection/NoCollectionMockRepository.ts | 1 + .../CollectionItemsPanel.stories.tsx | 20 ++++++++++ .../domain/models/CollectionItemsMother.ts | 38 ++++++++++++++++++- 4 files changed, 61 insertions(+), 1 deletion(-) diff --git a/src/stories/collection/CollectionMockRepository.ts b/src/stories/collection/CollectionMockRepository.ts index efb2e116a..aa0c88b65 100644 --- a/src/stories/collection/CollectionMockRepository.ts +++ b/src/stories/collection/CollectionMockRepository.ts @@ -59,6 +59,8 @@ export class CollectionMockRepository implements CollectionRepository { numberOfFiles }) + const facets = CollectionItemsMother.createItemsFacets() + const isDefaultSelected = searchCriteria?.itemTypes?.length === 2 && searchCriteria?.itemTypes?.includes(CollectionItemType.COLLECTION) && @@ -72,6 +74,7 @@ export class CollectionMockRepository implements CollectionRepository { setTimeout(() => { resolve({ items: filteredByTypeItems, + facets: facets, totalItemCount: isDefaultSelected ? 6 : 200 // This is a fake number, its big so we can always scroll to load more items for the story }) }, FakerHelper.loadingTimout()) diff --git a/src/stories/collection/NoCollectionMockRepository.ts b/src/stories/collection/NoCollectionMockRepository.ts index 63d8c5e00..69c9c21e6 100644 --- a/src/stories/collection/NoCollectionMockRepository.ts +++ b/src/stories/collection/NoCollectionMockRepository.ts @@ -32,6 +32,7 @@ export class NoCollectionMockRepository extends CollectionMockRepository { setTimeout(() => { resolve({ items: [], + facets: [], totalItemCount: 0 }) }, FakerHelper.loadingTimout()) diff --git a/src/stories/collection/collection-items-panel/CollectionItemsPanel.stories.tsx b/src/stories/collection/collection-items-panel/CollectionItemsPanel.stories.tsx index 4d0e23056..28282f2b5 100644 --- a/src/stories/collection/collection-items-panel/CollectionItemsPanel.stories.tsx +++ b/src/stories/collection/collection-items-panel/CollectionItemsPanel.stories.tsx @@ -52,6 +52,26 @@ export const WithAllFiltersAndSearchValue: Story = { ) } +export const WithFacetFiltersApplied: Story = { + render: () => ( + + ) +} + export const WithAddDataButtons: Story = { render: () => ( Date: Wed, 11 Dec 2024 23:14:17 -0300 Subject: [PATCH 20/28] fix: accesibility issues --- .../collection-items-panel/CollectionItemsPanel.tsx | 5 ++++- .../filter-panel/facets-filters/FacetFilterGroup.tsx | 6 ++++-- .../filter-panel/facets-filters/FacetsFilters.module.scss | 4 ++-- .../selected-facets/SelectedFacets.module.scss | 2 +- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/sections/collection/collection-items-panel/CollectionItemsPanel.tsx b/src/sections/collection/collection-items-panel/CollectionItemsPanel.tsx index 981fa6b4c..21e7b066a 100644 --- a/src/sections/collection/collection-items-panel/CollectionItemsPanel.tsx +++ b/src/sections/collection/collection-items-panel/CollectionItemsPanel.tsx @@ -37,13 +37,16 @@ interface CollectionItemsPanelProps { * 2. When the user scrolls to the bottom of the list and there are more items to load * 3. When the user submits a search query in the search panel * 4. When the user changes the item types in the filter panel - * 5. When the user navigates back and forward in the browser + * 5. When the user selects or removes a facet filter + * 6. When the user navigates back and forward in the browser * * It initializes the search criteria with the query params in the URL. * By default if no query params are present in the URL, the search query is empty and the item types are COLLECTION and DATASET. * Every time a load of items is triggered, the pagination info is updated and the URL is updated with the new query params so it can be shared and the user can navigate back and forward in the browser. */ +// TODO:ME - Fix Tests + export const CollectionItemsPanel = ({ collectionId, collectionRepository, diff --git a/src/sections/collection/collection-items-panel/filter-panel/facets-filters/FacetFilterGroup.tsx b/src/sections/collection/collection-items-panel/filter-panel/facets-filters/FacetFilterGroup.tsx index 1772de07f..4f9b7f90c 100644 --- a/src/sections/collection/collection-items-panel/filter-panel/facets-filters/FacetFilterGroup.tsx +++ b/src/sections/collection/collection-items-panel/filter-panel/facets-filters/FacetFilterGroup.tsx @@ -1,5 +1,6 @@ import { useState } from 'react' import { useTranslation } from 'react-i18next' +import cn from 'classnames' import { Button, Col, Row } from '@iqss/dataverse-design-system' import { X as CloseIcon } from 'react-bootstrap-icons' import { CollectionItemsFacet } from '@/collection/domain/models/CollectionItemSubset' @@ -64,8 +65,9 @@ export const FacetFilterGroup = ({