As the Katapult Pro software platform continues to grow and mature, it is becoming more important for our clients to have control over the various configurable aspects of the software. The Logic Editor in Katapult Pro gives users an easy-to-use interface where users can build out logical statements and scriptlets, analogous to Microsoft Excel functions, with as much or as little complexity as they require.
These Logic Editor blocks are organized in a tree-like structure, as shown in Figure 1. The root of the tree is the top-leftmost “node” (a "Logical And” expression here), and the leaves are connected by the lines extending from the root. Leaves can be “dead-end” blocks or branch out into other trees.
The data in Figure 1 has three trees in it. The first is the outer tree with a “Logical And” expression as its root, and leaves containing two other trees. The top inner tree has a root of “Equal” and leaves of a data block and a literal text block, while the bottom inner tree has a root of “Not Equal” and leaves of a data block and a literal text block. Just like with an Excel function, these expression trees dictate the conclusion of the Logic statement.
Logic Editor statements are made up of Logic blocks. Figure 2 depicts an expanded “Logical And” expression block. All blocks have a header and a collapsible details section. The block type determines what sections are seen when the block is expanded (reference Figure 2).
The block header has:
A short description of the block’s type and contents
An expand/collapse details button (single-arrow)
An expand/collapse all leaves button (double arrow)
A three-dot block management menu
The three-dot menu has several options for manipulating the block (reference Figure 2). You can:
Wrap the block in an expression, making the current block a leaf of a new expression
Convert the block to a procedure
Copy the block to the clipboard
Paste the block from the clipboard (replacing the current block and all its leaves)
Delete the block (and all its leaves)
Confirmation prompts appear when an action you are about to take (deleting or pasting) may result in data loss. This prompt can be bypassed by shift-clicking on the action.
There are four types of Logic blocks that can be used to make statements. These are: (1) expression blocks, (2) data blocks, (3) literal blocks, and (4) procedure blocks.
Expressions are the most fundamental Logic block. Akin to Excel functions, they tell the interpreter to take one or more input values, perform an operation on them, and hand back the resulting value. Because of this input-output system, expression blocks can be nested into trees, where the result of one expression can be an input for another, "parent" expression. Remember, the final “return value” of the entire statement is whatever the root block returns; if the root block is an expression, the statement’s return value is whatever that expression resolves to.
Each expression block has a drop down menu, which allows the user to select the expression’s operator. A description of the currently selected expression is displayed at the bottom of the Logic block under "Description." The block’s footer details the data type that the block will return, as well as a list of the expression’s inputs and their expected types. The leaves of a block are the block’s inputs (often called arguments). Order matters here. This expected order is the order of the items listed in the block’s footer.
Expressions as Arguments
Take a look at Figure 3. This expression (using the “Count If” operator) will count the number of items in a given list (the first argument) that pass a given condition (defined in the second argument). In order for this example block to be evaluated correctly, the first leaf of this block would need to be a block which produces a list, and the second leaf of this block would need to be a block which results in a true or false statement. Note: in this statement, both arguments are expressions, but the first produces a list (“List Object Values” returns a list of items) and the second is an expression that will be called for each of that list’s items.
Some expressions loop through a given list, which means that the user might want to access each item of the list individually. For these kinds of expressions, this can be done by setting the Item Data Key value, which is located below the description. You can input what you want the name of a given item taken out of the list to be into the text box, then you can use this identifier in any data block of any subtree of this expression whenever you want to access the value of this item. For reference, this kind of behavior is shown in Figure 3 in the data block with the word “item”.
Data blocks produce values from within the Logic statement’s data source (compare these to the data contained in cells and sheets that Excel functions have access to). Each implementation of Logic in Katapult Pro has a data source object that the editor can access (for example, the Quality Control Logic Editor provides data access to a Katapult Pro job, its metadata, photos, nodes, etc.). Data blocks, together with expression blocks, allow you to develop meaningful statements and functions with real data.
The exact value returned from a data block is specified with the “Path” input in the block’s details section. Without the path, data blocks would always return all of the data the statement has access to, which is not at all useful. Instead, the path input allows you to enter the location of the data you want to use.
Paths are formed by stringing entity names together with periods. This is called a dot-delimited path; it is similar to slash-delimited paths like what you see in a filesystem or URL, but using periods instead of forward slashes. Take a look at the job JSON data in Figure 4. If the user wanted to access the job’s name, their path input would be simply name, and a data block with that path would return “Colin Test”. A more complicated example: say the user wanted to know the value of the “Done” attribute of the first node. The path would look something like this:
Notice: in this example, we know the node’s ID (-N6iz7gzKB2N5x_UZvLe) but we might not know the key under the done attribute (as this key can be different from job to job). So instead of guessing, we use the * wildcard. This path delimiter effectively says: I don’t know what the exact key is here, just give me the first thing you can find. In this case, it finds the one and only key under “done” and completes the path. Thus, the value “false” is returned.
In expressions where you’re working with list data, the items from that list can be accessed with the value given to the expression’s Item Data Key input. In the data block of Figure 3, the value of the item data path becomes whatever list item the expression is currently on, so the data block under the “Equal” expression (item.firstName) will return whatever is that list item’s “firstName” property.
A literal block allows you to define a one-time, unchanging value for use in calculations (think constants). Users can define several types of literal values:
Boolean values (which are either TRUE or FALSE)
Text value (like “Bryan” from Figure 3)
Custom lookups (dictionaries with key-value pairs)
A collection of special values (new line characters, tabs, null etc.)
If you wanted to see if some data value was equal to the number 0, you would use an “Equal” expression block, a data block to access the value in question, and a literal block with “Value Type” of “Number” and a “Value” of 0.
A procedure block allows you to:
Split your Logic statement into sequential steps whose results are saved as variables you can use in other statements (via the Data block type)
Set the context or environment for the ending Logic statement
Figure 5 depicts the structure of a procedure block. All variables are defined inside the procedure block’s details section ("condition" and "count"). When you add a new variable, it is added to the list inside the block, and it becomes the root of a new tree attached to the procedure block. You can then build a statement on this new root whose result can be accessed by using the given variable name.
These “steps” are run from top to bottom, and as each statement is evaluated, the result is added to the Logic statement’s dataset under the provided variable name. Subsequent procedure steps have access to these variables. Their values can be accessed by creating a data block and entering the variable name in the “path” input. You can see an example of how variables are accessed in Figure 5, where the “condition” and “count” variables are used in the ending if-else block.
The final value of a procedure Logic block is whatever the last block (called the “return” block) evaluates to. Variables created in a procedure are “scoped” (available to) the procedure block and its leaves only. Variables are not permanently added to the dataset; they are unavailable outside of the procedure in which they were defined.
Thanks for reading! If you have any questions, reach out to us at email@example.com or 717.430.0910. How can we improve our documentation? Let us know in the comments below!