@datagouv/components-next 1.0.2-dev.4 → 1.0.2-dev.41
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-BAokThtJ.js +30 -0
- package/dist/JsonPreview.client-DGiaDxVv.js +40 -0
- package/dist/{MapContainer.client-DjjvdKBp.js → MapContainer.client-BKGsAP0Y.js} +35 -38
- package/dist/{PdfPreview.client-CsvKU0Aq.js → PdfPreview.client-CGjP5ZYb.js} +822 -865
- package/dist/{Pmtiles.client-uqg1fwOl.js → Pmtiles.client-C1I7pwT5.js} +574 -579
- package/dist/PreviewWrapper.vue_vue_type_script_setup_true_lang-BlcvVwW8.js +61 -0
- package/dist/Swagger.client-U7ZDVUHL.js +4 -0
- package/dist/XmlPreview.client-CHUVVEH6.js +34 -0
- package/dist/components-next.css +3 -3
- package/dist/components-next.js +83 -86
- package/dist/components.css +1 -1
- package/dist/{index-PMeuFwWj.js → index-CzClB3i0.js} +1 -1
- package/dist/{main-ByqZlhiZ.js → main-CF7lWk6R.js} +31224 -30474
- package/dist/{vue3-xml-viewer.common-DFrGHXJC.js → vue3-xml-viewer.common-CAwAbUJl.js} +1 -1
- package/package.json +10 -8
- package/src/components/ActivityList/ActivityList.vue +0 -2
- package/src/components/Form/SearchableSelect.vue +2 -1
- package/src/components/Pagination.vue +8 -5
- package/src/components/ReadMore.vue +1 -1
- package/src/components/ResourceAccordion/Datafair.client.vue +4 -10
- package/src/components/ResourceAccordion/JsonPreview.client.vue +23 -121
- package/src/components/ResourceAccordion/MapContainer.client.vue +7 -11
- package/src/components/ResourceAccordion/Metadata.vue +1 -2
- package/src/components/ResourceAccordion/PdfPreview.client.vue +24 -103
- package/src/components/ResourceAccordion/Pmtiles.client.vue +5 -10
- package/src/components/ResourceAccordion/Preview.vue +6 -11
- package/src/components/ResourceAccordion/PreviewLoader.vue +1 -2
- package/src/components/ResourceAccordion/PreviewUnavailable.vue +22 -0
- package/src/components/ResourceAccordion/PreviewWrapper.vue +82 -0
- package/src/components/ResourceAccordion/ResourceAccordion.vue +1 -2
- package/src/components/ResourceAccordion/XmlPreview.client.vue +16 -115
- package/src/components/ResourceExplorer/ResourceExplorer.vue +21 -10
- package/src/components/ResourceExplorer/ResourceExplorerViewer.vue +24 -3
- package/src/components/Search/GlobalSearch.vue +29 -4
- package/src/composables/useResourceCapabilities.ts +1 -1
- package/src/config.ts +2 -0
- package/src/functions/datasets.ts +0 -17
- package/src/functions/resources.ts +56 -1
- package/src/functions/tabularApi.ts +7 -84
- package/src/main.ts +3 -24
- package/src/types/dataservices.ts +2 -0
- package/src/types/organizations.ts +1 -1
- package/src/types/pages.ts +0 -5
- package/src/types/posts.ts +2 -2
- package/src/types/reports.ts +3 -0
- package/src/types/search.ts +26 -1
- package/src/types/site.ts +5 -3
- package/src/types/users.ts +0 -1
- package/dist/Datafair.client-c1cUKkQR.js +0 -35
- package/dist/JsonPreview.client-CAs9XTCX.js +0 -87
- package/dist/Swagger.client-BGrkka3l.js +0 -4
- package/dist/XmlPreview.client-BWbKzLte.js +0 -79
- package/src/components/Chart/ChartViewer.vue +0 -152
- package/src/components/Chart/ChartViewerWrapper.vue +0 -194
- package/src/functions/pagination.ts +0 -9
- package/src/types/visualizations.ts +0 -84
- /package/assets/illustrations/{_microscope.svg → microscope.svg} +0 -0
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<VChart
|
|
3
|
-
class="w-full min-h-96"
|
|
4
|
-
:option="echartsOption"
|
|
5
|
-
autoresize
|
|
6
|
-
/>
|
|
7
|
-
</template>
|
|
8
|
-
|
|
9
|
-
<script setup lang="ts">
|
|
10
|
-
import { format, use, type ComposeOption } from 'echarts/core'
|
|
11
|
-
import { CanvasRenderer } from 'echarts/renderers'
|
|
12
|
-
import { LineChart, BarChart, type BarSeriesOption, type LineSeriesOption } from 'echarts/charts'
|
|
13
|
-
import { TitleComponent, TooltipComponent, LegendComponent, GridComponent, DatasetComponent } from 'echarts/components'
|
|
14
|
-
import VChart from 'vue-echarts'
|
|
15
|
-
import { computed } from 'vue'
|
|
16
|
-
import { summarize } from '../../functions/helpers'
|
|
17
|
-
import type { Chart, DataSeries, XAxis, YAxis, ChartForm, XAxisForm } from '../../types/visualizations'
|
|
18
|
-
|
|
19
|
-
use([CanvasRenderer, LineChart, BarChart, TitleComponent, TooltipComponent, LegendComponent, GridComponent, DatasetComponent])
|
|
20
|
-
|
|
21
|
-
const props = defineProps<{
|
|
22
|
-
chart: Chart | ChartForm
|
|
23
|
-
series: {
|
|
24
|
-
data: Record<string, Array<Record<string, unknown>>>
|
|
25
|
-
columns: Record<string, Array<string>>
|
|
26
|
-
}
|
|
27
|
-
}>()
|
|
28
|
-
|
|
29
|
-
function mapSeriesType(type: DataSeries['type']): 'line' | 'bar' {
|
|
30
|
-
return (type ?? 'line') === 'histogram' ? 'bar' : 'line'
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function mapXAxisType(xAxis: XAxis | XAxisForm): 'category' | 'value' {
|
|
34
|
-
if (!xAxis) return 'category'
|
|
35
|
-
return (xAxis.type ?? 'discrete') === 'continuous' ? 'value' : 'category'
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function buildYAxisFormatter(yAxis: YAxis): ((value: number) => string) | undefined {
|
|
39
|
-
return (value: number) => {
|
|
40
|
-
const v = summarize(value)
|
|
41
|
-
if (!yAxis.unit) return v
|
|
42
|
-
if (yAxis.unit_position === 'prefix') return `${yAxis.unit} ${v}`
|
|
43
|
-
return `${v} ${yAxis.unit}`
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const echartsOption = computed(() => {
|
|
48
|
-
const seriesCount = props.chart.series.length
|
|
49
|
-
if (!props.chart.series || seriesCount === 0) return
|
|
50
|
-
|
|
51
|
-
// Create series configuration with data mapping
|
|
52
|
-
const seriesData = props.chart.series.map((s) => {
|
|
53
|
-
const xColumn = s.column_x_name_override ?? props.chart.x_axis.column_x
|
|
54
|
-
const yColumn = s.aggregate_y ? `${s.column_y}__${s.aggregate_y}` : s.column_y
|
|
55
|
-
const resourceId = s.resource_id
|
|
56
|
-
const seriesType = s.type
|
|
57
|
-
|
|
58
|
-
if (!xColumn || !yColumn || !resourceId || !seriesType || !props.series.data[resourceId] || !props.series.columns[resourceId]) {
|
|
59
|
-
return null
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// Sort data before passing to ECharts to avoid transform issues
|
|
63
|
-
const sortedData = [...props.series.data[resourceId]]
|
|
64
|
-
const sortBy = props.chart.x_axis.sort_x_by
|
|
65
|
-
const sortDirection = props.chart.x_axis.sort_x_direction ?? 'asc'
|
|
66
|
-
|
|
67
|
-
if (sortBy && sortDirection && props.chart.x_axis.column_x) {
|
|
68
|
-
const sortKey = sortBy === 'axis_x' ? xColumn : yColumn
|
|
69
|
-
sortedData.sort((a, b) => {
|
|
70
|
-
const valA = a[sortKey] as number
|
|
71
|
-
const valB = b[sortKey] as number
|
|
72
|
-
if (valA < valB) return sortDirection === 'asc' ? -1 : 1
|
|
73
|
-
if (valA > valB) return sortDirection === 'asc' ? 1 : -1
|
|
74
|
-
return 0
|
|
75
|
-
})
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
return {
|
|
79
|
-
series: {
|
|
80
|
-
type: mapSeriesType(seriesType),
|
|
81
|
-
dimensions: s.aggregate_y ? [xColumn, yColumn] : props.series.columns[resourceId],
|
|
82
|
-
name: s.column_y,
|
|
83
|
-
encode: {
|
|
84
|
-
x: xColumn,
|
|
85
|
-
y: yColumn,
|
|
86
|
-
},
|
|
87
|
-
} as LineSeriesOption | BarSeriesOption,
|
|
88
|
-
data: {
|
|
89
|
-
source: sortedData,
|
|
90
|
-
dimensions: s.aggregate_y ? [xColumn, yColumn] : props.series.columns[resourceId],
|
|
91
|
-
},
|
|
92
|
-
}
|
|
93
|
-
}).filter(Boolean).reduce((acc: { series: Array<LineSeriesOption | BarSeriesOption>, data: Array<Record<string, unknown>> }, curr) => {
|
|
94
|
-
if (curr) {
|
|
95
|
-
acc.series.push(curr.series)
|
|
96
|
-
acc.data.push(curr.data)
|
|
97
|
-
}
|
|
98
|
-
return acc
|
|
99
|
-
}, {
|
|
100
|
-
series: [],
|
|
101
|
-
data: [],
|
|
102
|
-
})
|
|
103
|
-
|
|
104
|
-
return {
|
|
105
|
-
dataset: [...seriesData.data],
|
|
106
|
-
title: {
|
|
107
|
-
text: props.chart.title,
|
|
108
|
-
left: 'center',
|
|
109
|
-
},
|
|
110
|
-
tooltip: {
|
|
111
|
-
trigger: 'axis' as const,
|
|
112
|
-
formatter: (params: Array<{ value: Record<string, unknown>, axisValueLabel: string, seriesName: string }>) => {
|
|
113
|
-
let tooltip = ''
|
|
114
|
-
for (const param of params) {
|
|
115
|
-
const keys = Object.keys(param.value)
|
|
116
|
-
const col = keys.find(key => key.startsWith(param.seriesName))!
|
|
117
|
-
const formatter = new Intl.NumberFormat('fr-FR')
|
|
118
|
-
tooltip += `${format.encodeHTML(param.axisValueLabel)}: <strong>${formatter.format(Number(param.value[col]))}</strong><br>`
|
|
119
|
-
}
|
|
120
|
-
return tooltip
|
|
121
|
-
},
|
|
122
|
-
},
|
|
123
|
-
legend: {
|
|
124
|
-
bottom: 0,
|
|
125
|
-
},
|
|
126
|
-
grid: {
|
|
127
|
-
top: 60,
|
|
128
|
-
bottom: 40,
|
|
129
|
-
left: 20,
|
|
130
|
-
right: 20,
|
|
131
|
-
containLabel: true,
|
|
132
|
-
},
|
|
133
|
-
xAxis: {
|
|
134
|
-
type: mapXAxisType(props.chart.x_axis),
|
|
135
|
-
name: (props.chart.x_axis as XAxis).column_x,
|
|
136
|
-
},
|
|
137
|
-
yAxis: {
|
|
138
|
-
type: 'value' as const,
|
|
139
|
-
name: props.chart.y_axis.label ?? undefined,
|
|
140
|
-
min: props.chart.y_axis.min ?? undefined,
|
|
141
|
-
max: props.chart.y_axis.max ?? undefined,
|
|
142
|
-
axisLabel: {
|
|
143
|
-
formatter: buildYAxisFormatter(props.chart.y_axis),
|
|
144
|
-
},
|
|
145
|
-
},
|
|
146
|
-
series: seriesData.series,
|
|
147
|
-
} satisfies ComposeOption<
|
|
148
|
-
| BarSeriesOption
|
|
149
|
-
| LineSeriesOption
|
|
150
|
-
>
|
|
151
|
-
})
|
|
152
|
-
</script>
|
|
@@ -1,194 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<LoadingBlock
|
|
3
|
-
:status="status"
|
|
4
|
-
:data="series"
|
|
5
|
-
>
|
|
6
|
-
<template #default="{ data }">
|
|
7
|
-
<ChartViewer
|
|
8
|
-
:chart="chart"
|
|
9
|
-
:series="data"
|
|
10
|
-
/>
|
|
11
|
-
</template>
|
|
12
|
-
<template #error>
|
|
13
|
-
<div class="text-center py-8 text-gray-500">
|
|
14
|
-
Une erreur est survenue lors du chargement des données du graphique.
|
|
15
|
-
</div>
|
|
16
|
-
</template>
|
|
17
|
-
</LoadingBlock>
|
|
18
|
-
</template>
|
|
19
|
-
|
|
20
|
-
<script setup lang="ts">
|
|
21
|
-
import { reactive, ref, watch } from 'vue'
|
|
22
|
-
import ChartViewer from './ChartViewer.vue'
|
|
23
|
-
import LoadingBlock from '../../components/LoadingBlock.vue'
|
|
24
|
-
import { useComponentsConfig } from '../../config'
|
|
25
|
-
import { fetchTabularData, useGetProfile, type TabularDataResponse, type TabularProfileResponse } from '../../functions/tabularApi'
|
|
26
|
-
import type { Chart, ChartForm } from '../../types/visualizations'
|
|
27
|
-
|
|
28
|
-
const chart = defineModel<Chart | ChartForm>({ required: true })
|
|
29
|
-
|
|
30
|
-
const emit = defineEmits<{
|
|
31
|
-
columns: [columns: Record<string, Array<string>>]
|
|
32
|
-
}>()
|
|
33
|
-
|
|
34
|
-
const config = useComponentsConfig()
|
|
35
|
-
const getProfile = useGetProfile()
|
|
36
|
-
|
|
37
|
-
// Loading and error states
|
|
38
|
-
const status = ref<'idle' | 'pending' | 'success' | 'error'>('idle')
|
|
39
|
-
const error = ref<Error | null>(null)
|
|
40
|
-
|
|
41
|
-
// Dataset source for the chart
|
|
42
|
-
const series = reactive<{
|
|
43
|
-
data: Record<string, Array<Record<string, unknown>>>
|
|
44
|
-
columns: Record<string, Array<string>>
|
|
45
|
-
}>({
|
|
46
|
-
data: {},
|
|
47
|
-
columns: {},
|
|
48
|
-
})
|
|
49
|
-
|
|
50
|
-
async function fetchSeriesProfile() {
|
|
51
|
-
status.value = 'pending'
|
|
52
|
-
error.value = null
|
|
53
|
-
|
|
54
|
-
try {
|
|
55
|
-
if (chart.value.series.length === 0) {
|
|
56
|
-
status.value = 'success'
|
|
57
|
-
series.data = {}
|
|
58
|
-
series.columns = {}
|
|
59
|
-
return
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// Fetch data for all series in parallel
|
|
63
|
-
const fetchPromises = chart.value.series.map(async (serie) => {
|
|
64
|
-
if (!serie.resource_id) return
|
|
65
|
-
return {
|
|
66
|
-
id: serie.resource_id,
|
|
67
|
-
profile: await getProfile(serie.resource_id),
|
|
68
|
-
}
|
|
69
|
-
}).filter(Boolean) as Array<Promise<{
|
|
70
|
-
id: string
|
|
71
|
-
profile: TabularProfileResponse
|
|
72
|
-
}>>
|
|
73
|
-
|
|
74
|
-
const results = (await Promise.allSettled(fetchPromises))
|
|
75
|
-
.filter(r => r.status === 'fulfilled')
|
|
76
|
-
.map(r => r.value)
|
|
77
|
-
series.columns = Object.fromEntries(results.map(result => [
|
|
78
|
-
result.id,
|
|
79
|
-
result.profile.profile.header,
|
|
80
|
-
]))
|
|
81
|
-
if (results.length > 0) {
|
|
82
|
-
const columns = results[0]?.profile.profile.header ?? []
|
|
83
|
-
const firstColumn = columns.filter(c => c !== '__id')[0]
|
|
84
|
-
if (!chart.value.x_axis.column_x && firstColumn) {
|
|
85
|
-
chart.value.x_axis.column_x = firstColumn
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
status.value = 'success'
|
|
89
|
-
}
|
|
90
|
-
catch (err) {
|
|
91
|
-
error.value = err instanceof Error ? err : new Error('Failed to fetch series profile')
|
|
92
|
-
status.value = 'error'
|
|
93
|
-
console.log(err)
|
|
94
|
-
series.columns = {}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
async function fetchSeriesData() {
|
|
99
|
-
status.value = 'pending'
|
|
100
|
-
error.value = null
|
|
101
|
-
|
|
102
|
-
try {
|
|
103
|
-
if (chart.value.series.length === 0 || !chart.value.x_axis.column_x) {
|
|
104
|
-
status.value = 'success'
|
|
105
|
-
series.data = {}
|
|
106
|
-
return
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// Fetch data for all series in parallel
|
|
110
|
-
const fetchPromises = chart.value.series.map(async (serie) => {
|
|
111
|
-
const xColumn = serie.column_x_name_override ?? chart.value.x_axis.column_x
|
|
112
|
-
if (!xColumn || !serie.resource_id || !serie.column_y) return
|
|
113
|
-
return {
|
|
114
|
-
id: serie.resource_id,
|
|
115
|
-
profile: await getProfile(serie.resource_id),
|
|
116
|
-
data: await fetchTabularData(config, {
|
|
117
|
-
columns: serie.aggregate_y ? undefined : [xColumn, serie.column_y],
|
|
118
|
-
resourceId: serie.resource_id,
|
|
119
|
-
page: 1,
|
|
120
|
-
pageSize: 100,
|
|
121
|
-
groupBy: xColumn,
|
|
122
|
-
aggregation: serie.column_y && serie.aggregate_y
|
|
123
|
-
? {
|
|
124
|
-
column: serie.column_y,
|
|
125
|
-
type: serie.aggregate_y,
|
|
126
|
-
}
|
|
127
|
-
: undefined,
|
|
128
|
-
}),
|
|
129
|
-
}
|
|
130
|
-
}).filter(Boolean) as Array<Promise<{
|
|
131
|
-
id: string
|
|
132
|
-
data: TabularDataResponse
|
|
133
|
-
}>>
|
|
134
|
-
|
|
135
|
-
const results = (await Promise.allSettled(fetchPromises))
|
|
136
|
-
.filter(r => r.status === 'fulfilled')
|
|
137
|
-
.map(r => r.value)
|
|
138
|
-
// Transform data into echarts format
|
|
139
|
-
series.data = Object.fromEntries(results.map(result => [
|
|
140
|
-
result.id,
|
|
141
|
-
result.data.data,
|
|
142
|
-
]))
|
|
143
|
-
status.value = 'success'
|
|
144
|
-
}
|
|
145
|
-
catch (err) {
|
|
146
|
-
error.value = err instanceof Error ? err : new Error('Failed to fetch series data')
|
|
147
|
-
status.value = 'error'
|
|
148
|
-
series.data = {}
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// Watch for changes in the chart or its series
|
|
153
|
-
watch(() => chart.value.series, async () => {
|
|
154
|
-
await fetchSeriesProfile()
|
|
155
|
-
}, { immediate: true, deep: true })
|
|
156
|
-
|
|
157
|
-
// Watch for changes in the chart or its series
|
|
158
|
-
watch([() => chart.value.series, () => chart.value.x_axis.column_x], async () => {
|
|
159
|
-
await fetchSeriesData()
|
|
160
|
-
}, { immediate: true, deep: true })
|
|
161
|
-
|
|
162
|
-
watch(() => series.columns, () => {
|
|
163
|
-
emit('columns', series.columns)
|
|
164
|
-
})
|
|
165
|
-
|
|
166
|
-
/**
|
|
167
|
-
* Combines data from multiple series into a single echarts dataset source
|
|
168
|
-
*/
|
|
169
|
-
// function combineSeriesData(seriesData: Array<TabularDataResponse | null>): Array<Array<unknown>> {
|
|
170
|
-
// if (!seriesData.length || seriesData.every(data => !data || !data.data || data.data.length === 0)) {
|
|
171
|
-
// return []
|
|
172
|
-
// }
|
|
173
|
-
|
|
174
|
-
// // Get all unique columns from all series
|
|
175
|
-
// const allColumns = Array.from(new Set(seriesData.flatMap(data =>
|
|
176
|
-
// data?.data?.flatMap(Object.keys) || []
|
|
177
|
-
// )))
|
|
178
|
-
|
|
179
|
-
// // Build the source array with headers
|
|
180
|
-
// const source: Array<Array<unknown>> = [allColumns]
|
|
181
|
-
|
|
182
|
-
// // Add data rows - for simplicity, we'll use data from the first series
|
|
183
|
-
// // In a real implementation, you'd want to merge/combine the data appropriately
|
|
184
|
-
// const firstData = seriesData.find(data => data?.data?.length)?.data
|
|
185
|
-
// if (firstData) {
|
|
186
|
-
// firstData.forEach(row => {
|
|
187
|
-
// const rowValues = allColumns.map(column => row[column])
|
|
188
|
-
// source.push(rowValues)
|
|
189
|
-
// })
|
|
190
|
-
// }
|
|
191
|
-
|
|
192
|
-
// return source
|
|
193
|
-
// }
|
|
194
|
-
</script>
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { useRoute } from 'vue-router'
|
|
2
|
-
|
|
3
|
-
export function getLink(page: number): string {
|
|
4
|
-
const route = useRoute()
|
|
5
|
-
const routePath = route.path
|
|
6
|
-
const search = new URLSearchParams(route.query as Record<string, string>)
|
|
7
|
-
search.set('page', page.toFixed(0))
|
|
8
|
-
return `${routePath}?${search.toString()}`
|
|
9
|
-
}
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import type { TabularAggregateType } from '../functions/tabularApi'
|
|
2
|
-
import type { Owned, OwnedWithId } from './owned'
|
|
3
|
-
|
|
4
|
-
export type FilterCondition = 'equal' | 'greater'
|
|
5
|
-
|
|
6
|
-
export type Filter = {
|
|
7
|
-
column: string
|
|
8
|
-
condition: FilterCondition
|
|
9
|
-
value?: string
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export type AndFilters = {
|
|
13
|
-
filters: Array<Filter | AndFilters>
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export type GenericFilter = Filter | AndFilters
|
|
17
|
-
|
|
18
|
-
export type XAxisType = 'discrete' | 'continuous'
|
|
19
|
-
|
|
20
|
-
export type XAxisSortBy = 'axis_x' | 'axis_y'
|
|
21
|
-
|
|
22
|
-
export type SortDirection = 'asc' | 'desc'
|
|
23
|
-
|
|
24
|
-
export type XAxis = {
|
|
25
|
-
column_x: string
|
|
26
|
-
sort_x_by: XAxisSortBy | null
|
|
27
|
-
sort_x_direction: SortDirection | null
|
|
28
|
-
type: XAxisType
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export type XAxisForm = Omit<XAxis, 'sort_x_by'> & { sort_x_by: XAxisSortBy | '' | null }
|
|
32
|
-
|
|
33
|
-
export type UnitPosition = 'prefix' | 'suffix'
|
|
34
|
-
|
|
35
|
-
export type YAxis = {
|
|
36
|
-
min: number | null
|
|
37
|
-
max: number | null
|
|
38
|
-
label: string | null
|
|
39
|
-
unit: string | null
|
|
40
|
-
unit_position: UnitPosition | null
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export type DataSeriesType = 'line' | 'histogram'
|
|
44
|
-
|
|
45
|
-
export type DataSeries = {
|
|
46
|
-
type: DataSeriesType
|
|
47
|
-
column_y: string
|
|
48
|
-
aggregate_y: TabularAggregateType | null
|
|
49
|
-
resource_id: string
|
|
50
|
-
column_x_name_override: string | null
|
|
51
|
-
filters: GenericFilter | null
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// Type for form where aggregate_y can be empty string for select binding
|
|
55
|
-
export type DataSeriesForm = Omit<DataSeries, 'aggregate_y'> & { aggregate_y: TabularAggregateType | '' | null }
|
|
56
|
-
|
|
57
|
-
export type Chart = Owned & {
|
|
58
|
-
id: string
|
|
59
|
-
title: string
|
|
60
|
-
slug: string
|
|
61
|
-
description: string
|
|
62
|
-
private: boolean
|
|
63
|
-
created_at: string
|
|
64
|
-
last_modified: string
|
|
65
|
-
deleted_at: string | null
|
|
66
|
-
uri: string
|
|
67
|
-
page: string
|
|
68
|
-
x_axis: XAxis
|
|
69
|
-
y_axis: YAxis
|
|
70
|
-
series: Array<DataSeries>
|
|
71
|
-
extras: Record<string, unknown>
|
|
72
|
-
permissions: { delete: boolean, edit: boolean, read: boolean }
|
|
73
|
-
metrics: {
|
|
74
|
-
views: number
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export type ChartForApi = OwnedWithId & Pick<Chart, 'title' | 'description' | 'private' | 'x_axis' | 'y_axis' | 'series' | 'extras'>
|
|
79
|
-
|
|
80
|
-
export type ChartForm = Omit<ChartForApi, 'x_axis' | 'series' | 'owner' | 'organization'> & {
|
|
81
|
-
owned: OwnedWithId
|
|
82
|
-
x_axis: XAxisForm
|
|
83
|
-
series: Array<DataSeriesForm>
|
|
84
|
-
}
|
|
File without changes
|