From 6c96719052655af4e3ee4661ed82a92b270412b8 Mon Sep 17 00:00:00 2001 From: bjperson Date: Thu, 18 Dec 2025 14:20:57 +0100 Subject: [PATCH 1/3] feat(datasets): add Atom feed link to search page Add a link to the datasets Atom feed on the search page. The link includes current search filters, allowing users to subscribe to filtered search results via their RSS reader. Requires opendatateam/udata#3578 for filter support on the Atom endpoint. --- pages/datasets/search.vue | 56 ++++++++++++++++++++++++++++++--------- 1 file changed, 44 insertions(+), 12 deletions(-) diff --git a/pages/datasets/search.vue b/pages/datasets/search.vue index e57f3fd2..2639030d 100644 --- a/pages/datasets/search.vue +++ b/pages/datasets/search.vue @@ -11,18 +11,43 @@ -

- {{ $t('Jeux de données') }} -

-

- {{ $t('Rechercher parmi les {count} jeux de données sur {site}', { - count: site.metrics.datasets, - site: config.public.title, - }) }} -

+
+
+

+ {{ $t('Jeux de données') }} +

+

+ {{ $t('Rechercher parmi les {count} jeux de données sur {site}', { + count: site.metrics.datasets, + site: config.public.title, + }) }} +

+
+ + + + + + RSS + +
@@ -39,5 +64,12 @@ useSeoMeta({ const config = useRuntimeConfig() +function openRss() { + const searchParams = window.location.search + const baseUrl = `${config.public.apiBase}/api/1/datasets/recent.atom` + const url = searchParams ? `${baseUrl}${searchParams}` : baseUrl + window.open(url, '_blank') +} + const { data: site } = await useAPI('/api/1/site/') From 2c4d7bed04695024efa6116b66bb046a0af7152d Mon Sep 17 00:00:00 2001 From: bjperson Date: Thu, 18 Dec 2025 18:58:08 +0100 Subject: [PATCH 2/3] feat(datasets): add Atom feed button to search results Move Atom feed link from page to SearchPage component as requested. Uses BrandedButton with RiRssLine icon, positioned next to sort control. URL built from nonFalsyParams for reactive filter support. Requires opendatateam/udata#3578 for filter support on the Atom endpoint. --- components/Datasets/SearchPage.vue | 66 +++++++++++++++++++----------- pages/datasets/search.vue | 56 ++++++------------------- 2 files changed, 53 insertions(+), 69 deletions(-) diff --git a/components/Datasets/SearchPage.vue b/components/Datasets/SearchPage.vue index 44c34d40..0236165b 100644 --- a/components/Datasets/SearchPage.vue +++ b/components/Datasets/SearchPage.vue @@ -185,33 +185,43 @@ > {{ t("{count} résultats | {count} résultat | {count} résultats", searchResults.total) }}

-
- -
- - {{ label }} - - + + + +
+ @@ -280,7 +290,7 @@ import { BrandedButton, getLink, getOrganizationTypes, LoadingBlock, Pagination, OTHER, USER } from '@datagouv/components-next' import type { DatasetV2, License, Organization, OrganizationTypes, RegisteredSchema, TranslatedBadge, OrganizationOrSuggest } from '@datagouv/components-next' import { ref, computed, type Component } from 'vue' -import { RiCloseCircleLine, RiDownloadLine } from '@remixicon/vue' +import { RiCloseCircleLine, RiDownloadLine, RiRssLine } from '@remixicon/vue' import { computedAsync, debouncedRef, useUrlSearchParams } from '@vueuse/core' import SearchInput from '~/components/Search/SearchInput.vue' import type { PaginatedArray, SpatialGranularity, SpatialZone, Tag } from '~/types/types' @@ -320,6 +330,12 @@ const nonFalsyParams = computed(() => { return { ...propsParams, ...Object.fromEntries(filteredParams), page_size: pageSize } }) +const atomFeedUrl = computed(() => { + const { page, page_size, ...feedParams } = nonFalsyParams.value + const query = new URLSearchParams(feedParams).toString() + return `${config.public.apiBase}/api/1/datasets/recent.atom${query ? `?${query}` : ''}` +}) + const { data: searchResults, status: searchResultsStatus, refresh } = await useAPI>('/api/2/datasets/search/', { params: nonFalsyParams, lazy: true, diff --git a/pages/datasets/search.vue b/pages/datasets/search.vue index 2639030d..e57f3fd2 100644 --- a/pages/datasets/search.vue +++ b/pages/datasets/search.vue @@ -11,43 +11,18 @@ -
-
-

- {{ $t('Jeux de données') }} -

-

- {{ $t('Rechercher parmi les {count} jeux de données sur {site}', { - count: site.metrics.datasets, - site: config.public.title, - }) }} -

-
- - - - - - RSS - -
+

+ {{ $t('Jeux de données') }} +

+

+ {{ $t('Rechercher parmi les {count} jeux de données sur {site}', { + count: site.metrics.datasets, + site: config.public.title, + }) }} +

@@ -64,12 +39,5 @@ useSeoMeta({ const config = useRuntimeConfig() -function openRss() { - const searchParams = window.location.search - const baseUrl = `${config.public.apiBase}/api/1/datasets/recent.atom` - const url = searchParams ? `${baseUrl}${searchParams}` : baseUrl - window.open(url, '_blank') -} - const { data: site } = await useAPI('/api/1/site/') From 870bdc812021dbcb044741b8a095dc8c72330ce7 Mon Sep 17 00:00:00 2001 From: Nicolas KEMPF Date: Tue, 6 Jan 2026 15:35:12 +0100 Subject: [PATCH 3/3] Update SearchPage.vue --- components/Datasets/SearchPage.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/Datasets/SearchPage.vue b/components/Datasets/SearchPage.vue index 155f9e56..555eb5b9 100644 --- a/components/Datasets/SearchPage.vue +++ b/components/Datasets/SearchPage.vue @@ -327,10 +327,10 @@ const params = useUrlSearchParams('history', { removeFalsyValues: true, }) -const nonFalsyParams = computed(() => { +const nonFalsyParams = computed(() => { const filteredParams = Object.entries(toValue(params)).filter(([_k, v]) => v) const propsParams = props.organization ? { organization: props.organization.id } : {} - return { ...propsParams, ...Object.fromEntries(filteredParams), page_size: pageSize } + return { ...propsParams, ...Object.fromEntries(filteredParams) as DatasetSearchParams, page_size: pageSize.toFixed(0) } }) const atomFeedUrl = computed(() => {