@datagouv/components-next 1.0.2-dev.141 → 1.0.2-dev.143

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import { g as Ke } from "./main-BU6kP4dE.js";
1
+ import { g as Ke } from "./main-BpmTmbJK.js";
2
2
  import We from "vue";
3
3
  function Fe($, K) {
4
4
  for (var V = 0; V < K.length; V++) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@datagouv/components-next",
3
- "version": "1.0.2-dev.141",
3
+ "version": "1.0.2-dev.143",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "engines": {
@@ -68,7 +68,7 @@ import { RiLockLine, RiSubtractLine } from '@remixicon/vue'
68
68
  import { computed } from 'vue'
69
69
  import type { RouteLocationRaw } from 'vue-router'
70
70
  import { useFormatDate } from '../functions/dates'
71
- import type { Reuse } from '../types/reuses'
71
+ import type { Reuse, ReuseV2 } from '../types/reuses'
72
72
  import type { TitleTag } from '../types/ui'
73
73
  import { useTranslation } from '../composables/useTranslation'
74
74
  import AppLink from './AppLink.vue'
@@ -77,7 +77,7 @@ import ReuseDetails from './ReuseDetails.vue'
77
77
  import Placeholder from './Placeholder.vue'
78
78
 
79
79
  const props = withDefaults(defineProps<{
80
- reuse: Reuse
80
+ reuse: Reuse | ReuseV2
81
81
 
82
82
  /**
83
83
  * The reuseUrl is a route location object to allow Vue Router to navigate to the details of a reuse.
@@ -32,11 +32,11 @@
32
32
  import { RiEyeLine, RiStarLine, RiSubtractLine } from '@remixicon/vue'
33
33
  import { useReuseType } from '../composables/useReuseType'
34
34
  import { summarize } from '../functions/helpers'
35
- import type { Reuse } from '../types/reuses'
35
+ import type { Reuse, ReuseV2 } from '../types/reuses'
36
36
  import { useTranslation } from '../composables/useTranslation'
37
37
 
38
38
  const props = defineProps<{
39
- reuse: Reuse
39
+ reuse: Reuse | ReuseV2
40
40
  }>()
41
41
 
42
42
  const { t } = useTranslation()
@@ -60,7 +60,7 @@
60
60
  <script setup lang="ts">
61
61
  import { RiArchiveLine, RiLineChartLine, RiLockLine } from '@remixicon/vue'
62
62
  import type { RouteLocationRaw } from 'vue-router'
63
- import type { Reuse } from '../types/reuses'
63
+ import type { Reuse, ReuseV2 } from '../types/reuses'
64
64
  import { useTranslation } from '../composables/useTranslation'
65
65
  import ReuseDetails from './ReuseDetails.vue'
66
66
  import Placeholder from './Placeholder.vue'
@@ -71,7 +71,7 @@ import ObjectCardShortDescription from './ObjectCardShortDescription.vue'
71
71
  import ObjectCardBadge from './ObjectCardBadge.vue'
72
72
 
73
73
  defineProps<{
74
- reuse: Reuse
74
+ reuse: Reuse | ReuseV2
75
75
  reuseUrl?: RouteLocationRaw
76
76
  organizationUrl?: RouteLocationRaw
77
77
  }>()
@@ -266,7 +266,7 @@
266
266
  name="reuse"
267
267
  :reuse="result"
268
268
  >
269
- <ReuseHorizontalCard :reuse="(result as Reuse)" />
269
+ <ReuseHorizontalCard :reuse="(result as ReuseV2)" />
270
270
  </slot>
271
271
  </template>
272
272
  <template v-else-if="currentTypeConfig?.class === 'organizations'">
@@ -368,7 +368,7 @@ import type { AsyncDataRequestStatus } from '../../functions/api.types'
368
368
  import type { Dataset } from '../../types/datasets'
369
369
  import type { Dataservice } from '../../types/dataservices'
370
370
  import type { Organization } from '../../types/organizations'
371
- import type { Reuse } from '../../types/reuses'
371
+ import type { ReuseV2 } from '../../types/reuses'
372
372
  import type { TopicV2 } from '../../types/topics'
373
373
  import type { GlobalSearchConfig, SearchResponseByClass, SearchType, SortOption, FacetItem } from '../../types/search'
374
374
  import { getDefaultGlobalSearchConfig } from '../../types/search'
@@ -597,6 +597,7 @@
597
597
  <script setup lang="ts">
598
598
  import { computed, nextTick, onUnmounted, ref, watch, useTemplateRef } from 'vue'
599
599
  import { ofetch } from 'ofetch'
600
+ import { useElementSize } from '@vueuse/core'
600
601
  import { flip, shift, autoUpdate, useFloating } from '@floating-ui/vue'
601
602
  import { Dialog, DialogPanel, DialogTitle, Popover, PopoverButton, PopoverPanel, TransitionChild, TransitionRoot } from '@headlessui/vue'
602
603
  import {
@@ -832,18 +833,43 @@ function redistributeColumnWidths() {
832
833
  columnWidths.value = widths
833
834
  }
834
835
 
835
- // Measure once both data and profile are ready (so the <thead> is rendered with
836
- // content-driven natural widths), then distribute.
836
+ // Measure the natural widths once (the <th> must still be auto-sized) and
837
+ // distribute them. No-op once measured or while no column is displayed.
838
+ function ensureMeasured() {
839
+ if (Object.keys(naturalWidths.value).length > 0) return
840
+ if (displayedColumns.value.length === 0) return
841
+ measureNaturalWidths()
842
+ redistributeColumnWidths()
843
+ }
844
+
845
+ // Drive measurement and re-stretch off the container's reactive width
846
+ // (`useElementSize` wraps a ResizeObserver and disconnects it on unmount). The
847
+ // width goes 0 -> N once the table is laid out in the DOM, which is also when
848
+ // the <thead> carries its content-driven natural widths: the first non-zero
849
+ // width measures the stable base, later changes (window resize) only
850
+ // redistribute it.
851
+ const { width: containerWidth } = useElementSize(scrollContainerRef)
852
+
853
+ watch(containerWidth, (width) => {
854
+ if (width === 0) return
855
+ if (Object.keys(naturalWidths.value).length === 0) {
856
+ ensureMeasured()
857
+ }
858
+ else {
859
+ redistributeColumnWidths()
860
+ }
861
+ })
862
+
863
+ // Fallback: re-run once columns appear if they weren't available when the
864
+ // container was first sized (standalone usage where the profile resolves late).
837
865
  watch(
838
866
  () => [tableData.value !== null, displayedColumns.value.length] as const,
839
867
  async ([dataReady, colCount]) => {
840
868
  if (!dataReady || colCount === 0) return
841
869
  if (Object.keys(naturalWidths.value).length > 0) return
842
870
  await nextTick()
843
- measureNaturalWidths()
844
- redistributeColumnWidths()
871
+ ensureMeasured()
845
872
  },
846
- { immediate: true },
847
873
  )
848
874
 
849
875
  // Re-stretch the remaining columns whenever the displayed set changes (columns
@@ -105,14 +105,29 @@ export const getResourceLabel = (type: ResourceType, count?: number) => {
105
105
  }
106
106
  return t('Fichiers principaux')
107
107
  case 'documentation':
108
+ if (typeof count === 'number') {
109
+ return t('Aucun fichier de documentation | 1 fichier de documentation | {n} fichiers de documentation', count)
110
+ }
108
111
  return t('Documentation')
109
112
  case 'update':
113
+ if (typeof count === 'number') {
114
+ return t('Aucune mise à jour | 1 mise à jour | {n} mises à jour', count)
115
+ }
110
116
  return t('Mise à jour')
111
117
  case 'api':
118
+ if (typeof count === 'number') {
119
+ return t('Aucune API | 1 API | {n} API', count)
120
+ }
112
121
  return t('API')
113
122
  case 'code':
123
+ if (typeof count === 'number') {
124
+ return t('Aucun fichier de code source | 1 fichier de code source | {n} fichiers de code source', count)
125
+ }
114
126
  return t('Code source')
115
127
  case 'other':
128
+ if (typeof count === 'number') {
129
+ return t('Aucun autre fichier | 1 autre fichier | {n} autres fichiers', count)
130
+ }
116
131
  return t('Autre')
117
132
  }
118
133
  }
package/src/main.ts CHANGED
@@ -15,7 +15,7 @@ import type { Owned, OwnedWithFullObject, OwnedWithId } from './types/owned'
15
15
  import type { Comment, Thread } from './types/discussions'
16
16
  import type { PageBloc, ContentBloc, BlocWithTitle, DatasetsListBloc, DataservicesListBloc, ReusesListBloc, LinkInBloc, LinksListBloc, MarkdownBloc, AccordionItemBloc, AccordionListBloc, HeroBloc } from './types/pages'
17
17
  import type { Post } from './types/posts'
18
- import type { ReuseReference, NewReuse, Reuse, ReuseTopic, ReuseType } from './types/reuses'
18
+ import type { ReuseReference, NewReuse, Reuse, ReuseV2, ReuseTopic, ReuseType } from './types/reuses'
19
19
  import type { RegisteredSchema, Schema, SchemaDetails, SchemaField, SchemaPath, SchemaPublicationMode, SchemaResponseData, SchemaVersion, ValidataError } from './types/schemas'
20
20
  import type { TopicV2, TopicElement, TopicElementClass, TopicElementRel } from './types/topics'
21
21
  import type { CommunityResource, FileResourceFileType, RemoteResourceFileType, ResourceFileType, ResourceGroup, ResourceType, Resource } from './types/resources'
@@ -228,6 +228,7 @@ export type {
228
228
  ResourceType,
229
229
  ReuseReference,
230
230
  Reuse,
231
+ ReuseV2,
231
232
  ReuseTopic,
232
233
  ReuseType,
233
234
  Schema,
@@ -1,5 +1,5 @@
1
1
  import type { Owned, OwnedWithId } from './owned'
2
- import type { Dataset } from './datasets'
2
+ import type { Dataset, Rel } from './datasets'
3
3
  import type { Badges } from './badges'
4
4
  import type { Dataservice } from './dataservices'
5
5
 
@@ -51,6 +51,17 @@ export type Reuse = BaseReuse & {
51
51
  permissions: { edit: boolean, delete: boolean }
52
52
  }
53
53
 
54
+ /**
55
+ * Lightweight reuse returned by the listing endpoints (`/api/2/reuses/` and
56
+ * `/api/2/reuses/search/`): the `datasets` and `dataservices` reference lists
57
+ * are replaced by links to their respective listing endpoints filtered on this
58
+ * reuse, so that listing reuses does not dereference every linked dataset.
59
+ */
60
+ export type ReuseV2 = Owned & Omit<Reuse, 'datasets' | 'dataservices'> & {
61
+ datasets: Rel
62
+ dataservices: Rel
63
+ }
64
+
54
65
  export type ReuseType = {
55
66
  id: string
56
67
  label: string
@@ -4,7 +4,7 @@ import type { AccessType } from './access_types'
4
4
  import type { Dataset } from './datasets'
5
5
  import type { Dataservice } from './dataservices'
6
6
  import type { Organization } from './organizations'
7
- import type { Reuse } from './reuses'
7
+ import type { ReuseV2 } from './reuses'
8
8
  import type { TopicV2 } from './topics'
9
9
  import type {
10
10
  CERTIFIED,
@@ -372,7 +372,7 @@ export type GlobalSearchConfig = SearchTypeConfig[]
372
372
  export type SearchResponseByClass = {
373
373
  datasets: DatasetSearchResponse<Dataset>
374
374
  dataservices: DataserviceSearchResponse<Dataservice>
375
- reuses: ReuseSearchResponse<Reuse>
375
+ reuses: ReuseSearchResponse<ReuseV2>
376
376
  organizations: OrganizationSearchResponse<Organization>
377
377
  topics: TopicSearchResponse<TopicV2>
378
378
  }