@datagouv/components-next 1.0.2-dev.52 → 1.0.2-dev.53

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,101 +0,0 @@
1
- <template>
2
- <Listbox v-model="model">
3
- <div class="relative min-w-0">
4
- <div
5
- ref="floatingReference"
6
- class="relative w-full cursor-default overflow-hidden bg-white text-left shadow-md focus:outline-none focus-visible:ring-2 focus-visible:ring-white/75 focus-visible:ring-offset-2 focus-visible:ring-offset-teal-300 sm:text-sm"
7
- >
8
- <ListboxButton class="input shadow-input text-sm flex items-center gap-2">
9
- <slot name="button">
10
- <div class="w-full flex items-center justify-between gap-2">
11
- <div
12
- class="truncate"
13
- :class="{ 'text-new-disabled-text': isDisabled(model) }"
14
- >
15
- {{ displayValue(model) }}
16
- </div>
17
- <RiArrowDownSLine class="flex-none size-4 justify-self-end" />
18
- </div>
19
- </slot>
20
- </ListboxButton>
21
- </div>
22
-
23
- <ListboxOptions
24
- ref="popover"
25
- :style="floatingStyles"
26
- class="z-10 mt-1 absolute max-h-60 min-w-80 w-full overflow-auto rounded-md bg-white text-base shadow-lg ring-1 ring-black/5 focus:outline-none sm:text-sm pl-0"
27
- >
28
- <ListboxOption
29
- v-for="option in options"
30
- :key="getOptionId(toValue(option))"
31
- v-slot="{ active, selected }"
32
- as="template"
33
- :value="option"
34
- >
35
- <li
36
- class="relative cursor-default select-none py-2 pr-4 list-none flex items-center gap-2 text-gray-900"
37
- :class="{
38
- 'bg-gray-lower': active && !isDisabled(toValue(option)),
39
- 'text-new-disabled-text': isDisabled(toValue(option)),
40
- 'pl-2': selected,
41
- 'pl-6': !selected,
42
- }"
43
- >
44
- <div class="flex items-center justify-center aspect-square">
45
- <RiCheckLine
46
- v-if="selected"
47
- class="size-4"
48
- :class="isDisabled(toValue(option)) ?' text-new-disabled-text' : 'text-new-primary'"
49
- />
50
- </div>
51
- <slot
52
- name="option"
53
- v-bind="{ option, active }"
54
- >
55
- {{ displayValue(option) }}
56
- </slot>
57
- </li>
58
- </ListboxOption>
59
- </ListboxOptions>
60
- </div>
61
- </Listbox>
62
- </template>
63
-
64
- <script setup lang="ts" generic="T extends string | number | object">
65
- import { Listbox, ListboxButton, ListboxOption, ListboxOptions } from '@headlessui/vue'
66
- import { useFloating, autoUpdate, autoPlacement } from '@floating-ui/vue'
67
- import { toValue, useTemplateRef } from 'vue'
68
- import { RiArrowDownSLine, RiCheckLine } from '@remixicon/vue'
69
-
70
- withDefaults(defineProps<{
71
- options?: Array<T>
72
- getOptionId?: (option: T) => string | number
73
- displayValue: (option: T | null) => string
74
- isDisabled?: (option: T | null) => boolean
75
- }>(), {
76
- getOptionId: (option: T): string | number => {
77
- if (typeof option === 'string') return option
78
- if (typeof option === 'number') return option
79
- if (typeof option === 'object' && 'id' in option) return option.id as string
80
-
81
- throw new Error('Please set getOptionId()')
82
- },
83
- isDisabled: (option: T | null): boolean => {
84
- if (option && typeof option === 'object' && 'disabled' in option) return option.disabled as boolean
85
-
86
- return false
87
- },
88
- })
89
-
90
- const model = defineModel<T | null>({ required: true })
91
-
92
- const referenceRef = useTemplateRef('floatingReference')
93
- const floatingRef = useTemplateRef<InstanceType<typeof ListboxOptions>>('popover')
94
- const { floatingStyles } = useFloating(referenceRef, floatingRef, {
95
- middleware: [autoPlacement({
96
- allowedPlacements: ['bottom-start', 'bottom', 'bottom-end'],
97
- crossAxis: true,
98
- })],
99
- whileElementsMounted: autoUpdate,
100
- })
101
- </script>
@@ -1,68 +0,0 @@
1
- import type { Chart, ChartForm, ChartForApi, Filter } from '../types/visualizations'
2
-
3
- export function toChartForm(chart: Chart) {
4
- const seriesFilter = chart.series[0]?.filters as Filter | null
5
-
6
- return {
7
- title: chart.title,
8
- description: chart.description,
9
- private: chart.private,
10
- owned: chart.organization ? { organization: chart.organization.id, owner: null } : { owner: chart.owner.id, organization: null },
11
- x_axis: {
12
- column_x: chart.x_axis.column_x,
13
- type: chart.x_axis.type,
14
- sort_combined: chart.x_axis.sort_x_by && chart.x_axis.sort_x_direction
15
- ? `${chart.x_axis.sort_x_by}-${chart.x_axis.sort_x_direction}`
16
- : '',
17
- },
18
- y_axis: {
19
- label: chart.y_axis.label || '',
20
- min: chart.y_axis.min,
21
- max: chart.y_axis.max,
22
- unit: chart.y_axis.unit || '',
23
- unit_position: chart.y_axis.unit_position || 'suffix',
24
- },
25
- series: chart.series.map(serie => ({
26
- ...serie,
27
- aggregate_y: serie.aggregate_y || '',
28
- })),
29
- extras: chart.extras,
30
- chart_type: chart.series[0] ? chart.series[0].type : null,
31
- filter: seriesFilter ?? null,
32
- } satisfies ChartForm
33
- }
34
-
35
- export function toChartApi(chartForm: ChartForm): ChartForApi {
36
- const xAxis = {
37
- column_x: chartForm.x_axis.column_x,
38
- type: chartForm.x_axis.type,
39
- sort_x_by: chartForm.x_axis.sort_combined
40
- ? (chartForm.x_axis.sort_combined.split('-')[0] as 'axis_x' | 'axis_y')
41
- : null,
42
- sort_x_direction: chartForm.x_axis.sort_combined
43
- ? (chartForm.x_axis.sort_combined.split('-')[1] as 'asc' | 'desc')
44
- : null,
45
- }
46
-
47
- return {
48
- ...chartForm.owned,
49
- title: chartForm.title,
50
- description: chartForm.description,
51
- private: chartForm.private,
52
- x_axis: xAxis,
53
- y_axis: {
54
- label: chartForm.y_axis.label ?? null,
55
- min: chartForm.y_axis.min ?? null,
56
- max: chartForm.y_axis.max ?? null,
57
- unit: chartForm.y_axis.unit ?? null,
58
- unit_position: chartForm.y_axis.unit_position ?? null,
59
- },
60
- series: chartForm.series.map((serie, index) => ({
61
- ...serie,
62
- type: index === 0 && chartForm.chart_type ? chartForm.chart_type : serie.type,
63
- aggregate_y: serie.aggregate_y || null,
64
- filters: serie.filters || (index === 0 && chartForm.filter ? chartForm.filter : null),
65
- })),
66
- extras: chartForm.extras,
67
- }
68
- }
@@ -1,89 +0,0 @@
1
- import type { TabularAggregateType } from '../functions/tabularApi'
2
- import type { Owned, OwnedWithId } from './owned'
3
-
4
- export type FilterCondition = 'exact' | 'differs' | 'is_null' | 'is_not_null' | 'greater' | 'less' | 'strictly_greater' | 'strictly_less'
5
- export type Filter = {
6
- _cls: 'Filter'
7
- column: string
8
- condition: FilterCondition
9
- value: string | null
10
- }
11
-
12
- export type AndFilters = {
13
- _cls: 'AndFilters'
14
- filters: Array<Filter | AndFilters>
15
- }
16
-
17
- export type GenericFilter = Filter | AndFilters
18
-
19
- export type XAxisType = 'discrete' | 'continuous'
20
-
21
- export type XAxisSortBy = 'axis_x' | 'axis_y'
22
-
23
- export type SortDirection = 'asc' | 'desc'
24
-
25
- export type XAxis = {
26
- column_x: string
27
- sort_x_by: XAxisSortBy | null
28
- sort_x_direction: SortDirection | null
29
- type: XAxisType
30
- }
31
-
32
- export type CombinedSort = '' | 'axis_x-asc' | 'axis_x-desc' | 'axis_y-asc' | 'axis_y-desc'
33
-
34
- export type XAxisForm = Omit<XAxis, 'sort_x_by' | 'sort_x_direction'> & { sort_combined: CombinedSort }
35
-
36
- export type UnitPosition = 'prefix' | 'suffix'
37
-
38
- export type YAxis = {
39
- min: number | null
40
- max: number | null
41
- label: string | null
42
- unit: string | null
43
- unit_position: UnitPosition | null
44
- }
45
-
46
- export type DataSeriesType = 'line' | 'histogram'
47
-
48
- export type DataSeries = {
49
- type: DataSeriesType
50
- column_y: string
51
- aggregate_y: TabularAggregateType | null
52
- resource_id: string
53
- column_x_name_override: string | null
54
- filters: GenericFilter | null
55
- }
56
-
57
- // Type for form where aggregate_y can be empty string for select binding
58
- export type DataSeriesForm = Omit<DataSeries, 'aggregate_y'> & { aggregate_y: TabularAggregateType | '' | null }
59
-
60
- export type Chart = Owned & {
61
- id: string
62
- title: string
63
- slug: string
64
- description: string
65
- private: boolean
66
- created_at: string
67
- last_modified: string
68
- deleted_at: string | null
69
- uri: string
70
- page: string
71
- x_axis: XAxis
72
- y_axis: YAxis
73
- series: Array<DataSeries>
74
- extras: Record<string, unknown>
75
- permissions: { delete: boolean, edit: boolean, read: boolean }
76
- metrics: {
77
- views: number
78
- }
79
- }
80
-
81
- export type ChartForApi = OwnedWithId & Pick<Chart, 'title' | 'description' | 'private' | 'x_axis' | 'y_axis' | 'series' | 'extras'>
82
-
83
- export type ChartForm = Omit<ChartForApi, 'x_axis' | 'series' | 'owner' | 'organization'> & {
84
- owned: OwnedWithId
85
- x_axis: XAxisForm
86
- series: Array<DataSeriesForm>
87
- chart_type?: DataSeriesType | null
88
- filter: GenericFilter | null
89
- }