@belmontdigitalmarketing/n8n-nodes-flowlu 0.4.0 → 0.5.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.
@@ -644,32 +644,56 @@ class Flowlu {
644
644
  displayOptions: { show: { resource: ['opportunity'], operation: ['create'] } },
645
645
  },
646
646
  {
647
- displayName: 'Pipeline Name or ID',
647
+ displayName: 'Pipeline',
648
648
  name: 'pipeline_id',
649
- type: 'options',
650
- typeOptions: { loadOptionsMethod: 'getPipelines' },
649
+ type: 'resourceLocator',
651
650
  required: true,
652
- default: '',
653
- description: 'The sales pipeline for this opportunity. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
651
+ default: { mode: 'list', value: '' },
652
+ description: 'The sales pipeline for this opportunity',
653
+ modes: [
654
+ {
655
+ displayName: 'From List',
656
+ name: 'list',
657
+ type: 'list',
658
+ typeOptions: { searchListMethod: 'searchPipelines', searchable: true },
659
+ },
660
+ { displayName: 'By ID', name: 'id', type: 'string', placeholder: 'e.g. 3' },
661
+ ],
654
662
  displayOptions: { show: { resource: ['opportunity'], operation: ['create'] } },
655
663
  },
656
664
  {
657
- displayName: 'Pipeline Stage Name or ID',
665
+ displayName: 'Pipeline Stage',
658
666
  name: 'pipeline_stage_id',
659
- type: 'options',
660
- typeOptions: { loadOptionsMethod: 'getPipelineStages' },
667
+ type: 'resourceLocator',
661
668
  required: true,
662
- default: '',
663
- description: 'The stage within the pipeline. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
669
+ default: { mode: 'list', value: '' },
670
+ description: 'The stage within the pipeline',
671
+ modes: [
672
+ {
673
+ displayName: 'From List',
674
+ name: 'list',
675
+ type: 'list',
676
+ typeOptions: { searchListMethod: 'searchPipelineStages', searchable: true },
677
+ },
678
+ { displayName: 'By ID', name: 'id', type: 'string', placeholder: 'e.g. 12' },
679
+ ],
664
680
  displayOptions: { show: { resource: ['opportunity'], operation: ['create'] } },
665
681
  },
666
682
  {
667
- displayName: 'Assignee Name or ID',
683
+ displayName: 'Assignee',
668
684
  name: 'opportunityAssignee',
669
- type: 'options',
670
- typeOptions: { loadOptionsMethod: 'getUsers' },
671
- default: '',
672
- description: 'The user responsible for this opportunity. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
685
+ type: 'resourceLocator',
686
+ default: { mode: 'list', value: '' },
687
+ description: 'The user responsible for this opportunity',
688
+ modes: [
689
+ {
690
+ displayName: 'From List',
691
+ name: 'list',
692
+ type: 'list',
693
+ typeOptions: { searchListMethod: 'searchUsers', searchable: true },
694
+ },
695
+ { displayName: 'By ID', name: 'id', type: 'string', placeholder: 'e.g. 176265' },
696
+ ],
673
697
  displayOptions: { show: { resource: ['opportunity'], operation: ['create'] } },
674
698
  },
675
699
  // Opportunity Create: Additional Fields
@@ -868,24 +892,37 @@ class Flowlu {
868
892
  displayOptions: { show: { resource: ['opportunity'], operation: ['getAll'] } },
869
893
  },
870
894
  {
871
- displayName: 'Pipeline Name or ID',
895
+ displayName: 'Pipeline',
872
896
  name: 'opportunityFilterPipeline',
873
- type: 'options',
874
- typeOptions: { loadOptionsMethod: 'getPipelines' },
875
- default: '',
876
- description: 'Filter by pipeline (also controls which stages appear below). Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
897
+ type: 'resourceLocator',
898
+ default: { mode: 'list', value: '' },
899
+ description: 'Filter by pipeline (also controls which stages appear below)',
900
+ modes: [
901
+ {
902
+ displayName: 'From List',
903
+ name: 'list',
904
+ type: 'list',
905
+ typeOptions: { searchListMethod: 'searchPipelines', searchable: true },
906
+ },
907
+ { displayName: 'By ID', name: 'id', type: 'string', placeholder: 'e.g. 3' },
908
+ ],
877
909
  displayOptions: { show: { resource: ['opportunity'], operation: ['getAll'] } },
878
910
  },
879
911
  {
880
- displayName: 'Pipeline Stage Name or ID',
912
+ displayName: 'Pipeline Stage',
881
913
  name: 'opportunityFilterStage',
882
- type: 'options',
883
- typeOptions: {
884
- loadOptionsMethod: 'getFilteredPipelineStages',
885
- loadOptionsDependsOn: ['opportunityFilterPipeline'],
886
- },
887
- default: '',
888
- description: 'Filter by stage (select a pipeline first to see its stages). Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
914
+ type: 'resourceLocator',
915
+ default: { mode: 'list', value: '' },
916
+ description: 'Filter by stage (select a pipeline first to narrow the list)',
917
+ modes: [
918
+ {
919
+ displayName: 'From List',
920
+ name: 'list',
921
+ type: 'list',
922
+ typeOptions: { searchListMethod: 'searchFilteredPipelineStages', searchable: true },
923
+ },
924
+ { displayName: 'By ID', name: 'id', type: 'string', placeholder: 'e.g. 12' },
925
+ ],
889
926
  displayOptions: { show: { resource: ['opportunity'], operation: ['getAll'] } },
890
927
  },
891
928
  {
@@ -948,12 +985,20 @@ class Flowlu {
948
985
  displayOptions: { show: { resource: ['project'], operation: ['create'] } },
949
986
  },
950
987
  {
951
- displayName: 'Manager Name or ID',
988
+ displayName: 'Manager',
952
989
  name: 'manager_id',
953
- type: 'options',
954
- typeOptions: { loadOptionsMethod: 'getUsers' },
955
- default: '',
956
- description: 'The user responsible for managing this project. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
990
+ type: 'resourceLocator',
991
+ default: { mode: 'list', value: '' },
992
+ description: 'The user responsible for managing this project',
993
+ modes: [
994
+ {
995
+ displayName: 'From List',
996
+ name: 'list',
997
+ type: 'list',
998
+ typeOptions: { searchListMethod: 'searchUsers', searchable: true },
999
+ },
1000
+ { displayName: 'By ID', name: 'id', type: 'string', placeholder: 'e.g. 176265' },
1001
+ ],
957
1002
  displayOptions: { show: { resource: ['project'], operation: ['create'] } },
958
1003
  },
959
1004
  {
@@ -1845,21 +1890,6 @@ class Flowlu {
1845
1890
  description: `Pipeline ID: ${s.pipeline_id}`,
1846
1891
  }));
1847
1892
  },
1848
- async getFilteredPipelineStages() {
1849
- const { baseUrl, apiKey } = await getFlowluCredentials(this);
1850
- let pipelineId;
1851
- try {
1852
- pipelineId = this.getNodeParameter('opportunityFilterPipeline');
1853
- }
1854
- catch {
1855
- /* not set yet */
1856
- }
1857
- const items = await flowluListAll.call(this, baseUrl, '/api/v1/module/crm/pipeline_stage/list', apiKey);
1858
- const stages = pipelineId
1859
- ? items.filter((s) => s.pipeline_id?.toString() === pipelineId)
1860
- : items;
1861
- return stages.map((s) => ({ name: s.name || `Stage ${s.id}`, value: s.id.toString() }));
1862
- },
1863
1893
  async getAllCrmAccounts() {
1864
1894
  const { baseUrl, apiKey } = await getFlowluCredentials(this);
1865
1895
  const items = await flowluListAll.call(this, baseUrl, '/api/v1/module/crm/account/list', apiKey);
@@ -2186,6 +2216,41 @@ class Flowlu {
2186
2216
  }));
2187
2217
  return { results };
2188
2218
  },
2219
+ async searchPipelines(filter) {
2220
+ const { baseUrl, apiKey } = await getFlowluCredentials(this);
2221
+ const items = await flowluListAll.call(this, baseUrl, '/api/v1/module/crm/pipeline/list', apiKey);
2222
+ const term = (filter ?? '').toLowerCase();
2223
+ const results = items
2224
+ .map((p) => ({ name: p.name || `Pipeline ${p.id}`, value: p.id.toString() }))
2225
+ .filter((r) => !term || r.name.toLowerCase().includes(term));
2226
+ return { results };
2227
+ },
2228
+ async searchPipelineStages(filter) {
2229
+ const { baseUrl, apiKey } = await getFlowluCredentials(this);
2230
+ const items = await flowluListAll.call(this, baseUrl, '/api/v1/module/crm/pipeline_stage/list', apiKey);
2231
+ const term = (filter ?? '').toLowerCase();
2232
+ const results = items
2233
+ .map((s) => ({ name: s.name || `Stage ${s.id}`, value: s.id.toString() }))
2234
+ .filter((r) => !term || r.name.toLowerCase().includes(term));
2235
+ return { results };
2236
+ },
2237
+ async searchFilteredPipelineStages(filter) {
2238
+ const { baseUrl, apiKey } = await getFlowluCredentials(this);
2239
+ let pipelineId = '';
2240
+ try {
2241
+ pipelineId = this.getCurrentNodeParameter('opportunityFilterPipeline', { extractValue: true }) || '';
2242
+ }
2243
+ catch {
2244
+ /* pipeline not selected yet */
2245
+ }
2246
+ const items = await flowluListAll.call(this, baseUrl, '/api/v1/module/crm/pipeline_stage/list', apiKey);
2247
+ const term = (filter ?? '').toLowerCase();
2248
+ const results = items
2249
+ .filter((s) => !pipelineId || s.pipeline_id?.toString() === pipelineId)
2250
+ .map((s) => ({ name: s.name || `Stage ${s.id}`, value: s.id.toString() }))
2251
+ .filter((r) => !term || r.name.toLowerCase().includes(term));
2252
+ return { results };
2253
+ },
2189
2254
  },
2190
2255
  };
2191
2256
  }
@@ -2330,10 +2395,10 @@ class Flowlu {
2330
2395
  if (operation === 'create') {
2331
2396
  const body = {
2332
2397
  name: this.getNodeParameter('opportunityName', i),
2333
- pipeline_id: this.getNodeParameter('pipeline_id', i),
2334
- pipeline_stage_id: this.getNodeParameter('pipeline_stage_id', i),
2398
+ pipeline_id: getResourceValue(this, 'pipeline_id', i),
2399
+ pipeline_stage_id: getResourceValue(this, 'pipeline_stage_id', i),
2335
2400
  };
2336
- const assignee = this.getNodeParameter('opportunityAssignee', i);
2401
+ const assignee = getResourceValue(this, 'opportunityAssignee', i);
2337
2402
  if (assignee)
2338
2403
  body.assignee_id = assignee;
2339
2404
  const additional = this.getNodeParameter('opportunityAdditionalFields', i);
@@ -2388,8 +2453,8 @@ class Flowlu {
2388
2453
  }
2389
2454
  else if (operation === 'getAll') {
2390
2455
  const limit = this.getNodeParameter('limit', i);
2391
- const pipelineId = this.getNodeParameter('opportunityFilterPipeline', i);
2392
- const stageId = this.getNodeParameter('opportunityFilterStage', i);
2456
+ const pipelineId = getResourceValue(this, 'opportunityFilterPipeline', i);
2457
+ const stageId = getResourceValue(this, 'opportunityFilterStage', i);
2393
2458
  const filters = this.getNodeParameter('opportunityFilters', i);
2394
2459
  const qs = { limit: limit.toString() };
2395
2460
  if (pipelineId)
@@ -2460,7 +2525,7 @@ class Flowlu {
2460
2525
  const body = {
2461
2526
  name: this.getNodeParameter('projectName', i),
2462
2527
  };
2463
- const managerId = this.getNodeParameter('manager_id', i);
2528
+ const managerId = getResourceValue(this, 'manager_id', i);
2464
2529
  if (managerId)
2465
2530
  body.manager_id = managerId;
2466
2531
  const desc = this.getNodeParameter('projectDescription', i);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@belmontdigitalmarketing/n8n-nodes-flowlu",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "n8n community node for the Flowlu CRM, project management, and task API",
5
5
  "keywords": [
6
6
  "n8n-community-node-package",