Hi!
Instead of a rant (ok, maybe it is a bit of a rant) I thought I would give Atlassian an insight in what it means to be a Marketplace Partner and developing apps using Atlassian Connect. I reckon you might not always be fully aware of the challenges we face.
I know you’re not deliberately making our lives miserable, and that there are plenty of priorities to attend, but I figured maybe this will make you more aware of how your decisions and/or inaction impact us as developer. Given the number of small annoyances are… euhm… rather big, perhaps I will turn this into a series
Part I: the challenge of sizing the iframe
NOTE: I’m using Jira in the examples, but this applies to all host products that support Atlassian Connect
Ok, so as you already know, the Connect apps run in an iframe. The size of that iframe is of vital importance to an app as this determines the screen estate we can consume.
There are three ways to influence the sizing of the iframe:
It is important to note, that sizeToParent
only works on the generalPages module, and not the other modules.
Why is this important? Because sizeToParent
is the only way a developer can fully control the screen estate of the app. It allows us to have in-context scroll bars (if necessary) and not have to rely on Atlassian and/or custom solutions to make sure the iframe height matches the height of the elements on the page.
To illustrate the issue, I will share a page I’ve been working on. It is a jiraProjectAdminTabPanels module.
If I do not use the resize data-option or call AP.resize
myself, the page will load like this:
To work around this, we have created our own custom resizeFix
method, which uses the MutationObserver to detect DOM changes and recalculate the scrollHeight of the root node. If that is enabled, the page loads correctly:
Looks great, right?
We’ve been using that resizeFix
for a couple of years now because iframe sizing has been broken for us for almost as long as we’ve been using Atlassian Connect. So why bother writing about this annoyance now, you might ask?
Because I wanted to add resizing animations to my app. If I add the CSS transition, this is what will happen:
As you can see, the transition works, but the iframe is not resized. This is because the MutationObserver is not triggered by the animation. The DOM change occurs before the transition start (change of style attribute), and is not triggered once the transition ends. The transition is a CSS property, not a DOM change.
In order to support this use case, I will need to add an onTransitionEnd
event handler which will trigger the resize:
The issue, obviously, is that we have to wait for the entire transition to end before the iframe is resized, meaning that the content will disappear for some time until the transition ends. Not a great user experience.
So how do we deal with this? Because we don’t know the height of the element at any point during the transition. We could add an window.setInterval
for every 100ms to recalculate the height:
That… sort of works? On my Apple MacBook Air M2 (2022) at least. Not sure how this is going to work on a crappy desktop found on almost every desk at Evil Corp Enterprise. This is probably not going to be the best UX.
So finally, the only real solution is to just pre-determine the required height and call AP.resize
with that hardcoded height prior to running the animation:
Finally, a smooth transition. There are still some edge-cases to attend, but I’m sure we’ll be able to sort them out. It does mean that every time we make content changes, we will need to adjust the hardcoded expected height of the final state after transition. If we forget updating this, we will get a crappy UX.
Now why am I sharing this? Because it took me two days to get this working. The first day I spent on trying to trick Atlassian Connect into allowing me to use a generalPage within the context of the Jira Project Settings decorator (as you can see in the screen grabs there is a atl.jira.proj.config/projectgroup1
location in the sidebar).
That proved to be somewhat hilarious because A) that location is pretty adement on which descriptor module properties are required (spoiler: it does not follow the webItem documentation) or it will not show the link and B) you can actually get a situation in which you have an iframe in an iframe, with a double Jira navigation bar. Unfortunately I forgot to screenshot that and I’m not going to retrace my steps on how I managed to break it, so you will just have to believe me
The second day was spent on trying to figure out how to get the height transition to work within the context of AP.resize.
Those are two days not spent on creating customer value, but just spent on working around the limitations imposed by Atlassian Connect implementation. I’m pretty sure this is not deliberate. It just not a priority and there are zero fucks given by Atlassian because you never have to deal with it.
I hope somehow this get’s some attention within the DevRel & Atlassian Connect teams. Pinging @dmorrow / @Bentley to see if they can spread the word. Maybe this might actually trigger someone looking into it, but I’m not holding my breath.
BTW, I’m not sure how this works in Forge, but I can image that this has similar challenges with sizing as Forge also runs in an iframe.
NB: the above example is how it works for a Team Managed project. If you use a jiraProjectAdminTabPanels in a Company Managed project, it will behave differently and will look differently (there is no mandatory breadcrumbs in Company Managed, which is in Team Managed). My next post will be about dealing with the inconsitencies between Team Managed and Company Managed