@blickwerk/n8n-nodes-microsoft-planner 1.2.3 → 1.3.0

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
@@ -181,6 +181,12 @@ Tested with n8n version 1.0.0 and above.
181
181
 
182
182
  ## Version History
183
183
 
184
+ ### 1.2.4
185
+ - **Fixed Bucket and Task dropdowns not showing!**
186
+ - Changed field type from 'string' back to 'options' for proper dropdown display
187
+ - Buckets now load correctly when Plan ID is entered
188
+ - Tasks dropdown now works properly
189
+
184
190
  ### 1.2.3
185
191
  - Improved error handling for Buckets and Tasks loading
186
192
  - Better fallback values when data cannot be loaded
@@ -2,9 +2,13 @@ import { IExecuteFunctions, ILoadOptionsFunctions, INodeExecutionData, INodeType
2
2
  export declare class MicrosoftPlanner implements INodeType {
3
3
  description: INodeTypeDescription;
4
4
  methods: {
5
- loadOptions: {
6
- getBuckets(this: ILoadOptionsFunctions): Promise<any>;
7
- getTasks(this: ILoadOptionsFunctions): Promise<any>;
5
+ listSearch: {
6
+ getBuckets(this: ILoadOptionsFunctions): Promise<{
7
+ results: any;
8
+ }>;
9
+ getTasks(this: ILoadOptionsFunctions): Promise<{
10
+ results: any;
11
+ }>;
8
12
  };
9
13
  };
10
14
  execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
@@ -44,53 +44,70 @@ class MicrosoftPlanner {
44
44
  ],
45
45
  };
46
46
  this.methods = {
47
- loadOptions: {
47
+ listSearch: {
48
48
  async getBuckets() {
49
49
  try {
50
50
  const planId = this.getNodeParameter('planId', 0);
51
51
  if (!planId) {
52
- return [];
52
+ return { results: [] };
53
53
  }
54
54
  const buckets = await GenericFunctions_1.microsoftApiRequestAllItems.call(this, 'value', 'GET', `/planner/plans/${planId}/buckets`);
55
55
  if (!buckets || buckets.length === 0) {
56
- return [];
56
+ return { results: [] };
57
57
  }
58
- return buckets.map((bucket) => ({
59
- name: bucket.name || bucket.id,
60
- value: bucket.id,
61
- }));
58
+ return {
59
+ results: buckets.map((bucket) => ({
60
+ name: bucket.name || bucket.id,
61
+ value: bucket.id,
62
+ })),
63
+ };
62
64
  }
63
65
  catch (error) {
64
66
  console.error('Error loading buckets:', error);
65
- return [];
67
+ return { results: [] };
66
68
  }
67
69
  },
68
70
  async getTasks() {
69
71
  try {
70
72
  const planId = this.getNodeParameter('planId', 0);
71
- const bucketId = this.getNodeParameter('bucketId', 0);
73
+ // Try to get bucketId - might be undefined or an object
74
+ let bucketIdValue = '';
75
+ try {
76
+ const bucketId = this.getNodeParameter('bucketId', 0);
77
+ if (typeof bucketId === 'string') {
78
+ bucketIdValue = bucketId;
79
+ }
80
+ else if (bucketId && typeof bucketId === 'object' && 'value' in bucketId) {
81
+ bucketIdValue = bucketId.value;
82
+ }
83
+ }
84
+ catch (error) {
85
+ // bucketId might not exist yet, that's ok
86
+ }
72
87
  let endpoint = '';
73
- if (bucketId) {
74
- endpoint = `/planner/buckets/${bucketId}/tasks`;
88
+ if (bucketIdValue) {
89
+ endpoint = `/planner/buckets/${bucketIdValue}/tasks`;
75
90
  }
76
91
  else if (planId) {
77
92
  endpoint = `/planner/plans/${planId}/tasks`;
78
93
  }
79
94
  else {
80
- return [];
95
+ return { results: [] };
81
96
  }
82
97
  const tasks = await GenericFunctions_1.microsoftApiRequestAllItems.call(this, 'value', 'GET', endpoint);
83
98
  if (!tasks || tasks.length === 0) {
84
- return [];
99
+ return { results: [] };
85
100
  }
86
- return tasks.map((task) => ({
87
- name: task.title || task.id,
88
- value: task.id,
89
- }));
101
+ return {
102
+ results: tasks.map((task) => ({
103
+ name: task.title || task.id,
104
+ value: task.id,
105
+ })),
106
+ };
90
107
  }
91
108
  catch (error) {
92
109
  console.error('Error loading tasks:', error);
93
- return [];
110
+ return { results: [] };
94
111
  }
95
112
  },
96
113
  },
@@ -109,7 +126,11 @@ class MicrosoftPlanner {
109
126
  // ----------------------------------
110
127
  if (operation === 'create') {
111
128
  const planId = this.getNodeParameter('planId', i);
112
- const bucketId = this.getNodeParameter('bucketId', i);
129
+ const bucketIdParam = this.getNodeParameter('bucketId', i);
130
+ // Extract bucketId value from resourceLocator object or string
131
+ const bucketId = typeof bucketIdParam === 'string'
132
+ ? bucketIdParam
133
+ : bucketIdParam.value;
113
134
  const title = this.getNodeParameter('title', i);
114
135
  const additionalFields = this.getNodeParameter('additionalFields', i);
115
136
  const body = {
@@ -169,7 +190,8 @@ class MicrosoftPlanner {
169
190
  // task:get
170
191
  // ----------------------------------
171
192
  if (operation === 'get') {
172
- const taskId = this.getNodeParameter('taskId', i);
193
+ const taskIdParam = this.getNodeParameter('taskId', i);
194
+ const taskId = typeof taskIdParam === 'string' ? taskIdParam : taskIdParam.value;
173
195
  const additionalFields = this.getNodeParameter('additionalFields', i);
174
196
  const responseData = await GenericFunctions_1.microsoftApiRequest.call(this, 'GET', `/planner/tasks/${taskId}`);
175
197
  if (additionalFields.includeDetails) {
@@ -210,7 +232,8 @@ class MicrosoftPlanner {
210
232
  // task:update
211
233
  // ----------------------------------
212
234
  if (operation === 'update') {
213
- const taskId = this.getNodeParameter('taskId', i);
235
+ const taskIdParam = this.getNodeParameter('taskId', i);
236
+ const taskId = typeof taskIdParam === 'string' ? taskIdParam : taskIdParam.value;
214
237
  const updateFields = this.getNodeParameter('updateFields', i);
215
238
  // Get current task to retrieve eTag
216
239
  const currentTask = await GenericFunctions_1.microsoftApiRequest.call(this, 'GET', `/planner/tasks/${taskId}`);
@@ -275,7 +298,8 @@ class MicrosoftPlanner {
275
298
  // task:delete
276
299
  // ----------------------------------
277
300
  if (operation === 'delete') {
278
- const taskId = this.getNodeParameter('taskId', i);
301
+ const taskIdParam = this.getNodeParameter('taskId', i);
302
+ const taskId = typeof taskIdParam === 'string' ? taskIdParam : taskIdParam.value;
279
303
  // Get current task to retrieve eTag
280
304
  const currentTask = await GenericFunctions_1.microsoftApiRequest.call(this, 'GET', `/planner/tasks/${taskId}`);
281
305
  const eTag = (0, GenericFunctions_1.cleanETag)(currentTask['@odata.etag']);
@@ -69,10 +69,8 @@ exports.taskFields = [
69
69
  {
70
70
  displayName: 'Bucket',
71
71
  name: 'bucketId',
72
- type: 'string',
73
- typeOptions: {
74
- loadOptionsMethod: 'getBuckets',
75
- },
72
+ type: 'resourceLocator',
73
+ default: { mode: 'list', value: '' },
76
74
  required: true,
77
75
  displayOptions: {
78
76
  show: {
@@ -80,9 +78,24 @@ exports.taskFields = [
80
78
  operation: ['create'],
81
79
  },
82
80
  },
83
- default: '',
84
- description: 'The bucket to which the task belongs. Choose from the dropdown or enter a Bucket ID manually.',
85
- placeholder: 'Select from dropdown or paste Bucket ID',
81
+ modes: [
82
+ {
83
+ displayName: 'From List',
84
+ name: 'list',
85
+ type: 'list',
86
+ typeOptions: {
87
+ searchListMethod: 'getBuckets',
88
+ searchable: true,
89
+ },
90
+ },
91
+ {
92
+ displayName: 'By ID',
93
+ name: 'id',
94
+ type: 'string',
95
+ placeholder: 'e.g. FTmIDbes6UyAjh1k0suR3JgACHty',
96
+ },
97
+ ],
98
+ description: 'The bucket to which the task belongs',
86
99
  },
87
100
  {
88
101
  displayName: 'Title',
@@ -183,10 +196,8 @@ exports.taskFields = [
183
196
  {
184
197
  displayName: 'Task',
185
198
  name: 'taskId',
186
- type: 'string',
187
- typeOptions: {
188
- loadOptionsMethod: 'getTasks',
189
- },
199
+ type: 'resourceLocator',
200
+ default: { mode: 'list', value: '' },
190
201
  required: true,
191
202
  displayOptions: {
192
203
  show: {
@@ -194,9 +205,24 @@ exports.taskFields = [
194
205
  operation: ['get', 'delete', 'update'],
195
206
  },
196
207
  },
197
- default: '',
198
- description: 'The task to operate on. Choose from the dropdown or enter a Task ID manually.',
199
- placeholder: 'Select from dropdown or paste Task ID',
208
+ modes: [
209
+ {
210
+ displayName: 'From List',
211
+ name: 'list',
212
+ type: 'list',
213
+ typeOptions: {
214
+ searchListMethod: 'getTasks',
215
+ searchable: true,
216
+ },
217
+ },
218
+ {
219
+ displayName: 'By ID',
220
+ name: 'id',
221
+ type: 'string',
222
+ placeholder: 'e.g. rz1EH6N_a0aLpRm-2QifxZgAF5OL',
223
+ },
224
+ ],
225
+ description: 'The task to operate on',
200
226
  },
201
227
  {
202
228
  displayName: 'Additional Fields',
@@ -278,13 +304,12 @@ exports.taskFields = [
278
304
  {
279
305
  displayName: 'Bucket',
280
306
  name: 'bucketId',
281
- type: 'string',
307
+ type: 'options',
282
308
  typeOptions: {
283
309
  loadOptionsMethod: 'getBuckets',
284
310
  },
285
311
  default: '',
286
- description: 'Filter tasks by bucket. Choose from the dropdown or enter a Bucket ID manually.',
287
- placeholder: 'Select from dropdown or paste Bucket ID',
312
+ description: 'Filter tasks by bucket',
288
313
  },
289
314
  ],
290
315
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blickwerk/n8n-nodes-microsoft-planner",
3
- "version": "1.2.3",
3
+ "version": "1.3.0",
4
4
  "description": "n8n node for Microsoft Planner - Create and retrieve tasks",
5
5
  "keywords": [
6
6
  "n8n-community-node-package",