import { ofetch } from 'ofetch' import { useComponentsConfig, type PluginConfig } from '../config' import type { GenericFilter } from '../types/visualizations' import type { SortConfig, TabularProfileResponse } from '../components/TabularExplorer/types' export type { SortConfig } export type TabularDataResponse = { data: Array> links: { profile: string swagger: string next: string } meta: { total: number } } export type TabularAggregateType = 'avg' | 'sum' | 'count' | 'min' | 'max' export type FetchTabularDataOptions = { resourceId: string page?: number pageSize?: number columns?: Array | undefined sort?: SortConfig groupBy?: string | undefined aggregation?: { column: string type: TabularAggregateType } | undefined filters?: GenericFilter | undefined } /** * Call Tabular-api to get table content with options object */ export async function fetchTabularData(config: PluginConfig, options: FetchTabularDataOptions): Promise { const page = options.page ?? 1 const pageSize = options.pageSize ?? config.tabularApiPageSize ?? 15 let url = `${config.tabularApiUrl}/api/resources/${options.resourceId}/data/?page=${page}&page_size=${pageSize}` if (options.columns) { url += `&columns=${options.columns.map(col => encodeURIComponent(col)).join(',')}` } if (options.sort) { url += `&${encodeURIComponent(options.sort.column)}__sort=${encodeURIComponent(options.sort.direction)}` } if (options.groupBy && options.aggregation?.type) { url += `&${encodeURIComponent(options.groupBy)}__groupby&${encodeURIComponent(options.aggregation.column)}__${encodeURIComponent(options.aggregation.type)}` } if (options.filters) { const filterQuery = buildFilterQuery(options.filters) if (filterQuery) { url += `&${filterQuery}` } } return await ofetch(url) } function buildFilterQuery(filters: GenericFilter): string { const params: Array = [] if ('filters' in filters) { for (const filter of filters.filters) { if ('filters' in filter) { params.push(buildFilterQuery(filter)) } else { if (filter.condition === 'is_null') { params.push(`${encodeURIComponent(filter.column)}__isnull`) } else if (filter.condition === 'is_not_null') { params.push(`${encodeURIComponent(filter.column)}__isnotnull`) } else if (filter.value !== null && filter.value !== undefined && filter.value !== '') { params.push(`${encodeURIComponent(filter.column)}__${encodeURIComponent(filter.condition)}=${encodeURIComponent(filter.value)}`) } } } } else { const filter = filters if (filter.condition === 'is_null') { params.push(`${encodeURIComponent(filter.column)}__isnull`) } else if (filter.condition === 'is_not_null') { params.push(`${encodeURIComponent(filter.column)}__isnotnull`) } else if (filter.value !== null && filter.value !== undefined && filter.value !== '') { params.push(`${encodeURIComponent(filter.column)}__${encodeURIComponent(filter.condition)}=${encodeURIComponent(filter.value)}`) } } return params.join('&') } /** * Call Tabular-api to get table content */ export async function getData(config: PluginConfig, id: string, page: number, sortConfig?: SortConfig | null): Promise { return fetchTabularData(config, { resourceId: id, page, sort: sortConfig ?? undefined, }) } /** * Call Tabular-api to get table profile */ export function useGetProfile() { const config = useComponentsConfig() return (id: string) => ofetch(`${config.tabularApiUrl}/api/resources/${id}/profile/`) }