@integry/sdk 4.6.91 → 4.6.93

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@integry/sdk",
3
- "version": "4.6.91",
3
+ "version": "4.6.93",
4
4
  "description": "Integry SDK",
5
5
  "main": "dist/umd/index.umd.js",
6
6
  "module": "dist/esm/index.csm.js",
@@ -1,11 +1,12 @@
1
+ 'use client';
2
+
1
3
  import { html } from 'htm/preact';
2
4
  import { connect } from 'unistore/preact';
3
- import { useContext, useEffect, useState } from 'preact/hooks';
4
- import { DynamicField, NestedObject } from '@/interfaces';
5
+ import { useContext, useEffect, useState, useRef } from 'preact/hooks';
6
+ import type { DynamicField, NestedObject } from '@/interfaces';
5
7
  import AppContext from '@/contexts/AppContext';
6
- import { StoreType } from '@/types/store';
7
- import { IntegryAPI } from '@/modules/api';
8
- import { Input } from '@/components/Input';
8
+ import type { StoreType } from '@/types/store';
9
+ import type { IntegryAPI } from '@/modules/api';
9
10
  import { MultipurposeField } from '@/components/MultipurposeField';
10
11
  import { Loader } from '@/components/Loader';
11
12
  import { actionFunctions } from '@/store';
@@ -36,6 +37,8 @@ export type DynamicFieldsProps = {
36
37
  value?: any;
37
38
  isDisabled?: boolean;
38
39
  onChangeCallback?: (val: any) => void;
40
+ dependsOn?: string[];
41
+ isArray?: boolean; // New prop to determine if the output should be an array
39
42
  } & StoreType;
40
43
 
41
44
  interface DynamicDataItem {
@@ -55,8 +58,6 @@ interface ApiResponse {
55
58
  const DynamicTypedFields = (props: DynamicFieldsProps) => {
56
59
  const {
57
60
  dynamicField,
58
- endpointData,
59
- sourceFunctionData = {},
60
61
  sourceFlowIntegrataionInvocationUrl = '',
61
62
  selectedAuthId = '',
62
63
  dataSourceBody,
@@ -67,21 +68,35 @@ const DynamicTypedFields = (props: DynamicFieldsProps) => {
67
68
  onChange,
68
69
  isDisabled = false,
69
70
  onChangeCallback = () => null,
71
+ dependsOn = [],
72
+ isArray = false, // Default to false for backward compatibility
70
73
  } = props;
71
74
  const [dynamicItems, setDynamicItems] = useState<DynamicDataItem[]>([]);
72
75
  const [loading, setLoading] = useState<boolean>(true);
73
- const [customFieldsData, setCustomFieldsData] = useState<any>(
74
- value && value !== '' && typeof value === 'string' ? JSON.parse(value) : {},
75
- );
76
+ const [customFieldsData, setCustomFieldsData] = useState<any>(() => {
77
+ // Initialize from value prop if available
78
+ if (value) {
79
+ const parsedValue = typeof value === 'string' ? JSON.parse(value) : value;
80
+
81
+ // If isArray is true and the value is an array, extract the first object
82
+ if (isArray && Array.isArray(parsedValue) && parsedValue.length > 0) {
83
+ return parsedValue[0];
84
+ }
85
+
86
+ return parsedValue;
87
+ }
88
+ return {};
89
+ });
76
90
  const [
77
91
  isErrorOnLoadingCustomFields,
78
92
  setIsErrorOnLoadingCustomFields,
79
93
  ] = useState<boolean>(false);
80
94
 
81
95
  const context = useContext(AppContext);
82
- const isReadOnly = context?.isReadOnly;
83
96
  const apiHandlerRef = context?.apiHandler || props.apiHandler;
84
97
 
98
+ const fieldsHaveBeenFetched = useRef(false);
99
+
85
100
  const resolveValue = (path: string, item: any): any => {
86
101
  // If the path contains template tags, process it
87
102
  if (/{([^}]+)}/.test(path)) {
@@ -149,25 +164,61 @@ const DynamicTypedFields = (props: DynamicFieldsProps) => {
149
164
  }
150
165
  };
151
166
 
167
+ // Split the effects - one for fetching fields, one for handling value changes
152
168
  useEffect(() => {
153
- if (value && Object.keys(value).length > 0) {
154
- setCustomFieldsData(value);
169
+ // Only fetch fields on initial mount or when parentFieldsChanged changes
170
+ if (dependsOn.length > 0 && !parentFieldsChanged) {
171
+ setLoading(false);
172
+ setIsErrorOnLoadingCustomFields(false);
173
+ return;
155
174
  }
156
- fetchDynamicFields();
157
- }, [parentFieldsChanged]);
158
-
159
- const onFieldChange = (id: string, val: string, type: string) => {
160
- const data = {
161
- ...customFieldsData,
162
- [id]: val,
163
- };
164
- setCustomFieldsData(data);
165
- if (onChange) {
166
- onChange(data);
175
+ if (!fieldsHaveBeenFetched.current || parentFieldsChanged) {
176
+ fetchDynamicFields();
177
+ fieldsHaveBeenFetched.current = true;
167
178
  }
168
- if (onChangeCallback) {
169
- onChangeCallback(JSON.stringify(data));
179
+ }, [parentFieldsChanged]); // Remove value from dependencies
180
+
181
+ // Separate effect for handling external value changes
182
+ useEffect(() => {
183
+ // Only update from props if the value is different from current state
184
+ // AND it's not coming from our own onChange (which would cause a loop)
185
+ if (value && !loading) {
186
+ let parsedValue = typeof value === 'string' ? JSON.parse(value) : value;
187
+
188
+ // If isArray is true and the value is an array, extract the first object for internal state
189
+ if (isArray && Array.isArray(parsedValue) && parsedValue.length > 0) {
190
+ [parsedValue] = parsedValue;
191
+ }
192
+
193
+ // Compare if the value is actually different to avoid unnecessary updates
194
+ const currentValueStr = JSON.stringify(customFieldsData);
195
+ const newValueStr = JSON.stringify(parsedValue);
196
+
197
+ if (currentValueStr !== newValueStr) {
198
+ setCustomFieldsData(parsedValue);
199
+ }
170
200
  }
201
+ }, [value, loading, isArray]);
202
+
203
+ // Modify the onFieldChange function to handle array output if isArray is true
204
+ const onFieldChange = (id: string, val: string, type: string) => {
205
+ // Update local state immediately
206
+ setCustomFieldsData((prevData: any) => {
207
+ const newData = {
208
+ ...prevData,
209
+ [id]: val,
210
+ };
211
+
212
+ // Call parent callbacks with the new data, wrapping in array if isArray is true
213
+ if (onChange) {
214
+ onChange(isArray ? [newData] : newData);
215
+ }
216
+ if (onChangeCallback) {
217
+ onChangeCallback(JSON.stringify(isArray ? [newData] : newData));
218
+ }
219
+
220
+ return newData;
221
+ });
171
222
  };
172
223
 
173
224
  return html`
@@ -182,7 +233,7 @@ const DynamicTypedFields = (props: DynamicFieldsProps) => {
182
233
  : html`
183
234
  ${dynamicItems.map(
184
235
  (el) => html`
185
- <div class=${styles.dynamicTypedFieldWrapper}>
236
+ <div class=${styles.dynamicTypedFieldWrapper} key=${el.id}>
186
237
  <${MultipurposeField}
187
238
  id="${el.id}"
188
239
  title="${el.title}"
@@ -52,6 +52,8 @@ interface ActionFormStateType {
52
52
  parentFields: any;
53
53
  parentFieldsChanged: boolean;
54
54
  aiAssistedFields: string[]; // New state to track fields with AI assist enabled
55
+ changedParentMachineName?: string; // New prop to track changes in parent machine name
56
+ parentChangeVersion?: number; // New prop to track changes in parent machine name
55
57
  }
56
58
 
57
59
  interface StepDataMapping {
@@ -78,6 +80,8 @@ class FunctionForm extends Component<
78
80
  parentFields: [],
79
81
  parentFieldsChanged: false,
80
82
  aiAssistedFields: [], // Initialize empty array for AI assisted fields
83
+ changedParentMachineName: '',
84
+ parentChangeVersion: 0,
81
85
  };
82
86
  }
83
87
 
@@ -411,7 +415,10 @@ class FunctionForm extends Component<
411
415
 
412
416
  // Check if the field is a parent field
413
417
  if (this.state.parentFields.includes(fieldId)) {
414
- this.setState({ parentFieldsChanged: !this.state.parentFieldsChanged });
418
+ this.setState({
419
+ changedParentMachineName: fieldId,
420
+ parentChangeVersion: Date.now(),
421
+ });
415
422
  }
416
423
 
417
424
  if (this.props.customSaveCallback) {
@@ -894,7 +901,12 @@ class FunctionForm extends Component<
894
901
  field.dataSourceBody,
895
902
  this.state.dynamicFieldDataState,
896
903
  )}
897
- parentFieldsChanged=${this.state.parentFieldsChanged}
904
+ parentFieldsChanged=${field.dependsOn.length > 0 &&
905
+ field.dependsOn.includes(
906
+ this.state.changedParentMachineName,
907
+ )
908
+ ? this.state.parentChangeVersion
909
+ : 0}
898
910
  activityOutputData=${arrayToNestedJSONWithFirstValue(
899
911
  JSONToActivityOutputData(this.props.variables || {}),
900
912
  JSONToDynamicFieldData(this.props.variables || {}),
@@ -904,6 +916,8 @@ class FunctionForm extends Component<
904
916
  )}
905
917
  value=${this.state.dynamicFieldDataState[field.id] || {}}
906
918
  isDisabled=${isAIAssisted}
919
+ dependsOn=${field.dependsOn}
920
+ isArray=${field.dataType === 'array'}
907
921
  />
908
922
  `,
909
923
  )}
package/src/index.ts CHANGED
@@ -609,7 +609,8 @@ export class IntegryJS {
609
609
  if (
610
610
  options.connectedAccountId &&
611
611
  !response.meta.app.connected_accounts.find(
612
- (account: any) => account.id === options.connectedAccountId,
612
+ (account: any) =>
613
+ Number(account.id) === Number(options.connectedAccountId),
613
614
  )
614
615
  ) {
615
616
  return reject(new Error('Connected account not found.'));
@@ -2055,6 +2056,11 @@ export class IntegryJS {
2055
2056
  onTagSelect: () => {
2056
2057
  // Placeholder function for future implementation
2057
2058
  },
2059
+ renderValuesTab: false,
2060
+ options: [],
2061
+ onOptionClick: () => {
2062
+ // Placeholder function for future implementation
2063
+ },
2058
2064
  },
2059
2065
  ) => {
2060
2066
  const target = document.getElementById(options.containerId);
@@ -2074,6 +2080,9 @@ export class IntegryJS {
2074
2080
  <${TagsMenu}
2075
2081
  tagsTree=${options.tagsTree}
2076
2082
  onSelect=${options.onTagSelect}
2083
+ renderValuesTab=${options.renderValuesTab}
2084
+ options=${options.options}
2085
+ onOptionClick=${options.onOptionClick}
2077
2086
  />
2078
2087
  <//>
2079
2088
  <//>
@@ -304,6 +304,11 @@ export type RenderMappingMenuOptions = {
304
304
  containerId: string;
305
305
  tagsTree: any;
306
306
  onTagSelect: (tag: any) => void;
307
+ renderValuesTab?: boolean;
308
+ options?: {
309
+ [key: string]: any;
310
+ };
311
+ onOptionClick?: (option: any) => void;
307
312
  };
308
313
  export type ShowFunctionOptions = {
309
314
  params?: Record<string, any>;