Hello.
I’m struggling to pass information to the resource used in a Frame
. What I preferably want to do, is something like this:
<Frame resource="my-frame" />
Or maybe more classic URL style:
<Frame resource="my-frame?some-param=true" />
Well, even duplicating the resource in the Manifest would be ‘good enough’:
- key: macro-view
path: macro-ui/dist?preview=false
tunnel:
port: 3001
-key: macro-preview
path: macro-ui/dist?preview=true
tunnel:
port: 3001
Yet another way that would be fine to point to a sub-path within resource. Something like:
- Either: `
- Or in the manifest:
- key: macro-view
path: macro-ui/dist?preview=false
tunnel:
port: 3001
in-resource: regular
-key: macro-preview
path: macro-ui/dist
in-resource: preview
That all seems impossible. Another way would be an API that sends a message to a specific frame, not to all frames as the events
do.
Another good enough work around would be to give the Frame and id that I can control. There seems to be a <Frame resource=... frameId="your-id"/>
. However, it is undocumented and I don’t see it ending up in a place where I can inspect it. Seems to be only placed into a Window title, and that is a bit too fragile to rely on.
At the moment I’m stuck. The only way seems to be to ‘package’ the custom ui / resource twice, so that I statically can back in some parameter. I really would love to a better solution than that.
So, the work around we probably go for is to duplicate the frontend/resource.
We build the front-end twice, with two different variables backed in. And then we have two Forge resources for the flavor of the front-end.
Of course this is ugly:
- The customers will have a slower app, as it downloads the front-end twice: More to download, more cache misses, more JavaScript load etc.
- Worse dev cycle: More fragile, more to deploy, more build complexity.
However, the alternatives are also ugly for us. Either we have to leave in jarring bugs, or have work around based on undocumented Forge implementation details.
Of course, I still hope we missed the ‘obvious’ way on how you pass some kind of parameter to a resource. Then this ugly work-around would evaporate instantly.
Hi @RomanStoffel , the events
API does send a message to each of you resources, but only the resources that are listening will catch the message. Instead of having two separate resources, was it possible to emit a message from your main resource and catch it in your frame resource? Something like:
Main app resource:
if (preview) {
events.emit('EVENT_NAME', {preview: true})
}
Frame resource:
events.on('EVENT_NAME', handlePreview);
The frameId
was a prop from our EAP that meant to help with communications but it was deemed too confusing to use and functionality around it was removed.
1 Like
@QuocLieu
Yes, in our resource we do something like this:
if (preview) {
events.on('render-preview', handlePreviewUpdate)
}
However, I have to know if the resource was included as a preview, or is the macro (in our case). So, I want to give the resource the information that it runs in preview mode. I couldn’t find out a way to do it.
So, as said: At the moment we duplicate the resource, having it twice. The only difference is that we ‘bake in’ the preview flag as a difference between the resources.
Ah is the problem with using events is that emitting it from one macro to it’s own Frame, means all other Frames within the other macros are receiving this message? It should still be possible to pass this information via the events API.
You could use the localId
from the context object to differentiate them. localId
is unique per macro
...
const context = await view.getContext();
...
if (preview && localId) {
events.emit(`EVENT_NAME_{localId}`, {preview: true})
}
...
const context = await view.getContext();
...
events.on(`EVENT_NAME_{localId}`, handlePreview);
Would this work for your case?
@QuocLieu Thanks.
We also do this already. We use the localId
to ensure that the preview only shows the preview of the current macro to edit.
However, the preview is in the custom macro editor: And therefore has the same localId
. Filtering only by localId
will show preview events in both, the actual macro and the macro editor. This works fine, as long as the Confluence user saves the macro. If they close the macro editor, then the actual macro has the last preview stuck and the page is inconstant with its actual state. This results in a super puzzling bug for the end user.
To avoid that, we want to ignore the events in the actual macro view. Aka have a `preview’ variable or some way to detect in what context the resource is used.
So, your code example is correct, but the issue is that we have no way to have this preview
variable. To have it, we have to duplicate the resource, so we can add it as a built time constant.
Thanks for the context @RomanStoffel . So I can understand this better, this is a UI Kit macro extension with a custom config. Both the config and the actual macro are rendering the Frame
component that can be either in preview or standard view. If they switched to the preview Frame
in macro editor , the macro also displays the preview Frame
. The problem is if they close the macro editor without saving, the macro still displays preview Frame
when it should be displaying the standard view instead. Is this correct?
If we provided a bridge method that can send a message back to the macro to switch it back to standard view when the macro editor is closed without saving, would this fix your problem?
@QuocLieu Yes, your summary is correct.
Yes, having a way to send a event when the macro editor is closed would help. Then we can send a reset event so that the main macro shows the stored content again.
It fixes our particular issue.
However, long term having a way to pass parameter to a resource via custome-ui/Frame is helpful in the overall system. It allows a piece of custom UI to adopt to the context. Especially showing the ‘same UI’ in different places in some flavor: Adopt the UI to the context it is placed in. (eg. in the differnet Bitbucket cards, different Jira panels). Creating a resource for each adds a lot of cost/friction: Its more to download/cache/JS for customers. More friction in development with more builds, more debug process (for the tunnel port per resource).
Summary:
- Yes, having a close event on the Macro editor works for this specific case to.
- However, the inflexibility to ‘pass any parameter or path’ in a resource shows up again in things like supporting different panels etc.
Hey @RomanStoffel,
Thanks for the insight on this issue! We definitely want to create a long term flexible solution to this so I’ve created an FRGE ticket here to track this suggestion. If you could add your own context or requests to this, that would be great to help us prioritise the item and create a solution suitable to you.
Vicky