Documentation Index Fetch the complete documentation index at: https://quill.co/docs/llms.txt
Use this file to discover all available pages before exploring further.
Used alongside useDashboardReport for fully customizable dashboards. Below is an example with shadcn showing fully custom styling.
import {
QuillProvider ,
useDashboard ,
useDashboardReport ,
StaticChart ,
} from "@quillsql/react" ;
import { Card , CardHeader } from "@/components/ui/card" ;
import { Skeleton } from "@/components/ui/skeleton" ;
function App () {
return (
< QuillProvider
tenants = { [{ tenantField: "customer_id" , tenantIds: [ 2 ] }] }
publicKey = "6579031b3e41c378aa8180ec"
>
< CustomDashboard />
</ QuillProvider >
);
}
function CustomDashboard () {
const { sections , isLoading } = useDashboard ( "quill demo dashboard" );
return (
<>
< ChartsSection reports = { sections [ "charts" ] } />
</>
);
}
function ChartsSection ({ reports } : { reports : any [] }) {
return (
< div className = "grid grid-cols-1 lg:grid-cols-6 gap-6" >
{ reports . map (( report : any ) => (
< ChartCard reportId = { report . id } name = { report . name } />
)) }
</ div >
);
}
function ChartCard ({ reportId , name }) {
const { report , loading } = useDashboardReport ( reportId );
if ( loading ) {
return (
< div className = "lg:col-span-1" >
< Card
className = "h-full shadow-none bg-transparent border-none"
title = { name }
>
< Skeleton />
</ Card >
</ div >
);
}
return (
< div className = "lg:col-span-1" >
< Card
className = "h-full shadow-none bg-transparent border-none"
title = { name }
>
< StaticChart reportId = { report . id } />
</ Card >
</ div >
);
}
Working with filters
useDashboard returns a filters array describing the dashboard’s available filters and an applyFilters function for updating them. Each filter has a type of "select", "multiselect", "date", or "tenant", plus a label, current value, and an options list.
The example below renders each filter type with a native control and applies updates via applyFilters:
import {
QuillProvider ,
useDashboard ,
StaticChart ,
} from "@quillsql/react" ;
function App () {
return (
< QuillProvider
tenants = { [{ tenantField: "customer_id" , tenantIds: [ 2 ] }] }
publicKey = "6579031b3e41c378aa8180ec"
>
< FilteredDashboard name = "quill demo dashboard" />
</ QuillProvider >
);
}
function FilteredDashboard ({ name } : { name : string }) {
const { sections , filters , applyFilters , isLoading } = useDashboard ( name );
return (
< div >
< div style = { { display: "flex" , gap: 12 , marginBottom: 16 } } >
{ filters . map (( filter ) => {
if ( filter . type === "select" ) {
return (
< select
key = { filter . label }
value = { filter . value ?? "" }
onChange = { ( e ) =>
applyFilters ([{ label: filter . label , value: e . target . value }])
}
>
< option value = "" > All </ option >
{ filter . options . map (( option ) => (
< option key = { option . value } value = { option . value } >
{ option . label }
</ option >
)) }
</ select >
);
}
if ( filter . type === "multiselect" ) {
return (
< select
key = { filter . label }
multiple
value = { filter . value }
onChange = { ( e ) => {
const value = Array . from ( e . target . selectedOptions ). map (
( option ) => option . value ,
);
applyFilters ([{ label: filter . label , value }]);
} }
>
{ filter . options . map (( option ) => (
< option key = { option . value } value = { option . value } >
{ option . label }
</ option >
)) }
</ select >
);
}
if ( filter . type === "date" ) {
return (
< select
key = { filter . label }
value = { filter . value . presetValue ?? "" }
onChange = { ( e ) => {
const preset = filter . options . find (
( option ) => option . value === e . target . value ,
);
if ( ! preset ) return ;
applyFilters ([
{
label: filter . label ,
value: {
startDate: preset . startDate ,
endDate: preset . endDate ,
},
},
]);
} }
>
{ filter . options . map (( option ) => (
< option key = { option . value } value = { option . value } >
{ option . label }
</ option >
)) }
</ select >
);
}
if ( filter . type === "tenant" ) {
// value is string | number | (string | number)[] | null
const selected = Array . isArray ( filter . value )
? filter . value . map ( String )
: filter . value === null
? ""
: String ( filter . value );
return (
< select
key = { filter . label }
multiple = { Array . isArray ( selected ) }
value = { selected }
onChange = { ( e ) => {
const value = Array . isArray ( selected )
? Array . from ( e . target . selectedOptions ). map (( o ) => o . value )
: e . target . value ;
applyFilters ([{ label: filter . label , value }]);
} }
>
{ ! Array . isArray ( selected ) && < option value = "" > All </ option > }
{ filter . options . map (( option ) => (
< option key = { option . value } value = { String ( option . value ) } >
{ option . label }
</ option >
)) }
</ select >
);
}
return null ;
}) }
</ div >
{ ! isLoading &&
sections &&
Object . values ( sections )
. flat ()
. map (( report ) => < StaticChart key = { report . id } reportId = { report . id } /> ) }
</ div >
);
}
Filter shapes
typevalueoptions"select"string{ label: string; value: string }[]"multiselect"string[]{ label: string; value: string }[]"date"{ presetValue?: string; startDate: Date | undefined; endDate: Date | undefined }{ label: string; value: string; startDate?: Date; endDate?: Date }[]"tenant"string | number | (string | number)[] | null{ label: string; value: string | number }[]
The "tenant" filter only appears if you have multiple Tenants defined in the BI platform and the viewing tenant has a mapping to the dashboard’s owner tenant. For example, a parent organization can use a multiselect tenant filter to view any subset of the child organizations it maps to.
applyFilters payload
applyFilters accepts an array of { label, value } objects. label must match a filter’s label from the filters array, and value must match the shape expected for that filter:
"select" — value: string
"multiselect" — value: string[]
"date" — value: { startDate?: Date; endDate?: Date; preset?: string }
"tenant" — value: string | string[] (coerce numeric tenant IDs to strings; pass an array when the tenant filter is multi-select)
Parameters
The name of the dashboard to load
Configuration options for the dashboard The number of rows per page for the tabular rows of a report. Defaults to
10.
Returns
Whether the dashboard data is currently loading
sections
Record<string, QuillReport[]> | null
The dashboard sections containing reports, organized by section name The name of the dashboard this report belongs to
rows
{ [key: string]: string }[]
required
The rows of data returned from this report’s query
The columns data returned from this report’s query
dateField
{ table: string; field: string }
The table and field this report uses for date filtering, if any
The pivot used in this query, if any
The field to use for this report’s xAxis
The format for this report’s xAxis
The template flag for a report
yAxisFields
{ field: string; label: string; format: AxisFormat }[]
required
A list of metadata about the yAxes of this report
The relative ordering of this report in relation to its siblings. Ordering
starts at 1 and counts up (eg. 1, 2, 3, etc.). Reports in the same section are
first grouped by chartType and then each group is sorted by order.
compareRows
{ [key: string]: string }[]
required
The rows of data returned from this report’s query over the comparison date
range as opposed to the primary date range
An array filters that have been applied to this query
A page prop used for smart table pagination
sort
{ field: string; direction: string }
A sort prop used for smart table pagination
A total row count used for SQL pagination
A query for the report used by the report builder on initial load of report
filterMap
{ [key: string]: { table: string; field: string } }
A map of dashboard filters to the appropriate table and field for the report
referenceLines
{ label: string; query: [number, number] | string }[]
A list of reference lines to render on compatible charts
referenceLineYValues
{ label: string; query: [number, number] }[]
Resolved reference line y values
A flag to determine whether to automatically display custom fields
Columns with custom fields
pivotRows
{ [key: string]: string }[]
The pivot row info
A list of metadata about the pivot yAxes of this report
Available filters for the dashboard. These are typically rendered with html
select or similar UI components.
applyFilters
(filters: Array<{ label: string; value: string | string[] | { startDate?: Date; endDate?: Date }; } | Filter>) => void
Function to apply filters to the dashboard