Skip to main content

Create an Issue Tracker App with Supabase - Part 2 Customize Your App

· 5 min read
Adam Kovacs

This article aims to further customize you existing Issue Tracker application described in "Create an Issue Tracker App with Supabase in 15 Minutes".

info

This article is part of a series. If you haven't read the first part, you can find it here.

Create an Issue Tracker App with Supabase and Windmill

tip

Windmill has a community website called Windmill Hub where - among other Scripts and Flows - you can find the full version of this App.

Where we left off

In the previous article, we created a basic Issue Tracker application with Supabase. We uploaded a few issues, displayed them in a table and created scripts to add new ones and delete them. There is only one part missing of the CRUD functionality - updating the issues.

Updating issues

For now, we are going to enable users to update only the status and the severity properties of an issue but feel free to customize it your needs. Let's start with adding titles for the update form:

  1. Insert a Text component.

  2. Enter Update Issue as the input.

  3. Select Subtitle as the style.

  4. Align it vertically on the bottom.

  5. Insert below a second Text component.

  6. Enter ${b?.selectedRow?.summary || '(Select a row in the table)'} as the input.

    tip

    The b variable is a reference to the Table component. If you have a different ID for it, you need to change it accordingly.

  7. Enter color: #6e6e6e; in the Extra Style argument.

Update issue form title

Next, we need to add a Select component for the status property:

  1. Insert a Text component.

  2. Enter Status as the input.

  3. Select Label as the style.

  4. Align it vertically on the bottom.

  5. Insert below a Select component.

  6. Enter these 3 items in the Configuration:

    { "label": "PENDING" }
    { "label": "WORKED ON" }
    { "label": "FINISHED" }
  7. Set the Item Key argument to label.

Status field of the update issue form

Repeat the previous steps for the severity property as well but with the following items:

{ "label": "LOW" }
{ "label": "MEDIUM" }
{ "label": "HIGH" }

Severity field of the update issue form

Finally, we need to add a Button component to submit the form:

  1. Insert a Button component.

  2. Enter Update Issue as the Label.

  3. Align it to the bottom-left corner.

  4. Find the ID of the Load Issues background runnable and check Recompute on it in the Recompute others section.

  5. Click Create an inline script, select Deno as language, name it Update Issue and paste in the following code:

    import { createClient } from 'https://esm.sh/@supabase/supabase-js@2';

    type Supabase = {
    url: string;
    key: string;
    };

    export async function main(auth: Supabase, issue: any, status?: string, severity?: string) {
    if (!(issue && (status || severity))) {
    return 'Make sure that an issue is selected in the table';
    }
    const client = createClient(auth.url, auth.key);
    await client
    .from('issues')
    .update({
    ...issue,
    status: status || issue.status,
    severity: severity || issue.severity
    })
    .filter('id', 'eq', issue.id);
    return '';
    }
  6. Select your Supabase resource for the auth argument of the script in the Settings pane on the right.

  7. Select the selectedRow property of the Table component for the issue argument.

  8. Select the result property of the corresponding Select component for the status and severity argument.

Update issue form submit button

More charts

Now that we have a fully functional issue tracker, let's add one more chart, namely a line chart to display the number of issues in the past days. Let's start with adding a Number input to control how many days we want to display:

  1. Insert a Number component.
  2. Enter Days as the Placeholder.
  3. Enter 30 as the Default Value.

Next, create a title for the chart and use the value of the recently added number input:

  1. Insert a Text component.

  2. Enter Number of Issues Created in the Past ${ac.result || 30} Days as the input.

    tip

    The ac variable is a reference to the previously added Number component. If you have a different ID for it, you need to change it accordingly.

  3. Select Subtitle as the style.

  4. Align it vertically on the bottom.

Title of number of issues created in the past days chart

Lastly, add the actual chart component to display the data:

  1. Insert a Bar/Line Chart component.

  2. Toggle the Line attribute.

  3. Click Create an inline script, select Deno as language, name it Last Issues Chart Data and paste in the following code:

    export async function main(issues: { created_at: string }[], days: number = 30) {
    if (!issues?.length) {
    return { data: [], labels: [] };
    }
    const dates = [...Array(days)]
    .map((_, i) => {
    const d = new Date();
    d.setDate(d.getDate() - i);
    return d.toISOString().split('T')[0];
    })
    .reverse();
    const issueNumbers = dates.map((date) => {
    return issues.filter(({ created_at }) => created_at.startsWith(date)).length;
    });
    return {
    data: issueNumbers,
    labels: dates
    };
    }
  4. Select the result property of the Load Issues background runnable for the issues argument.

  5. Select the result property of the recently created Number component for the days argument.

Responsive layout

Before finishing our app, the final step is to make the layout responsive. The component layout can be configured in 2 views: desktop and mobile, which can be toggled in the header row, next to the Editor-Preview mode switch. The desktop view is used by default and is shown when the window width is greater than 690px and the mobile view is shown when the width is less than or equal to 690px. The views are saved separately, so moving the components around in one of them will not affect the other. Let's switch to the mobile view and place the components to resemble the following layout.

Mobile layout of the issue tracker app

Windmill Logo
Windmill is an open-source and self-hostable serverless runtime and platform combining the power of code with the velocity of low-code. We turn your scripts into internal apps and composable steps of flows that automate repetitive workflows.

You can self-host Windmill using a docker compose up, or go with the cloud app.