Skip to content

Commit a59de06

Browse files
peternanderssonalisonjlaiAlison Lai
authored
Add support for Actions within plugins (#17)
Co-authored-by: Alison Lai <[email protected]> Co-authored-by: Alison Lai <[email protected]>
1 parent ae99639 commit a59de06

File tree

4 files changed

+141
-3
lines changed

4 files changed

+141
-3
lines changed

README.md

Lines changed: 66 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,8 @@ Before you start:
159159
#### CustomPluginConfigOptions
160160
161161
A plugin can be configured with any number of configuration fields. Each field
162-
type has its own configuration options. Each field type is also garunteed to
163-
have a the following options:
162+
type has its own configuration options. Each field type is also guaranteed to
163+
have the following options:
164164
165165
- `name : string` - the name of the field
166166
- `type : string` - the field type
@@ -247,6 +247,16 @@ type CustomPluginConfigOptions =
247247
type: 'interaction';
248248
name: string;
249249
label?: string;
250+
}
251+
| {
252+
type: 'action-trigger';
253+
name: string;
254+
label?: string;
255+
}
256+
| {
257+
type: 'action-effect';
258+
name: string;
259+
label?: string;
250260
};
251261
```
252262
@@ -376,6 +386,14 @@ Additional Fields
376386
377387
A configurable workbook interaction to interact with other charts within your workbook
378388
389+
**Action Trigger**
390+
391+
A configurable action trigger to trigger actions in other elements within your workbook
392+
393+
**Action Effect**
394+
395+
A configurable action effect that can be triggered by other elements within your workbook
396+
379397
#### PluginInstance
380398
381399
```ts
@@ -437,6 +455,16 @@ interface PluginInstance<T> {
437455
selection: WorkbookSelection[],
438456
): void;
439457
458+
/**
459+
* Triggers an action based on the provided action trigger ID
460+
*/
461+
triggerAction(id: string): void;
462+
463+
/**
464+
* Registers an effect with the provided action effect ID
465+
*/
466+
registerEffect(id: string, effect: Function): void;
467+
440468
/**
441469
* Overrider function for Config Ready state
442470
*/
@@ -678,7 +706,7 @@ function setVariableCallback(...values: unknown[]): void;
678706
679707
#### useInteraction()
680708
681-
Returns a given interaction's selection state and a setter to update that interation
709+
Returns a given interaction's selection state and a setter to update that interaction
682710
683711
```ts
684712
function useInteraction(
@@ -699,6 +727,41 @@ The returned setter function accepts an array of workbook selection elements
699727
function setVariableCallback(value: WorkbookSelection[]): void;
700728
```
701729
730+
#### useActionTrigger()
731+
732+
- `configId : string` - The ID of the action trigger from the Plugin Config
733+
734+
Returns a callback function to trigger one or more action effects for a given action trigger
735+
736+
```ts
737+
function useActionTrigger(configId: string): () => void;
738+
```
739+
740+
#### triggerActionCallback();
741+
742+
Arguments
743+
744+
- `configId : string` - The ID of the action trigger from the Plugin Config
745+
746+
The function that can be called to asynchronously trigger the action
747+
748+
```ts
749+
function triggerActionCallback(configId: string): void;
750+
```
751+
752+
#### useActionEffect()
753+
754+
Registers and unregisters an action effect within the plugin
755+
756+
```ts
757+
function useActionEffect(effectId: string, effect: () => void);
758+
```
759+
760+
Arguments
761+
762+
- `effectId : string` - The ID of the action effect
763+
- `effect : Function` - The function to be called when the effect is triggered
764+
702765
#### useConfig()
703766
704767
Returns the workbook element’s current configuration. If a key is provided, only

src/client/initialize.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export function initialize<T = {}>(): PluginInstance<T> {
1414

1515
let subscribedInteractions: Record<string, WorkbookSelection[]> = {};
1616
let subscribedWorkbookVars: Record<string, WorkbookVariable> = {};
17+
const registeredEffects: Record<string, () => void> = {};
1718

1819
const listeners: {
1920
[event: string]: Function[];
@@ -59,6 +60,14 @@ export function initialize<T = {}>(): PluginInstance<T> {
5960
Object.assign(subscribedInteractions, updatedInteractions);
6061
});
6162

63+
on('wb:plugin:action-effect:invoke', (configId: string) => {
64+
const effect = registeredEffects[configId];
65+
if (!effect) {
66+
throw new Error(`Unknown action effect with name: ${configId}`);
67+
}
68+
effect();
69+
});
70+
6271
function on(event: string, listener: Function) {
6372
listeners[event] = listeners[event] || [];
6473
listeners[event].push(listener);
@@ -135,6 +144,15 @@ export function initialize<T = {}>(): PluginInstance<T> {
135144
) {
136145
void execPromise('wb:plugin:selection:set', id, elementId, selection);
137146
},
147+
triggerAction(configId: string) {
148+
void execPromise('wb:plugin:action-trigger:invoke', configId);
149+
},
150+
registerEffect(configId: string, effect: () => void) {
151+
registeredEffects[configId] = effect;
152+
return () => {
153+
delete registeredEffects[configId];
154+
};
155+
},
138156
configureEditorPanel(options) {
139157
void execPromise('wb:plugin:config:inspector', options);
140158
},

src/react/hooks.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,3 +210,36 @@ export function useInteraction(
210210

211211
return [workbookInteraction, setInteraction];
212212
}
213+
214+
/**
215+
* React hook for returning a triggering callback function for the registered
216+
* action trigger
217+
* @param {string} configId ID of action trigger from the plugin config
218+
* @returns {Function} A callback function to trigger the action
219+
*/
220+
export function useActionTrigger(configId: string): () => void {
221+
const client = usePlugin();
222+
223+
return useCallback(() => {
224+
client.config.triggerAction(configId);
225+
}, [client, configId]);
226+
}
227+
228+
/**
229+
* React hook for registering and unregistering an action effect
230+
* @param {string} configId ID of action effect from plugin config
231+
* @param {Function} effect The function to be called when the action is triggered
232+
*/
233+
export function useActionEffect(configId: string, effect: () => void) {
234+
const client = usePlugin();
235+
236+
const effectRef = useRef(effect);
237+
238+
useEffect(() => {
239+
effectRef.current = effect;
240+
});
241+
242+
useEffect(() => {
243+
return client.config.registerEffect(configId, effectRef.current);
244+
}, [client, configId, effect]);
245+
}

src/types.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,16 @@ export type CustomPluginConfigOptions =
166166
type: 'interaction';
167167
name: string;
168168
label?: string;
169+
}
170+
| {
171+
type: 'action-trigger';
172+
name: string;
173+
label?: string;
174+
}
175+
| {
176+
type: 'action-effect';
177+
name: string;
178+
label?: string;
169179
};
170180

171181
/**
@@ -255,6 +265,20 @@ export interface PluginInstance<T = any> {
255265
selection: WorkbookSelection[],
256266
): void;
257267

268+
/**
269+
* Triggers an action based on the provided action trigger ID
270+
* @param {string} configId ID from action-trigger type in Plugin Config
271+
*/
272+
triggerAction(configId: string): void;
273+
274+
/**
275+
* Registers an effect with the provided action effect ID
276+
* @param {string} configId ID from action-effect type in Plugin Config
277+
* @param effect The effect function to register
278+
* @returns {Unsubscriber} A callable unsubscriber
279+
*/
280+
registerEffect(configId: string, effect: () => void): () => void;
281+
258282
/**
259283
* Overrider function for Config Ready state
260284
* @param {boolean} loadingState Boolean representing if Plugin Config is still loading

0 commit comments

Comments
 (0)