@datagouv/components-next 1.0.2-dev.221 → 1.0.2-dev.222

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-HU94LBny.js";
1
+ import { g as Ke } from "./main-DAxkqaSe.js";
2
2
  import We from "vue";
3
3
  function Fe(I, 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.221",
3
+ "version": "1.0.2-dev.222",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "engines": {
@@ -4,7 +4,8 @@
4
4
  icon-only
5
5
  :icon="RiPencilLine"
6
6
  color="warning"
7
- :title="t('Éditer le fichier')"
7
+ :disabled="!!disabledReason"
8
+ :title="disabledReason ?? t('Éditer le fichier')"
8
9
  data-testid="edit-button"
9
10
  />
10
11
  </template>
@@ -19,10 +20,12 @@ type Props = {
19
20
  datasetId: string
20
21
  isCommunityResource?: boolean
21
22
  resourceId: string
23
+ disabledReason?: string | null
22
24
  }
23
25
 
24
26
  const props = withDefaults(defineProps<Props>(), {
25
27
  isCommunityResource: false,
28
+ disabledReason: null,
26
29
  })
27
30
 
28
31
  const { t } = useTranslation()
@@ -173,6 +173,7 @@
173
173
  :dataset-id="dataset.id"
174
174
  :resource-id="resource.id"
175
175
  :is-community-resource="isCommunityResource"
176
+ :disabled-reason="editDisabledReason"
176
177
  size="xs"
177
178
  />
178
179
  </p>
@@ -327,7 +328,7 @@ import { trackEvent } from '../../functions/matomo'
327
328
  import CopyButton from '../CopyButton.vue'
328
329
  import { useComponentsConfig } from '../../config'
329
330
  import { getOwnerName } from '../../functions/owned'
330
- import { getResourceFormatIcon, getResourceTitleId, detectOgcService, getResourceFilesize, isImagePreviewFormat, resolveResourceExternalUrl } from '../../functions/resources'
331
+ import { getResourceFormatIcon, getResourceTitleId, detectOgcService, getResourceFilesize, isGeopfSynced, isImagePreviewFormat, resolveResourceExternalUrl } from '../../functions/resources'
331
332
  import BrandedButton from '../BrandedButton.vue'
332
333
  import { useTranslation } from '../../composables/useTranslation'
333
334
  import { useHasTabularData } from '../../composables/useHasTabularData'
@@ -384,6 +385,10 @@ const hasPmtiles = computed(() => {
384
385
  return props.resource.extras['analysis:parsing:pmtiles_url'] || props.resource.format === 'pmtiles'
385
386
  })
386
387
 
388
+ const editDisabledReason = computed(() => {
389
+ return isGeopfSynced(props.resource) ? t('Vous ne pouvez pas modifier cette ressource car elle est synchronisée avec cartes.gouv.fr') : null
390
+ })
391
+
387
392
  const hasDatafairPreview = computed(() => {
388
393
  // Checks if there are the corresponding extras for a datafair preview.
389
394
  // Limited only to datasets published by certified organizations since it will load an iframe.
@@ -80,7 +80,7 @@ import {
80
80
  } from '@remixicon/vue'
81
81
  import { toast } from 'vue-sonner'
82
82
  import { useTranslation } from '../../composables/useTranslation'
83
- import { buildCellValueFilter, buildTypeConfig } from '../../functions/tabular'
83
+ import { buildTypeConfig, toIsoDay } from '../../functions/tabular'
84
84
  import ClientOnly from '../ClientOnly.vue'
85
85
  import type { ColumnType, ColumnFilters } from './types'
86
86
 
@@ -128,10 +128,36 @@ function close() {
128
128
 
129
129
  function filterByValue() {
130
130
  if (!cell.value) return
131
+ const val = String(cell.value.value ?? '')
131
132
  const col = cell.value.column
132
- filters.value = {
133
- ...filters.value,
134
- [col]: buildCellValueFilter(cell.value.columnType, cell.value.value, filters.value[col] ?? {}),
133
+ const existing = filters.value[col] ?? {}
134
+ // A date goes through the same `date` filter the column panel writes, so the
135
+ // calendar opens on the day that was clicked instead of on an empty month.
136
+ if (cell.value.columnType === 'date') {
137
+ const day = toIsoDay(cell.value.value)
138
+ if (day) {
139
+ filters.value = { ...filters.value, [col]: { ...existing, date: { operator: 'is', start: day } } }
140
+ }
141
+ // An empty cell has no day to select: filtering on the missing values is
142
+ // what "this value" means there, and the panel shows it as such.
143
+ else if (cell.value.value == null || cell.value.value === '') {
144
+ filters.value = { ...filters.value, [col]: { ...existing, null: 'only' } }
145
+ }
146
+ }
147
+ else if (cell.value.columnType === 'categorical' || cell.value.columnType === 'text' || cell.value.columnType === 'year') {
148
+ const current = existing.in ?? []
149
+ if (!current.includes(val)) {
150
+ filters.value = { ...filters.value, [col]: { ...existing, in: [...current, val] } }
151
+ }
152
+ }
153
+ else if (cell.value.columnType === 'number') {
154
+ const num = Number(cell.value.value)
155
+ if (Number.isFinite(num)) {
156
+ filters.value = { ...filters.value, [col]: { ...existing, min: num, max: num } }
157
+ }
158
+ }
159
+ else if (cell.value.columnType === 'boolean') {
160
+ filters.value = { ...filters.value, [col]: { ...existing, exact: val } }
135
161
  }
136
162
  close()
137
163
  }
@@ -179,6 +179,10 @@ export function getResourceExternalUrl(dataset: Dataset | DatasetV2 | Omit<Datas
179
179
  return `${dataset.page}${isCommunityResource(resource) ? '/community-resources' : ''}?resource_id=${resource.id}`
180
180
  }
181
181
 
182
+ export function isGeopfSynced(resource: Resource | CommunityResource): boolean {
183
+ return resource.geopf?.push_status != null || typeof resource.geopf?.offering_id === 'string'
184
+ }
185
+
182
186
  export function resolveResourceExternalUrl<R extends Resource | CommunityResource>(
183
187
  dataset: Dataset | DatasetV2 | Omit<Dataset, 'resources' | 'community_resources'>,
184
188
  resource: R,
@@ -93,39 +93,6 @@ export function buildDateFilterParams(column: string, filter: DateFilter): Recor
93
93
  return params
94
94
  }
95
95
 
96
- /**
97
- * The filter "filter by this value" sets on a column for the cell that was
98
- * clicked, merged into the filters already set on that column.
99
- *
100
- * An empty cell holds no value to match on: whatever the column type, filtering
101
- * on the missing values is what "this value" means there — and it is the filter
102
- * the column panel offers for them.
103
- */
104
- export function buildCellValueFilter(columnType: ColumnType, value: unknown, existing: ColumnFilters): ColumnFilters {
105
- if (value == null || value === '') return { ...existing, null: 'only' }
106
- switch (columnType) {
107
- // A date goes through the same `date` filter the column panel writes, so the
108
- // calendar opens on the day that was clicked instead of on an empty month.
109
- case 'date': {
110
- const day = toIsoDay(value)
111
- return day ? { ...existing, date: { operator: 'is', start: day } } : existing
112
- }
113
- case 'number': {
114
- const num = Number(value)
115
- return Number.isFinite(num) ? { ...existing, min: num, max: num } : existing
116
- }
117
- case 'boolean':
118
- return { ...existing, exact: String(value) }
119
- case 'categorical':
120
- case 'text':
121
- case 'year': {
122
- const val = String(value)
123
- const selected = existing.in ?? []
124
- return selected.includes(val) ? existing : { ...existing, in: [...selected, val] }
125
- }
126
- }
127
- }
128
-
129
96
  export type TypeDisplay = {
130
97
  icon: Component
131
98
  label: string
@@ -12,6 +12,11 @@ export type FileResourceFileType = 'file'
12
12
 
13
13
  export type ResourceFileType = RemoteResourceFileType | FileResourceFileType
14
14
 
15
+ export type GeopfResourceMetadata = {
16
+ push_status?: 'pending' | 'done' | 'error' | 'timeout' | null
17
+ offering_id?: string | null
18
+ }
19
+
15
20
  export type Resource = {
16
21
  id: string
17
22
  title: string
@@ -22,6 +27,7 @@ export type Resource = {
22
27
  extras: Record<string, unknown>
23
28
  metrics: { views: number }
24
29
  harvest: Harvest
30
+ geopf: GeopfResourceMetadata | null
25
31
  filesize: number | null
26
32
  filetype: ResourceFileType
27
33
  format: string