@blickwerk/n8n-nodes-microsoft-planner 1.1.1 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -84,6 +84,13 @@ Configure the Microsoft Planner OAuth2 API credentials in n8n:
84
84
  4. Click **Connect my account**
85
85
  5. Complete the OAuth flow
86
86
 
87
+ ## Features
88
+
89
+ - **Dynamic Dropdowns**: Automatically loads and displays your Plans, Buckets, and Tasks - no need to manually copy IDs!
90
+ - **User Assignment**: Assign tasks to users by email address
91
+ - **Priority Management**: Easy-to-use priority dropdown (Urgent, Important, Medium, Low)
92
+ - **Full CRUD Operations**: Create, Read, Update, and Delete tasks
93
+
87
94
  ## Operations
88
95
 
89
96
  ### Task
@@ -98,10 +105,10 @@ Configure the Microsoft Planner OAuth2 API credentials in n8n:
98
105
 
99
106
  ### Creating a Task
100
107
 
101
- To create a task, you need:
102
- - **Plan ID**: The ID of the plan
103
- - **Bucket ID**: The ID of the bucket within the plan
104
- - **Title**: The task title
108
+ To create a task:
109
+ 1. Select a **Plan** from the dropdown (automatically loaded from your Microsoft 365)
110
+ 2. Select a **Bucket** from the dropdown (loads buckets from the selected plan)
111
+ 3. Enter the **Title** of the task
105
112
 
106
113
  Optional fields:
107
114
  - **Description**: Detailed task description
@@ -117,14 +124,19 @@ Optional fields:
117
124
 
118
125
  ### Getting Tasks
119
126
 
120
- You can retrieve tasks by:
121
- - **Task ID**: Get a specific task
122
- - **Plan ID**: Get all tasks in a plan
123
- - **Bucket ID**: Get all tasks in a bucket
127
+ **Get a single task:**
128
+ - Select the task from the dropdown (automatically loaded from your plans)
129
+
130
+ **Get many tasks:**
131
+ - Filter by **Plan** (select from dropdown)
132
+ - Or filter by **Bucket** (select from dropdown)
133
+ - Set a limit or return all tasks
124
134
 
125
135
  ### Updating a Task
126
136
 
127
- To update a task, provide the Task ID and the fields you want to update. You can update:
137
+ To update a task:
138
+ 1. Select the **Task** from the dropdown
139
+ 2. Update any of these fields:
128
140
  - Title
129
141
  - Description
130
142
  - Priority (via dropdown)
@@ -134,15 +146,14 @@ To update a task, provide the Task ID and the fields you want to update. You can
134
146
  - Percent Complete
135
147
  - Move to different bucket
136
148
 
137
- ### Finding Plan and Bucket IDs
149
+ ### How Dynamic Dropdowns Work
138
150
 
139
- You can find Plan IDs and Bucket IDs using the Microsoft Graph Explorer:
151
+ The node automatically fetches your data from Microsoft 365:
152
+ - **Plans**: Loaded from your account when you open the Plan dropdown
153
+ - **Buckets**: Dynamically loaded based on the selected Plan
154
+ - **Tasks**: Loaded from the selected Plan or Bucket
140
155
 
141
- 1. Go to [Microsoft Graph Explorer](https://developer.microsoft.com/en-us/graph/graph-explorer)
142
- 2. Sign in with your Microsoft account
143
- 3. Use these queries:
144
- - Get all plans: `GET https://graph.microsoft.com/v1.0/me/planner/plans`
145
- - Get buckets in a plan: `GET https://graph.microsoft.com/v1.0/planner/plans/{plan-id}/buckets`
156
+ No need to manually look up IDs anymore! Just select from the dropdown menus.
146
157
 
147
158
  ## Compatibility
148
159
 
@@ -156,6 +167,27 @@ Tested with n8n version 1.0.0 and above.
156
167
 
157
168
  ## Version History
158
169
 
170
+ ### 1.2.1
171
+ - Fixed Plans not loading (improved API endpoint to fetch from groups)
172
+ - Allow manual ID input in all dropdown fields
173
+ - You can now choose from dropdown OR paste IDs manually
174
+ - Added placeholders and better descriptions for all ID fields
175
+ - Improved error handling for plans loading
176
+
177
+ ### 1.2.0
178
+ - **Major UX Improvement**: Added dynamic dropdowns for Plans, Buckets, and Tasks
179
+ - No more manual ID lookup - select from dropdown menus
180
+ - Plans load automatically from your Microsoft 365 account
181
+ - Buckets load dynamically based on selected Plan
182
+ - Tasks load from selected Plan or Bucket
183
+ - Improved user experience with clearer field labels
184
+
185
+ ### 1.1.1
186
+ - Fixed startDateTime not being set (was returning null)
187
+ - Fixed user assignment by adding User.Read.All permission requirement
188
+ - Added error logging for failed user lookups
189
+ - Improved README documentation with all required permissions
190
+
159
191
  ### 1.1.0
160
192
  - Added priority dropdown (Urgent, Important, Medium, Low) instead of number input
161
193
  - Added user assignment functionality (assign tasks by email)
@@ -1,5 +1,15 @@
1
- import { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from 'n8n-workflow';
1
+ import { IExecuteFunctions, ILoadOptionsFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from 'n8n-workflow';
2
2
  export declare class MicrosoftPlanner implements INodeType {
3
3
  description: INodeTypeDescription;
4
+ methods: {
5
+ loadOptions: {
6
+ getPlans(this: ILoadOptionsFunctions): Promise<{
7
+ name: any;
8
+ value: any;
9
+ }[]>;
10
+ getBuckets(this: ILoadOptionsFunctions): Promise<any>;
11
+ getTasks(this: ILoadOptionsFunctions): Promise<any>;
12
+ };
13
+ };
4
14
  execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
5
15
  }
@@ -43,6 +43,67 @@ class MicrosoftPlanner {
43
43
  ...TaskDescription_1.taskFields,
44
44
  ],
45
45
  };
46
+ this.methods = {
47
+ loadOptions: {
48
+ async getPlans() {
49
+ try {
50
+ // Try to get plans from groups the user is member of
51
+ const groups = await GenericFunctions_1.microsoftApiRequestAllItems.call(this, 'value', 'GET', '/me/memberOf/microsoft.graph.group?$filter=groupTypes/any(c:c+eq+%27Unified%27)');
52
+ const plans = [];
53
+ for (const group of groups) {
54
+ try {
55
+ const groupPlans = await GenericFunctions_1.microsoftApiRequest.call(this, 'GET', `/groups/${group.id}/planner/plans`);
56
+ if (groupPlans.value && groupPlans.value.length > 0) {
57
+ plans.push(...groupPlans.value);
58
+ }
59
+ }
60
+ catch (error) {
61
+ // Skip groups without plans
62
+ continue;
63
+ }
64
+ }
65
+ return plans.map((plan) => ({
66
+ name: plan.title || plan.id,
67
+ value: plan.id,
68
+ }));
69
+ }
70
+ catch (error) {
71
+ console.error('Error loading plans:', error);
72
+ return [];
73
+ }
74
+ },
75
+ async getBuckets() {
76
+ const planId = this.getNodeParameter('planId', 0);
77
+ if (!planId) {
78
+ return [];
79
+ }
80
+ const buckets = await GenericFunctions_1.microsoftApiRequestAllItems.call(this, 'value', 'GET', `/planner/plans/${planId}/buckets`);
81
+ return buckets.map((bucket) => ({
82
+ name: bucket.name,
83
+ value: bucket.id,
84
+ }));
85
+ },
86
+ async getTasks() {
87
+ const planId = this.getNodeParameter('planId', 0);
88
+ const bucketId = this.getNodeParameter('bucketId', 0);
89
+ let endpoint = '';
90
+ if (bucketId) {
91
+ endpoint = `/planner/buckets/${bucketId}/tasks`;
92
+ }
93
+ else if (planId) {
94
+ endpoint = `/planner/plans/${planId}/tasks`;
95
+ }
96
+ else {
97
+ return [];
98
+ }
99
+ const tasks = await GenericFunctions_1.microsoftApiRequestAllItems.call(this, 'value', 'GET', endpoint);
100
+ return tasks.map((task) => ({
101
+ name: task.title,
102
+ value: task.id,
103
+ }));
104
+ },
105
+ },
106
+ };
46
107
  }
47
108
  async execute() {
48
109
  const items = this.getInputData();
@@ -52,9 +52,12 @@ exports.taskFields = [
52
52
  // task:create
53
53
  // ----------------------------------
54
54
  {
55
- displayName: 'Plan ID',
55
+ displayName: 'Plan',
56
56
  name: 'planId',
57
57
  type: 'string',
58
+ typeOptions: {
59
+ loadOptionsMethod: 'getPlans',
60
+ },
58
61
  required: true,
59
62
  displayOptions: {
60
63
  show: {
@@ -63,12 +66,16 @@ exports.taskFields = [
63
66
  },
64
67
  },
65
68
  default: '',
66
- description: 'The ID of the plan to which the task belongs',
69
+ description: 'The plan to which the task belongs. Choose from the dropdown or enter a Plan ID manually.',
70
+ placeholder: 'Select from dropdown or paste Plan ID',
67
71
  },
68
72
  {
69
- displayName: 'Bucket ID',
73
+ displayName: 'Bucket',
70
74
  name: 'bucketId',
71
75
  type: 'string',
76
+ typeOptions: {
77
+ loadOptionsMethod: 'getBuckets',
78
+ },
72
79
  required: true,
73
80
  displayOptions: {
74
81
  show: {
@@ -77,7 +84,8 @@ exports.taskFields = [
77
84
  },
78
85
  },
79
86
  default: '',
80
- description: 'The ID of the bucket to which the task belongs',
87
+ description: 'The bucket to which the task belongs. Choose from the dropdown or enter a Bucket ID manually.',
88
+ placeholder: 'Select from dropdown or paste Bucket ID',
81
89
  },
82
90
  {
83
91
  displayName: 'Title',
@@ -176,9 +184,12 @@ exports.taskFields = [
176
184
  // task:get
177
185
  // ----------------------------------
178
186
  {
179
- displayName: 'Task ID',
187
+ displayName: 'Task',
180
188
  name: 'taskId',
181
189
  type: 'string',
190
+ typeOptions: {
191
+ loadOptionsMethod: 'getTasks',
192
+ },
182
193
  required: true,
183
194
  displayOptions: {
184
195
  show: {
@@ -187,7 +198,8 @@ exports.taskFields = [
187
198
  },
188
199
  },
189
200
  default: '',
190
- description: 'The ID of the task',
201
+ description: 'The task to operate on. Choose from the dropdown or enter a Task ID manually.',
202
+ placeholder: 'Select from dropdown or paste Task ID',
191
203
  },
192
204
  {
193
205
  displayName: 'Additional Fields',
@@ -259,18 +271,26 @@ exports.taskFields = [
259
271
  },
260
272
  options: [
261
273
  {
262
- displayName: 'Plan ID',
274
+ displayName: 'Plan',
263
275
  name: 'planId',
264
276
  type: 'string',
277
+ typeOptions: {
278
+ loadOptionsMethod: 'getPlans',
279
+ },
265
280
  default: '',
266
- description: 'Filter tasks by plan ID',
281
+ description: 'Filter tasks by plan. Choose from the dropdown or enter a Plan ID manually.',
282
+ placeholder: 'Select from dropdown or paste Plan ID',
267
283
  },
268
284
  {
269
- displayName: 'Bucket ID',
285
+ displayName: 'Bucket',
270
286
  name: 'bucketId',
271
287
  type: 'string',
288
+ typeOptions: {
289
+ loadOptionsMethod: 'getBuckets',
290
+ },
272
291
  default: '',
273
- description: 'Filter tasks by bucket ID',
292
+ description: 'Filter tasks by bucket. Choose from the dropdown or enter a Bucket ID manually.',
293
+ placeholder: 'Select from dropdown or paste Bucket ID',
274
294
  },
275
295
  ],
276
296
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blickwerk/n8n-nodes-microsoft-planner",
3
- "version": "1.1.1",
3
+ "version": "1.2.1",
4
4
  "description": "n8n node for Microsoft Planner - Create and retrieve tasks",
5
5
  "keywords": [
6
6
  "n8n-community-node-package",