Skip to content

Commit ad86de3

Browse files
committed
Add URL parameter support, enabling plugins to get and update URL parameters as long as they don't start with :
1 parent 87f84bd commit ad86de3

4 files changed

Lines changed: 97 additions & 1 deletion

File tree

.nvmrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
v18.16.1
1+
v20.17.0

src/client/initialize.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
PluginInstance,
55
PluginMessageResponse,
66
PluginStyle,
7+
UrlParameter,
78
WorkbookSelection,
89
WorkbookVariable,
910
} from '../types';
@@ -15,6 +16,7 @@ export function initialize<T = {}>(): PluginInstance<T> {
1516

1617
let subscribedInteractions: Record<string, WorkbookSelection[]> = {};
1718
let subscribedWorkbookVars: Record<string, WorkbookVariable> = {};
19+
let subscribedUrlParameters: Record<string, UrlParameter> = {};
1820
const registeredEffects: Record<string, () => void> = {};
1921

2022
const listeners: {
@@ -61,6 +63,14 @@ export function initialize<T = {}>(): PluginInstance<T> {
6163
Object.assign(subscribedInteractions, updatedInteractions);
6264
});
6365

66+
on(
67+
'wb:plugin:url-parameter:update',
68+
(updatedUrlParameters: Record<string, UrlParameter>) => {
69+
subscribedUrlParameters = {};
70+
Object.assign(subscribedUrlParameters, updatedUrlParameters);
71+
},
72+
);
73+
6474
on('wb:plugin:action-effect:invoke', (configId: string) => {
6575
const effect = registeredEffects[configId];
6676
if (!effect) {
@@ -191,6 +201,25 @@ export function initialize<T = {}>(): PluginInstance<T> {
191201
off('wb:plugin:selection:update', setValues);
192202
};
193203
},
204+
subscribeToUrlParameter(configId, callback) {
205+
validateConfigId(configId, 'url-parameter');
206+
const setValues = (values: Record<string, UrlParameter>) => {
207+
callback(values[configId]);
208+
};
209+
setValues(subscribedUrlParameters);
210+
on('wb:plugin:url-parameter:update', setValues);
211+
return () => {
212+
off('wb:plugin:url-parameter:update', setValues);
213+
};
214+
},
215+
getUrlParameter(configId: string) {
216+
validateConfigId(configId, 'url-parameter');
217+
return subscribedUrlParameters[configId];
218+
},
219+
setUrlParameter(configId: string, value: string) {
220+
validateConfigId(configId, 'url-parameter');
221+
void execPromise('wb:plugin:url-parameter:set', configId, value);
222+
}
194223
},
195224
elements: {
196225
getElementColumns(configId) {

src/react/hooks.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
WorkbookSelection,
1010
WorkbookVariable,
1111
PluginStyle,
12+
UrlParameter,
1213
} from '../types';
1314
import { deepEqual } from '../utils/deepEqual';
1415

@@ -184,6 +185,35 @@ export function useVariable(
184185
return [workbookVariable, setVariable];
185186
}
186187

188+
/**
189+
* React hook for accessing a url parameter
190+
* @param {string} id ID from the config of type: 'url-parameter'
191+
* @returns {[(UrlParameter | undefined), Function]} Constantly updating value of the url parameter and setter for the url parameter
192+
*/
193+
export function useUrlParameter(
194+
id: string
195+
): [UrlParameter | undefined, (value: string) => void] {
196+
const client = usePlugin();
197+
const [urlParameter, setUrlParameter] = useState<UrlParameter>();
198+
199+
const isFirstRender = useRef<boolean>(true);
200+
201+
useEffect(() => {
202+
if (isFirstRender.current) {
203+
setUrlParameter(client.config.getUrlParameter(id));
204+
isFirstRender.current = false;
205+
}
206+
return client.config.subscribeToUrlParameter(id, setUrlParameter);
207+
}, [client, id]);
208+
209+
const setVariable = useCallback(
210+
(value: string) => client.config.setUrlParameter(id, value),
211+
[client, id],
212+
);
213+
214+
return [urlParameter, setVariable];
215+
}
216+
187217
/**
188218
* @deprecated Use Action API instead
189219
* React hook for accessing a workbook interaction selections state

src/types.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,14 @@ export interface WorkbookVariable {
4242
defaultValue: { type: string };
4343
}
4444

45+
/**
46+
* @typedef {object} UrlParameter
47+
* @property {string} value Current url value
48+
*/
49+
export interface UrlParameter {
50+
value: string;
51+
}
52+
4553
export type WorkbookSelection = Record<string, { type: string; val?: unknown }>;
4654

4755
export type PluginMessageResponse = MessageEvent<{
@@ -185,6 +193,10 @@ export type CustomPluginConfigOptions =
185193
type: 'action-effect';
186194
name: string;
187195
label?: string;
196+
}
197+
| {
198+
type: 'url-parameter',
199+
name: string
188200
};
189201

190202
/**
@@ -307,6 +319,31 @@ export interface PluginInstance<T = any> {
307319
callback: (input: WorkbookVariable) => void,
308320
): Unsubscriber;
309321

322+
/**
323+
* Allows users to subscribe to changes in the url parameter
324+
* @param {string} configId ID from config of type: 'url-parameter'
325+
* @callback callback Function to be called upon receiving an updated url parameter
326+
* @returns {Unsubscriber} A callable unsubscriber
327+
*/
328+
subscribeToUrlParameter(
329+
configId: string,
330+
callback: (input: UrlParameter) => void,
331+
): Unsubscriber;
332+
333+
/**
334+
* Gets the current value of a url parameter
335+
* @param {string} configId ID from config of type: 'url-parameter'
336+
* @returns {UrlParameter} Current value of the url parameter
337+
*/
338+
getUrlParameter(configId: string): UrlParameter;
339+
340+
/**
341+
* Setter for url parameter
342+
* @param {string} configId ID from config of type: 'url-parameter'
343+
* @param {string} value Value to assign to the url parameter
344+
*/
345+
setUrlParameter(configId: string, value: string): void;
346+
310347
/**
311348
* @deprecated Use Action API instead
312349
* Allows users to subscribe to changes in the passed in interaction ID

0 commit comments

Comments
 (0)