Note: check out Gantt's website, just freshly out of the oven!
I first started work on Gantt in the last month of my internship.
Frappe Gantt was a nice project to work on. It was one of Frappe's most popular libraries, before a lack of maintanence had made it quite buggy and outdated. It had 145 GH issues when I started, and I figured it would be a good "end-to-end" project.
I wanted to bring it up to the standard before the end of my internship. The - perhaps unsurprising - problem with end-to-end projects is that the end never really comes, there is always more to do.
Broadly, I had three purposes in April: improve the UI, add a couple of the most-requested features - like a fixed header, more time views, edit access, export - and make Gantt seem maintained - that's fixing GH Issues and improving the tooling.
So over the course of the month, I closed more than a hundred issues, and took this...
... and made it this:
(I was quite proud of it back then, though when I returned I would think it sucked.)
I had tried to upgrade the tooling at the last minute and royally messed up, so I left with a huge dangling PR.
I then went to a summer camp that sadly didn't allow laptops, and when I returned, my mentor was in sabbatical, so I didn't really work on Gantt much except for a brief session in September while I merged that PR, slightly broken it might be.
I joined Frappe as a full-time employee on my birthday; the 28th of November. My first project was to wrap up Gantt - there was still a decent amount of work to do. I first started by working on two features I hadn't got to in April: more view modes and exporting.
Gantt already provided for a sizeable number of view modes - hour, quarter day, half day, day, week, month, and year. But people kept asking for more. The codebase also had the details of all view modes hard-coded: for example, here's a snapshot:
if (view_mode === VIEW_MODE.HOUR) {
this.options.step = 24 / 24;
this.options.column_width = 38;
} else if (view_mode === VIEW_MODE.DAY) {
this.options.step = 24;
this.options.column_width = 38;
} else if (view_mode === VIEW_MODE.HALF_DAY) {
this.options.step = 24 / 2;
this.options.column_width = 38;
} else if (view_mode === VIEW_MODE.QUARTER_DAY) {
this.options.step = 24 / 4;
this.options.column_width = 38;
} else if (view_mode === VIEW_MODE.WEEK) {
this.options.step = 24 * 7;
this.options.column_width = 140;
} else if (view_mode === VIEW_MODE.MONTH) {
this.options.step = 24 * 30;
this.options.column_width = 120;
} else if (view_mode === VIEW_MODE.YEAR) {
this.options.step = 24 * 365;
this.options.column_width = 120;
}
Now, Gantts are time-based charts. Everything changes with the view mode. You can imagine how this plays out - there is a ton of bloat.
So I extracted all view mode related configuration to one JS object (thanks to @moradlarbi for their help here!). This reduced the codebase by ~15%, and more importantly, made it a lot cleaner. Users can also add their own view modes very easily now.
I then worked on a cool feature that nobody else seems to have - ignoring regions. Gantt charts are often used by companies to track tasks and progress on them, and companies have holidays - weekends and others.
I had already added holiday highlighting in April - but I wanted to not just visually indicate holidays, but actually exclude some regions from the chart for all purposes - for example, progress calculation.
I got quite cranky while building this one - so many annoying little bugs cropped up. But I felt great when I shipped it. Try out this feature with the ignore
option!
Next, I pushed a few more features (like infinite extension), and made Gantt far more configurable. I patted my back - I was 90% done, just one demo, and we could release v1 soon.
This was around mid-December. So I then started working on an interactive demo. I'd done a lot in two weeks, so I - overestimating, I thought - said that I would be done with the demo before Christmas.
That was, put generously, a flop. I finally published the demo on the 8th of January, almost three weeks after I planned.
There were a couple major reasons for this. The most important reason is that while working on the demo, I was now seeing things from a user's perspective, not the developer's. When you're in the driver's seat, you might not love your driving, but you probably don't hate it. When you're actually using the product, though, it's harder to ignore stuff.
Sitting in the passenger's seat was not good for my ego. Gantt still had tons of usability issues. It was flaky. It looked unprofessional.
So I would start work on one bit of the demo, spend thirty minutes and discover so many things to fix, and spend the rest of the day fixing them.
It burnt a lot of time - minor ironing out is far more time-consuming than major feature work, as you're constantly switching context. But Gantt is a far more stable, reliable, product now, so it was definitely worth it.
Two other things I overhauled while working on the demo were the API and UI. Users previously couldn't change the Gantt chart easily after rendering. Now, we have a complete API for all your needs, including a specialized one for the popup (another new feature! It used to be a non-interactive tooltip). We also support "theming" - all the colors can be changed simply with CSS variables.
A lot of time was put into improving the UI. My mentor, Faris Ansari, was very particular on this. I definitely struggled with this one. Back in April, after a couple horrendous prototypes from me, Faris provided a Figma design that I could use. We decided to go even further now - we've based our new design off our internal Calendar designs and Notion's Gantt.
Design work can be frustrating occasionally because of the low output-to-time ratio - good design is essentially about experimentation, and experimentation is very random. You won't regret the time put in when you do get a good design, though, and Gantt looks pretty good to me now:
One other reason for the delay is that I always find demo/docs/tests quite boring compared to the "real" coding work. This problem was exacerbated by the fact that I had to use Frappe Builder, as all our demo sites are on it. It was my first experience with Builder. While it seems great for HTML/CSS website, my demo involved a lot of scripting, and the experience was very subpar.
(That said, Builder is our product - I compiled a rather long feedback list and sent it to Builder's engineer, so it's a net positive for Frappe.)
So here we are, finally publishing v1. The tooling is upgraded, the codebase is sleeker, the customization is huge (almost 2x more options), the UI is professional. We have a demo and comprehensive documentation.
Frappe Gantt is now a mature library.
Use Gantt in your projects now! Install through NPM:
$ npm install frappe-gantt
Or use directly from the CDN:
<script src="https://cdn.jsdelivr.net/npm/frappe-gantt/dist/frappe-gantt.umd.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/frappe-gantt/dist/frappe-gantt.css">
I will be working on Frappe Drive now (stay tuned), but please do offer your feedback - let's make Gantt a better product together.