@belmontdigitalmarketing/n8n-nodes-flowlu 0.3.1 → 0.4.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/dist/nodes/Flowlu/Flowlu.node.js +104 -24
- package/package.json +1 -1
|
@@ -105,6 +105,15 @@ function applyResourceMapperFields(context, body, paramName, itemIndex) {
|
|
|
105
105
|
// No custom fields set - ignore
|
|
106
106
|
}
|
|
107
107
|
}
|
|
108
|
+
// Read a resourceLocator parameter (or a legacy scalar value) as its underlying id.
|
|
109
|
+
function getResourceValue(context, name, itemIndex) {
|
|
110
|
+
const raw = context.getNodeParameter(name, itemIndex, '');
|
|
111
|
+
if (raw && typeof raw === 'object' && 'value' in raw) {
|
|
112
|
+
const value = raw.value;
|
|
113
|
+
return value === undefined || value === null ? '' : String(value);
|
|
114
|
+
}
|
|
115
|
+
return raw ? String(raw) : '';
|
|
116
|
+
}
|
|
108
117
|
// Helper to load an entity's custom fields as name/value options.
|
|
109
118
|
async function loadCustomFieldsForEntity(context, moduleFilter, modelFilter) {
|
|
110
119
|
const { baseUrl, apiKey } = await getFlowluCredentials(context);
|
|
@@ -1300,13 +1309,21 @@ class Flowlu {
|
|
|
1300
1309
|
displayOptions: { show: { resource: ['task'], operation: ['create'] } },
|
|
1301
1310
|
},
|
|
1302
1311
|
{
|
|
1303
|
-
displayName: 'Assignee
|
|
1312
|
+
displayName: 'Assignee',
|
|
1304
1313
|
name: 'responsible_id',
|
|
1305
|
-
type: '
|
|
1306
|
-
typeOptions: { loadOptionsMethod: 'getUsers' },
|
|
1314
|
+
type: 'resourceLocator',
|
|
1307
1315
|
required: true,
|
|
1308
|
-
default: '',
|
|
1309
|
-
description: 'The user responsible for completing this task
|
|
1316
|
+
default: { mode: 'list', value: '' },
|
|
1317
|
+
description: 'The user responsible for completing this task',
|
|
1318
|
+
modes: [
|
|
1319
|
+
{
|
|
1320
|
+
displayName: 'From List',
|
|
1321
|
+
name: 'list',
|
|
1322
|
+
type: 'list',
|
|
1323
|
+
typeOptions: { searchListMethod: 'searchUsers', searchable: true },
|
|
1324
|
+
},
|
|
1325
|
+
{ displayName: 'By ID', name: 'id', type: 'string', placeholder: 'e.g. 176265' },
|
|
1326
|
+
],
|
|
1310
1327
|
displayOptions: { show: { resource: ['task'], operation: ['create'] } },
|
|
1311
1328
|
},
|
|
1312
1329
|
{
|
|
@@ -1318,12 +1335,20 @@ class Flowlu {
|
|
|
1318
1335
|
displayOptions: { show: { resource: ['task'], operation: ['create'] } },
|
|
1319
1336
|
},
|
|
1320
1337
|
{
|
|
1321
|
-
displayName: 'Owner
|
|
1338
|
+
displayName: 'Owner',
|
|
1322
1339
|
name: 'owner_id',
|
|
1323
|
-
type: '
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1340
|
+
type: 'resourceLocator',
|
|
1341
|
+
default: { mode: 'list', value: '' },
|
|
1342
|
+
description: 'The user who owns this task. If left blank, the credential\'s Default Task Owner is used.',
|
|
1343
|
+
modes: [
|
|
1344
|
+
{
|
|
1345
|
+
displayName: 'From List',
|
|
1346
|
+
name: 'list',
|
|
1347
|
+
type: 'list',
|
|
1348
|
+
typeOptions: { searchListMethod: 'searchUsers', searchable: true },
|
|
1349
|
+
},
|
|
1350
|
+
{ displayName: 'By ID', name: 'id', type: 'string', placeholder: 'e.g. 176265' },
|
|
1351
|
+
],
|
|
1327
1352
|
displayOptions: { show: { resource: ['task'], operation: ['create'] } },
|
|
1328
1353
|
},
|
|
1329
1354
|
{
|
|
@@ -1339,21 +1364,37 @@ class Flowlu {
|
|
|
1339
1364
|
displayOptions: { show: { resource: ['task'], operation: ['create'] } },
|
|
1340
1365
|
},
|
|
1341
1366
|
{
|
|
1342
|
-
displayName: 'Contact
|
|
1367
|
+
displayName: 'Contact',
|
|
1343
1368
|
name: 'contact_id',
|
|
1344
|
-
type: '
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1369
|
+
type: 'resourceLocator',
|
|
1370
|
+
default: { mode: 'list', value: '' },
|
|
1371
|
+
description: 'The contact this task is related to. Search by name, or enter a contact ID.',
|
|
1372
|
+
modes: [
|
|
1373
|
+
{
|
|
1374
|
+
displayName: 'From List',
|
|
1375
|
+
name: 'list',
|
|
1376
|
+
type: 'list',
|
|
1377
|
+
typeOptions: { searchListMethod: 'searchContacts', searchable: true },
|
|
1378
|
+
},
|
|
1379
|
+
{ displayName: 'By ID', name: 'id', type: 'string', placeholder: 'e.g. 12345' },
|
|
1380
|
+
],
|
|
1348
1381
|
displayOptions: { show: { resource: ['task'], operation: ['create'] } },
|
|
1349
1382
|
},
|
|
1350
1383
|
{
|
|
1351
|
-
displayName: 'Project
|
|
1384
|
+
displayName: 'Project',
|
|
1352
1385
|
name: 'model_id',
|
|
1353
|
-
type: '
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1386
|
+
type: 'resourceLocator',
|
|
1387
|
+
default: { mode: 'list', value: '' },
|
|
1388
|
+
description: 'The project this task belongs to',
|
|
1389
|
+
modes: [
|
|
1390
|
+
{
|
|
1391
|
+
displayName: 'From List',
|
|
1392
|
+
name: 'list',
|
|
1393
|
+
type: 'list',
|
|
1394
|
+
typeOptions: { searchListMethod: 'searchProjects', searchable: true },
|
|
1395
|
+
},
|
|
1396
|
+
{ displayName: 'By ID', name: 'id', type: 'string', placeholder: 'e.g. 678' },
|
|
1397
|
+
],
|
|
1357
1398
|
displayOptions: { show: { resource: ['task'], operation: ['create'] } },
|
|
1358
1399
|
},
|
|
1359
1400
|
{
|
|
@@ -2107,6 +2148,45 @@ class Flowlu {
|
|
|
2107
2148
|
}
|
|
2108
2149
|
},
|
|
2109
2150
|
},
|
|
2151
|
+
listSearch: {
|
|
2152
|
+
async searchUsers(filter) {
|
|
2153
|
+
const { baseUrl, apiKey } = await getFlowluCredentials(this);
|
|
2154
|
+
const items = await flowluListAll.call(this, baseUrl, '/api/v1/module/core/user/list', apiKey, {
|
|
2155
|
+
'filter[role_login]': '1',
|
|
2156
|
+
});
|
|
2157
|
+
const term = (filter ?? '').toLowerCase();
|
|
2158
|
+
const results = items
|
|
2159
|
+
.map((u) => ({ name: u.name || u.email || `User ${u.id}`, value: u.id.toString() }))
|
|
2160
|
+
.filter((r) => !term || r.name.toLowerCase().includes(term));
|
|
2161
|
+
return { results };
|
|
2162
|
+
},
|
|
2163
|
+
async searchProjects(filter) {
|
|
2164
|
+
const { baseUrl, apiKey } = await getFlowluCredentials(this);
|
|
2165
|
+
const items = await flowluListAll.call(this, baseUrl, '/api/v1/module/st/projects/list', apiKey, {
|
|
2166
|
+
'filter[is_archive]': '0',
|
|
2167
|
+
});
|
|
2168
|
+
const term = (filter ?? '').toLowerCase();
|
|
2169
|
+
const results = items
|
|
2170
|
+
.map((p) => ({ name: p.name || `Project ${p.id}`, value: p.id.toString() }))
|
|
2171
|
+
.filter((r) => !term || r.name.toLowerCase().includes(term));
|
|
2172
|
+
return { results };
|
|
2173
|
+
},
|
|
2174
|
+
async searchContacts(filter) {
|
|
2175
|
+
const { baseUrl, apiKey } = await getFlowluCredentials(this);
|
|
2176
|
+
const qs = { 'filter[type]': '2' };
|
|
2177
|
+
// Contacts can number in the thousands, so use Flowlu's server-side search and
|
|
2178
|
+
// take just the first page rather than paginating the whole list.
|
|
2179
|
+
if (filter)
|
|
2180
|
+
qs.search = filter;
|
|
2181
|
+
const response = await flowluApiGetWithRetry.call(this, baseUrl, '/api/v1/module/crm/account/list', apiKey, qs);
|
|
2182
|
+
const items = response?.response?.items ?? [];
|
|
2183
|
+
const results = items.map((c) => ({
|
|
2184
|
+
name: c.name || `Contact ${c.id}`,
|
|
2185
|
+
value: c.id.toString(),
|
|
2186
|
+
}));
|
|
2187
|
+
return { results };
|
|
2188
|
+
},
|
|
2189
|
+
},
|
|
2110
2190
|
};
|
|
2111
2191
|
}
|
|
2112
2192
|
async execute() {
|
|
@@ -2530,7 +2610,7 @@ class Flowlu {
|
|
|
2530
2610
|
if (operation === 'create') {
|
|
2531
2611
|
const body = {
|
|
2532
2612
|
name: this.getNodeParameter('taskName', i),
|
|
2533
|
-
responsible_id: this
|
|
2613
|
+
responsible_id: getResourceValue(this, 'responsible_id', i),
|
|
2534
2614
|
};
|
|
2535
2615
|
const description = this.getNodeParameter('description', i);
|
|
2536
2616
|
if (description)
|
|
@@ -2540,10 +2620,10 @@ class Flowlu {
|
|
|
2540
2620
|
body.workflow_stage_id = additional.workflow_stage_id || '1';
|
|
2541
2621
|
// Owner/Priority/Contact/Project/Start/End moved to top-level fields; fall back to
|
|
2542
2622
|
// Additional Fields so task-create nodes built before the move keep working.
|
|
2543
|
-
const ownerId = this
|
|
2623
|
+
const ownerId = getResourceValue(this, 'owner_id', i) || additional.owner_id || defaultOwnerId;
|
|
2544
2624
|
if (ownerId)
|
|
2545
2625
|
body.owner_id = ownerId;
|
|
2546
|
-
const contactId = this
|
|
2626
|
+
const contactId = getResourceValue(this, 'contact_id', i) || additional.contact_id;
|
|
2547
2627
|
if (contactId)
|
|
2548
2628
|
body.crm_account_id = parseInt(contactId, 10);
|
|
2549
2629
|
body.priority =
|
|
@@ -2576,7 +2656,7 @@ class Flowlu {
|
|
|
2576
2656
|
if (additional.parent_id && additional.parent_id > 0) {
|
|
2577
2657
|
body.parent_id = additional.parent_id;
|
|
2578
2658
|
}
|
|
2579
|
-
const modelId = this
|
|
2659
|
+
const modelId = getResourceValue(this, 'model_id', i) || additional.model_id;
|
|
2580
2660
|
if (modelId) {
|
|
2581
2661
|
body.model_id = modelId;
|
|
2582
2662
|
body.model = 'project';
|
package/package.json
CHANGED