Skip to content

fix: support authHeaders for vegaliteViz #358

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 19, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,12 @@ export const InvalidChart = {

export const InteractiveMap = {
args: {
getAuthHeaders: () =>
Promise.resolve({
headers: {
Authorization: 'Bearer example-token',
},
}),
spec: {
$schema: 'https://vega.github.io/schema/vega-lite/v5.json',
width: 'container',
Expand Down
51 changes: 49 additions & 2 deletions src/components/visualization/vegaLiteViz/vegaLiteViz.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ import Typography from '@mui/material/Typography'
import Box from '@mui/system/Box'
import Stack from '@mui/system/Stack'
import useTheme from '@mui/system/useTheme'
import axios from 'axios'
import React, { useEffect, useRef, useState } from 'react'
import { renderToStaticMarkup } from 'react-dom/server'
import * as vega from 'vega'
import { default as VegaEmbed } from 'vega-embed'

import MarkedMarkdown from '../../markdown/markedMarkdown'
import PopoverMenu, { type PopoverMenuItem } from '../../menu/popoverMenu'
import type { VegaLiteData } from './vegaLiteViz.types'
import type { VegaLiteProps } from './vegaLiteViz.types'

/** The `VegaLiteViz` component is a versatile tool for visualizing data using the Vega-Lite grammar. With support for various graphic types, it empowers users to create engaging and informative data visualizations effortlessly.
*
Expand All @@ -26,14 +28,58 @@ function VegaLiteViz({
dark: 'dark' as const,
},
...props
}: VegaLiteData) {
}: VegaLiteProps) {
const chartRef = useRef<HTMLDivElement>(null)
const [hasError, setHasError] = useState<boolean>(false)

const rusticTheme: Theme = useTheme()
const isDarkTheme = rusticTheme.palette.mode === 'dark'
const defaultFont = rusticTheme.typography.fontFamily

const customHttpLoader = (
url: string,
options: RequestInit
): Promise<string> => {
const axiosOptions = {
method: (options.method as string) || 'GET',
headers: options.headers as Record<string, string>,
responseType: 'text' as const,
data: options.body,
}

let updateRequestHeaders

if (props.getAuthHeaders) {
updateRequestHeaders = props.getAuthHeaders().then((authData) => {
axiosOptions.headers = {
...axiosOptions.headers,
...authData.headers,
}
return axiosOptions
})
} else {
updateRequestHeaders = Promise.resolve(axiosOptions)
}

return updateRequestHeaders
.then((finalOptions) => {
return axios(url, finalOptions)
})
.then((response) => {
return response.data
})
}

function createLoader(): vega.Loader {
const loader = vega.loader()

if (props.getAuthHeaders) {
loader.http = customHttpLoader
}

return loader
}

const tooltipStyle = {
backgroundColor: rusticTheme.palette.primary.main,
color: rusticTheme.palette.background.paper,
Expand Down Expand Up @@ -82,6 +128,7 @@ function VegaLiteViz({
theme: isDarkTheme ? theme.dark : theme.light,
tooltip: tooltipOptions,
actions: false,
loader: createLoader(),
}

if (!props.options?.config?.font) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { Renderers } from 'vega'
import type { EmbedOptions, VisualizationSpec } from 'vega-embed'

import type { Updates, VisualizationFormat } from '../../types'
import type { GetAuthHeaders, Updates, VisualizationFormat } from '../../types'

//VegaLite's typescript doesn't recognize font as a valid props
type VegaLiteOptions = EmbedOptions<string, Renderers> & {
Expand All @@ -21,3 +21,8 @@ export interface VegaLiteFormat extends VisualizationFormat {
}

export type VegaLiteData = VegaLiteFormat & Updates<VegaLiteFormat>

export interface VegaLiteProps extends VegaLiteData {
/** A function that can be used to get the headers for the data requests. */
getAuthHeaders?: GetAuthHeaders
}