New features to Planner Gantt Chart app

The following couple of features are added to the Gantt Chart App. They are introduced below. Meanwhile, if you just want to go ahead and download the latest version of the app, you can do so here.

Feature #1: Task status indicator

You can now quickly see whether your task is Not Started (red hollow circle), In Progress (yellow half filled circle) or Completed (fully filled green circle).

Feature #2: Star rating

Upper right hand corner on the start screen now contains a 5-star rating indicator that displays current average of stars the app users have given to the app.

Users can click on the desired star to cast in their own vote.

And as a bonus: you can click as many times as you like, and they all count 😆

Feature #3: App versioning and visibility to the latest version

Header ares of the start screen now also contains information about the current installed version of the app as well as the lates available version in GitHub!

Current version number of the app is something that I manually maintain whenever I edit the app in canvas studio. You can find it as the first row in App OnStart.

The latest GitHub version is something bit more magical… You might have read my recent article titled “Sending and receiving data in your Power Apps canvas app without ANY connector!“. Well, I’m using similary mechanism as in that experiment. Only this time – instead of fetching chat messages from Azure storage table – I’m fetching the latest commit date from GitHub as the latest available version number.

Fetching the GitHub commits is quite straight forward. Below is my entire function code. It’s also available in the same repository with the Gantt Chart package.

    public static class fnGetLastCommitDate
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", 
            Route = "GetLastCommitDate/{cacheInvalidator}/{charIndex}/img.jpg")] HttpRequest req,
            int charIndex,
            ILogger log)
            if (charIndex > 7)
                log.LogInformation("char index:" + charIndex);
                log.LogInformation("End of message -> E");
                return GetImageResultForCharacter('E', log); // As in End

            string patToken = Environment.GetEnvironmentVariable("GitHubPatToken");

            using (var client = new HttpClient())
                client.DefaultRequestHeaders.Add("Accept", "application/vnd.github+json");
                client.DefaultRequestHeaders.Add("Authorization", "Bearer " + patToken);
                client.DefaultRequestHeaders.Add("X-GitHub-Api-Version", "2022-11-28");
                client.DefaultRequestHeaders.Add("User-Agent", "terhoantila");

                var response = await client.SendAsync(new HttpRequestMessage(HttpMethod.Get,
                using (var ms = new MemoryStream())
                    await response.Content.CopyToAsync(ms);
                    ms.Position = 0;
                    using (StreamReader reader = new StreamReader(ms))
                        var commit = JArray.Parse(reader.ReadToEnd()).First;
                        var date = (DateTime?) commit["commit"]["author"]["date"];
                        var dateStr = date.Value.ToString("yyyyMMdd");
                        log.LogInformation("Date:" + dateStr);
                        log.LogInformation("Char index:" + charIndex);
                        var c = dateStr[charIndex];
                        log.LogInformation("Char:" + c);

                        return GetImageResultForCharacter(c, log);

        private static FileContentResult GetImageResultForCharacter(char v, ILogger log)
            var returnCode = GetCodeToMatchHeight(v);
            log.LogInformation($"IMAGE HEIGHT: {returnCode}");
            var img = new System.Drawing.Bitmap(1, returnCode);
            using (var ms = new MemoryStream())
                img.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
                return new FileContentResult(ms.ToArray(), "img/jpg");

        private static int GetCodeToMatchHeight(int desiredHeight)
            // 26 -> height 32
            return desiredHeight - 6;

Feature #4: Information page

I added additional screen to the app which user can enter by clicking on the large circular i-icon on the home screen.

The info screen provides links to my blog and to the GitHub repository where to download the latest version of the app, if one wishes to update it. Tha page also displays the current app version as well as the latest version available, and instruct the user to update the app if the versions differ.

Leave a Comment

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s