Conditional Workflow State Management

I have a common configuration: Tasks with optional Sub-Tasks, each their own dbase (not that it matters for my question, but I’ve also configured self-relations enabling Tasks to have dependencies on other Tasks and Sub-Tasks on other Sub-Tasks).

I would like to do something similar to this: How to update a task state when all subtasks related to it have a certain state. The twist I have is conditional logic that impacts the UI:

  1. If a Task has no Sub-Tasks, the Task’s State needs to be manually managed by a user
  2. If a Task has one or more Sub-Tasks, the Task’s State is inherited from the Sub-Tasks

I know how to implement 2. as I already have formulas running for a scenario like this. What I can’t quite work out is the best way to do “no Sub-Tasks” vs “with Sub-Tasks” which isn’t
confusing for users.

Claude.ai suggested I create three fields on the Task entity:

  1. Computed State (Formula field) - automatically calculated from Sub-Tasks
  2. Manual State (Single Select field) - for manual management
  3. Effective State (Formula field) - the actual state to display

Does this seem like a good idea? Is there a better approach? I will also have to do something similar for Start Date + End Date.

The main concern I have it showing 2 fields to the UI: I could hide Computed State, but would have to surface both Manual and Effective. I’ve searched the User Manual and Forums and it appears conditional or formula-driven “show / hide field” or “enable / disable field” has been suggested a few times, but not yet implemented.

Also, is the Workflow field type a flavor of Single Select or is there something special about Workflow fields I’d be giving up moving to a Single Select like the suggestion above?

Here’s a suggestion:
You have a State field in the Task db.
You have an automation (#1) that updates this value based on subtasks (if there are any).

(in this example, the parent Task takes the State value of the most progressed subtask, but your logic can be whatever you like)

You have an automation (#2) to override any changes made to the State value by a user, if the Task has subtasks (or accept the change if not)

1 Like

I like this approach. I have a Formula field that already has logic I would use for Automation #1 (if all child Entities = To Do, then To Do else if all child Entities = Done, then Done else In Progress). Automation #2 is a nice refinement. Thanks for the idea!

Ooooh tricky!
I’ll share thought process:

  1. Idea: Using automations. If someone sets it to done, but there are subtasks that are not done yet, set the checkbox back to undone. Not ideal, as the user might not know why its not setting to done. Another option is that when the parent task is set to done, it propogates to the subtasks and sets them all to done as well, but maybe that’s not desired… And undo-ing that would be tricky.
  2. Using the “Hide when empty” somehow. This might be cleaner in terms of UI on the entity view, but won’t really work in table view… If shown on the table, the users could still be able to edit the parent task without. It would work in most other views though! Let’s try it. The idea is to automatically add values / set values to empty based on if it has subtasks. Then it will only show the things that are not empty, and hide the things that are empty.

It works! Here it is:

Dates need to work differently as there is no “default” state for the date, so we can’t make it show for the user to set it. Plus, its nice to add dates on creation in the form. I think this balances user experience and data. Down side if that you have two field resposible for knowing if a task is done. But you could add another field to just pull the right percentage (either 100 is status is done, or the percentage value), for easier reporting and such. I added this after recording the video. Also! If you dont want the arrow to “show hidden fields” set it to 2 column, and pin the fields. Also implimented after recording video.

How it works:
Status:

Dates:

This was fun :))

1 Like

Thanks for alternative idea! The videos are super useful.

For State, I like the “hide field when empty” usage as a concern I had about introducing additional fields (like the Claude.ai suggestion) was confusing the UI with multiple fields having potentially unclear purposes. I knew about “hide field when empty”, but it didn’t click to use it until your suggestion.

Re: Dates, like with State, my aim is to place Date control on the Children (not allow on both Parent and Children), but if no Children, then of course allow the Entity’s dates to be directly managed. One way I could do this would be to have two Date fields (both configured with Start & End Dates)… one manual and another populated by a Formula looking for the min and max dates in Children Entities. Maybe I could use the Rules + “hide field when empty” trick there as well? Plus “Always require a value” and set the default Date range to sometime in the far past (so it’s super obvious it needs to be fixed) will drive Rules.

Question: The Template is on URL https://shared.fibery.io/sign-up?appShareId=56aa88c6-06ce-40da-a44d-216dddc7d8c7-daud which requires the creation of a new Workspace. How did you generate that URL? It would normally be https://shared.fibery.io/t/56aa88c6-06ce-40da-a44d-216dddc7d8c7-daud which obviously brings the Template as a Space into an existing Workspace.

Yeah for some reason when putting template link in the forums, they change… not sure why…
Glad you were able to get the right link though.

I’m glad :))

The core issue you’re trying to solve is using one database for two different type of things. Parent task, and sub task. This is generally bad practice, as it means half the time, half the fields are empty, but in the case of recursive parent/children its needed to be done like this.

Its harder with dates as there isn’t a default date, and we need to set a date on creation, or else the field will be hidden and then not accessible. But what i missed in my thought proccess before is that we can safely assume is that a task with no subtasks will always be created first. So indeed possible to ask for the date input on creation, then if there are subtasks created, clear the date range and hide it, and then show the formula. As done for the status, as you said!

The only down side is data input. Like you said, we could have a date in the past be the default, (if its empty on creation), this way it’s not empty when created, and then people can set it, but thats a bit finicky and not so nice for user, as then when you press the date, it will show the day selected, not today, effectively making the date picker useless (thought from the future as I was testing: setting the default date range to “Today - Today”, that way its still easy to edit). There are 2 other possible things. 1. Make a form and make it required in form, (not in the field, as then we can’t ever clear it), and set that to be the form that pops up when people press the plus button. Down side: some might press the “Add new” in-line and not the plus button, and then the form won’t pop up… and then they wont have a place to enter the dates when they create a task.

Another option: Make it part of the “Name by formula”, and add another field called “Title” or something. Then anywhere they create, it will ask for both the title and the date range.

Mocked it up here https://shared.fibery.io/t/56aa88c6-06ce-40da-a44d-216dddc7d8c7-daud.

I did both: 1. put it formula so a user can input on creation, 2. if its created with no daterange, it defaults to today.

(The name formula is a bit of a hack to make sure it shows, even though its not explicitly used, just because i like having smaller formulas in seperate columns, rather than one behemoth formula. This way you can also set automations if tasks are starting / due in a couple days)

And an extra edge case: if you add subtasks, then remove them, it will go back to the date range you made in the beginning on creation using the “Saved date range”

Sorry if this feels like a bit of a ramble, I think sharing thought process can be helpful.

Looking back at this though, it might make sense from a user input perspecive to ditch the Name Formula, and set the default to today-today. It’s slightly less convenient, but thats where you can tell them to just use the plus on the top right to create tasks, and not the inline tasks. And if someone accidentally does use the inline creation, it will still give them a place to set their dates afterwards.

Also! Since we have the backup in case its empty (today-today), we don’t need to make a new form and set a required field. We can just put it in the “Default form” that way that will be the default for all views, including the “Create anything”. This is safer, as people might not change to this form in the “Create anything” and then its not only not required, but doesn’t even show on the form.

Let me know if this makes sense. Happy to make a video if needed!

I have two databases…

I needed a Task / Sub-Task structure AND Dependencies, so I went for two databases. I guess I could have one this all in one database, but I thought it would be easier to manage and would (hopefully) discourage users from adding endless layers of Tasks. Now you know that, does this scenario trigger other suggestions?

What you’ve shown is pretty straight-forward (I’m somewhat new to Fibery and I can follow the ideas and Template), but I always favor implementing the least complex method to solve the problem (and thus least complex to maintain).

Aaaaah damn. I missed this in the first description. That said, actually its the same principles.

The sub-task database is much simpler though, as that needs not conditions, or automations. always just show state and date range.

Then the task database is the same as explained above. Sometimes it should act as it’s own task, and sometimes it should act as a “Subtasks container” which has different fields and different behaviour. So still its trying to use one DB as two different types.

So the parent can still work in the same way, while the subtask is much simpler. (I updated the template)

That being said, the way Chris suggested with automations is much neater from a data perspective as its all in one field, so more aligned with: 1 db, 1 data type. It won’t have fields that are empty half the time.

You are just sacrificing UX of users trying to click, and it just reverts back after a second. Technically its read only (as automation reverts any changes) but the the ui shows it that its editable.

You can achive the same thing with automation with dates, where if it has subtasks and the user tried to to change the task date, the rule will fire to set it back to the subtasks range.

It’s neater from a data perspective, but less neat from a user experience perspective. You can decide what you prefer!

I don’t see other viable alternatives for this other than these two, but maybe someone else will!

1 Like

I’m trying to implement your suggestion, but struggling a bit with Formula syntax and the AI helper isn’t delivering a valid result.

First, I am adding the Rule to my Task dbase (not Sub-Task dbase). Second, the trigger is:

When → Task Updated with the changed Field being a Formula that counts the Sub-Tasks under a Task plus a Filter for the automation to fire only on Task with >0 Sub-Tasks.

The State update logic I’d like requires IF / THEN, but I’m clearly not doing it properly:

(cutoff at bottom of Formula screenshot is just closing parens)

So, two questions:

  1. Am I overcomplicating the Rule with my Changed Field selection plus a Filter? What Change Fields did you select in your Rule #1 and Rule #2 suggestions?
  2. What’s wrong with my syntax (probably a couple things)?

I went through the various User Guide pages on Formulas as well as Automations, but couldn’t find an example where State was being manipulated, but may have missed it.

After many iterations, I landed on a solution combining ideas and tips from @Chr1sG, @RonMakesSystems, @Polina_Zenevich and @Kseniya_Piotuh. Apologies in advance for the length of this post: I wanted to include information on what didn’t work and why. Hopefully others find it useful.

Basic requirements:

  • One database called “Tasks” and another called “Sub-Task”. “Task” has a one:many relationship with “Sub-Task”.
  • If a Task has no Sub-Tasks, the Task’s State and Dates needs to be manually managed by a user.
  • If a Task has one or more Sub-Tasks, the Task’s State and Dates are inherited from its Sub-Tasks.

It’s possible to build this app with just a single Task database. In my case, there are additional levels above Task and I wanted a clear, obvious app structure for other maintainers. My approach might be blunt, but I believe it’s easier for less advanced admins (like me and my colleagues) to understand and debug.

Sub-Tasks dbase setup:

  • “Dates” field with Start & End Dates = on
  • “State” field using Workflow (To Do, In Progress, Done) with Default = To Do; a Single Select field with a similar configuration (inc. Always require = on with Value = To Do) could also be used

Tasks dbase setup:

  • “Dates” field with Start & End Dates = on
  • “Sub-Task Dates” formula field:

DateRange([Sub-Tasks].Min(Dates.Start()), [Sub-Tasks].Max(Dates.End()))

  • “Synch Task Dates w/ Sub-Task Dates” rule:

WHEN Task Updated → Sub-Task Dates WHERE Rule Filter - Sub-Tasks Count > 0
THEN Update → Dates → formula:

[Step 1 Task].[Sub-Task Dates]

With the Date synch sorted, I moved along to State synch.

  • “State” field using Workflow (To Do, In Progress, Done) with Default = To Do; a Single Select field with a similar configuration (inc. Always require = on with Value = To Do) could also be used
  • “Rule Trigger - State Effective” formula field:
If(
  [Sub-Tasks].Count() = 0,
  State.Name,
  If(
    [Sub-Tasks].Filter(State.Name != "To Do").Count() = 0,
    "To Do",
    If(
      [Sub-Tasks].Filter(State.Name != "Done").Count() = 0,
      "Done",
      "In Progress"
    )
  )
)
  • “Rule Filter - Sub-Tasks Count” formula field:

[Sub-Tasks].Count()

TL;DR. What comes next is the complicated part that ultimately failed. If you don’t care about what happened, skip down to “Here’s what I finally implemented”. That said, the method described next could be useful for other situations.

  • “Synch Task State w/ Sub-Task State” rule:

WHEN Task Updated → Rule Trigger - State Effective WHERE Rule Filter - Sub-Tasks Count > 0
THEN Update → State → formula:

If(
  [Step 1 Task].[Rule Trigger - State Effective] = "To Do",
  [Step 1 Task].[Sub-Tasks]
    .Filter(State.Name = "To Do")
    .Sort([Creation Date])
    .First().State,
  If(
    [Step 1 Task].[Rule Trigger - State Effective] = "In Progress",
    [Step 1 Task].[Sub-Tasks]
      .Filter(State.Name = "In Progress")
      .Sort([Creation Date])
      .First().State,
    [Step 1 Task].[Sub-Tasks]
      .Filter(State.Name = "Done")
      .Sort([Creation Date])
      .First().State
  )
)

The nested IF statements above deliver the following logic:

  • IF all a Task’s Sub-Tasks are To Do, THEN the Task is To Do
  • ELSE IF all a Task’s Sub-Tasks are Done, THEN the Task is Done
  • ELSE the Task is In Progress

For those unaware (like myself), under the hood State is a database rather than a text field. To manipulate a State value, you need to access actual State from an Entity which can be done by directly referencing a State option in a formula.

Since the parent Task’s State field is a Workflow field configured exactly like the child Sub-Task’s State field, the State options can gathered from a child Sub-Task. Some parts of the formula are easier to interpret than others. For example:

  • [Step 1 Task].[Sub-Tasks].Filter(State.Name != “To Do”).Count() = 0:
    – Filter the Task’s Sub-Tasks where State.Name does not equal To Do and Count them; IF the answser is 0, THEN…
  • [Step 1 Task].[Sub-Tasks].Filter(State.Name = “To Do”).Sort([Creation Date]).First().State:
    Filter the Task’s Sub-Tasks where State.Name equals To Do, and…
    Sort the Sub-Task list by Creation Date (I just used the default ascending… the order doesn’t really matter as it’s really about what comes next) and…
    – Finally grab the First State value which is then passed to the Task’s State field as its new value. You could also use Last().State.

Tricky, no? I never would have figured this out w/o the clues from @Chr1sG and @Polina_Zenevich. I may have missed it, but I scoured the User Guide pages on Formulas, Automations and the Workflow field, but didn’t find anything that would have led me to this method.

Unfortunately, it didn’t work. A problem arises when I need to pass a particular Workflow State to a Task when there isn’t a Sub-Task with the State. For example, I have a Task with one Sub-Task in To Do and one in Done. State Effective calculates that combination as In Progress, which I think is commonsense logic, but there isn’t a Sub-Task I can scrape to get the In Progress value to then pass to the Task, thus the Rule fails. Drat.

Here’s what I finally implemented for the Tasks dbase State automation:

  • Keep the original “State” field, “Rule Trigger - State Effective” formula field and “Rule Filter - Sub-Tasks Count” formula field.

  • Create “Synch Task State w/ Sub-Task State - To Do” rule:

WHEN Task Updated → Rule Trigger - State Effective WHERE Rule Filter - Sub-Tasks Count > 0 AND State Effective = To Do
THEN Update → State → To Do

  • Create “Synch Task State w/ Sub-Task State - Done” rule:

WHEN Task Updated → Rule Trigger - State Effective WHERE Rule Filter - Sub-Tasks Count > 0 AND State Effective = Done
THEN Update → State → Done

  • Create “Synch Task State w/ Sub-Task State - In Progress” rule:

WHEN Task Updated → Rule Trigger - State Effective WHERE Rule Filter - Sub-Tasks Count > 0 AND State Effective = In Progress
THEN Update → State → In Progress

This is three Rules instead of one, but simple enough to create and maintain. Bummed I couldn’t get the original scheme to work, but it is what it is.

Notes on this overall approach to Dates and States synch:

  • If a Task has one or more Sub-Tasks, its State and Dates will be dictated by its children.
  • You can set State and Dates on a Task with no children and that will work fine, but if you add Sub-Tasks they will take over.
  • If you manually change State or Dates on a Task with children, the next time a child’s State or Dates are updated, the Task’s State or Dates will be overwritten by the child.
  • I think “Rule Filter - Sub-Tasks Count” is probably not needed as the “Rule Trigger - State Effective” formula only works (thus only changes) if a Task has Sub-Tasks.
1 Like