OmniFocus Automation - Kanban Board

I have been looking at using kanban board for personal use and was thinking about incorporating it into my OmniFocus workflow.

I looked online and found a few options for extracting OmniFocus data and creating a kanban board view, but I wasn’t interested in that. I wanted to view the data in OmniFocus.
So after noodling around with the idea for a little while, I decided on a workflow (supported by a few OmniFocus automation scripts) that works for me. Hopefully, this would help anyone else who’s been thinking about doing starting a kanban board.

I’ve done a full write up on my blog - it has screenshots and also has the download links for the automation bundles I created - but I’ve tried to summaries the pertinent points below:

  • I use tags to denote when a task was in “To Do”, “In Progress”, “Waiting” or “Done”. (I’m not a programmer, so I replaced “Testing” with “Waiting”)
  • I created Perspectives for each of the tags and load them up using Keyboard Maestro to open up multiple instances of OmniFocus and arrange them in columns so I get the “kanban view”.
  • Alternatively, I go into Tags view and select the four tags to show the tasks in a “Top-to-Bottom” view (instead of Left-to-Right)
  • I created OmniFocus automation scripts to quickly move my items through the different “columns” of the kanban board
  • I put the scripts in the OmniFocus toolbar for easy access (I’ve included individual icons for each script)

Let me know what you think.

6 Likes

Creative and very Interesting application of the Kanban concept! Way to go.

As a help for others following this thread, here’s a script (and link) for automatically creating the tag set mentioned in vishae’s post:

var targetTag = flattenedTags.byName("Kanban")
if(targetTag){
	var title = "Item Exists"
	var msg = "A tag titled “Kanban” already exists."
	var tagID = targetTag.id.primaryKey
	new Alert(title, msg).show(result => {
		URL.fromString("omnifocus:///tag/" + tagID).open()
	})
	console.error(msg)
} else {
	var KanbanTag = new Tag("Kanban")
	var tagID = KanbanTag.id.primaryKey
	var tagTitles = ["To Do", "In Progress", "Waiting", "Done"]
	tagTitles.forEach(title => {
		new Tag(title, KanbanTag)
	})
	URL.fromString("omnifocus:///tag/" + tagID).open()
}

Run Script

1 Like

And here’s a script for switching to Tags perspective and selecting the Kanban tag set:

var targetTag = flattenedTags.byName("Kanban")
if(targetTag){
	var tagIDs = targetTag.children.map(tag => tag.id.primaryKey)
	var tagIDsString =  tagIDs.join(",")
	URL.fromString("omnifocus:///tag/" + tagIDsString).open()
}

Run Script

1 Like

FYI, if you want to add clickable script URLs to your webpages, you can use the encoding tools on this webpage:

https://omni-automation.com/script-url/tools.html

1 Like

Hi Vishae (and Sal),

This is a great and simple solution. I like the concept that it is working in OmniFocus.

I am having one problem. I have set up the 3 perspectives (To Do/ In Progress/ Waiting for) and created a Keyboard Maestro Macro to get the three windows on one screen. When I am trying to run the “In Progress” script in the To Do window nothing is happening. However when I am in Tag view it is running correctly.

Do you have any suggestions?

When you say you run the “In Progress” script, you’ve selected the task and clicked the button and nothing happened? When looking at the inspector for the task, did the appropriate tag get assigned?

Can you try Cmd+K to refresh the list?

oh, that is very useful! If you don’t mind, can I add this to the bundle?

Can this work with automation bundles that include icons, or does only work with single-action scripts?

Hi Vishae, thanks for your quick response.

I have found the cause of the problem, not the solution yet. In my Keyboard Maestro macro I am hiding the inspector, than it is not working. When I show the inspector it is working.

Greetings! Again, thank you for sharing your creativity.

If you don’t mind, can I add this to the bundle?

Certainly you can use these scripts or any of the scripts in the omni-automation.com website in your projects.

Can this work with automation bundles that include icons, or does only work with single-action scripts?

I’m not sure I understand your question? Encoded script URLs are most often used to run Omni Automation scripts from 3rd-party apps and webpages. Did you want to use them in plug-ins?

Here’s the plug-in for displaying the child tags in the Kanban tag set, which will be created if needed. UPDATE: Thanks to @draft8 for the wisdom. I’ve added code for creating child tags if needed, and reordering them if needed.

/*{
	"type": "action",
	"targets": ["omnifocus"],
	"author": "Otto Automator",
	"identifier": "com.omni-automation.of.display-kanban-tags",
	"version": "1.0",
	"description": "Plug-in will select all of the child tags of the “Kanban” tag set, which will be created if needed.",
	"label": "Display Kanban Tags",
	"shortLabel": "Kanban"
}*/
(() => {
	var action = new PlugIn.Action(function(selection, sender){
		
		// IDENTIFY KANBAN TAG, CREATE IF MISSING
		var targetTag = flattenedTags.byName("Kanban") || new Tag("Kanban")
		
		// ADD KANBAN CATEGORIES IF MISSING
		var tagTitles = ["To Do", "In Progress", "Waiting", "Done"]
		tagTitles.forEach(title => {
			if (!targetTag.children.byName(title)){
				new Tag(title, targetTag)
			}
		})
		
		// REORDER THE CATEGORIES
		tagTitles.forEach(title => {
			var tag = targetTag.children.byName(title)
			moveTags([tag], targetTag)
		})
		
		// SHOW THE TAGS
		var tagIDs = targetTag.children.map(tag => tag.id.primaryKey)
		var tagIDsString =  tagIDs.join(",")
		URL.fromString("omnifocus:///tag/" + tagIDsString).open()
		
	});
	
	return action;
})();

@Sal’s code helpfully creates a Kanban tag if none is found, but is a bit less helpful if Kanban lacks the expected children:

We just need to be a bit more consistent with the found or created pattern, extending it to the child tags, as well as the parent tag.

Perhaps something more like:

/*{
    "author": "Author Name",
    "targets": ["omnifocus"],
    "type": "action",
    "identifier": "com.mycompany.showKanban",
    "version": "0.1",
    "description": "Kanban tags found or created, and selected",
    "label": "showKanban",
    "mediumLabel": "showKanban",
    "paletteLabel": "showKanban",
}*/
(() => {
    return new PlugIn.Action(() => {

        // ------- THE KANBAN TAG FOUND OR CREATED -------
        const
            targetTag = flattenedTags.byName(
                'Kanban'
            ) || (new Tag('Kanban')),

            //  IDS OF THE CHILD TAGS (FOUND OR CREATED) -
            tagIDs = [
                'To Do',
                'In Progress',
                'Waiting',
                'Done'
            ].map(
                tagName => (
                    targetTag.children.byName(
                        tagName
                    ) || (new Tag(tagName, targetTag))
                ).id.primaryKey
            ),

            // ---------- URL WITH LIST OF IDs -----------
            url = `omnifocus:///tag/${tagIDs.join(',')}`;

        // ---------- URL COPIED TO THE CONSOLE ----------
        return (
            // In Console:
            console.log(url),

            // --- AND USED IN THE APPLICATION WINDOW ----
            URL.fromString(url).open()
        );
    });
})();

That’s very strange, because I also hide the inspector (and the sidebar) and I can’t reproduce the issue. When I activate the script, the appropriate tags gets assigned.

When you say it’s not working, is it that the task doesn’t display in the correct column, or does the tag not get assigned either?

Also, have you tried manually aligning your windows (don’t use Keyboard Maestro), then run the script and see whether it works then? I’m just wondering whether something in your Keyboard Maestro script might be interfering with something (though I can’t see how).

I’ve updated the plug-in to now include the script to display the kanban tags.

Excellent work! Thank you for sharing such a useful tool with the Automation community. I look forward to downloading the update when it’s posted. Cheers. – SAL

It is the KeyBoard Maestro macro causing the problem. Could you share the one you use?

A dead link at the moment ?

( It seems to 404 )

oops, sorry! I’ve updated the link now.

I’m not sure my Keyboard Maestro script would be useful to other people. It’s essentially a collection of “Type a Keystroke” commands that activate keyboard shortcuts for other applications (and it’s very hacky).

Here’s how my KM script works:

  • Open OmniFocus
  • Pause 5 second
  • “Type a Keystroke” action (Shift + Ctrl + Opt + Cmd + 1) <-- This has been set to open the “To Do” Perspective" (I use Karabiner to map “Shift + Ctrl + Opt + Cmd” to Cap Lock)
  • Pause .5 second
  • “Type a Keystroke” action (Ctrl + Opt + d) <-- resizes the window to 1/3 window width and move to the left of the screen (this uses Magnet app)
  • Pause .5 second
  • “Type a Keystroke” action (Opt + Cmd + N) <-- Open new OmniFocus window
  • repeat the above but using the keyboard shortcuts to open the other perspectives and resizing+moving window to the correct position.

As you can see this relies on a couple of other applications (Magnet and Karabiner) and personal keyboard shortcuts, so it really wouldn’t be helpful to others. And it’s so inelegant (all this pausing)!
I’m finding myself using Sal’s script above for opening the Tag view more often.

I have a different approach, I will try to use yours:

@vishae that’s a really useful piece of work! It fits right in with what I needed.

Because I’m partial to the three column layout myself (I’m so old I’ve used actual physical Kanban boards on factory floors …) I’ve rejigged a Keyboard maestro to put everything in place as I like it.
I’ve uploaded it on the Keyboard Maestro Forum if anyone’s interested.

Thank you for posting that - a few people have asked me for my Keyboard Maestro script and I always feel bad that I don’t have something useful for them.