Skip to content

Commit d72540a

Browse files
authoredDec 28, 2023
doc: Update tile extension SDK api documentation (#1417)
Also breaks out a couple of functions that are for internal use only into there own interfaces. Also deprecates and replaces the addErrors and clearErrors functions. Finally: 1. changes the tile extension theme to use google coloring. 2. changes the tile extensions to use the new addError and clearError functions.
1 parent 0142318 commit d72540a

File tree

9 files changed

+206
-44
lines changed

9 files changed

+206
-44
lines changed
 

‎packages/extension-sdk-react/src/components/ExtensionConnector/ExtensionConnector.tsx

+6-2
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,11 @@
2727
import isEqual from 'lodash/isEqual'
2828
import React, { useEffect, useState, useCallback, useRef } from 'react'
2929
import { MemoryRouter } from 'react-router-dom'
30-
import type { RawVisualizationData, TileHostData } from '@looker/extension-sdk'
30+
import type {
31+
RawVisualizationData,
32+
TileHostData,
33+
TileSDKInternal,
34+
} from '@looker/extension-sdk'
3135
import { connectExtensionHost } from '@looker/extension-sdk'
3236
import { ErrorMessage } from '../ErrorMessage'
3337
import { RouteChangeListener } from '../RouteChangeListener'
@@ -101,7 +105,7 @@ export const ExtensionConnector: React.FC<ExtensionConnectorProps> = ({
101105
(partialHostData: Partial<TileHostData>) => {
102106
if (contextDataRef.current.tileSDK) {
103107
const { tileSDK } = contextDataRef.current
104-
tileSDK.tileHostDataChanged(partialHostData)
108+
;(tileSDK as TileSDKInternal).tileHostDataChanged(partialHostData)
105109
updateContextData({
106110
tileHostData: tileSDK.tileHostData,
107111
})

‎packages/extension-sdk/src/connect/extension_host_api.ts

+12-5
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,14 @@ import { logError } from '../util'
3030
import type {
3131
VisualizationDataReceivedCallback,
3232
VisualizationSDK,
33+
VisualizationSDKInternal,
3334
} from './visualization'
3435
import { VisualizationSDKImpl } from './visualization/visualization_sdk'
35-
import type { TileHostDataChangedCallback, TileSDK } from './tile'
36+
import type {
37+
TileHostDataChangedCallback,
38+
TileSDK,
39+
TileSDKInternal,
40+
} from './tile'
3641
import { TileSDKImpl } from './tile/tile_sdk'
3742
import { FetchProxyImpl } from './fetch_proxy'
3843
import type {
@@ -62,8 +67,8 @@ export class ExtensionHostApiImpl implements ExtensionHostApi {
6267
private hostChangedRoute?: (route: string, routeState?: any) => void
6368
private visualizationDataReceivedCallback?: VisualizationDataReceivedCallback
6469
private tileHostDataChangedCallback?: TileHostDataChangedCallback
65-
private _visualizationSDK?: VisualizationSDK
66-
private _tileSDK?: TileSDK
70+
private _visualizationSDK?: VisualizationSDKInternal
71+
private _tileSDK?: TileSDKInternal
6772

6873
private contextData?: string
6974

@@ -127,15 +132,17 @@ export class ExtensionHostApiImpl implements ExtensionHostApi {
127132
}
128133
case ExtensionNotificationType.VISUALIZATION_DATA: {
129134
const { payload } = message
130-
this.visualizationSDK.updateVisData(payload)
135+
;(this.visualizationSDK as VisualizationSDKInternal).updateVisData(
136+
payload
137+
)
131138
if (this.visualizationDataReceivedCallback) {
132139
this.visualizationDataReceivedCallback(payload)
133140
}
134141
return undefined
135142
}
136143
case ExtensionNotificationType.TILE_HOST_DATA: {
137144
const { payload } = message
138-
this.tileSDK.tileHostDataChanged(payload)
145+
;(this.tileSDK as TileSDKInternal).tileHostDataChanged(payload)
139146
if (this.tileHostDataChangedCallback) {
140147
this.tileHostDataChangedCallback(payload)
141148
}

‎packages/extension-sdk/src/connect/tile/tile_sdk.spec.ts

+15
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,21 @@ describe('TileSDK', () => {
131131
expect(dashboardFilters).toEqual({})
132132
})
133133

134+
it('sends add error message ', () => {
135+
const message1 = { title: 'Title1', message: 'Message1', group: 'abc' }
136+
const tileSdk = makeTileSdk()
137+
tileSdk.addError(message1)
138+
expect(api.send).toBeCalledWith('TILE_ADD_ERRORS', {
139+
errors: [message1],
140+
})
141+
})
142+
143+
it('sends clear error message ', () => {
144+
const tileSdk = makeTileSdk()
145+
tileSdk.clearError()
146+
expect(api.send).toBeCalledWith('TILE_CLEAR_ERRORS', { group: undefined })
147+
})
148+
134149
it('sends add errors message ', () => {
135150
const message1 = { title: 'Title1', message: 'Message1', group: 'abc' }
136151
const message2 = { title: 'Title2', message: 'Message2', group: 'abc' }

‎packages/extension-sdk/src/connect/tile/tile_sdk.ts

+22-2
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,12 @@ import { NOT_DASHBOARD_MOUNT_NOT_SUPPORTED_ERROR } from '../../util/errors'
2929
import { ExtensionRequestType } from '../types'
3030
import type { ExtensionHostApiImpl } from '../extension_host_api'
3131
import type {
32-
TileSDK,
3332
TileError,
3433
DrillMenuOptions,
3534
CrossFilterOptions,
3635
Filters,
3736
TileHostData,
37+
TileSDKInternal,
3838
} from './types'
3939
import { DashboardRunState } from './types'
4040

@@ -43,7 +43,7 @@ const defaultHostData: TileHostData = {
4343
dashboardRunState: DashboardRunState.UNKNOWN,
4444
dashboardFilters: {},
4545
}
46-
export class TileSDKImpl implements TileSDK {
46+
export class TileSDKImpl implements TileSDKInternal {
4747
hostApi: ExtensionHostApiImpl
4848
tileHostData: TileHostData
4949

@@ -60,6 +60,26 @@ export class TileSDKImpl implements TileSDK {
6060
}
6161
}
6262

63+
addError(error: TileError) {
64+
if (this.hostApi.isDashboardMountSupported) {
65+
this.hostApi.send(ExtensionRequestType.TILE_ADD_ERRORS, {
66+
errors: [error],
67+
})
68+
} else {
69+
throw NOT_DASHBOARD_MOUNT_NOT_SUPPORTED_ERROR
70+
}
71+
}
72+
73+
clearError() {
74+
if (this.hostApi.isDashboardMountSupported) {
75+
this.hostApi.send(ExtensionRequestType.TILE_CLEAR_ERRORS, {
76+
group: undefined,
77+
})
78+
} else {
79+
throw NOT_DASHBOARD_MOUNT_NOT_SUPPORTED_ERROR
80+
}
81+
}
82+
6383
addErrors(...errors: TileError[]) {
6484
if (this.hostApi.isDashboardMountSupported) {
6585
this.hostApi.send(ExtensionRequestType.TILE_ADD_ERRORS, { errors })

‎packages/extension-sdk/src/connect/tile/types.ts

+47-2
Original file line numberDiff line numberDiff line change
@@ -204,18 +204,63 @@ export interface Filters {
204204
[key: string]: string
205205
}
206206

207+
/**
208+
* For internal use only
209+
*/
210+
export interface TileSDKInternal extends TileSDK {
211+
tileHostDataChanged: (hostData: Partial<TileHostData>) => void
212+
}
213+
207214
/**
208215
* Extension tile SDK
209216
*/
210217
export interface TileSDK {
218+
/**
219+
* Tile host data.
220+
*/
211221
tileHostData: TileHostData
212-
tileHostDataChanged: (hostData: Partial<TileHostData>) => void
222+
/**
223+
* Display an error beneath the tile extension.
224+
*/
225+
addError: (error: TileError) => void
226+
/**
227+
* Clear an error beneath the tile extension.
228+
*/
229+
clearError: () => void
230+
/**
231+
* Display an error beneath the tile extension.
232+
* @deprecated
233+
*/
213234
addErrors: (...errors: TileError[]) => void
235+
/**
236+
* Clear an error beneath the tile extension.
237+
* @deprecated
238+
*/
214239
clearErrors: (group?: string) => void
240+
/**
241+
* Open a drill menu. The event controls positioning of the drill menu.
242+
* Set the pageX and pageY properties on the event to control the
243+
* positioning (all other properties are ignored).
244+
*/
215245
openDrillMenu: (options: DrillMenuOptions, event?: MouseEvent) => void
246+
/**
247+
* Toggle cross filters. This is ignored when running in an explore.
248+
*/
216249
toggleCrossFilter: (options: CrossFilterOptions, event?: MouseEvent) => void
250+
/**
251+
* Run the current dashboard. This is ignored when running in an explore.
252+
*/
217253
runDashboard: () => void
254+
/**
255+
* Stop the current dashboard. This is ignored when running in an explore.
256+
*/
218257
stopDashboard: () => void
219-
updateFilters: (filters: Filters, runDashboard?: boolean) => void
258+
/**
259+
* Update the current filters.
260+
*/
261+
updateFilters: (filters: Filters, run?: boolean) => void
262+
/**
263+
* Open the schedule dialog. This is ignored when running in an explore.
264+
*/
220265
openScheduleDialog: () => Promise<void>
221266
}

‎packages/extension-sdk/src/connect/visualization/types.ts

+82-1
Original file line numberDiff line numberDiff line change
@@ -93,34 +93,115 @@ export interface PivotConfig extends RawPivotConfig {
9393
[key: string]: any
9494
}
9595

96+
/**
97+
* Visualization configuration data.
98+
*/
9699
export interface VisualizationConfig {
100+
/**
101+
* Measure information
102+
*/
97103
queryFieldMeasures: Measure[]
104+
/**
105+
* Dimension information
106+
*/
98107
queryFieldDimensions: Dimension[]
108+
/**
109+
* Table calculation information
110+
*/
99111
queryFieldTableCalculations: TableCalculation[]
112+
/**
113+
* Pivot information
114+
*/
100115
queryFieldPivots: PivotConfig[]
116+
/**
117+
* Visual configuration data. This should be merged with the default
118+
* configuration and applied to the visualization rendered by the
119+
* extension.
120+
*/
101121
visConfig: RawVisConfig
102122
}
103123

104124
export interface QueryResponse {
125+
/**
126+
* Row data.
127+
*/
105128
data: Row[]
129+
/**
130+
* Field measure information
131+
*/
106132
fieldMeasures: Measure[]
133+
/**
134+
* Field dimension information
135+
*/
107136
fieldDimensions: Dimension[]
137+
/**
138+
* Field table calculation information
139+
*/
108140
fieldTableCalculations: TableCalculation[]
141+
/**
142+
* Field pivot information
143+
*/
109144
fieldPivots: PivotConfig[]
145+
/*
146+
* A concatenated array of field measure information and table calculations
147+
* that behave like measures.
148+
*/
110149
fieldMeasureLike: Measure[]
150+
/*
151+
* A concatenated array of field dimension information and table calculations
152+
* that behave like dimensions.
153+
*/
111154
fieldDimensionLike: Dimension[]
112155
}
113156

157+
/**
158+
* For internal use only.
159+
*/
160+
export interface VisualizationSDKInternal extends VisualizationSDK {
161+
updateVisData: (rawVisData: RawVisualizationData) => void
162+
}
163+
114164
/**
115165
* Extension visualization SDK
116166
*/
117167
export interface VisualizationSDK {
168+
/**
169+
* Visualization (combination of visConfig and queryResponse data)
170+
*/
118171
visualizationData?: RawVisualizationData
172+
/**
173+
* Visualization configuration data.
174+
* - measure configurations
175+
* - dimension configurations
176+
* - table calculations
177+
* - pivot configurations
178+
* - visualization configurations. These would be used to customize
179+
* the look and feel of a visualization in an explore.
180+
*/
119181
visConfig: VisualizationConfig
182+
/**
183+
* Response data from query.
184+
* - row data
185+
* - field measures
186+
* - field table calculations
187+
* - field pivots
188+
* - field measure like
189+
* - field dimension like
190+
*/
120191
queryResponse: QueryResponse
121-
updateVisData: (rawVisData: RawVisualizationData) => void
192+
/**
193+
* Set the default configurations for an extension visualization.
194+
* The configurations will be rendered inside of the explore
195+
* visualization editor. This should only be called once.
196+
*/
122197
configureVisualization: (options: VisOptions) => void
198+
/**
199+
* Update the visualization configuration.
200+
*/
123201
setVisConfig: (config: RawVisConfig) => void
202+
/**
203+
* Update the query row limit.
204+
*/
124205
updateRowLimit: (rowLimit: number) => void
125206
}
126207

‎packages/extension-sdk/src/connect/visualization/visualization_sdk.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import type { ExtensionHostApiImpl } from '../extension_host_api'
2929
import { ExtensionRequestType } from '../types'
3030
import type { Row } from '../tile'
3131
import type {
32-
VisualizationSDK,
32+
VisualizationSDKInternal,
3333
RawVisualizationData,
3434
RawVisConfig,
3535
VisualizationConfig,
@@ -114,7 +114,7 @@ class VisualizationConfigImpl implements VisualizationConfig {
114114
}
115115
}
116116

117-
export class VisualizationSDKImpl implements VisualizationSDK {
117+
export class VisualizationSDKImpl implements VisualizationSDKInternal {
118118
hostApi: ExtensionHostApiImpl
119119
visualizationData?: RawVisualizationData
120120
_visConfig?: VisualizationConfigImpl

‎packages/extension-tile-playground/src/TileExtension.tsx

+5-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,11 @@ export const TileExtension: React.FC = () => {
5151
const { lookerHostData } = useContext(ExtensionContext40)
5252

5353
return (
54-
<ComponentsProvider>
54+
<ComponentsProvider
55+
themeCustomizations={{
56+
colors: { key: '#1A73E8' },
57+
}}
58+
>
5559
<Switch>
5660
<Route path="/inspect">
5761
<Inspector />

‎packages/extension-tile-playground/src/components/Inspector/components/EventTester/EventTester.tsx

+15-29
Original file line numberDiff line numberDiff line change
@@ -45,27 +45,16 @@ export const EventTester: React.FC = () => {
4545
} = useContext(ExtensionContext40)
4646
const [runDashboard, setRunDashboard] = useState(false)
4747

48-
const addErrorsClick = useCallback(() => {
49-
tileSDK.addErrors(
50-
{
51-
title: 'Oh no',
52-
message: "I've fallen and I can't get up!",
53-
group: 'error_group_1',
54-
},
55-
{
56-
title: 'Oh no',
57-
message: 'I pressed the wrong button!',
58-
group: 'error_group_2',
59-
}
60-
)
61-
}, [tileSDK])
62-
63-
const partiallyClearErrorsClick = useCallback(() => {
64-
tileSDK.clearErrors('error_group_1')
48+
const addErrorClick = useCallback(() => {
49+
tileSDK.addError({
50+
title: 'Oh no',
51+
message: "I've fallen and I can't get up!",
52+
group: 'error_group_1',
53+
})
6554
}, [tileSDK])
6655

67-
const clearAllErrorsClick = useCallback(() => {
68-
tileSDK.clearErrors()
56+
const clearErrorClick = useCallback(() => {
57+
tileSDK.clearError()
6958
}, [tileSDK])
7059

7160
const toggleCrossFilterClick = useCallback(
@@ -123,24 +112,18 @@ export const EventTester: React.FC = () => {
123112
<CardContent>
124113
<Accordion2 label="Event Tester" defaultOpen>
125114
<Grid columns={2} mt="medium">
126-
<ButtonOutline onClick={addErrorsClick} width="100%">
127-
Test add errors
128-
</ButtonOutline>
129-
<ButtonOutline onClick={partiallyClearErrorsClick} width="100%">
130-
Test partially clear errors
115+
<ButtonOutline onClick={addErrorClick} width="100%">
116+
Test add error
131117
</ButtonOutline>
132-
<ButtonOutline onClick={clearAllErrorsClick} width="100%">
133-
Test clear all errors
118+
<ButtonOutline onClick={clearErrorClick} width="100%">
119+
Test clear error
134120
</ButtonOutline>
135121
<ButtonOutline onClick={updateRowLimit} width="100%">
136122
Test Update Row Limit
137123
</ButtonOutline>
138124
<ButtonOutline onClick={openDrillMenuClick} width="100%">
139125
Test open drill menu
140126
</ButtonOutline>
141-
<ButtonOutline onClick={toggleCrossFilterClick} width="100%">
142-
Test toggle cross filter
143-
</ButtonOutline>
144127
<ButtonOutline onClick={runDashboardClick} width="100%">
145128
Test run dashboard
146129
</ButtonOutline>
@@ -159,6 +142,9 @@ export const EventTester: React.FC = () => {
159142
on={runDashboard}
160143
></FieldToggleSwitch>
161144
</Space>
145+
<ButtonOutline onClick={toggleCrossFilterClick} width="100%">
146+
Test toggle cross filter
147+
</ButtonOutline>
162148
<ButtonOutline onClick={openScheduleDialogClick} width="100%">
163149
Test open schedule dialog
164150
</ButtonOutline>

0 commit comments

Comments
 (0)
Please sign in to comment.