@integry/sdk 4.5.8 → 4.5.10

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.5.8",
3
+ "version": "4.5.10",
4
4
  "description": "Integry SDK",
5
5
  "main": "dist/umd/index.umd.js",
6
6
  "module": "dist/esm/index.csm.js",
@@ -369,7 +369,11 @@ const FieldDropdown = (props: FieldMenuProps) => {
369
369
  <a
370
370
  className=${styles.optionsRefresh}
371
371
  href="#"
372
- onclick=${handleRefresh}
372
+ onclick=${(e: any) => {
373
+ e.preventDefault();
374
+ e.stopPropagation();
375
+ handleRefresh();
376
+ }}
373
377
  >
374
378
  ${' '}Try again?</a
375
379
  >`}
@@ -52,6 +52,7 @@ interface MultipurposeFieldProps {
52
52
  buttonText?: string;
53
53
  onButtonClickScript?: string;
54
54
  buttonScriptRequiresAuthToken?: boolean;
55
+ tagsComponent?: any;
55
56
  }
56
57
 
57
58
  const MultipurposeField = (props: MultipurposeFieldProps) => {
@@ -84,6 +85,7 @@ const MultipurposeField = (props: MultipurposeFieldProps) => {
84
85
  buttonText = 'Add',
85
86
  onButtonClickScript = '',
86
87
  buttonScriptRequiresAuthToken = false,
88
+ tagsComponent = null,
87
89
  } = props;
88
90
  const [showTagMenu, setShowTagMenu] = useState(false);
89
91
  const [currentValue, setCurrentValue] = useState(value);
@@ -0,0 +1,21 @@
1
+ import { html } from 'htm/preact';
2
+ import cx from 'classnames';
3
+
4
+ import { Hint } from '@/components/Tooltip';
5
+ import { ThreeDotLoader } from '@/components/ThreeDotLoader';
6
+
7
+ import styles from './styles.module.scss';
8
+
9
+ export interface TestProps {
10
+ label: string;
11
+ }
12
+
13
+ /**
14
+ * Test component
15
+ *
16
+ */
17
+ export const Test = (props: TestProps) => {
18
+ const { label, ...restOfProps } = props;
19
+
20
+ return html` <div>Hello world</div> `;
21
+ };
@@ -0,0 +1,152 @@
1
+ .button {
2
+ outline: none;
3
+ cursor: pointer;
4
+ appearance: none;
5
+ font-size: 12px;
6
+ padding: 0px 15px;
7
+ height: 30px;
8
+ &.btnPrimary {
9
+ border: 1px solid #4250f0;
10
+ background: #4250f0;
11
+ border-radius: 4px;
12
+ font-size: 12px;
13
+ color: #ffffff;
14
+ &:not(.disabled):hover {
15
+ background: var(--theme-accent-blue-2, #3a46d5);
16
+ border: 1px solid var(--theme-accent-blue-2, #3a46d5);
17
+ }
18
+ }
19
+ &.btnSecondary {
20
+ border: 1px solid #4250f0;
21
+ background: transparent;
22
+ text-align: center;
23
+ font-size: 12px;
24
+ color: #4250f0;
25
+ border-radius: 4px;
26
+ &:not(.disabled):hover {
27
+ background: #4250f0;
28
+ color: white;
29
+ }
30
+ }
31
+ &.buttonLink {
32
+ border: none;
33
+ color: #4250f0;
34
+ font-weight: 500;
35
+ font-size: 12px;
36
+ background: transparent;
37
+ padding: 0;
38
+ margin: 0;
39
+ &:not(.disabled):hover {
40
+ color: #473a64;
41
+ }
42
+ }
43
+
44
+ &.tell-us-more-btn {
45
+ width: 113px;
46
+ height: 36px;
47
+ background: #ffffff;
48
+ border: 1px solid #4250f0;
49
+ // box-shadow: 0px 1px 0px rgba(0, 0, 0, 0.08), inset 0px -1px 0px rgba(0, 0, 0, 0.2);
50
+ border-radius: 5px;
51
+ font-family: inherit;
52
+ font-style: normal;
53
+ font-weight: 500;
54
+ font-size: 14px;
55
+ line-height: 20px;
56
+ color: #4250f0;
57
+ &:not(.disabled):hover {
58
+ background: #ffffff;
59
+ color: #4250f0;
60
+ }
61
+ padding: 0px;
62
+ }
63
+
64
+ &.integry-primary-btn {
65
+ width: auto;
66
+ height: auto;
67
+ background: #4250f0;
68
+ border: 1px solid #4250f0;
69
+ box-shadow: 0px 1px 0px rgba(0, 0, 0, 0.08),
70
+ inset 0px -1px 0px rgba(0, 0, 0, 0.2);
71
+ border-radius: 5px;
72
+ font-family: inherit;
73
+ font-style: normal;
74
+ font-weight: 500;
75
+ font-size: 14px;
76
+ line-height: 20px;
77
+ text-align: center;
78
+ color: #ffffff;
79
+ &:not(.disabled):hover {
80
+ background: #2c36ad;
81
+ color: #ffffff;
82
+ }
83
+ padding: 0px;
84
+ }
85
+
86
+ &.integry-btn-grey {
87
+ width: auto;
88
+ height: auto;
89
+ background: #f3f3f3;
90
+ border: 1px solid #f3f3f3;
91
+ box-shadow: 0px 1px 0px rgba(0, 0, 0, 0.08),
92
+ inset 0px -1px 0px rgba(0, 0, 0, 0.2);
93
+ border-radius: 5px;
94
+ font-family: inherit;
95
+ font-style: normal;
96
+ font-weight: 500;
97
+ font-size: 14px;
98
+ line-height: 20px;
99
+ text-align: center;
100
+ color: #333333;
101
+ &:not(.disabled):hover {
102
+ background: #e6e6e6;
103
+ color: #333333;
104
+ }
105
+ padding: 0px;
106
+ }
107
+
108
+ &.integry-secondary-btn {
109
+ width: auto;
110
+ height: auto;
111
+ background: #ffffff;
112
+ border: 1px solid #4250f0;
113
+ // box-shadow: 0px 1px 0px rgba(0, 0, 0, 0.08), inset 0px -1px 0px rgba(0, 0, 0, 0.2);
114
+ border-radius: 5px;
115
+ font-family: inherit;
116
+ font-style: normal;
117
+ font-weight: 500;
118
+ font-size: 14px;
119
+ line-height: 20px;
120
+ color: #4250f0;
121
+ &:not(.disabled):hover {
122
+ background: #4250f0;
123
+ color: #ffffff;
124
+ }
125
+ padding: 0px;
126
+ }
127
+
128
+ &.disabled {
129
+ opacity: 0.5;
130
+ cursor: not-allowed;
131
+ }
132
+
133
+ &.flowWrapButton {
134
+ border-radius: 5px;
135
+ border: 1px solid var(--theme-accent-blue-1, #4250f0);
136
+ background: var(--theme-accent-blue-1, #4250f0);
137
+ color: #fff;
138
+ font-family: Inter;
139
+ font-size: 13px;
140
+ font-style: normal;
141
+ font-weight: 400;
142
+ line-height: normal;
143
+ padding: 4.5px 10px;
144
+ cursor: pointer;
145
+ height: auto;
146
+
147
+ &:hover {
148
+ background: var(--theme-accent-blue-2, #3a46d5) !important;
149
+ border: 1px solid var(--theme-accent-blue-2, #3a46d5) !important;
150
+ }
151
+ }
152
+ }
@@ -9,6 +9,7 @@ import { ListBox } from '@/components/MultipurposeField/Dropdown';
9
9
  import { Loader } from '@/components/Loader';
10
10
  import {
11
11
  IntegryStep,
12
+ TemplateStep,
12
13
  TemplateField,
13
14
  IncomingWebhookObject,
14
15
  NestedObject,
@@ -46,30 +47,41 @@ interface ActionFormPropsType extends StoreType {
46
47
  isReadOnly?: boolean;
47
48
  accountConnected: boolean;
48
49
  selectedAuthId: string;
49
- tagsTree: any;
50
50
  onFieldChangeCallback?: (fieldId: string, value: string) => void;
51
51
  }
52
52
 
53
53
  interface ActionFormStateType {
54
54
  loading: boolean;
55
55
  dynamicFieldDataState: any;
56
- tagsTree: any;
56
+ parentChildMapping: any;
57
+ dynamicFieldsData: any;
58
+ parentFieldChanged: boolean;
57
59
  }
58
60
 
59
61
  interface StepDataMapping {
60
62
  [key: string]: any;
61
63
  }
62
64
 
65
+ type FieldMapping = {
66
+ [key: string]: {
67
+ fieldId: number;
68
+ childFields: any[] | null;
69
+ parentFields: any[] | null;
70
+ };
71
+ };
72
+
73
+ type Mapping = Record<number, any>;
74
+
63
75
  class ActionForm extends Component<ActionFormPropsType, ActionFormStateType> {
64
76
  constructor(props: ActionFormPropsType) {
65
77
  super(props);
78
+ const templateStep: any = props.step;
66
79
  this.state = {
67
80
  loading: false,
68
81
  dynamicFieldDataState: {},
69
- tagsTree:
70
- this.props.tagsTree && Object.keys(this.props.tagsTree).length > 0
71
- ? JSONToActivityOutputData(this.props.tagsTree)
72
- : {},
82
+ parentChildMapping: this.setParentChildMapping([templateStep]),
83
+ dynamicFieldsData: {},
84
+ parentFieldChanged: false,
73
85
  };
74
86
  }
75
87
 
@@ -105,6 +117,54 @@ class ActionForm extends Component<ActionFormPropsType, ActionFormStateType> {
105
117
  }
106
118
  }
107
119
 
120
+ setParentChildMapping(steps: TemplateStep[]) {
121
+ this.setState((prevState) => {
122
+ const parentChildMapping = steps.reduce((mapping: Mapping, step) => {
123
+ const stepMapping = step.template_fields.reduce(
124
+ (fields: FieldMapping, field) => {
125
+ const activityField = field.activity_field;
126
+
127
+ if (activityField) {
128
+ // Create a copy of the fields object to avoid mutating it
129
+ const updatedFields = { ...fields };
130
+
131
+ updatedFields[activityField.machine_name] = {
132
+ fieldId: field.id,
133
+ childFields: activityField.child_fields
134
+ ? JSON.parse(activityField.child_fields)
135
+ : null,
136
+ parentFields: activityField.parent_fields
137
+ ? JSON.parse(activityField.parent_fields)
138
+ : null,
139
+ };
140
+
141
+ return updatedFields;
142
+ }
143
+
144
+ return fields;
145
+ },
146
+ {}, // Initial empty object
147
+ );
148
+
149
+ // Create a new object for `mapping` to avoid mutation
150
+ return {
151
+ ...mapping, // Spread the existing mapping to preserve the previous entries
152
+ [step.id]: {
153
+ ...(prevState.parentChildMapping?.[step.id] || {}), // Ensure it starts with the previous state or empty object
154
+ ...stepMapping, // Merge the new step mapping
155
+ },
156
+ };
157
+ }, {});
158
+
159
+ return {
160
+ parentChildMapping: {
161
+ ...prevState.parentChildMapping, // Spread the previous state to preserve other data
162
+ ...parentChildMapping, // Add the newly calculated `parentChildMapping`
163
+ },
164
+ };
165
+ });
166
+ }
167
+
108
168
  getVisibleFieldsDataOnRootStep = (
109
169
  stepId: number,
110
170
  ): {
@@ -829,7 +889,8 @@ class ActionForm extends Component<ActionFormPropsType, ActionFormStateType> {
829
889
 
830
890
  private shouldShowOldMapping = () => {
831
891
  const stepId = this.props.step.id;
832
- const stepObject = this.props.stepMapping && this.props.stepMapping[stepId];
892
+ const stepObject = (this.props.stepMapping &&
893
+ this.props.stepMapping[stepId]) || { step: this.props.step };
833
894
  if (this.stepIsOfType(['ADAPTER', 'ACTION'])) {
834
895
  const anyVisibleFields = stepObject.step.template_fields.filter(
835
896
  (el) => el.is_visible,
@@ -918,6 +979,18 @@ class ActionForm extends Component<ActionFormPropsType, ActionFormStateType> {
918
979
  return payload;
919
980
  };
920
981
 
982
+ private isParentField = (
983
+ mapping: Record<string, Record<string, any>>,
984
+ machineName: string,
985
+ ): boolean =>
986
+ Object.values(mapping).some((fields) =>
987
+ Object.values(fields).some(
988
+ (field) =>
989
+ Array.isArray(field.parentFields) &&
990
+ field.parentFields.includes(machineName),
991
+ ),
992
+ );
993
+
921
994
  private onFieldChange = ({
922
995
  stepId,
923
996
  fieldId,
@@ -933,6 +1006,19 @@ class ActionForm extends Component<ActionFormPropsType, ActionFormStateType> {
933
1006
  }) => {
934
1007
  // we want to check if callback function is passed in props, if yes then call it
935
1008
  if (this.props.onFieldChangeCallback) {
1009
+ this.setState((prevState) => ({
1010
+ dynamicFieldsData: {
1011
+ ...prevState.dynamicFieldsData,
1012
+ [machineName || '']: value,
1013
+ },
1014
+ }));
1015
+
1016
+ if (
1017
+ this.isParentField(this.state.parentChildMapping, machineName || '')
1018
+ ) {
1019
+ this.setState({ parentFieldChanged: !this.state.parentFieldChanged });
1020
+ }
1021
+
936
1022
  this.props.onFieldChangeCallback(machineName || '', value);
937
1023
  } else {
938
1024
  this.props.setStepFieldData({
@@ -1351,15 +1437,13 @@ class ActionForm extends Component<ActionFormPropsType, ActionFormStateType> {
1351
1437
  el.title || el.activity_field?.title
1352
1438
  }
1353
1439
  activityOutputData=${this.arrayToNestedJSONWithFirstValue(
1354
- this.props.activityOutputData ||
1355
- this.state.tagsTree,
1440
+ this.props.activityOutputData,
1356
1441
  this.props.dynamicFieldData ||
1357
1442
  this.state.dynamicFieldDataState ||
1358
1443
  {},
1359
1444
  )}
1360
1445
  activityOutputDataRaw=${
1361
- this.props.activityOutputData ||
1362
- this.state.tagsTree
1446
+ this.props.activityOutputData
1363
1447
  }
1364
1448
  description=${elDescription}
1365
1449
  value=${
@@ -1540,11 +1624,13 @@ class ActionForm extends Component<ActionFormPropsType, ActionFormStateType> {
1540
1624
  dynamicField=${el}
1541
1625
  endpointData=${JSON.stringify({
1542
1626
  authorization_id:
1543
- this.props.stepMapping &&
1544
- this.props.stepMapping[
1545
- this.props.step.id
1546
- ]?.selectedAuthId,
1627
+ (this.props.stepMapping &&
1628
+ this.props.stepMapping[
1629
+ this.props.step.id
1630
+ ]?.selectedAuthId) ||
1631
+ this.props.selectedAuthId,
1547
1632
  ...this.fieldDynamicData(el),
1633
+ ...this.state.dynamicFieldsData,
1548
1634
  })}
1549
1635
  activityOutputData=${this.arrayToNestedJSONWithFirstValue(
1550
1636
  this.props.activityOutputData,
@@ -1560,7 +1646,9 @@ class ActionForm extends Component<ActionFormPropsType, ActionFormStateType> {
1560
1646
  selectedAuthId=${`${
1561
1647
  this.props.stepMapping[
1562
1648
  this.props.step.id
1563
- ]?.selectedAuthId || ''
1649
+ ]?.selectedAuthId ||
1650
+ this.props.selectedAuthId ||
1651
+ ''
1564
1652
  }`}
1565
1653
  sourceFlowData=${this.sourceFlowData(el)}
1566
1654
  sourceFlowIntegrataionInvocationUrl=${el.source_flow_integration_invocation_url}
@@ -1569,6 +1657,8 @@ class ActionForm extends Component<ActionFormPropsType, ActionFormStateType> {
1569
1657
  allowTagsInText=${el.allow_tags_in_text}
1570
1658
  refreshRootStepData=${this
1571
1659
  .refreshRootStepData}
1660
+ parentFieldChanged=${this.state
1661
+ .parentFieldChanged}
1572
1662
  />
1573
1663
  </div>
1574
1664
  `;
@@ -26,6 +26,7 @@ export type DynamicFieldsProps = {
26
26
  allowTagsInText?: boolean;
27
27
  placeHolder?: string;
28
28
  refreshRootStepData?: (callback?: any) => void;
29
+ parentFieldChanged?: boolean;
29
30
  } & StoreType;
30
31
 
31
32
  interface DynamicDataItem {
@@ -50,6 +51,7 @@ const DynamicFields = (props: DynamicFieldsProps) => {
50
51
  allowTagsInText = true,
51
52
  placeHolder = '',
52
53
  refreshRootStepData,
54
+ parentFieldChanged = false,
53
55
  } = props;
54
56
  const [dynamicItems, setDynamicItems] = useState<DynamicDataItem[]>([]);
55
57
  const [loading, setLoading] = useState<boolean>(true);
@@ -66,6 +68,7 @@ const DynamicFields = (props: DynamicFieldsProps) => {
66
68
  // if configMode is true, then don't fetch dynamic items
67
69
  // fetch dynamic items from endpoint
68
70
  if (sourceFlowIntegrataionInvocationUrl && selectedAuthId) {
71
+ setLoading(true);
69
72
  context?.apiHandler
70
73
  .callSourceFlowIntegrationInvocationUrl<DynamicDataItem[]>(
71
74
  new URL(sourceFlowIntegrataionInvocationUrl),
@@ -90,6 +93,7 @@ const DynamicFields = (props: DynamicFieldsProps) => {
90
93
  .finally(() => setLoading(false));
91
94
  } else if (activity_field && activity_field.dynamic_field_src) {
92
95
  let data;
96
+ setLoading(true);
93
97
  try {
94
98
  data = JSON.parse(endpointData);
95
99
  } catch (error) {
@@ -121,7 +125,7 @@ const DynamicFields = (props: DynamicFieldsProps) => {
121
125
 
122
126
  useEffect(() => {
123
127
  fetchDynamicFields();
124
- }, [dynamicField, endpointData, selectedAuthId]);
128
+ }, [dynamicField, endpointData, selectedAuthId, parentFieldChanged]);
125
129
 
126
130
  const getPlaceholder = () => {
127
131
  let placeHolderValue = 'Enter text or map to fields...';
@@ -163,7 +167,9 @@ const DynamicFields = (props: DynamicFieldsProps) => {
163
167
  Loading custom fields...
164
168
  </div> `
165
169
  : html` ${dynamicItems.map((el) => {
166
- const ele = props.stepDataMapping[stepId][dynamicField.id];
170
+ const ele = props.stepDataMapping[stepId]
171
+ ? props.stepDataMapping[stepId][dynamicField.id]
172
+ : ({} as { objectValue: Record<string, string | number> });
167
173
  let fieldVal = '';
168
174
  const parsedVal = ele.objectValue as Record<
169
175
  string,
package/src/index.ts CHANGED
@@ -28,6 +28,7 @@ import {
28
28
  RenderModes,
29
29
  Layouts,
30
30
  SetupIntegrationOptions,
31
+ RenderFlowStepOptions,
31
32
  } from '@/types';
32
33
 
33
34
  import { createSDKStore, initialState } from '@/store';
@@ -1982,13 +1983,17 @@ export class IntegryJS {
1982
1983
  };
1983
1984
 
1984
1985
  public renderFlowStep = (
1985
- containerId: string,
1986
- step: any,
1987
- connectedAccountId: string,
1988
- tagsTree = {},
1989
- onFieldChangeCallback?: (fieldId: string, value: string) => void,
1986
+ options: RenderFlowStepOptions = {
1987
+ containerId: 'integry-marketplace',
1988
+ step: {},
1989
+ connectedAccountId: '',
1990
+ tagsComponent: null,
1991
+ onFieldChangeCallback: () => {
1992
+ // Placeholder function for future implementation
1993
+ },
1994
+ },
1990
1995
  ) => {
1991
- const target = document.getElementById(containerId);
1996
+ const target = document.getElementById(options.containerId);
1992
1997
 
1993
1998
  if (target) {
1994
1999
  const store = createSDKStore();
@@ -2003,16 +2008,16 @@ export class IntegryJS {
2003
2008
  >
2004
2009
  <${Provider} store=${store} key=${this.getRandomFlowId(10)}>
2005
2010
  <${ActionForm}
2006
- step=${step}
2011
+ step=${options.step}
2007
2012
  stepType=${'CONFIGURE'}
2008
2013
  showStepValidation=${false}
2009
2014
  apiHandler=${this.apiHandler}
2010
2015
  eventEmitter=${this.eventEmitter}
2011
2016
  isReadOnly="${false}"
2012
- selectedAuthId="${connectedAccountId}"
2017
+ selectedAuthId="${options.connectedAccountId}"
2013
2018
  accountConnected=${true}
2014
- tagsTree=${tagsTree}
2015
- onFieldChangeCallback=${onFieldChangeCallback}
2019
+ tagsComponent=${options.tagsComponent}
2020
+ onFieldChangeCallback=${options.onFieldChangeCallback}
2016
2021
  />
2017
2022
  <//>
2018
2023
  <//>
@@ -2021,7 +2026,7 @@ export class IntegryJS {
2021
2026
  );
2022
2027
  } else {
2023
2028
  console.warn(
2024
- `Integry SDK render target with id ${containerId} was not found`,
2029
+ `Integry SDK render target with id ${options.containerId} was not found`,
2025
2030
  );
2026
2031
  }
2027
2032
  };
@@ -1,5 +1,3 @@
1
- import { type } from 'superstruct';
2
-
3
1
  export type IntegrySDKEventType =
4
2
  | 'authorizations'
5
3
  | 'did-add-authorization'
@@ -291,3 +289,10 @@ export type SetupIntegrationOptions = {
291
289
  integrationId?: number;
292
290
  params?: Record<string, string>;
293
291
  };
292
+ export type RenderFlowStepOptions = {
293
+ containerId: string;
294
+ step: any;
295
+ connectedAccountId: string;
296
+ tagsComponent?: any;
297
+ onFieldChangeCallback: (fieldId: string, value: any) => void;
298
+ };