Hi folks,
As we try and grow the Tulip Community, I wanted to start committing to regular content posts that help explain certain app concepts, new features, or apps that we on the Customer Team may be testing out. The plan to start will be posts every two weeks, which will hopefully grow more frequent if these seem helpful. I’d like to also open this up in the future and structure posts as a response to specific asks from the prior week. Please leave any and all feedback to help structure this in the most useful manner.
For the first post, I wanted to cover an application structure that I’ve been working on closely with several customers. I want to try and distill this down to it’s most generic format, explain how the application functions, and then give a little context into how it’s being used today. I’m a little split on how much detail to go into so please if there are any follow up questions, I’m happy to respond to any questions.
NOTE: This does require more advanced knowledge of Tulip including SQL connectors, although provides the basic queries needed to run.
Application Goal:
Provide a dynamic, interactive view into a database to manage states. For this article, I’m going to build a quick app to manage tasks.
Use Cases:
Work order management, audit task tracking, material requests and replenishment, parts picker, etc.
Application Overview:
Before we go any further, I want to show what this app will enable you to do.
SQL Database
Currently, this application does require a SQL (Structured Query Language) database to function. In the Tulip Knowledge Base there’s a few different instructions on how you can spin up your own database and connect to Tulip, so I won’t expand much further on that, but feel free to reach out with questions. One thing to note about SQL - while it’s a standard language, it has different dialects per provider (MySQL, MS SQL, PostgreSQL, etc.).
Once you have a database created, you can use SQL clients to easily visualize the underlying structure. Personally, I’ve used Postico (PostgresQL - Mac) and DBeaver (universal).
Table Structure
The columns in the table represent the following. As previously mentioned, this can be structured in many different ways with different pieces of information.
id - A primary key (unique identifier) for a task
Task - The task to be completed
Status - Defaults to requested, while move to in progress before final completion
Creator - Name of the person creating the request
Assigned - Name of the person the task is assigned to
Request Date - Date the request is made
Completion Date - Date the request is completed
Tulip Connector Functions
Once your database is connected to Tulip and the the table above has been created, we’re ready to start building functions to be used. There’s many tools to help learn the basics of SQL, so I don’t want to focus too much on this.
NOTE: This development typically happens in parallel with the application, building additional functions when the need arises.
This application will use three types of functions:
- Display Open Tasks
A few notes about the above query. SELECT
allows us to map individual columns from our database to outputs of this function. We’re mostly mapping one-to-one, with two exceptions. Request date (stored as a timestamp) is being split into a date and time output using the substring
keyword - essentially focusing on a set characters from the timestamp.
The FROM
identifies the name of your table. As the name suggests, this function should only return the open work orders, so we add a WHERE
clause to exclude any work orders with a complete or cancel status. Lastly, we order the tasks by the date and time so oldest requests will show higher up in the list.
Ensure the Return Multiple Rows checkbox is selected as we will be managing several tasks.
- Create New Task
This function will serve as our input into the table. When creating a task, the user will provide the task name, the name of the task creator, and the name of the individual the task is assigned to. These serve as inputs into the function, but we will also pass in the current time stamp as the request time using the NOW()
keyword which returns the UTC time, which we adjust for EST.
When running a test, we can see that the information is appropriately populated into the database, with the id and status being appropriately assigned.
- Status Changes
We’ll build status change functions for in progress, complete, and cancel. This can be expanded to any number of states but the general function is the same.
Use the UPDATE
keyword and the id (primary key) of the record to change it’s status accordingly. The only difference between these status changes is we most likely want to record a completion time for the complete/cancel status changes. When testing the function with our first task (id = 1).
Tulip Application Structure
The Tulip application is effectively two pages: the main view of the task list and the form to create a request. The app starts with a step open trigger that performs a few steps:
- Runs the Display Open Table connector function and saves to a variable
TaskList
, which contains a list of varying tasks - Stores the static value 0 into a variable called
Index
, which will keep track of where we are when navigating through open orders - Stores the length of TaskList into a variable called
Length
- Gets the first task from the TaskList and stores into a
CurrentTask
variable
These triggers are replicated in the refresh button.
The TaskList
is then shown in the top portion as a variable, which allows you to pick and choose the columns shown and order they’re shown in. The individual variables from CurrentTask
are broken down in the bottom section to show which task the action taken will record against.
The arrow icons navigate the TaskList
, repopulating the CurrentTask
with the next or previous option. This has a small amount of logic to make sure it loops appropriately (i.e. pressing the next button when on the last element brings you back to the first element).
The Create New Task button just navigates to the next step of the application, which has two form variables: the task itself and the user the task will be assigned to. Upon pressing the Submit button on this page, a trigger that runs the Create New Task connector function executes and the app completes and returns to the main page. The current user of the application is automatically filled in as the creator.
Lastly, the status buttons at the bottom all perform a similar function, where they run their associated connector functions using the id
field of the CurrentTask
and complete the app.
Results
From the recorded video above, we can see now the database keeps a record of the work orders, which can provide value from a historical perspective.
There’s also several ways for us to begin creating analytics around these applications. For example, when the app is complete, we could first perform a SQL calculation on the duration between completion and request times. This would allow us to trend average times tasks stay open, as well as keeping track of the number of tasks that are completed on a daily basis. I’d be happy to expand upon this further upon request.
This ended up being much longer than I originally anticipated, but hopefully it was helpful to provide an idea on how you could go about building your own application following this structure. The beautiful thing about this app concept is you could have many people interacting with this single application. A variation of this application is currently being used by ~15 people for material replenishment purposes, with plans to scale upwards of 80 people working from this same infrastructure.
If you’re interested in implementing an application of this nature, please reach out and I’d be happy to provide guidance. Let me know of any feedback or if there are any requests for a style of application you may like to see featured for the next post!
Best,
Grant