@worktables/n8n-nodes-worktables 12.1.1 → 12.1.3

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.
@@ -244,6 +244,12 @@ class Worktables {
244
244
  description: 'Search items in a board using a filter',
245
245
  action: 'Search items by filter',
246
246
  },
247
+ {
248
+ name: 'Advanced Search Items',
249
+ value: 'searchItemsAdvanced',
250
+ description: 'Advanced search with date ranges, numeric comparisons, and complex filters',
251
+ action: 'Advanced search items',
252
+ },
247
253
  {
248
254
  name: 'List Item Subscribers',
249
255
  value: 'listItemSubscribers',
@@ -1022,7 +1028,7 @@ class Worktables {
1022
1028
  description: 'Select a Monday board. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.',
1023
1029
  displayOptions: {
1024
1030
  show: {
1025
- operation: ['duplicateItem', 'searchItems', 'uploadItemFile', 'getGroup'],
1031
+ operation: ['duplicateItem', 'searchItems', 'searchItemsAdvanced', 'uploadItemFile', 'getGroup'],
1026
1032
  },
1027
1033
  },
1028
1034
  },
@@ -1563,6 +1569,60 @@ class Worktables {
1563
1569
  },
1564
1570
  },
1565
1571
  },
1572
+ {
1573
+ displayName: 'Limit',
1574
+ name: 'limit',
1575
+ type: 'number',
1576
+ default: 50,
1577
+ description: 'Max number of results to return',
1578
+ displayOptions: {
1579
+ show: {
1580
+ resource: ['item'],
1581
+ operation: ['searchItemsAdvanced'],
1582
+ },
1583
+ },
1584
+ typeOptions: {
1585
+ minValue: 1,
1586
+ },
1587
+ },
1588
+ {
1589
+ displayName: 'Cursor',
1590
+ name: 'cursor',
1591
+ type: 'string',
1592
+ default: '',
1593
+ description: 'Cursor for pagination (get from previous response)',
1594
+ displayOptions: {
1595
+ show: {
1596
+ resource: ['item'],
1597
+ operation: ['searchItemsAdvanced'],
1598
+ },
1599
+ },
1600
+ },
1601
+ {
1602
+ displayName: 'Search Term',
1603
+ name: 'searchTerm',
1604
+ type: 'string',
1605
+ default: '',
1606
+ description: 'Search term for text-based search across items',
1607
+ displayOptions: {
1608
+ show: {
1609
+ resource: ['item'],
1610
+ operation: ['searchItemsAdvanced'],
1611
+ },
1612
+ },
1613
+ },
1614
+ {
1615
+ displayName: 'Fetch Column Values',
1616
+ name: 'fetchColumnValuesAdvanced',
1617
+ type: 'boolean',
1618
+ default: true,
1619
+ description: 'Whether to fetch column values',
1620
+ displayOptions: {
1621
+ show: {
1622
+ operation: ['searchItemsAdvanced'],
1623
+ },
1624
+ },
1625
+ },
1566
1626
  {
1567
1627
  displayName: 'Filter Rules',
1568
1628
  name: 'filterRules',
@@ -1634,6 +1694,100 @@ class Worktables {
1634
1694
  },
1635
1695
  ],
1636
1696
  },
1697
+ {
1698
+ displayName: 'Advanced Filter Rules',
1699
+ name: 'advancedFilterRules',
1700
+ type: 'fixedCollection',
1701
+ typeOptions: { multipleValues: true },
1702
+ default: {},
1703
+ displayOptions: {
1704
+ show: {
1705
+ resource: ['item'],
1706
+ operation: ['searchItemsAdvanced'],
1707
+ },
1708
+ },
1709
+ options: [
1710
+ {
1711
+ displayName: 'Rule',
1712
+ name: 'rule',
1713
+ values: [
1714
+ {
1715
+ displayName: 'Column',
1716
+ name: 'columnId',
1717
+ type: 'options',
1718
+ description: 'Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>',
1719
+ typeOptions: {
1720
+ loadOptionsDependsOn: ['boardId'],
1721
+ loadOptionsMethod: 'getColumnsItems',
1722
+ },
1723
+ default: '',
1724
+ },
1725
+ {
1726
+ displayName: 'Compare Attribute',
1727
+ name: 'compareAttribute',
1728
+ type: 'string',
1729
+ default: '',
1730
+ description: 'Optional attribute for comparison (dependent on column type)',
1731
+ },
1732
+ {
1733
+ displayName: 'Operator',
1734
+ name: 'operator',
1735
+ type: 'options',
1736
+ options: [
1737
+ { name: 'Any Of', value: 'any_of' },
1738
+ { name: 'Not Any Of', value: 'not_any_of' },
1739
+ { name: 'Is Empty', value: 'is_empty' },
1740
+ { name: 'Is Not Empty', value: 'is_not_empty' },
1741
+ { name: 'Greater Than', value: 'greater_than' },
1742
+ { name: 'Greater Than or Equal', value: 'greater_than_or_equals' },
1743
+ { name: 'Less Than', value: 'lower_than' },
1744
+ { name: 'Less Than or Equal', value: 'lower_than_or_equal' },
1745
+ { name: 'Between', value: 'between' },
1746
+ { name: 'Contains Text', value: 'contains_text' },
1747
+ { name: 'Does Not Contain Text', value: 'not_contains_text' },
1748
+ { name: 'Contains Terms', value: 'contains_terms' },
1749
+ { name: 'Starts With', value: 'starts_with' },
1750
+ { name: 'Ends With', value: 'ends_with' },
1751
+ { name: 'Within the Next', value: 'within_the_next' },
1752
+ { name: 'Within the Last', value: 'within_the_last' },
1753
+ ],
1754
+ default: 'any_of',
1755
+ description: 'The condition for value comparison',
1756
+ },
1757
+ {
1758
+ displayName: 'Compare Value',
1759
+ name: 'compareValue',
1760
+ type: 'string',
1761
+ default: '',
1762
+ description: 'The value to filter by (format depends on column type)',
1763
+ },
1764
+ ],
1765
+ },
1766
+ ],
1767
+ },
1768
+ {
1769
+ displayName: 'Logical Operator',
1770
+ name: 'logicalOperatorAdvanced',
1771
+ type: 'options',
1772
+ options: [
1773
+ {
1774
+ name: 'AND',
1775
+ value: 'and',
1776
+ },
1777
+ {
1778
+ name: 'OR',
1779
+ value: 'or',
1780
+ },
1781
+ ],
1782
+ default: 'and',
1783
+ description: 'Logical operator to use between filter rules',
1784
+ displayOptions: {
1785
+ show: {
1786
+ resource: ['item'],
1787
+ operation: ['searchItemsAdvanced'],
1788
+ },
1789
+ },
1790
+ },
1637
1791
  {
1638
1792
  displayName: 'Sort Options',
1639
1793
  name: 'sortOptions',
@@ -1677,6 +1831,49 @@ class Worktables {
1677
1831
  },
1678
1832
  ],
1679
1833
  },
1834
+ {
1835
+ displayName: 'Advanced Sort Options',
1836
+ name: 'advancedSortOptions',
1837
+ type: 'fixedCollection',
1838
+ typeOptions: { multipleValues: true },
1839
+ default: {},
1840
+ displayOptions: {
1841
+ show: {
1842
+ resource: ['item'],
1843
+ operation: ['searchItemsAdvanced'],
1844
+ },
1845
+ },
1846
+ options: [
1847
+ {
1848
+ displayName: 'Sort By',
1849
+ name: 'sortBy',
1850
+ values: [
1851
+ {
1852
+ displayName: 'Column',
1853
+ name: 'columnId',
1854
+ type: 'options',
1855
+ description: 'Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>',
1856
+ typeOptions: {
1857
+ loadOptionsDependsOn: ['boardId'],
1858
+ loadOptionsMethod: 'getColumnsItems',
1859
+ },
1860
+ default: '',
1861
+ },
1862
+ {
1863
+ displayName: 'Direction',
1864
+ name: 'direction',
1865
+ type: 'options',
1866
+ options: [
1867
+ { name: 'Ascending', value: 'asc' },
1868
+ { name: 'Descending', value: 'desc' },
1869
+ ],
1870
+ default: 'asc',
1871
+ description: 'The sort direction',
1872
+ },
1873
+ ],
1874
+ },
1875
+ ],
1876
+ },
1680
1877
  {
1681
1878
  displayName: 'File Column',
1682
1879
  name: 'fileColumnId',
@@ -2535,7 +2732,7 @@ class Worktables {
2535
2732
  };
2536
2733
  }
2537
2734
  async execute() {
2538
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11;
2735
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16;
2539
2736
  const resource = this.getNodeParameter('resource', 0);
2540
2737
  const operation = this.getNodeParameter('operation', 0);
2541
2738
  const credentials = await this.getCredentials('WorktablesApi');
@@ -4375,6 +4572,174 @@ class Worktables {
4375
4572
  response = JSON.stringify(formattedItems);
4376
4573
  break;
4377
4574
  }
4575
+ case 'searchItemsAdvanced': {
4576
+ const boardId = this.getNodeParameter('boardId', 0);
4577
+ const limit = this.getNodeParameter('limit', 0, 25);
4578
+ const cursor = this.getNodeParameter('cursor', 0, '');
4579
+ const searchTerm = this.getNodeParameter('searchTerm', 0, '');
4580
+ const fetchColumnValues = this.getNodeParameter('fetchColumnValuesAdvanced', 0, true);
4581
+ const advancedFilterRules = this.getNodeParameter('advancedFilterRules', 0);
4582
+ const advancedSortOptions = this.getNodeParameter('advancedSortOptions', 0, { sortBy: [] });
4583
+ const logicalOperator = this.getNodeParameter('logicalOperatorAdvanced', 0);
4584
+ let rulesArray = [];
4585
+ if (((_2 = advancedFilterRules === null || advancedFilterRules === void 0 ? void 0 : advancedFilterRules.rule) === null || _2 === void 0 ? void 0 : _2.length) > 0) {
4586
+ rulesArray = advancedFilterRules.rule.map((rule) => {
4587
+ let formattedValue;
4588
+ if (['is_empty', 'is_not_empty'].includes(rule.operator)) {
4589
+ formattedValue = '""';
4590
+ }
4591
+ else if (rule.operator === 'between') {
4592
+ try {
4593
+ const rangeValues = JSON.parse(rule.compareValue);
4594
+ formattedValue = JSON.stringify(rangeValues);
4595
+ }
4596
+ catch (e) {
4597
+ const values = rule.compareValue.split(',').map((v) => v.trim());
4598
+ formattedValue = JSON.stringify(values);
4599
+ }
4600
+ }
4601
+ else if (['any_of', 'not_any_of'].includes(rule.operator)) {
4602
+ try {
4603
+ const multiValues = JSON.parse(rule.compareValue);
4604
+ formattedValue = Array.isArray(multiValues)
4605
+ ? JSON.stringify(multiValues)
4606
+ : JSON.stringify([rule.compareValue]);
4607
+ }
4608
+ catch (e) {
4609
+ const values = rule.compareValue.split(',').map((v) => v.trim());
4610
+ formattedValue = JSON.stringify(values);
4611
+ }
4612
+ }
4613
+ else if (['within_the_next', 'within_the_last'].includes(rule.operator)) {
4614
+ try {
4615
+ const dateRange = JSON.parse(rule.compareValue);
4616
+ formattedValue = JSON.stringify(dateRange);
4617
+ }
4618
+ catch (e) {
4619
+ formattedValue = JSON.stringify({ days: parseInt(rule.compareValue) || 7 });
4620
+ }
4621
+ }
4622
+ else if (['greater_than', 'greater_than_or_equals', 'lower_than', 'lower_than_or_equal'].includes(rule.operator)) {
4623
+ if (rule.compareAttribute === 'date') {
4624
+ const dateValue = new Date(rule.compareValue).toISOString();
4625
+ formattedValue = JSON.stringify(dateValue);
4626
+ }
4627
+ else {
4628
+ formattedValue = JSON.stringify(rule.compareValue);
4629
+ }
4630
+ }
4631
+ else {
4632
+ formattedValue = JSON.stringify(rule.compareValue);
4633
+ }
4634
+ return `{
4635
+ column_id: "${rule.columnId}",
4636
+ ${rule.compareAttribute ? `compare_attribute: "${rule.compareAttribute}",` : ''}
4637
+ compare_value: ${formattedValue},
4638
+ operator: ${rule.operator}
4639
+ }`;
4640
+ });
4641
+ }
4642
+ const orderByArray = [];
4643
+ if (((_3 = advancedSortOptions === null || advancedSortOptions === void 0 ? void 0 : advancedSortOptions.sortBy) === null || _3 === void 0 ? void 0 : _3.length) > 0) {
4644
+ advancedSortOptions.sortBy.forEach((sort) => {
4645
+ orderByArray.push(`{
4646
+ column_id: "${sort.columnId}",
4647
+ direction: ${sort.direction}
4648
+ }`);
4649
+ });
4650
+ }
4651
+ const query = `query {
4652
+ boards(ids: [${boardId}]) {
4653
+ items_page(limit: ${limit}, ${cursor ? `cursor: "${cursor}",` : ''} query_params: {
4654
+ ${logicalOperator ? `operator: ${logicalOperator},` : ''}
4655
+ ${rulesArray.length > 0 ? `rules: [${rulesArray.join(', ')}],` : ''}
4656
+ ${orderByArray.length > 0 ? `order_by: [${orderByArray.join(', ')}]` : ''}
4657
+ }${searchTerm ? `, search_term: "${searchTerm}"` : ''}) {
4658
+ items {
4659
+ id
4660
+ name
4661
+ column_values {
4662
+ id
4663
+ text
4664
+ value
4665
+ type
4666
+ display_value
4667
+ }
4668
+ group {
4669
+ id
4670
+ title
4671
+ color
4672
+ position
4673
+ }
4674
+ state
4675
+ created_at
4676
+ updated_at
4677
+ subscribers {
4678
+ id
4679
+ name
4680
+ email
4681
+ }
4682
+ }
4683
+ cursor
4684
+ has_more
4685
+ }
4686
+ }
4687
+ }`;
4688
+ console.log('Advanced Search Query: ', query);
4689
+ const rawResponse = await this.helpers.request({
4690
+ method: 'POST',
4691
+ url: 'https://api.monday.com/v2',
4692
+ headers,
4693
+ body: { query },
4694
+ });
4695
+ const parsed = JSON.parse(rawResponse);
4696
+ const itemsPage = (_6 = (_5 = (_4 = parsed === null || parsed === void 0 ? void 0 : parsed.data) === null || _4 === void 0 ? void 0 : _4.boards) === null || _5 === void 0 ? void 0 : _5[0]) === null || _6 === void 0 ? void 0 : _6.items_page;
4697
+ const items = (itemsPage === null || itemsPage === void 0 ? void 0 : itemsPage.items) || [];
4698
+ const nextCursor = itemsPage === null || itemsPage === void 0 ? void 0 : itemsPage.cursor;
4699
+ const hasMore = itemsPage === null || itemsPage === void 0 ? void 0 : itemsPage.has_more;
4700
+ const formattedItems = await Promise.all(items.map(async (item) => {
4701
+ const formatted = {
4702
+ id: item.id,
4703
+ name: item.name,
4704
+ group: item.group,
4705
+ state: item.state,
4706
+ created_at: item.created_at,
4707
+ updated_at: item.updated_at,
4708
+ subscribers: item.subscribers,
4709
+ column_values: !fetchColumnValues ? undefined : {},
4710
+ _pagination: {
4711
+ nextCursor,
4712
+ hasMore,
4713
+ },
4714
+ };
4715
+ if (!fetchColumnValues)
4716
+ return formatted;
4717
+ for (const col of item.column_values || []) {
4718
+ if (col.type === 'subtasks')
4719
+ continue;
4720
+ const formattedCol = {
4721
+ type: col.type,
4722
+ value: await (0, parseValue_1.parseValue)(col.value),
4723
+ text: col.text,
4724
+ };
4725
+ if ('display_value' in col) {
4726
+ formattedCol.display_value = col.display_value;
4727
+ }
4728
+ formatted.column_values[col.id] = formattedCol;
4729
+ }
4730
+ return formatted;
4731
+ }));
4732
+ const result = {
4733
+ items: formattedItems,
4734
+ pagination: {
4735
+ nextCursor,
4736
+ hasMore,
4737
+ totalReturned: formattedItems.length,
4738
+ },
4739
+ };
4740
+ response = JSON.stringify(result);
4741
+ break;
4742
+ }
4378
4743
  case 'uploadItemFile': {
4379
4744
  const itemId = this.getNodeParameter('itemId', 0);
4380
4745
  const columnId = this.getNodeParameter('fileColumnId', 0);
@@ -4476,7 +4841,7 @@ class Worktables {
4476
4841
  body: { query },
4477
4842
  });
4478
4843
  const parsed = JSON.parse(rawResponse);
4479
- const items = ((_7 = (_6 = (_5 = (_4 = (_3 = (_2 = parsed === null || parsed === void 0 ? void 0 : parsed.data) === null || _2 === void 0 ? void 0 : _2.boards) === null || _3 === void 0 ? void 0 : _3[0]) === null || _4 === void 0 ? void 0 : _4.groups) === null || _5 === void 0 ? void 0 : _5[0]) === null || _6 === void 0 ? void 0 : _6.items_page) === null || _7 === void 0 ? void 0 : _7.items) || [];
4844
+ const items = ((_12 = (_11 = (_10 = (_9 = (_8 = (_7 = parsed === null || parsed === void 0 ? void 0 : parsed.data) === null || _7 === void 0 ? void 0 : _7.boards) === null || _8 === void 0 ? void 0 : _8[0]) === null || _9 === void 0 ? void 0 : _9.groups) === null || _10 === void 0 ? void 0 : _10[0]) === null || _11 === void 0 ? void 0 : _11.items_page) === null || _12 === void 0 ? void 0 : _12.items) || [];
4480
4845
  const formattedItems = await Promise.all(items.map(async (item) => {
4481
4846
  const formatted = {
4482
4847
  id: item.id,
@@ -4600,7 +4965,7 @@ class Worktables {
4600
4965
  body: { query: mutation },
4601
4966
  });
4602
4967
  console.log('Create Update Result:', JSON.stringify(response, null, 2));
4603
- const updateId = (_9 = (_8 = JSON.parse(response).data) === null || _8 === void 0 ? void 0 : _8.create_update) === null || _9 === void 0 ? void 0 : _9.id;
4968
+ const updateId = (_14 = (_13 = JSON.parse(response).data) === null || _13 === void 0 ? void 0 : _13.create_update) === null || _14 === void 0 ? void 0 : _14.id;
4604
4969
  if (!updateId) {
4605
4970
  throw new n8n_workflow_1.NodeApiError(this.getNode(), {
4606
4971
  message: 'Error creating update: Update not created, no ID returned',
@@ -4920,7 +5285,7 @@ class Worktables {
4920
5285
  body: { query },
4921
5286
  json: true,
4922
5287
  });
4923
- const asset = (_11 = (_10 = responseFile === null || responseFile === void 0 ? void 0 : responseFile.data) === null || _10 === void 0 ? void 0 : _10.assets) === null || _11 === void 0 ? void 0 : _11[0];
5288
+ const asset = (_16 = (_15 = responseFile === null || responseFile === void 0 ? void 0 : responseFile.data) === null || _15 === void 0 ? void 0 : _15.assets) === null || _16 === void 0 ? void 0 : _16[0];
4924
5289
  if (!(asset === null || asset === void 0 ? void 0 : asset.public_url)) {
4925
5290
  throw new n8n_workflow_1.NodeApiError(this.getNode(), {
4926
5291
  message: 'Public URL not found for the given file ID.',