Dynamic Step List Summary Text with Custom CSS

So I came up with a solution to a problem, and it may not be pretty, but it works!

So here is my problem:
I have this step component in the sidebar, and it looks nice

That sure is a lot of wasted vertical space :frowning:
Sadly, there is no GUI option for a caption, or second line
image

So, how do we solve this? I really would like to show something under each step, with something that is a summary of each step....

The Solution

It consists of one transformer (StepListCSS) that generates the CSS and one variable (StepListCSS_Data) that will store a mapping of the step keys to the value we want to show under each step.

The Variable

The initial value is simply the values as keys from the steps

{{ _.zipObject(app_steps.values, Array(app_steps.values.length).fill("")) }}

The Transformer

const steps = {{ app_steps.data }};
const currentStep = {{ app_steps.selectedIndex }};
const stepData = {{ StepListCSS_Data.value }};

return steps.map((step, i) => {
  const content = stepData[step.value];
  return `
  ._retool-app_steps ol > li:nth-child(${i+1}) > div > div:last-child:after {
    /*border: 1px solid yellow;*/
    display: ${currentStep > i ? "block" : "none"};
    padding-left: 5px;
    font-size: larger;
    color: #870bc8;
    content: "${content}"
  }`;
}).join("\n");

Here we compose some blocks of CSS, that target the step containers' list items. For each index, we add some :after that has content. The value of content is referenced from the variable we setup earlier.

Finally, add the transformer to your Custom CSS input for the app's settings.
image

Usage

In a query, or from a button, use the setIn method on the variable we defined erlier. For example, this is in a query that "saves" my "step 1"

const key = app_steps.data[0].value;
const formatted = numbro(rawValue).formatCurrency();
StepListCSS_Data.setIn([key], formatted);

Result

A beautiful summary of the step
image

Thank you for coming to my Ted Talk

3 Likes

Ooh I like this! Thanks for sharing, @khill-fbmc! :fire:

1 Like

This is a nice workaround! I like the visual flow of it.

I really love how it turned out :slight_smile:
image

And I actually came up with a better solution to display the step values. Instead of a variable saving each step by key, I now have a second transformer that emits an array with the corresponding values at the proper indexes. This eliminates the need for matching keys and using setIn completely! :partying_face:

StepListCSS_Content

const percent = (v) =>
  numbro(v * 100)
    .format({ mantissa: 1 })
    .concat(" %");
const dollars = (v) =>
  numbro(v).formatCurrency({
    spaceSeparated: true,
    mantissa: 2,
  });
const dollarsPerHour = (v) => `${dollars(v)} / HR`;

return [
  dollarsPerHour({{ TTC_LOAD_PER_HOUR.value }}),
  percent({{ CLIENT_REVENUE_PERCENT.value }}),
  dollarsPerHour({{ PER_HOUR_RESOURCE_COST_ALLOC.value }}),
  dollarsPerHour({{ USE_CASE_COST_ALLOC.value }}),
  dollarsPerHour({{ FULLY_BURDENED_AGENT_COST.value }}),
  dollarsPerHour({{ BILL_RATE.value }}),
  "per_position_revenue", // TODO
];

StepListCSS

const steps = {{ app_steps.data }};
const currentStep = {{ app_steps.selectedIndex }};
const stepData = {{ StepListCSS_Content.value }};

return steps.map((_, i) => `
  ._retool-app_steps ol > li:nth-child(${i+1}) > div > div:last-child:after {
    display: ${currentStep > i ? "block" : "none"};
    padding-left: 5px;
    font-size: larger;
    color: #870bc8;
    content: "${stepData[i]}"
  }`
).join("\n");
2 Likes

very nice!