Skip to content

Commit

Permalink
feat: ✨ add 'Move To Action Group In Folder (Skip Project Selection)'
Browse files Browse the repository at this point in the history
  • Loading branch information
ksalzke committed Sep 1, 2023
1 parent bf296c5 commit c436b17
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 23 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
"label" = "Move to Action Group In Folder (Skip Project Selection)";
"shortLabel" = "Move to Action Group In Folder (Skip Project Selection)";
"mediumLabel" = "Move to Action Group In Folder (Skip Project Selection)";
"longLabel" = "Move to Action Group In Folder (Skip Project Selection)";
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
(() => {
const action = new PlugIn.Action(async (selection) => {
const lib = this.libraries[0];
const tasks = [...selection.tasks, ...selection.projects.map(project => project.task)];
await lib.processTasks(tasks, false, true);
});
action.validate = (selection) => {
// valid if tasks are selected and they all belong to the same project/assigned project
const tasks = [...selection.tasks, ...selection.projects.map(project => project.task)];
if (tasks.length == 0)
return false;
else
return true;
};
return action;
})();
24 changes: 13 additions & 11 deletions MoveToActionGroup.omnifocusjs/Resources/moveToActionGroupLib.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@
tasks[0].assignedContainer
: lastSelectedSection;
/*======= Prompt for folder (if relevant) =======*/
const folder = (promptForFolder) ? await lib.promptForFolder() : null;
const folder = (promptForFolder) ? await lib.promptForFolder() : null; // folder: Omni Automation
/*------- Prompt for section (if enabled) -------*/
const section = (promptForProject) ? await lib.promptForSection(defaultSelection, folder) : null;
const section = (promptForProject) ? await lib.promptForSection(defaultSelection, folder) : null; // section: Omni Automation
/*------- Prompt for tag(s) (if enabled and no tags) -------*/
if (lib.tagPrompt() && tasks.some(task => task.tags.length === 0))
await lib.promptForTags(tasks);
Expand All @@ -36,7 +36,8 @@
return;
}
/*------- Otherwise, prompt for action group based on project -------*/
const actionGroupForm = await lib.actionGroupForm(section);
const filter = section || folder;
const actionGroupForm = await lib.actionGroupForm(filter);
await actionGroupForm.show('Select Action Group', 'OK');
const actionGroupSelection = actionGroupForm.values.menuItem;
const setPosition = actionGroupForm.values.setPosition;
Expand All @@ -50,9 +51,10 @@
await lib.moveTasks(tasks, section, setPosition);
break;
default:
if (actionGroupSelection.project) {
if (actionGroupSelection.project || actionGroupSelection instanceof Project) {
const project = actionGroupSelection instanceof Project ? actionGroupSelection : actionGroupSelection.project;
// selected item was a project
const secondActionGroupForm = await lib.actionGroupForm(actionGroupSelection.project);
const secondActionGroupForm = await lib.actionGroupForm(project);
await secondActionGroupForm.show('Select Action Group', 'OK');
await lib.moveTasks(tasks, secondActionGroupForm.values.menuItem, secondActionGroupForm.values.setPosition);
}
Expand Down Expand Up @@ -235,9 +237,9 @@
newProjectForm.addField(new Form.Field.String('projectName', 'Project Name', null, null), null);
return newProjectForm;
};
lib.actionGroupForm = async (proj) => {
lib.actionGroupForm = async (section) => {
const fuzzySearchLib = lib.getFuzzySearchLib();
const groups = await lib.potentialActionGroups(proj);
const groups = await lib.potentialActionGroups(section);
const additionalOptions = ['Add to root of project', 'New action group'];
const formOptions = [...groups, ...additionalOptions];
const formLabels = [...groups.map(fuzzySearchLib.getTaskPath), ...additionalOptions];
Expand Down Expand Up @@ -268,12 +270,12 @@
return form;
};
/*------------------ Other Helper Functions -----------------*/
lib.potentialActionGroups = async (proj) => {
lib.potentialActionGroups = async (section) => {
const tag = await lib.getPrefTag('actionGroupTag');
const allTasks = (proj === null) ? flattenedTasks : proj.flattenedTasks;
const allTasks = (section === null) ? flattenedTasks : (section instanceof Project ? section.flattenedTasks : [...section.flattenedProjects].flatMap(proj => [proj, ...proj.flattenedTasks]));
const allActionGroups = allTasks.filter(task => {
if (task.project !== null && proj !== null)
return false;
if (task.project !== null && section instanceof Project)
return false; // exclude project task if project is used for filtering (leave if folder)
if (task.tags.includes(tag))
return true;
if (lib.autoInclude() === 'all tasks')
Expand Down
4 changes: 4 additions & 0 deletions MoveToActionGroup.omnifocusjs/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
"identifier": "moveToActionGroupSkipProj",
"image": "arrow.right.square"
},
{
"identifier": "moveToActionGroupInFolderSkipProj",
"image": "arrow.right.square.fill"
},
{
"identifier": "goToLastMoved",
"image": "backward.fill"
Expand Down
21 changes: 21 additions & 0 deletions src/moveToActionGroupInFolderSkipProj.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
(() => {
const action = new PlugIn.Action(async (selection: Selection) => {

const lib = this.libraries[0]
const tasks = [...selection.tasks, ...selection.projects.map(project => project.task)]

await lib.processTasks(tasks, false, true)

})

action.validate = (selection: Selection) => {

// valid if tasks are selected and they all belong to the same project/assigned project
const tasks = [...selection.tasks, ...selection.projects.map(project => project.task)]

if (tasks.length == 0) return false
else return true
}

return action
})()
26 changes: 14 additions & 12 deletions src/moveToActionGroupLib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,12 @@ interface ActionGroupLib extends PlugIn.Library {
tagForm?: () => TagForm
sectionForm?: (defaultSelection: Project | Folder, folder: Folder | null) => SectionForm
newProjectForm?: () => NewProjectForm
actionGroupForm?: (project: Project) => Promise<ActionGroupForm>
actionGroupForm?: (section: Project | Folder) => Promise<ActionGroupForm>
positionForm?: (group: Task | Project) => PositionForm
newActionGroupForm?: () => NewActionGroupForm

// other helper functions
potentialActionGroups?: (proj: Project | null) => Promise<Task[]>
potentialActionGroups?: (section: Project | Folder | null) => Promise<Task[]>
goTo?: (task: Task) => Promise<void>
promptForFolder?: () => Promise<Folder>
}
Expand Down Expand Up @@ -152,10 +152,10 @@ interface ActionGroupLib extends PlugIn.Library {


/*======= Prompt for folder (if relevant) =======*/
const folder = (promptForFolder) ? await lib.promptForFolder() : null
const folder = (promptForFolder) ? await lib.promptForFolder() : null // folder: Omni Automation

/*------- Prompt for section (if enabled) -------*/
const section: null | Project | Folder = (promptForProject) ? await lib.promptForSection(defaultSelection, folder) : null
const section: null | Project | Folder = (promptForProject) ? await lib.promptForSection(defaultSelection, folder) : null // section: Omni Automation

/*------- Prompt for tag(s) (if enabled and no tags) -------*/
if (lib.tagPrompt() && tasks.some(task => task.tags.length === 0)) await lib.promptForTags(tasks)
Expand All @@ -169,7 +169,8 @@ interface ActionGroupLib extends PlugIn.Library {
}

/*------- Otherwise, prompt for action group based on project -------*/
const actionGroupForm = await lib.actionGroupForm(section)
const filter = section || folder
const actionGroupForm = await lib.actionGroupForm(filter)
await actionGroupForm.show('Select Action Group', 'OK')

const actionGroupSelection: Task | 'New action group' | 'Add to root of project' = actionGroupForm.values.menuItem
Expand All @@ -185,9 +186,10 @@ interface ActionGroupLib extends PlugIn.Library {
await lib.moveTasks(tasks, section, setPosition)
break
default:
if (actionGroupSelection.project) {
if (actionGroupSelection.project || actionGroupSelection instanceof Project) {
const project = actionGroupSelection instanceof Project ? actionGroupSelection : actionGroupSelection.project
// selected item was a project
const secondActionGroupForm = await lib.actionGroupForm(actionGroupSelection.project)
const secondActionGroupForm = await lib.actionGroupForm(project)
await secondActionGroupForm.show('Select Action Group', 'OK')
await lib.moveTasks(tasks, secondActionGroupForm.values.menuItem, secondActionGroupForm.values.setPosition)
} else {
Expand Down Expand Up @@ -401,9 +403,9 @@ interface ActionGroupLib extends PlugIn.Library {
return newProjectForm
}

lib.actionGroupForm = async (proj: Project): Promise<ActionGroupForm> => {
lib.actionGroupForm = async (section: Project | Folder): Promise<ActionGroupForm> => {
const fuzzySearchLib = lib.getFuzzySearchLib()
const groups = await lib.potentialActionGroups(proj)
const groups = await lib.potentialActionGroups(section)

const additionalOptions = ['Add to root of project', 'New action group']

Expand Down Expand Up @@ -444,13 +446,13 @@ interface ActionGroupLib extends PlugIn.Library {

/*------------------ Other Helper Functions -----------------*/

lib.potentialActionGroups = async (proj: Project | null): Promise<Task[]> => {
lib.potentialActionGroups = async (section: Project | Folder | null): Promise<Task[]> => {
const tag = await lib.getPrefTag('actionGroupTag')

const allTasks = (proj === null) ? flattenedTasks : proj.flattenedTasks
const allTasks = (section === null) ? flattenedTasks : (section instanceof Project ? section.flattenedTasks : [...section.flattenedProjects].flatMap(proj => [proj, ...proj.flattenedTasks]))

const allActionGroups = allTasks.filter(task => {
if (task.project !== null && proj !== null) return false
if (task.project !== null && section instanceof Project) return false // exclude project task if project is used for filtering (leave if folder)
if (task.tags.includes(tag)) return true
if (lib.autoInclude() === 'all tasks') return true
if (lib.autoInclude() === 'all' && task.hasChildren) return true
Expand Down

0 comments on commit c436b17

Please sign in to comment.