Ok, got it figure out. The key was a custom component with Allow popups to escape sandbox enabled. Took a little bit of figuring as I am not a React guy, but luckily I have done a bit with vue.js. The other thing that got me a head start was this post from @church.
Here is how I did this with Carbone.io for other to follow.
Set up an account with carbone.io and make a template. I will let their docs guide you in this.
Drop a custom component on the app.
Turn on Allow popups to escape sandbox.
Edit the model to pass in the data you are passing to the carbone.io including the Auth token you got and the templateId for whichever template you want. Mine looks something like this:
{
"data": {{qryLineItemsSelect.data}},
"carboneAuthToken": {{carboneAuthToken.value}},
"carboneTemplateId": {{carboneInvoiceTemplate.value}}
}
I am just making a simple button that displays an invoice. The button is a material-ui button that doesn’t quite look the the standard retool version but is passable. Replace the entire MyCustomComponent with this:
const MyCustomComponent = ({ triggerQuery, model, modelUpdate }) => (
<Button
color="primary"
variant="contained"
size="small"
fullWidth="true"
onClick={() => {
printInvoice(model.data, model.carboneAuthToken, model.carboneTemplateId)
}}
>
Open Invoice
</Button>
);
Now you just need a function to do the actual work of making and displaying the PDF. You can put this in the same script block:
async function printInvoice(data, authToken, templateId) {
const resp = await fetch('https://render.carbone.io/render/' + templateId, {
method:"POST",
mode: 'cors',
body : JSON.stringify({
"convertTo" : 'pdf',
"data" : data
}),
headers : {
"content-type": 'application/json',
"Authorization": 'Bearer ' + authToken,
"carbone-version": '3',
}
}).then(res => res.json());
if (resp && resp.success === true && resp.data && resp.data.renderId) {
// Get the result with a simple HTTP GET
var newWindow=window.open(`https://render.carbone.io/render/${resp.data.renderId}`, '_blank');
newWindow.focus();
} else if (resp && resp.error) {
return (resp.error);
}
}
The PDF opens in another tab and sends your eyeballs there!
I cannot seem to get the print dialog working programmatically, window.print()
just flashes a blank dialog in Chrome, Edge and FF so that’s kinda weird. If anyone gets that part working, let us know eh?
Also, if you know how to make that button look more seamless please pass that along.