TomFrankly/pipedream-notion-recurring-tasks

Formula Update Error?

Closed this issue · 16 comments

Good Evening,

Tonight i was implementing this tool in one of my task databases and came across a strange result within notion while testing the automation:

The "Type" field on my tasks within the target database I was implementing the automation on would change after a test pass with the integration to improperly show as a one time task despite having shown properly as a recurring task prior to the automation test.

Here are my reproduction steps:

  • Create task in target notion database
  • Set Recur field to 1
  • this changes the "type" field to reflect recurring
  • conduct test process for setup within pipedream
  • observe end result that the "type" field now shows it as a one-time task.

Investigation:

  • I reviewed the formula that the box was using to calculate what showed and noticed that it had been set to a formula duplicating the "one time" event type.
if(empty(prop("Recur Interval")), "⏳One-Time", "⏳One-Time")

I would revert the formula back to the proper formula from the how-to guide, and this would solve the issue.

if(empty(prop("Recur Interval")), "⏳One-Time", "🔄Recurring") 

I would then re-run the automation test which just resulted in the same end change to the formula in that field.

Suspect Cause

  • I reviewed the repository tonight to see if I could identify the cause, and I believe that it might be line 403 replacing the formula with the one duplicating the event type. I have linked this below.

expression: `if(empty(prop("Recur Interval")), "⏳One-Time", "⏳One-Time")`,

Thank you for your attention. Please let me know if I also have totally misunderstood the intent with this field, but it seems to be not working as I would expect based on the documentation and my expected outcomes/intuition.

Sorry, was a bit of a jumble in my initial message. I hope the update edits made it more clear.

Potential fix submitted for review here: #3

@NinjaMittens this is done on purpose, actually!

When a task has the "Recurring" type, it will not leave normal task views when you check Done or set Kanban Status to Done.

I built this into the filters for people who process recurring tasks manually (who don't use this automation). For them, if they were to accidentally check Done instead of just moving the Due date, their task would disappear – and it wouldn't come back, as they're probably expecting.

So the only real function of that Type property is to prevent user error. (It is also used in the filtes on task views to counteract a bug with Notion formulas, but that's not related to recurring tasks).

When someone is using this automation, we want them to be able to check Done and have the task disappear from their task views until it's relevant again (e.g. until this automation processes it). So we change the formula to "One-Time" just to bypass the filters they have in their template.

It's a bit of a clunky solution, but we've had to make it work because our automations have to work for people who have copies of my templates going all the way back to 2019. We can't remotely update somone's Notion template, so sometimes we have to get clever and work with what we have.

@NinjaMittens if you're using the automation, things will work as you'd expect. Every task will have a Type of "One-Time", but it doesn't really matter as that property is never shown anywhere.

If you're not using the automation, that's where Type being "Recurring" becomes relevant – and even then, the only reason it exists is to prevent tasks from being cleared from your Task views if you check them off (since if you're doing manual recurring task tracking, you can't just check tasks off).

@NinjaMittens ah gotcha!

Here's a way you might like better:

CleanShot 2024-04-09 at 14 06 59@2x

This is a little formula I just called "Recur Symbol". Here's the forumla:

ifs(
	not empty(prop("Next Due")),
	"🔁"
)

If a task is Recurring, it'll have a Next Due date. If that's the case, this will return that little 🔁 symbol. If not, it'll be empty.

That way, it'll only take up space in a List view of your tasks if the task is indeed recurring.

I just added a dedicated "Recurring" status to make identification easy.

I was about to report this issue too. I am not using your full template, but integrated this pipedream workflow into my project management database. (Thank you for providing this free of charge, TF and team!)

I was using the status as part of my filter for my workflow. This piece was being used to show all "one-time" items, and only those "recurring items" that are marked with a due date of less than one week from today, so that most of the things that are not due within the week are hidden.

You may account for this in your ultimate tasks / brain templates a different way.

For those interested, I plan to solve this by simply making a similar formula named differently and leaving the default field alone!

The upcoming versions of Ultimate Brain and Ultimate Tasks have a new "Meta Symbols" property that will show when a task is recurring, as well as if it contains sub-tasks.

CleanShot 2024-07-31 at 13 38 51@2x

I'm also doing away with the Type property we've discussed here, and any filters that use it.

Instead, the Task Manager has a dedicated Recurring tab, and Done tasks don't get cleared from it. They just go to the Done section when checked.

Recurring tasks will still show up everywhere else, too, but this will solve the problem of users not "losing" recurring tasks if they check them off without having the automation set up to automatically un-check them. And it will cut down on a ton of the confusion that the Type property has caused over the years.

CleanShot 2024-07-31 at 13 40 24@2x

@TomFrankly Thanks for the reply!

Sounds like a great move, and from my own experiences, it feels good to clean up issues and make a system more elegant. Thanks for continuing to improve this and for sharing what is coming down the line.

Not sure if there is a better place to "request features", but I find it hugely useful to have a "Recur Unit" of "Day(s) after complete". I added this myself, and it is by far my most used type. (simply adding the number of days from "Recur Interval" to today's date for the "next due"). Might be a nice addition to the new versions of UB and UT.

Keep up the great work, Cheers!

@wysockijake interesting! If I'm understanding this correctly, would the only functionality different part of that recur unit be for tasks that have a Due Date further into the future compared to today? (e.g. tasks you're completing early?)

@TomFrankly -
image

It might be interesting if it were doing anything different than you already are. Upon closer inspection, it seems I have misunderstood how "day(s)" worked!🤦

I was under the impression that "Day(s)" calculated the Next Due based off the Due Date, similar to Week(s) and Month(s), rather than the current date. (correct me if I am wrong though!)

The only thing I can say at this point of possible value to you is there might be room to make this more explicit in the UI how "day(s)" differs from other interval types. It may be obvious to others, or you may explain this in your videos, but for some reason, I completely misunderstood how this worked. (I swear I tested it a while back before including my own, seemingly redundant functionality... but 🤷)

I included a little more description of what led to my confusion and the desired behavior below if you are curious; otherwise, thank you again, and keep up the good work!


The behavior I was asking for was to have a recurring type that would ignore the due date and set the Next Due a given number of days from when I last completed a task (current date when the automation runs). I use this for most of my recurring tasks because they fall under the category of "maintenance" (most chores), which are intended to prevent things from getting out of hand, but don't have a "hard" due date.

Take the example of a task "perform maintenance on water heater" that I want to do 2x a year. If I don't do this exactly every 6 months, who cares? I also don't care if it is marked "overdue" in my system, so I wouldn't keep updating the due date. Additionally, the day of the month is not important.

My first thought would be to use "months" in your system, because I want to do it every 6 months. But based on a quick test, I believe it would produce results that are undesirable unless I complete it more or less on the due date, or change the due date to the current date when I mark it as done.

If I completed this task 2 months "late", I would want my system to remind me to do it again in 6 months from the date I mark it complete, not 6 months from when it was due. If I were using "Month(s)" with an interval of "6", the next due is calculated to be 6 months from the date in the Due field, which is only 4 months in the future, not the 6 months in the future as I actually want.

The solution is to use a unit of "day(s)" with a unit of, say 180, which produces the desired behavior.

The way "month(s)" is implemented makes sense for other things, so I am not suggesting any change with this, btw.

I am happy to discuss more if there are any follow-up questions (I have a user research background and understand how valuable it can be to understand a user's experience!); just let me know!

Even though this "request" stemmed from my seeming misunderstanding, hopefully there is some value out of the interaction anyway. Thanks again!

@wysockijake I'm fairly certain that "Day(s)" works the same as all other intervals. The logic is this:

  • If the task is overdue, calculate intervals until we get to the next one (still based off of Due) that is after today
  • If the task is not overdue, calculate the very next interval based on the due date.

E.g. these produce the same result (61 days vs 2 months, both on a task that's overdue):

CleanShot 2024-08-01 at 12 21 17@2x CleanShot 2024-08-01 at 12 21 38@2x

We modeled this to work like most other task management systems we studied – e.g. Todoist. It seems to be an established pattern, and it makes sense; if you were overdue on a task by multiple interval cycles (e.g. you're 2 weeks overdue on a daily task), you'd want Next Due to be tomorrow, not 13 days ago.

That said, I definitely understand your use case! E.g. if you were supposed to do the maintenance Jan 1 but didn't get to it until March 1, then you'd want the next rough due date for it to be Aug 1 instead of June 1.

Unfortunately, adding that to our formula would add a lot of complexity and would likely take several hours of dev work, so I don't think we can fit it in at the moment. It would require adding a new property to the Tasks database – something like "Calculate Next Due based on Today's Date" (which is a mouthful). I don't think we'd want to just add more Recur options, as that would require a lot more user education around the subtle differences we're discussing here.

What I'd recommend doing in these cases is setting the Due date to today's date before you check off the task. You know your tasks pretty well, so you'll have a good idea of which ones should retain their date if they're overdue (e.g. a tax deadline) and which can have that due date shifted to today's date.

Hope that helps!

@TomFrankly - Thank you for confirming all this! I must have broken something in Next Due when integrating your Next Due formula into my existing database, or broken it when adding the new option. It behaves as you describe in my untouched version of Ultimate Tasks that I just checked. (Good news for me is that I am not crazy, not as good news, you went and dug into this stuff when you probably have better things to do 😬).

So not sure what happened, but glad we are on the same page, and thank you for considering this feature, I understand if you don't want to add complexity and the possibility for confusion, thanks for hearing me out!

Just to close the loop:

  • This feature is one I missed when moving from Asana to Todist (Not sure if Asana still uses it - they call them 'periodic' tasks), though they only go about 30 days - as at least a few people over the years have commented on.
  • FWIW, Here is how I implemented it:
  • image
  • added or(prop("Recur Unit") == at(at(prop("Localization Key"), 1), 0), prop("Recur Unit") == "Day(s) After Complete"), "daysaftercomplete", under recurUnits on line 6
  • added recurUnit == "daysaftercomplete", dateAdd(conditionalDateNow, prop("Recur Interval"), "days"), under nextDueStart on line 122

PS- not expecting a response, you have already be more than gracious with your time!
As always - thanks again and keep up the good work!