Skip to content

Commit

Permalink
feat: ✨ add 'Prompt for Project' preference
Browse files Browse the repository at this point in the history
  • Loading branch information
ksalzke committed Jun 24, 2022
1 parent 719588a commit 0578308
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 14 deletions.
3 changes: 1 addition & 2 deletions MoveToActionGroup.omnifocusjs/Resources/moveToActionGroup.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@
const tasks = [...selection.tasks, ...selection.projects.map(project => project.task)]

// get currently assigned project - if none show prompt
const proj = tasks[0].assignedContainer !== null ? tasks[0].assignedContainer : await lib.projectPrompt()

const proj = (!lib.promptForProject()) ? null : tasks[0].assignedContainer !== null ? tasks[0].assignedContainer : await lib.projectPrompt()
// check that a tag has been assigned to all tasks, if that setting is enabled - and if not show prompt and assign
if (lib.tagPrompt() && tasks.some(task => task.tags.length === 0)) await lib.addTags(tasks)

Expand Down
24 changes: 18 additions & 6 deletions MoveToActionGroup.omnifocusjs/Resources/moveToActionGroupLib.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@
return preferences.readBoolean('tagPrompt')
}

lib.promptForProject = () => {
const preferences = lib.loadSyncedPrefs()
if (preferences.read('projectPrompt') !== null) return preferences.read('projectPrompt')
else return true
}

lib.searchForm = async (allItems, itemTitles, firstSelected, matchingFunction) => {
const form = new Form()

Expand Down Expand Up @@ -161,7 +167,11 @@

lib.potentialActionGroups = async (proj) => {
const tag = await lib.getPrefTag('actionGroupTag')
const allActionGroups = proj.flattenedTasks.filter(task => {

const allTasks = (proj === null) ? flattenedTasks : proj.flattenedTasks

const allActionGroups = allTasks.filter(task => {
if (task.project !== null) return false
if (task.tags.includes(tag)) return true
if (lib.autoInclude() === 'all' && task.hasChildren) return true
if (lib.autoInclude() === 'top' && task.hasChildren && task.parent.project !== null) return true
Expand All @@ -176,17 +186,19 @@
lib.actionGroupPrompt = async (tasks, proj) => {
const getGroupPath = (task) => {
const getPath = (task) => {
if (task.parent === task.containingProject.task) return task.name
if (task.parent === task.containingProject.task && proj === null) return `${task.containingProject.name} > ${task.name}`
else if (task.parent === task.containingProject.task) return task.name
else return `${getPath(task.parent)} > ${task.name}`
}
return getPath(task)
}
const groups = await lib.potentialActionGroups(proj)
const selection = (groups.length) > 0 ? groups[0] : 'Add to root of project'

const formOptions = [...groups, 'New action group', 'Add to root of project']
const formLabels = [...groups.map(getGroupPath), 'New action group', 'Add to root of project']
const searchForm = await lib.searchForm(formOptions, formLabels, selection, null)
const additionalOptions = lib.promptForProject() ? ['Add to root of project', 'New action group'] : []

const formOptions = [...groups, ...additionalOptions]
const formLabels = [...groups.map(getGroupPath), ...additionalOptions]
const searchForm = await lib.searchForm(formOptions, formLabels, formOptions[0], null)
searchForm.addField(new Form.Field.Checkbox('setPosition', 'Set position', false))

const actionGroupForm = await searchForm.show('Select Action Group', 'OK')
Expand Down
3 changes: 3 additions & 0 deletions MoveToActionGroup.omnifocusjs/Resources/preferences.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,22 @@
const actionGroupTag = lib.prefTag('actionGroupTag')
const autoInclude = lib.autoInclude()
const tagPrompt = lib.tagPrompt()
const projectPrompt = lib.promptForProject()

// create and show form
const form = new Form()
const tagNames = flattenedTags.map(t => t.name)
form.addField(new Form.Field.Option('actionGroupTag', 'Action Group Tag', flattenedTags, tagNames, actionGroupTag, null))
form.addField(new Form.Field.Option('autoInclude', 'Automatically Include Action Groups', ['none', 'top', 'all'], ['None', 'Top-Level', 'All'], autoInclude))
form.addField(new Form.Field.Checkbox('tagPrompt', 'Prompt for Tags', tagPrompt))
form.addField(new Form.Field.Checkbox('projectPrompt', 'Prompt for Projects', projectPrompt))
await form.show('Preferences: Move To Action Group', 'OK')

// save preferences
syncedPrefs.write('actionGroupTagID', form.values.actionGroupTag.id.primaryKey)
syncedPrefs.write('autoInclude', form.values.autoInclude)
syncedPrefs.write('tagPrompt', form.values.tagPrompt)
syncedPrefs.write('projectPrompt', form.values.projectPrompt)
})

action.validate = function (selection, sender) {
Expand Down
17 changes: 11 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@ This action can be run when one or more tasks are selected. The selected tasks m

The action then completes the following:

1. The user is prompted to select a project.
1. The user is prompted to select a project. (If 'Prompt for Project' is deselected in the Preferences, this prompt is not shown.)

2. If no tags have been assigned, the user is prompted to select a tag, or tags, to be applied to the selected tasks. (If 'Prompt for Tags' is deselected in the Preferences, this prompt is not shown.)
2. If no tags have been assigned and the user has selected 'Prompt for Tags' in the Preferences, the user is prompted to select a tag, or tags, to be applied to the selected tasks.

3. The user is prompted to select an action group to move the task(s) to, if appropriate action groups (determined by the preferences) exist in the selected project. Alternatively, a new action group can be created (with a prompt for the user to enter the name) or the task(s) can be moved to the root of the previously selected project.
3. The user is prompted to select an action group to move the task(s) to, if appropriate action groups (determined by the preferences) exist (either in the selected project, or in the entire database if the 'Prompt for Project' preference is not active). Alternatively, a new action group can be created (with a prompt for the user to enter the name) or the task(s) can be moved to the root of the previously selected project.
Optionally, the user can select the checkbox to select the position of the task(s) in the next step.

4. Based on the previous selection, the user may be prompted to select where in the group the selected task(s) should be moved. By default, tasks are added to the end of the action group. There is also the option to navigate to the task after it is moved. The user may also opt to add the project to the note of the task that's selected, rather than as a subtask. This may be useful in conjunction with my [Note To Subtasks](https://github.com/ksalzke/notes-to-subtasks-omnifocus-plugin) plug-in.
Expand All @@ -55,6 +55,7 @@ The following preferences are available:
* **Action Group Tag**. This is a tag that can optionally be used to denote action groups. It can be used to restrict the action groups that show in the options to a predefined subset.
* **Automatically Include Action Groups**. This setting can be set to 'None' (only action group tagged with the Action Group Tag, set above, are included as options), 'Top-Level' (all top-level action groups are included as options), or 'All' (all action groups included).
* **Prompt for Tags**. If this is selected and none of the selected tasks have tags, the user will be prompted to add one or more tags to them prior to selecting an action group to move them to.
* **Prompt for Project**. If this is selected, the user will be prompted for a project prior to the action group prompt. If unselected, all action groups across the database will be shown. Note that _not_ prompting for the project will result in slower performance.


# Functions
Expand Down Expand Up @@ -84,7 +85,11 @@ Returns the current setting for the 'Automatically Include Action Groups' prefer

## `tagPrompt () : Boolean`

Returns the current setting for the 'Prompt For Tags' preference.
Returns the current setting for the 'Prompt For Tags' preference. If no preference is set, returns false.

## `promptForProject () : Boolean`

Returns the current setting for the 'Prompt For Projects' preference. If no preference is set, returns true.

## `searchForm (allItems: Array<T>, itemTitles: Array<String>, firstSelected: T, matchingFunction: function | null) : Form` (asynchronous)

Expand All @@ -108,9 +113,9 @@ Returns a form for the user to select a tag, using the `searchForm` and an addit

Shows a `tagForm` prompt for the user to add a tag, repeatedly while the 'Add another?' checkbox is selected.

## `potentialActionGroups (proj: Project) : Array<Task>` (asynchronous)
## `potentialActionGroups (proj: Project | null) : Array<Task>` (asynchronous)

Returns an array of action groups within the given project. The action groups that are returned depends on the setting chosen in Preferences.
Returns an array of action groups within the given project. The action groups that are returned depends on the setting chosen in Preferences. If null is passed as a parameter, all action groups within the database are checked.

## `actionGroupPrompt (tasks: Array<Task>, proj: Project)` (asynchronous)

Expand Down

0 comments on commit 0578308

Please sign in to comment.