The issue at hand
Like many companies, at Potato we use GitLab as part of our everyday product development workflow. It’s feature-rich, open source and the team are great at taking on feedback and feature requests from the community.
It seemed however, that one area of GitLab seemed to suit the Engineer mindset much more than it suited the Product mindset. Our Product Leads had a persistent issue with the GitLab boards where they were unable to see or edit descriptions and comments of the issues directly from the board view. This was a feature that those who had previously been familiar with tools such as JIRA particularly struggled with.
We did a bit of searching around and found that this issue had already been raised. It wasn’t in a state where merge requests were being accepted, or the final direction had been decided. So we set about seeing what we could do to address the issue ourselves in as lean a way as possible. A design had already been put together on the issue in question, so we had everything we needed to jump straight into dev tools and start tinkering.
After exploring a couple of different approaches, it became clear that the fastest way to get a feature-rich details view would be to use the details page itself, leveraging an iframe to include it into the existing sidebar. As well as being simple to execute, this would ensure that any updates to the functionality of the details page would be reflected in our extension. Then it was a case of adding a click event to listen for when an issue was clicked on, and reading the URL for the link to update the source of the iframe.
The next thing to validate was how to inject the iframe into the page of everyone who wanted it. A Chrome Extension seemed like the obvious candidate here, as most of us use Google Chrome at Potato, and they can be easily ported over to FireFox to extend the reach (and also to please our Tech Director, Luke). I hadn’t personally built a Chrome Extension before, but a quick bit of research showed that a feature called Content Scripts would give us a simple way to inject CSS and JS files onto pages that match our URL pattern.
Defining the MVP
Once we’d proved to ourselves that this was possible, and we had a sensible direction in place, we wanted to define the minimum set of requirements that would make this extension useful. The goal was to get this to real users at Potato and see if we can improve the workflow for our Product Leads. After a quick brainstorming session, the set we came up with was:
- Ability to see and interact with the issue details view directly from the board
- Option to toggle the expanded details view
- Expanded state should persist between tickets and on reload
- Users should still be able to interact with the full board in the background
- Expanded view is not appropriate for small screens
- Details view should have a stripped back UI to integrate better into the sidebar
Polishing up the MVP
We had a few things to do to get from the proof of concept that we were copy-pasting into the developer console to our first release candidate, some of which proved easier than others. Saving the toggled state was simple enough. The toggle relied on flipping a boolean in the code and updating some CSS classes accordingly. localStorage seemed like a good candidate for the implementation as the extension is installed at a browser level, just like the scope of localStorage. All that needed to be done to persist the state was writing the new state every time it was changed. Then on initialisation, read this value back from localStorage (converting between string and boolean).
One thing that proved more challenging was correctly handling the creation of new issues on the board. Using Mutation Observer seemed like a good fit for this, and it was a good excuse for me to try it out with a more complicated use-case. Initially this seemed really simple to filter the mutations down to the creation of new cards but there were a few edge cases. Dragging and dropping created clones of each card, but this could be fixed by tracking which issue numbers had been seen before. The final hurdle was to handle the startup when all of the issues were being added to the board asynchronously. We didn’t want this to treat each card being added to the board the same way as a new issue being created. As the cards are added all at once, a simple debouncing of the function handling new cards being added reduced the occurrences down to a single firing of the event that could be safely ignored until user interaction.
Finally, to get things ready for internal testing, we needed to create a store page, give our extension a name and capture a screenshot of the extension in action.
Internal dogfooding & finishing touches
The newly named GitLab Details Sidebar was very well received across the teams at Potato. People across the disciplines found it a useful addition to their workflow and it swiftly became the most installed internal Chrome Extension at Potato. From this use we discovered and fixed a few bugs, and got some good feedback on some potential future enhancements.
As well as offering some bug fixes, one of my colleagues made a great contribution to speed up the workflow. Using GitLab’s CI pipeline to automate the release process, uploading a zip file directly to the Chrome Web Store, then publishing the extension via the API. Now anyone in the team can release a successful commit from master without having to build anything locally.
Publish to the world
Finally we were ready to share our creation. We included a simple popup-window to show some info about the extension and link back to the issue board and the source code and then change the extension from private to public and republished.
You can find the GitLab Details Sidebar on the Chrome Web Store and on the Add-ons for Firefox site where you can install it completely free. We fully welcome any feedback or feature requests. Hopefully this extension will improve your daily workflow just as much as it has ours.