Kanabish: a Kanban board plugin for Outerbase with Slack integration

rhutik parabrhutik parab
7 min read

Introduction

Hi, I'm Rhutik Parab, a software developer and a hackathon enthusiast. In this blog post, I'm going to share my experience of participating in the hackathon organized by Outerbase, the interface for your database.

Outerbase is a platform that lets you access and manage your databases in a secure, cloud environment. You can run queries, visualize data, collaborate with your team, and more. Outerbase also supports plugins that extend its functionality and integrate with other tools.

I started my project one day before the deadline. thankfully deadline got extended which helped me in polishing the project and writing this blog for submission.

For the hackathon, I decided to create a plugin named Kanabish that shows a Kanban board for the database table.

Demo Video

Note: if the video is not visible use this link :-https://drive.google.com/file/d/1YXPyS5OJqqJ8KJkpSEGRK_0P2TwdLWgK/view?usp=sharing

What is Kanabish?

Kanabish (It is not what you are thinking! It is a combination of Kanban and Hash) is a plugin for Outerbase that adds a Kanban board view to your database table. A Kanban board is a visual tool that helps you manage your workflow by dividing it into stages or columns. Each stage represents a step in your process, and each item in the stage represents a task or a record. You can drag and drop items from one stage to another as they progress through the workflow. Kanabish lets you create a Kanban board from any table in your database, and customize the stages and the fields to display.

But that's not all. Kanabish also integrates with Slack, the popular communication platform for teams. You can set up a Slack channel for your Kanban board, and get notified whenever an item changes its status. This way, you can keep track of your progress, collaborate with your teammates, and get feedback from your stakeholders.

Why did I create this plugin?

I wanted to create a plugin that would make it easier for me and my team to manage our projects and tasks using Outerbase. I thought it would be useful to have a kanban board view for our database tables, where each row would be a card. This way, we could see at a glance what we need to work on, what we have completed, and what we have pending. We could also update the status of our tasks by simply dragging and dropping the cards from one column to another.

Additionally, I wanted to integrate Slack with this plugin, so that we could get notified whenever the status of a task changed. This would help us stay on top of our work and communicate better with our team members.

Implementation

Since code was 1400 lines i did not add it over here but entire plugin code can be viewed on github:- https://github.com/c0deb1ind31/kanabish-outerbase-plugin/blob/main/table-plugin/kanabish-outerbase-plugin.js

Kanban Board plugged into outerbase

kanaban board shows all the rows as cards and sorts them based on the status column in the table, when we drag and drop the card to new status place it picks up the previous status and also the new status along with row id and makes a fetch to outerbase command which than updates the row based on id and also send a slack notification to the slack channel.

Slack notification

Code for outerbase commads

UPDATE public.tasks SET status={{request.body.status}} WHERE id={{request.body.id}};
function userCode() {
  let statusRel ={
    'to-do':"TO DO🎯",
    'work-in-progress':"WORK IN PROGRESS🕒",
    'under-review':"UNDER REVIEW📝",
    'completed':"COMPLETED🎉"
  }
     const id = {{request.body.id}}
    const taskName = {{request.body.title}}
    const taskNewStatus = {{request.body.status}}
    const taskPrevStatus = {{request.body.previous}}  
   const msg = `#Board-${id}, *${taskName}* has been moved from *${statusRel[taskPrevStatus]}* to *${statusRel[taskNewStatus]}*`;
   fetch(
    "https://hooks.slack.com/services/<YOUR-WEBHOOK-ID>",
    {
      method: "POST",
      body: JSON.stringify({ text: msg }),
      headers: {
        "Content-type": "application/json; charset=UTF-8",
      },
    }
  );
}

Command fetch to be integrated in code

Currently i hardcoded the fetch url due to time constaint but as a future scope we cant take url from configuration panel.

fetch("https://polite-aquamarine.cmd.outerbase.io/update-status", {
  'method': 'POST',
  'headers': {
    'content-type': 'application/json'
   },
  'body': '{"status":<card-new-status>,"previous":<card-previous-status>,"title":<card-title>,"id":<card-id>}'
})

Create New Task

On clicking add entry the pop up takes the status from where the add task has been click and opens a pop up, here you can add your new task. when you click submit it send a request to outerbase command to create new row. as i was unable to integrate adding new row from table view plugin due to some bug in table view plugin triggers were not working, so i had to use commands to create new row, but once trigger bug gets fixed we can directly add new row and save it, keeping this as future scope.

Code for outerbase commads

INSERT INTO public.tasks (name, assigned_to, description,doc_link , priority, project_tag,due_date,status) VALUES ({{request.body.name}},{{request.body.assigned_to}},{{request.body.description}},{{request.body.doc_link}},{{request.body.priority}},{{request.body.project_tag}},{{request.body.due_date}},{{request.body.status}});
fetch("https://polite-aquamarine.cmd.outerbase.io/create-task", {
  'method': 'POST',
  'headers': {
    'content-type': 'application/json'
   },
  'body': '{"assigned_to":<data>,"description":<data>,"due_date":<data>,"priority":<data>,"doc_link":<data>,"status":<data>,"name":<data>,"project_tag":<data>}'
})

Delete a task

To delete a task you have to click on delete button, it filters out the deleted row and re-renders the component and sents a delete request to outerbase command with the row id, also this can be done directly from table view without using commands, as i disucussed above due to table bug i could not save it.

Code for outerbase commads

DELETE FROM public.tasks WHERE id={{request.body.id}};
fetch("https://polite-aquamarine.cmd.outerbase.io/delete-task", {
  'method': 'DELETE',
  'headers': {
    'content-type': 'application/json'
   },
  'body': '{"id":<row-id>}'
})

How i implemented the drag and drop feature.

when user drags the card i get the data such as title, id, currentStatus, previousStatus of the card html element. the id is taken from the html element data attribute. this id is also the id of row in the table. once user drops the card in new block, i transfer all the data to new block and send a update fetch request to the commands with data provided.

<div class="board" data-status="${status}">
  <div class="board-body">
    <div
      class="board-card"
      draggable="true"
      id="task${id}"
      data-pkid="${id}"
    >
    // rest code for board card
    </div>
  </div>
</div>
//rest of the boards
    let kanbanBlock = this.shadow.querySelectorAll(".board-body");
    kanbanBlock.forEach((el) => {
      el.addEventListener("drop", (ev) => {
        drop(ev, this.shadow);
      });
      el.addEventListener("dragover", allowDrop);
    });

    let tasks = this.shadow.querySelectorAll(".board-card");
    tasks.forEach((el) => {
      el.addEventListener("dragstart", drag);
    });

    function drag(ev) {
      console.log(ev);
      ev.dataTransfer.setData("pkid", ev.target.dataset.pkid);
      ev.dataTransfer.setData(
        "prevStatus",
        ev.srcElement.parentNode.parentNode.dataset.status
      );
      ev.dataTransfer.setData(
        "title",
        ev.srcElement.childNodes[3].childNodes[1].innerText
      );
    }

    function allowDrop(ev) {
      ev.preventDefault();
    }

    function drop(ev, shadow) {
      ev.preventDefault();
      var pkid = ev.dataTransfer.getData("pkid");
      var title = ev.dataTransfer.getData("title");
      var prevStatus = ev.dataTransfer.getData("prevStatus");

      const status = ev.currentTarget.parentNode.dataset.status;
      if (pkid && title && prevStatus !== status) {
        //call to outerbase commands
        updateTaskStatus(pkid, status, prevStatus, title);
      }
      ev.currentTarget.insertBefore(
        shadow.querySelector(`#${data}`),
        ev.currentTarget.children[0]
      );
    }

The Challenges

I faced some challenges while building the plugin. One of them was that the table plugin view was not adding and saving new rows dynamically. This meant that I could not add new tasks to the Kanban board from within the plugin. Instead, I had to use the command feature to add new row in the table.

Another challenge was that I ran out of time before finishing the plugin. I started my project one day before the deadline, which was not a very smart move. I underestimated the complexity and scope of the project and thought I could finish it in a few hours. However, I soon realized that it was not as easy as I thought and I had to spend a lot of time debugging and testing my code.

Future scope

In the future, I am planning to make Kanabish a full-fledged plugin for task/project management that includes: a Dashboard view, Kanban board view, Timeline view, Workflow view, and Calendar view.

I also want to add more integrations with other platforms and services, such as Google Calendar, Gmail, Twillio, Mailgun, Discord Etc.

Conclusion

I hope you enjoyed reading this blog post and learned something new about Outerbase and Kanabish. I had a lot of fun building this plugin and participating in the hackathon. I want to thank Outerbase for organizing this event and providing such an amazing platform for data enthusiasts, I'm also planning to make open source contribution to Outerbase as I liked what the Outerbase team is doing and how they are revolutionizing the way we work with databases. I think Outerbase has a lot of potential and room for improvement and I would love to be a part of it.

If you have any questions or feedback, please feel free to leave them in the comments section below or reach out to me on Twitter (@rhutikparab)

Happy hacking!

#Outerbase #OuterbaseHackathon

5
Subscribe to my newsletter

Read articles from rhutik parab directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

rhutik parab
rhutik parab

I'm a software developer and tech enthusiast from India. I love to fiddle with new technologies and explore their potential. I enjoy learning new skills and solving problems. I'm always looking for new challenges and opportunities to grow as a developer and a person.