@datagouv/components-next 1.0.2-dev.221 → 1.0.2-dev.223
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.
- package/dist/{Datafair.client-BQzHk6je.js → Datafair.client-Df0Q4FOf.js} +1 -1
- package/dist/{ImagePreview.client-Cld46eGd.js → ImagePreview.client-C1nnlB26.js} +1 -1
- package/dist/{JsonPreview.client-BXURFXgZ.js → JsonPreview.client-C50x2wrd.js} +2 -2
- package/dist/{MapContainer.client-Dc4DB5l3.js → MapContainer.client-B5GhGdk1.js} +2 -2
- package/dist/{PdfPreview.client-llrHD630.js → PdfPreview.client-95sxmcl7.js} +2 -2
- package/dist/{Pmtiles.client-DFP8oK6A.js → Pmtiles.client-B7ItZ-PQ.js} +1 -1
- package/dist/{PreviewWrapper.vue_vue_type_script_setup_true_lang-5yjTI07B.js → PreviewWrapper.vue_vue_type_script_setup_true_lang-D07VQ55G.js} +1 -1
- package/dist/{XmlPreview.client-C3OEOuUI.js → XmlPreview.client-BWlVL8M8.js} +3 -3
- package/dist/components-next.js +115 -113
- package/dist/{index-5j8dwm1I.js → index-AG-SbiCt.js} +1 -1
- package/dist/{leaflet-src-CtezwTk4.js → leaflet-src-xwWnVeIm.js} +1 -1
- package/dist/{main-HU94LBny.js → main-BzR7HPLe.js} +12788 -12766
- package/dist/{vue3-xml-viewer.common-C1QomD0e.js → vue3-xml-viewer.common-DCzadi-B.js} +1 -1
- package/package.json +1 -1
- package/src/functions/charts.ts +2 -2
- package/src/functions/tabular.ts +9 -8
- package/src/functions/tabularApi.ts +52 -25
- package/src/main.ts +2 -1
- package/src/types/visualizations.ts +6 -1
package/package.json
CHANGED
package/src/functions/charts.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { Chart, ChartForm, ChartForApi,
|
|
1
|
+
import type { Chart, ChartForm, ChartForApi, GenericFilter, ColumnDefinition } from '../types/visualizations'
|
|
2
2
|
import type { ColumnType, TabularProfile } from '../components/TabularExplorer/types'
|
|
3
3
|
import { resolveColumnType } from './tabular'
|
|
4
4
|
|
|
5
5
|
export function toChartForm(chart: Chart) {
|
|
6
|
-
const seriesFilter = chart.series[0]?.filters
|
|
6
|
+
const seriesFilter: GenericFilter | null = chart.series[0]?.filters ?? null
|
|
7
7
|
|
|
8
8
|
return {
|
|
9
9
|
title: chart.title,
|
package/src/functions/tabular.ts
CHANGED
|
@@ -257,15 +257,16 @@ const FALSY_VALUES = ['false', '0', 'non', 'no']
|
|
|
257
257
|
|
|
258
258
|
// `encodeURIComponent` leaves `.`, `(` and `)` as-is, but they are the operator
|
|
259
259
|
// separator and the delimiters of the API's `or(...)` grammar: a search value
|
|
260
|
-
// containing one makes the parser reject the whole query with a 400.
|
|
261
|
-
//
|
|
262
|
-
//
|
|
263
|
-
//
|
|
264
|
-
|
|
260
|
+
// containing one makes the parser reject the whole query with a 400.
|
|
261
|
+
// The API percent-decodes the query string once before running the grammar
|
|
262
|
+
// parser, then percent-decodes the parsed value: grammar-significant characters
|
|
263
|
+
// must therefore be sent double-encoded (`%252E`) so the first decode leaves
|
|
264
|
+
// them escaped (`%2E`) for the parser to unquote after parsing.
|
|
265
|
+
export function encodeConditionValue(value: string): string {
|
|
265
266
|
return encodeURIComponent(value)
|
|
266
|
-
.replace(/\./g, '%
|
|
267
|
-
.replace(/\(/g, '%
|
|
268
|
-
.replace(/\)/g, '%
|
|
267
|
+
.replace(/\./g, '%252E')
|
|
268
|
+
.replace(/\(/g, '%2528')
|
|
269
|
+
.replace(/\)/g, '%2529')
|
|
269
270
|
}
|
|
270
271
|
|
|
271
272
|
// A decimal literal, not `Number()`: the API compares against a number column,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ofetch } from 'ofetch'
|
|
2
2
|
import { useComponentsConfig, type PluginConfig } from '../config'
|
|
3
|
-
import
|
|
3
|
+
import { encodeConditionValue } from './tabular'
|
|
4
|
+
import type { AndFilters, Filter, GenericFilter, OrFilters } from '../types/visualizations'
|
|
4
5
|
import type { SortConfig, TabularProfileResponse } from '../components/TabularExplorer/types'
|
|
5
6
|
|
|
6
7
|
export type { SortConfig }
|
|
@@ -56,41 +57,67 @@ export async function fetchTabularData(config: PluginConfig, options: FetchTabul
|
|
|
56
57
|
return await ofetch<TabularDataResponse>(url)
|
|
57
58
|
}
|
|
58
59
|
|
|
59
|
-
|
|
60
|
+
/**
|
|
61
|
+
* Serialize a filter tree into tabular-api query params.
|
|
62
|
+
* - `Filter` → `column__condition=value` (ANDed with the other params)
|
|
63
|
+
* - root `AndFilters` → one param per child; `OrFilters` children become `or=(...)` params
|
|
64
|
+
* - root `OrFilters` → a single `or=(...)` param, with `AndFilters` children nested as `and(...)`
|
|
65
|
+
* (nested-condition grammar: `.` instead of `=`, no value for isnull/isnotnull)
|
|
66
|
+
*/
|
|
67
|
+
export function buildFilterQuery(filters: GenericFilter): string {
|
|
60
68
|
const params: Array<string> = []
|
|
61
|
-
if (
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
69
|
+
if (filters._cls === 'Filter') {
|
|
70
|
+
const param = serializeParam(filters)
|
|
71
|
+
if (param) params.push(param)
|
|
72
|
+
}
|
|
73
|
+
else if (filters._cls === 'AndFilters') {
|
|
74
|
+
for (const child of filters.filters) {
|
|
75
|
+
if (child._cls === 'Filter') {
|
|
76
|
+
const param = serializeParam(child)
|
|
77
|
+
if (param) params.push(param)
|
|
65
78
|
}
|
|
66
79
|
else {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
}
|
|
70
|
-
else if (filter.condition === 'is_not_null') {
|
|
71
|
-
params.push(`${encodeURIComponent(filter.column)}__isnotnull`)
|
|
72
|
-
}
|
|
73
|
-
else if (filter.value !== null && filter.value !== undefined && filter.value !== '') {
|
|
74
|
-
params.push(`${encodeURIComponent(filter.column)}__${encodeURIComponent(filter.condition)}=${encodeURIComponent(filter.value)}`)
|
|
75
|
-
}
|
|
80
|
+
// child is an OrFilters group: serializeGroup returns `or(...)`, the param is `or=(...)`
|
|
81
|
+
const nested = serializeGroup(child)
|
|
82
|
+
if (nested) params.push(`or=${nested.slice(2)}`)
|
|
76
83
|
}
|
|
77
84
|
}
|
|
78
85
|
}
|
|
79
86
|
else {
|
|
80
|
-
const
|
|
81
|
-
if (
|
|
82
|
-
params.push(`${encodeURIComponent(filter.column)}__isnull`)
|
|
83
|
-
}
|
|
84
|
-
else if (filter.condition === 'is_not_null') {
|
|
85
|
-
params.push(`${encodeURIComponent(filter.column)}__isnotnull`)
|
|
86
|
-
}
|
|
87
|
-
else if (filter.value !== null && filter.value !== undefined && filter.value !== '') {
|
|
88
|
-
params.push(`${encodeURIComponent(filter.column)}__${encodeURIComponent(filter.condition)}=${encodeURIComponent(filter.value)}`)
|
|
89
|
-
}
|
|
87
|
+
const nested = serializeGroup(filters)
|
|
88
|
+
if (nested) params.push(`or=${nested.slice(2)}`)
|
|
90
89
|
}
|
|
91
90
|
return params.join('&')
|
|
92
91
|
}
|
|
93
92
|
|
|
93
|
+
/** `column__condition=value` param for a top-level (ANDed) filter, null when empty */
|
|
94
|
+
function serializeParam(filter: Filter): string | null {
|
|
95
|
+
const column = encodeURIComponent(filter.column)
|
|
96
|
+
if (filter.condition === 'is_null') return `${column}__isnull`
|
|
97
|
+
if (filter.condition === 'is_not_null') return `${column}__isnotnull`
|
|
98
|
+
if (filter.value === null || filter.value === undefined || filter.value === '') return null
|
|
99
|
+
return `${column}__${encodeURIComponent(filter.condition)}=${encodeURIComponent(filter.value)}`
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** `column__condition.value` condition for the `or(...)` / `and(...)` grammar, null when empty */
|
|
103
|
+
function serializeCondition(filter: Filter): string | null {
|
|
104
|
+
const column = encodeURIComponent(filter.column)
|
|
105
|
+
if (filter.condition === 'is_null') return `${column}__isnull`
|
|
106
|
+
if (filter.condition === 'is_not_null') return `${column}__isnotnull`
|
|
107
|
+
if (filter.value === null || filter.value === undefined || filter.value === '') return null
|
|
108
|
+
return `${column}__${encodeURIComponent(filter.condition)}.${encodeConditionValue(filter.value)}`
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** `or(a,b,...)` / `and(a,b,...)` for the nested-condition grammar, null when empty */
|
|
112
|
+
function serializeGroup(group: AndFilters | OrFilters): string | null {
|
|
113
|
+
const operator = group._cls === 'OrFilters' ? 'or' : 'and'
|
|
114
|
+
const conditions = group.filters
|
|
115
|
+
.map(child => ('filters' in child ? serializeGroup(child) : serializeCondition(child)))
|
|
116
|
+
.filter((condition): condition is string => condition !== null)
|
|
117
|
+
if (conditions.length === 0) return null
|
|
118
|
+
return `${operator}(${conditions.join(',')})`
|
|
119
|
+
}
|
|
120
|
+
|
|
94
121
|
/**
|
|
95
122
|
* Call Tabular-api to get table content
|
|
96
123
|
*/
|
package/src/main.ts
CHANGED
|
@@ -23,7 +23,7 @@ import type { Site } from './types/site'
|
|
|
23
23
|
import type { Weight, WellType } from './types/ui'
|
|
24
24
|
import type { User, UserReference } from './types/users'
|
|
25
25
|
import type { Report, ReportSubject, ReportReason } from './types/reports'
|
|
26
|
-
import type { Chart, ChartForm, ChartForApi, FilterCondition, Filter, AndFilters, GenericFilter, XAxisType, XAxisSortBy, SortDirection, XAxis, XAxisForm, UnitPosition, YAxis, DataSeriesType, DataSeries, DataSeriesForm, CombinedSort, ColumnDefinition, ColumnsDefinition } from './types/visualizations'
|
|
26
|
+
import type { Chart, ChartForm, ChartForApi, FilterCondition, Filter, AndFilters, OrFilters, GenericFilter, XAxisType, XAxisSortBy, SortDirection, XAxis, XAxisForm, UnitPosition, YAxis, DataSeriesType, DataSeries, DataSeriesForm, CombinedSort, ColumnDefinition, ColumnsDefinition } from './types/visualizations'
|
|
27
27
|
import type { ColumnFilters, ColumnType, TabularRow } from './components/TabularExplorer/types'
|
|
28
28
|
import type { GlobalSearchConfig, SearchType, SearchTypeConfig, SortOption, HiddenFilter, BuiltInFilterKey, DatasetSearchConfig, DatasetSearchFilters, DataserviceSearchConfig, DataserviceSearchFilters, ReuseSearchConfig, ReuseSearchFilters, OrganizationSearchConfig, OrganizationSearchFilters, TopicSearchConfig, TopicSearchFilters } from './types/search'
|
|
29
29
|
import { getDefaultDatasetConfig, getDefaultDataserviceConfig, getDefaultReuseConfig, getDefaultOrganizationConfig, getDefaultTopicConfig, getDefaultGlobalSearchConfig, defaultDatasetSortOptions, defaultDataserviceSortOptions, defaultReuseSortOptions, defaultOrganizationSortOptions } from './types/search'
|
|
@@ -272,6 +272,7 @@ export type {
|
|
|
272
272
|
FilterCondition,
|
|
273
273
|
Filter,
|
|
274
274
|
AndFilters,
|
|
275
|
+
OrFilters,
|
|
275
276
|
GenericFilter,
|
|
276
277
|
XAxisType,
|
|
277
278
|
XAxisSortBy,
|
|
@@ -12,10 +12,15 @@ export type Filter = {
|
|
|
12
12
|
|
|
13
13
|
export type AndFilters = {
|
|
14
14
|
_cls: 'AndFilters'
|
|
15
|
+
filters: Array<Filter | OrFilters>
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export type OrFilters = {
|
|
19
|
+
_cls: 'OrFilters'
|
|
15
20
|
filters: Array<Filter | AndFilters>
|
|
16
21
|
}
|
|
17
22
|
|
|
18
|
-
export type GenericFilter = Filter | AndFilters
|
|
23
|
+
export type GenericFilter = Filter | AndFilters | OrFilters
|
|
19
24
|
|
|
20
25
|
export type XAxisType = 'discrete' | 'continuous'
|
|
21
26
|
|