I’m working in Palantir Foundry’s Workshop and have a function that generates a PDF from a dashboard. I’d like to trigger this function using a button, but I’m struggling to wire it up correctly.
Specifically, I’ve added a button widget, and under the “ON CLICK” configuration, I’m presented with several options: ACTION
, EVENT
, EXPORT
, SCENARIO EVENT
, FUNCTION BACKED EXPORT
, and EXPORT MEDIA
. I’ve tried all of them, but none successfully trigger my function.
My question: How can I configure a Workshop button to trigger a custom function that generates a PDF?
If possible, I’d appreciate guidance on:
- Which “ON CLICK” type is correct for triggering custom TypeScript logic
Here’s the code I’m trying to trigger:
typescript
import { Function, StringPropertyBaseType } from “@foundry/functions-api”;
import { PDFDocument, rgb, StandardFonts } from “pdf-lib”;
export class DashboardExportFunctions {
@Function()
public async exportPDF(dashboardRID: string): Promise {
try {
const pdfBase64 = await this.exportDashboardToPDF(dashboardRID);
const pdfBlob = this.base64ToBlob(pdfBase64, ‘application/pdf’);
const url = URL.createObjectURL(pdfBlob);
const a = document.createElement(‘a’);
a.href = url;
a.download = ‘dashboard.pdf’;
a.click();
URL.revokeObjectURL(url);
return true; // Indicate success
} catch (error) {
console.error(‘Error exporting PDF:’, error);
return false; // Indicate failure
}
}
private async exportDashboardToPDF(dashboardRID: string): Promise<string> {
const pdfDoc = await PDFDocument.create();
const page = pdfDoc.addPage();
const { width, height } = page.getSize();
const font = await pdfDoc.embedFont(StandardFonts.Helvetica);
page.drawText('Dashboard Export', {
x: 50,
y: height - 50,
size: 30,
font: font,
color: rgb(0, 0, 0),
});
const pdfBytes = await pdfDoc.save();
return Buffer.from(pdfBytes).toString('base64');
}
private base64ToBlob(base64: string, mimeType: string): Blob {
const byteCharacters = atob(base64);
const byteNumbers = new Array(byteCharacters.length);
for (let i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
return new Blob([byteArray], { type: mimeType });
}
}
Any direction or example would be greatly appreciated — this seemingly simple task has cost me hours.