@oneuptime/common 12.0.7 → 12.0.8

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.
Files changed (186) hide show
  1. package/Models/DatabaseModels/TelemetryEntity.ts +45 -0
  2. package/Models/DatabaseModels/TelemetryEntityRelationship.ts +26 -0
  3. package/Models/DatabaseModels/WorkflowLog.ts +38 -0
  4. package/Server/API/UserAPI.ts +16 -1
  5. package/Server/Infrastructure/Postgres/SchemaMigrations/1786551733814-MigrationName.ts +41 -0
  6. package/Server/Infrastructure/Postgres/SchemaMigrations/1786559879134-AddWorkflowLogStepTrace.ts +17 -0
  7. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +4 -0
  8. package/Server/Middleware/MasterAdminAuthorization.ts +11 -6
  9. package/Server/Services/TelemetryEntityRelationshipService.ts +3 -0
  10. package/Server/Services/TelemetryEntityService.ts +114 -1
  11. package/Server/Types/Workflow/Components/API/Utils.ts +44 -1
  12. package/Server/Types/Workflow/TriggerCode.ts +12 -0
  13. package/Server/Types/Workflow/Workflow.ts +5 -0
  14. package/Server/Utils/Telemetry/InventoryEntityRegistry.ts +689 -0
  15. package/Server/Utils/VM/VMAPI.ts +56 -8
  16. package/Tests/App/Dashboard/MonitorCriteriaAttributeFilter.test.tsx +574 -0
  17. package/Tests/Server/API/UserProjectsAPI.test.ts +478 -4
  18. package/Tests/Server/Services/TelemetryEntityManualCreate.test.ts +248 -0
  19. package/Tests/Server/Types/Workflow/Components/ApiComponentHeaders.test.ts +192 -0
  20. package/Tests/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.test.ts +152 -0
  21. package/Tests/Server/Utils/Telemetry/InventoryEntityRegistry.test.ts +322 -0
  22. package/Tests/Server/Utils/VM/VMAPISubstitution.test.ts +243 -0
  23. package/Tests/Types/SerializableObjectDictionaryImportCycle.test.ts +197 -0
  24. package/Tests/Types/Telemetry/EntityTypeGroups.test.ts +140 -0
  25. package/Tests/Types/Workflow/StepTrace.test.ts +235 -0
  26. package/Tests/Types/Workflow/TemplateSyntax.test.ts +379 -0
  27. package/Tests/Types/Workflow/Templates.test.ts +403 -0
  28. package/Tests/UI/Components/CustomTimeRangeModal.test.tsx +459 -0
  29. package/Tests/UI/Components/DictionaryAttributeFilterRow.test.tsx +477 -0
  30. package/Tests/UI/Components/Forms/AnchoredFieldPopupKeyboard.test.tsx +382 -0
  31. package/Tests/UI/Components/Forms/ColorPickerPicking.test.tsx +569 -0
  32. package/Tests/UI/Components/Forms/ValidationJSON.test.ts +241 -0
  33. package/Tests/UI/Components/LogTimeRangePicker.test.tsx +42 -0
  34. package/Tests/UI/Components/ModalPortalDismissal.test.tsx +90 -0
  35. package/Tests/UI/Components/TelemetryTimeRangePicker.test.tsx +49 -7
  36. package/Tests/UI/Components/TimeRangePickerDropdown.test.tsx +325 -0
  37. package/Tests/UI/Components/Workflow/GraphLint.test.ts +821 -0
  38. package/Tests/UI/Components/Workflow/ModelColumnEditor.test.ts +287 -0
  39. package/Tests/UI/Components/Workflow/ModelColumnEditorServerContract.test.ts +185 -0
  40. package/Tests/UI/Components/Workflow/ModelSchema.test.ts +174 -0
  41. package/Tests/UI/Components/Workflow/RunStatusWatcher.test.ts +152 -0
  42. package/Tests/UI/Components/Workflow/Utils.test.ts +192 -0
  43. package/Tests/UI/Monitor/MonitorStepCriteriaView.test.tsx +432 -0
  44. package/Tests/Utils/Monitor/NetworkDeviceRoleUtil.test.ts +514 -0
  45. package/Tests/Utils/Monitor/NetworkTopologyUtil.test.ts +240 -0
  46. package/Tests/Utils/Schema/AnalyticsModelSchema.test.ts +469 -0
  47. package/Tests/Utils/Schema/ModelSchema.test.ts +268 -0
  48. package/Tests/Utils/Telemetry/EntityKeyNonTelemetry.test.ts +193 -0
  49. package/Types/Monitor/SnmpMonitor/NetworkTopology.ts +31 -0
  50. package/Types/SerializableObjectDictionary.ts +133 -39
  51. package/Types/Telemetry/EntitySource.ts +40 -0
  52. package/Types/Telemetry/EntityType.ts +27 -0
  53. package/Types/Telemetry/EntityTypeGroups.ts +65 -0
  54. package/Types/Workflow/Component.ts +29 -0
  55. package/Types/Workflow/Components/API.ts +35 -0
  56. package/Types/Workflow/Components/BaseModel.ts +7 -3
  57. package/Types/Workflow/StepTrace.ts +181 -0
  58. package/Types/Workflow/TemplateSyntax.ts +499 -0
  59. package/Types/Workflow/Templates.ts +316 -0
  60. package/UI/Components/Date/CustomTimeRangeModal.tsx +278 -0
  61. package/UI/Components/Date/TimeRangePickerDropdown.tsx +250 -0
  62. package/UI/Components/Dictionary/Dictionary.tsx +23 -6
  63. package/UI/Components/Forms/Fields/ColorPicker.tsx +66 -10
  64. package/UI/Components/Forms/Fields/IconPicker.tsx +48 -10
  65. package/UI/Components/Forms/Types/Field.ts +7 -0
  66. package/UI/Components/Forms/Validation.ts +63 -1
  67. package/UI/Components/Input/Input.tsx +31 -3
  68. package/UI/Components/LogsViewer/components/LogTimeRangePicker.tsx +11 -216
  69. package/UI/Components/Modal/Modal.tsx +37 -4
  70. package/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.tsx +11 -210
  71. package/UI/Components/Workflow/ArgumentsForm.tsx +194 -7
  72. package/UI/Components/Workflow/Component.tsx +28 -26
  73. package/UI/Components/Workflow/ComponentSettingsModal.tsx +69 -8
  74. package/UI/Components/Workflow/GraphLint.ts +591 -0
  75. package/UI/Components/Workflow/ModelColumnEditor.tsx +396 -0
  76. package/UI/Components/Workflow/ModelSchema.ts +196 -0
  77. package/UI/Components/Workflow/RunForm.tsx +41 -7
  78. package/UI/Components/Workflow/RunStatusWatcher.ts +122 -0
  79. package/UI/Components/Workflow/StepTraceViewer.tsx +186 -0
  80. package/UI/Components/Workflow/Utils.ts +93 -1
  81. package/UI/Components/Workflow/Workflow.tsx +77 -4
  82. package/UI/Types/LayeredDismissal.ts +31 -0
  83. package/UI/Types/UseAnchoredFieldPopup.ts +99 -0
  84. package/Utils/Monitor/NetworkDeviceRoleUtil.ts +533 -0
  85. package/Utils/Monitor/NetworkTopologyUtil.ts +45 -7
  86. package/Utils/Telemetry/EntityKey.ts +66 -0
  87. package/build/dist/Models/DatabaseModels/TelemetryEntity.js +47 -0
  88. package/build/dist/Models/DatabaseModels/TelemetryEntity.js.map +1 -1
  89. package/build/dist/Models/DatabaseModels/TelemetryEntityRelationship.js +27 -0
  90. package/build/dist/Models/DatabaseModels/TelemetryEntityRelationship.js.map +1 -1
  91. package/build/dist/Models/DatabaseModels/WorkflowLog.js +39 -0
  92. package/build/dist/Models/DatabaseModels/WorkflowLog.js.map +1 -1
  93. package/build/dist/Server/API/UserAPI.js +16 -1
  94. package/build/dist/Server/API/UserAPI.js.map +1 -1
  95. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786551733814-MigrationName.js +20 -0
  96. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786551733814-MigrationName.js.map +1 -0
  97. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786559879134-AddWorkflowLogStepTrace.js +12 -0
  98. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786559879134-AddWorkflowLogStepTrace.js.map +1 -0
  99. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +4 -0
  100. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  101. package/build/dist/Server/Middleware/MasterAdminAuthorization.js +11 -6
  102. package/build/dist/Server/Middleware/MasterAdminAuthorization.js.map +1 -1
  103. package/build/dist/Server/Services/TelemetryEntityRelationshipService.js +3 -0
  104. package/build/dist/Server/Services/TelemetryEntityRelationshipService.js.map +1 -1
  105. package/build/dist/Server/Services/TelemetryEntityService.js +91 -1
  106. package/build/dist/Server/Services/TelemetryEntityService.js.map +1 -1
  107. package/build/dist/Server/Types/Workflow/Components/API/Utils.js +28 -0
  108. package/build/dist/Server/Types/Workflow/Components/API/Utils.js.map +1 -1
  109. package/build/dist/Server/Types/Workflow/TriggerCode.js.map +1 -1
  110. package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js +507 -0
  111. package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js.map +1 -0
  112. package/build/dist/Server/Utils/VM/VMAPI.js +51 -4
  113. package/build/dist/Server/Utils/VM/VMAPI.js.map +1 -1
  114. package/build/dist/Types/SerializableObjectDictionary.js +133 -39
  115. package/build/dist/Types/SerializableObjectDictionary.js.map +1 -1
  116. package/build/dist/Types/Telemetry/EntitySource.js +39 -0
  117. package/build/dist/Types/Telemetry/EntitySource.js.map +1 -0
  118. package/build/dist/Types/Telemetry/EntityType.js +27 -0
  119. package/build/dist/Types/Telemetry/EntityType.js.map +1 -1
  120. package/build/dist/Types/Telemetry/EntityTypeGroups.js +57 -0
  121. package/build/dist/Types/Telemetry/EntityTypeGroups.js.map +1 -0
  122. package/build/dist/Types/Workflow/Component.js +21 -0
  123. package/build/dist/Types/Workflow/Component.js.map +1 -1
  124. package/build/dist/Types/Workflow/Components/API.js +35 -0
  125. package/build/dist/Types/Workflow/Components/API.js.map +1 -1
  126. package/build/dist/Types/Workflow/Components/BaseModel.js +7 -3
  127. package/build/dist/Types/Workflow/Components/BaseModel.js.map +1 -1
  128. package/build/dist/Types/Workflow/StepTrace.js +104 -0
  129. package/build/dist/Types/Workflow/StepTrace.js.map +1 -0
  130. package/build/dist/Types/Workflow/TemplateSyntax.js +326 -0
  131. package/build/dist/Types/Workflow/TemplateSyntax.js.map +1 -0
  132. package/build/dist/Types/Workflow/Templates.js +218 -0
  133. package/build/dist/Types/Workflow/Templates.js.map +1 -0
  134. package/build/dist/UI/Components/Date/CustomTimeRangeModal.js +126 -0
  135. package/build/dist/UI/Components/Date/CustomTimeRangeModal.js.map +1 -0
  136. package/build/dist/UI/Components/Date/TimeRangePickerDropdown.js +123 -0
  137. package/build/dist/UI/Components/Date/TimeRangePickerDropdown.js.map +1 -0
  138. package/build/dist/UI/Components/Dictionary/Dictionary.js +22 -6
  139. package/build/dist/UI/Components/Dictionary/Dictionary.js.map +1 -1
  140. package/build/dist/UI/Components/Forms/Fields/ColorPicker.js +52 -13
  141. package/build/dist/UI/Components/Forms/Fields/ColorPicker.js.map +1 -1
  142. package/build/dist/UI/Components/Forms/Fields/IconPicker.js +28 -12
  143. package/build/dist/UI/Components/Forms/Fields/IconPicker.js.map +1 -1
  144. package/build/dist/UI/Components/Forms/Validation.js +44 -0
  145. package/build/dist/UI/Components/Forms/Validation.js.map +1 -1
  146. package/build/dist/UI/Components/Input/Input.js +12 -4
  147. package/build/dist/UI/Components/Input/Input.js.map +1 -1
  148. package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js +5 -108
  149. package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js.map +1 -1
  150. package/build/dist/UI/Components/Modal/Modal.js +31 -5
  151. package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
  152. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js +5 -105
  153. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js.map +1 -1
  154. package/build/dist/UI/Components/Workflow/ArgumentsForm.js +140 -11
  155. package/build/dist/UI/Components/Workflow/ArgumentsForm.js.map +1 -1
  156. package/build/dist/UI/Components/Workflow/Component.js +20 -19
  157. package/build/dist/UI/Components/Workflow/Component.js.map +1 -1
  158. package/build/dist/UI/Components/Workflow/ComponentSettingsModal.js +31 -3
  159. package/build/dist/UI/Components/Workflow/ComponentSettingsModal.js.map +1 -1
  160. package/build/dist/UI/Components/Workflow/GraphLint.js +396 -0
  161. package/build/dist/UI/Components/Workflow/GraphLint.js.map +1 -0
  162. package/build/dist/UI/Components/Workflow/ModelColumnEditor.js +225 -0
  163. package/build/dist/UI/Components/Workflow/ModelColumnEditor.js.map +1 -0
  164. package/build/dist/UI/Components/Workflow/ModelSchema.js +118 -0
  165. package/build/dist/UI/Components/Workflow/ModelSchema.js.map +1 -0
  166. package/build/dist/UI/Components/Workflow/RunForm.js +22 -6
  167. package/build/dist/UI/Components/Workflow/RunForm.js.map +1 -1
  168. package/build/dist/UI/Components/Workflow/RunStatusWatcher.js +76 -0
  169. package/build/dist/UI/Components/Workflow/RunStatusWatcher.js.map +1 -0
  170. package/build/dist/UI/Components/Workflow/StepTraceViewer.js +76 -0
  171. package/build/dist/UI/Components/Workflow/StepTraceViewer.js.map +1 -0
  172. package/build/dist/UI/Components/Workflow/Utils.js +73 -1
  173. package/build/dist/UI/Components/Workflow/Utils.js.map +1 -1
  174. package/build/dist/UI/Components/Workflow/Workflow.js +51 -6
  175. package/build/dist/UI/Components/Workflow/Workflow.js.map +1 -1
  176. package/build/dist/UI/Types/LayeredDismissal.js +21 -0
  177. package/build/dist/UI/Types/LayeredDismissal.js.map +1 -0
  178. package/build/dist/UI/Types/UseAnchoredFieldPopup.js +74 -1
  179. package/build/dist/UI/Types/UseAnchoredFieldPopup.js.map +1 -1
  180. package/build/dist/Utils/Monitor/NetworkDeviceRoleUtil.js +386 -0
  181. package/build/dist/Utils/Monitor/NetworkDeviceRoleUtil.js.map +1 -0
  182. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +35 -6
  183. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
  184. package/build/dist/Utils/Telemetry/EntityKey.js +52 -0
  185. package/build/dist/Utils/Telemetry/EntityKey.js.map +1 -1
  186. package/package.json +1 -1
@@ -0,0 +1,118 @@
1
+ /*
2
+ * Shared access to the workflow /model-schema/:tableName endpoint.
3
+ *
4
+ * Three builder inputs are backed by a model's column list — the field picker
5
+ * for Select arguments, the query builder for Query arguments, and the record
6
+ * form for create/update arguments — and all three want the same fetch, the
7
+ * same loading and error handling, and the same column shape.
8
+ */
9
+ import HTTPErrorResponse from "../../../Types/API/HTTPErrorResponse";
10
+ import URL from "../../../Types/API/URL";
11
+ import { WORKFLOW_URL } from "../../Config";
12
+ import API from "../../Utils/API/API";
13
+ import { useEffect, useState } from "react";
14
+ export const fetchModelSchema = async (tableName) => {
15
+ const url = URL.fromString(WORKFLOW_URL.toString()).addRoute(`/model-schema/${encodeURIComponent(tableName)}`);
16
+ const result = await API.get({ url });
17
+ if (result instanceof HTTPErrorResponse) {
18
+ throw result;
19
+ }
20
+ const data = result.data;
21
+ return data["columns"] || [];
22
+ };
23
+ /**
24
+ * Load a model's columns, once per table name.
25
+ *
26
+ * Never throws: a failure leaves `columns` as an empty array and puts the
27
+ * message in `error`, so a caller can fall back to its JSON editor rather than
28
+ * showing the builder a blank panel.
29
+ */
30
+ export const useModelSchema = (tableName) => {
31
+ const [columns, setColumns] = useState(null);
32
+ const [isLoading, setIsLoading] = useState(Boolean(tableName));
33
+ const [error, setError] = useState(null);
34
+ useEffect(() => {
35
+ if (!tableName) {
36
+ setColumns([]);
37
+ setIsLoading(false);
38
+ return;
39
+ }
40
+ let cancelled = false;
41
+ const load = async () => {
42
+ setIsLoading(true);
43
+ setError(null);
44
+ try {
45
+ const loaded = await fetchModelSchema(tableName);
46
+ if (cancelled) {
47
+ return;
48
+ }
49
+ setColumns(loaded);
50
+ }
51
+ catch (err) {
52
+ if (cancelled) {
53
+ return;
54
+ }
55
+ setError(API.getFriendlyMessage(err));
56
+ setColumns([]);
57
+ }
58
+ finally {
59
+ if (!cancelled) {
60
+ setIsLoading(false);
61
+ }
62
+ }
63
+ };
64
+ void load();
65
+ return () => {
66
+ cancelled = true;
67
+ };
68
+ }, [tableName]);
69
+ return { columns: columns, isLoading: isLoading, error: error };
70
+ };
71
+ /*
72
+ * Column types that hold a single scalar the builder can sensibly type into a
73
+ * box. Everything else (relations, JSON blobs, buffers) needs the JSON editor.
74
+ */
75
+ const SCALAR_COLUMN_TYPES = [
76
+ "ShortText",
77
+ "LongText",
78
+ "VeryLongText",
79
+ "Slug",
80
+ "Email",
81
+ "Phone",
82
+ "Color",
83
+ "Domain",
84
+ "Name",
85
+ "Description",
86
+ "ObjectID",
87
+ "Number",
88
+ "PositiveNumber",
89
+ "Boolean",
90
+ "Date",
91
+ "Password",
92
+ "HashedString",
93
+ "Port",
94
+ "Hostname",
95
+ "URL",
96
+ "Route",
97
+ "IP",
98
+ "Version",
99
+ "Markdown",
100
+ "HTML",
101
+ "JavaScript",
102
+ "CSS",
103
+ ];
104
+ export const isScalarColumn = (column) => {
105
+ return !column.isRelation && SCALAR_COLUMN_TYPES.includes(column.type);
106
+ };
107
+ export const isNumericColumn = (column) => {
108
+ return column.type === "Number" || column.type === "PositiveNumber";
109
+ };
110
+ export const isBooleanColumn = (column) => {
111
+ return column.type === "Boolean";
112
+ };
113
+ export const findColumn = (columns, columnId) => {
114
+ return columns.find((column) => {
115
+ return column.id === columnId;
116
+ });
117
+ };
118
+ //# sourceMappingURL=ModelSchema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ModelSchema.js","sourceRoot":"","sources":["../../../../../UI/Components/Workflow/ModelSchema.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import ErrorMessage from "../ErrorMessage/ErrorMessage";
2
2
  import BasicForm from "../Forms/BasicForm";
3
- import { componentInputTypeToFormFieldType } from "./Utils";
3
+ import { componentInputTypeToFormFieldType, parseStringDictionaryValue, } from "./Utils";
4
+ import { ComponentInputType, } from "../../../Types/Workflow/Component";
4
5
  import React, { useEffect, useRef, useState, } from "react";
5
6
  const RunForm = (props) => {
6
7
  const formRef = useRef(null);
@@ -12,6 +13,23 @@ const RunForm = (props) => {
12
13
  useEffect(() => {
13
14
  props.onFormChange(component);
14
15
  }, [component]);
16
+ /*
17
+ * Same hydration ArgumentsForm does: a StringDictionary renders as key/value
18
+ * rows, and those need a real object rather than the JSON string older
19
+ * workflows stored. The field type is chosen from the same value, so the two
20
+ * cannot disagree about which editor is on screen.
21
+ */
22
+ const formInitialValues = Object.assign({}, (component.arguments || {}));
23
+ for (const argument of component.metadata.runWorkflowManuallyArguments ||
24
+ []) {
25
+ if (argument.type !== ComponentInputType.StringDictionary) {
26
+ continue;
27
+ }
28
+ const parsed = parseStringDictionaryValue(formInitialValues[argument.id]);
29
+ if (parsed !== null) {
30
+ formInitialValues[argument.id] = parsed;
31
+ }
32
+ }
15
33
  return (React.createElement("div", { className: "mb-3 mt-3" },
16
34
  React.createElement("div", { className: "mt-5 mb-5" },
17
35
  React.createElement("h2", { className: "text-base font-medium text-gray-500" },
@@ -21,18 +39,16 @@ const RunForm = (props) => {
21
39
  component.metadata.runWorkflowManuallyArguments &&
22
40
  component.metadata.runWorkflowManuallyArguments.length === 0 && (React.createElement(ErrorMessage, { message: 'This workflow trigger does not take any values. You can run it by clicking the "Run" button below.' })),
23
41
  component.metadata.runWorkflowManuallyArguments &&
24
- component.metadata.runWorkflowManuallyArguments.length > 0 && (React.createElement(BasicForm, { hideSubmitButton: true, ref: formRef, initialValues: Object.assign({}, (component.arguments || {})), onChange: (values) => {
42
+ component.metadata.runWorkflowManuallyArguments.length > 0 && (React.createElement(BasicForm, { hideSubmitButton: true, ref: formRef, initialValues: Object.assign({}, formInitialValues), onChange: (values) => {
25
43
  setComponent(Object.assign(Object.assign({}, component), { arguments: Object.assign(Object.assign({}, (component.arguments || {})), (values || {})) }));
26
44
  }, onFormValidationErrorChanged: (hasError) => {
27
45
  setHasFormValidationErrors(hasError);
28
46
  }, fields: component.metadata.runWorkflowManuallyArguments &&
29
47
  component.metadata.runWorkflowManuallyArguments.map((argument) => {
48
+ var _a;
30
49
  return Object.assign({ title: `${argument.name}`, description: `${argument.required ? "Required" : "Optional"}. ${argument.description}`, field: {
31
50
  [argument.id]: true,
32
- }, required: argument.required, placeholder: argument.placeholder }, componentInputTypeToFormFieldType(argument.type, component.returnValues &&
33
- component.returnValues[argument.id]
34
- ? component.returnValues[argument.id]
35
- : null));
51
+ }, required: argument.required, placeholder: argument.placeholder }, componentInputTypeToFormFieldType(argument.type, (_a = formInitialValues[argument.id]) !== null && _a !== void 0 ? _a : null));
36
52
  }) })))));
37
53
  };
38
54
  export default RunForm;
@@ -1 +1 @@
1
- {"version":3,"file":"RunForm.js","sourceRoot":"","sources":["../../../../../UI/Components/Workflow/RunForm.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"RunForm.js","sourceRoot":"","sources":["../../../../../UI/Components/Workflow/RunForm.tsx"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,8BAA8B,CAAC;AACxD,OAAO,SAAwB,MAAM,oBAAoB,CAAC;AAE1D,OAAO,EACL,iCAAiC,EACjC,0BAA0B,GAC3B,MAAM,SAAS,CAAC;AAEjB,OAAO,EAEL,kBAAkB,GAEnB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,KAAK,EAAE,EAGZ,SAAS,EACT,MAAM,EACN,QAAQ,GACT,MAAM,OAAO,CAAC;AAQf,MAAM,OAAO,GAAsC,CACjD,KAAqB,EACP,EAAE;IAChB,MAAM,OAAO,GAAQ,MAAM,CAAoC,IAAI,CAAC,CAAC;IACrE,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAe,KAAK,CAAC,SAAS,CAAC,CAAC;IAC1E,MAAM,CAAC,uBAAuB,EAAE,0BAA0B,CAAC,GACzD,QAAQ,CAAU,KAAK,CAAC,CAAC;IAE3B,SAAS,CAAC,GAAG,EAAE;QACb,KAAK,CAAC,yBAAyB,CAAC,uBAAuB,CAAC,CAAC;IAC3D,CAAC,EAAE,CAAC,uBAAuB,CAAC,CAAC,CAAC;IAE9B,SAAS,CAAC,GAAG,EAAE;QACb,KAAK,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;IAChC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;IAEhB;;;;;OAKG;IACH,MAAM,iBAAiB,qBAAoB,CAAC,SAAS,CAAC,SAAS,IAAI,EAAE,CAAC,CAAE,CAAC;IAEzE,KAAK,MAAM,QAAQ,IAAI,SAAS,CAAC,QAAQ,CAAC,4BAA4B;QACpE,EAAE,EAAE,CAAC;QACL,IAAI,QAAQ,CAAC,IAAI,KAAK,kBAAkB,CAAC,gBAAgB,EAAE,CAAC;YAC1D,SAAS;QACX,CAAC;QAED,MAAM,MAAM,GAAsB,0BAA0B,CAC1D,iBAAiB,CAAC,QAAQ,CAAC,EAAE,CAAC,CAC/B,CAAC;QAEF,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YACpB,iBAAiB,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC;QAC1C,CAAC;IACH,CAAC;IAED,OAAO,CACL,6BAAK,SAAS,EAAC,WAAW;QACxB,6BAAK,SAAS,EAAC,WAAW;YACxB,4BAAI,SAAS,EAAC,qCAAqC;;gBAC5C,SAAS,CAAC,QAAQ,CAAC,KAAK,CAC1B;YACL,2BAAG,SAAS,EAAC,wCAAwC,IAClD,SAAS,CAAC,QAAQ,CAAC,WAAW,CAC7B;YACH,SAAS,CAAC,QAAQ,CAAC,4BAA4B;gBAC9C,SAAS,CAAC,QAAQ,CAAC,4BAA4B,CAAC,MAAM,KAAK,CAAC,IAAI,CAC9D,oBAAC,YAAY,IACX,OAAO,EACL,oGAAoG,GAEtG,CACH;YACF,SAAS,CAAC,QAAQ,CAAC,4BAA4B;gBAC9C,SAAS,CAAC,QAAQ,CAAC,4BAA4B,CAAC,MAAM,GAAG,CAAC,IAAI,CAC5D,oBAAC,SAAS,IACR,gBAAgB,EAAE,IAAI,EACtB,GAAG,EAAE,OAAO,EACZ,aAAa,oBACR,iBAAiB,GAEtB,QAAQ,EAAE,CAAC,MAA8B,EAAE,EAAE;oBAC3C,YAAY,iCACP,SAAS,KACZ,SAAS,kCACJ,CAAE,SAAS,CAAC,SAAwB,IAAI,EAAE,CAAC,GAC3C,CAAE,MAAqB,IAAI,EAAE,CAAC,KAEnC,CAAC;gBACL,CAAC,EACD,4BAA4B,EAAE,CAAC,QAAiB,EAAE,EAAE;oBAClD,0BAA0B,CAAC,QAAQ,CAAC,CAAC;gBACvC,CAAC,EACD,MAAM,EACJ,SAAS,CAAC,QAAQ,CAAC,4BAA4B;oBAC/C,SAAS,CAAC,QAAQ,CAAC,4BAA4B,CAAC,GAAG,CACjD,CAAC,QAAkB,EAAE,EAAE;;wBACrB,uBACE,KAAK,EAAE,GAAG,QAAQ,CAAC,IAAI,EAAE,EAEzB,WAAW,EAAE,GACX,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UACnC,KAAK,QAAQ,CAAC,WAAW,EAAE,EAC3B,KAAK,EAAE;gCACL,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,IAAI;6BACpB,EACD,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAC3B,WAAW,EAAE,QAAQ,CAAC,WAAW,IAQ9B,iCAAiC,CAClC,QAAQ,CAAC,IAAI,EACb,MAAA,iBAAiB,CAAC,QAAQ,CAAC,EAAE,CAAC,mCAAI,IAAI,CACvC,EACD;oBACJ,CAAC,CACF,GAEH,CACH,CACC,CACF,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,OAAO,CAAC"}
@@ -0,0 +1,76 @@
1
+ /*
2
+ * Pure helpers behind the builder's "what happened to the run I just started"
3
+ * strip.
4
+ *
5
+ * Triggering a run from the builder used to end at a modal saying the workflow
6
+ * had been scheduled and that the Logs tab would know more. That left the one
7
+ * question the builder actually has — did it work — to a different page, a
8
+ * table, and a text blob. The runner does not hand back a log id at enqueue
9
+ * time (RunWorkflow creates the WorkflowLog itself once it picks the job up),
10
+ * so the builder watches for the run instead of being told about it.
11
+ *
12
+ * The logic that decides when to stop watching lives here, separate from the
13
+ * page, because it is the part worth testing.
14
+ */
15
+ import WorkflowStatus from "../../../Types/Workflow/WorkflowStatus";
16
+ /**
17
+ * Statuses a run never moves on from. Waiting is not one of them — a Sleep
18
+ * step parks a run for as long as it likes and it carries on afterwards.
19
+ */
20
+ const TERMINAL_STATUSES = [
21
+ WorkflowStatus.Success,
22
+ WorkflowStatus.Error,
23
+ WorkflowStatus.Timeout,
24
+ WorkflowStatus.WorkflowCountExceeded,
25
+ ];
26
+ export const isTerminalRunStatus = (status) => {
27
+ if (!status) {
28
+ return false;
29
+ }
30
+ return TERMINAL_STATUSES.includes(status);
31
+ };
32
+ export const isFailedRunStatus = (status) => {
33
+ return (status === WorkflowStatus.Error ||
34
+ status === WorkflowStatus.Timeout ||
35
+ status === WorkflowStatus.WorkflowCountExceeded);
36
+ };
37
+ /*
38
+ * How long to keep watching. A run that suspends on a Sleep step can outlive
39
+ * any sensible watch, so the strip stops following it and points at the Logs
40
+ * tab rather than polling for hours.
41
+ */
42
+ export const MAX_RUN_WATCH_POLLS = 60;
43
+ export const RUN_WATCH_POLL_INTERVAL_MS = 2000;
44
+ /**
45
+ * What the strip should say, and whether to keep looking.
46
+ */
47
+ export const decideRunWatch = (params) => {
48
+ if (params.pollCount >= MAX_RUN_WATCH_POLLS) {
49
+ return {
50
+ shouldContinue: false,
51
+ message: "This run is taking a while. Open the Logs tab to follow it from there.",
52
+ };
53
+ }
54
+ if (!params.run) {
55
+ return { shouldContinue: true, message: "Starting run…" };
56
+ }
57
+ if (isTerminalRunStatus(params.run.status)) {
58
+ return {
59
+ shouldContinue: false,
60
+ message: isFailedRunStatus(params.run.status)
61
+ ? `Run ${params.run.status.toLowerCase()}. Open the Logs tab to see why.`
62
+ : "Run finished successfully.",
63
+ };
64
+ }
65
+ if (params.run.status === WorkflowStatus.Waiting) {
66
+ return {
67
+ shouldContinue: false,
68
+ message: "This run is sleeping and will carry on by itself. Follow it in the Logs tab.",
69
+ };
70
+ }
71
+ return {
72
+ shouldContinue: true,
73
+ message: `Run ${params.run.status.toLowerCase()}…`,
74
+ };
75
+ };
76
+ //# sourceMappingURL=RunStatusWatcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RunStatusWatcher.js","sourceRoot":"","sources":["../../../../../UI/Components/Workflow/RunStatusWatcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,cAAc,MAAM,wCAAwC,CAAC;AAEpE;;;GAGG;AACH,MAAM,iBAAiB,GAA0B;IAC/C,cAAc,CAAC,OAAO;IACtB,cAAc,CAAC,KAAK;IACpB,cAAc,CAAC,OAAO;IACtB,cAAc,CAAC,qBAAqB;CACrC,CAAC;AAMF,MAAM,CAAC,MAAM,mBAAmB,GAAgC,CAC9D,MAAyC,EAChC,EAAE;IACX,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,iBAAiB,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AAC5C,CAAC,CAAC;AAMF,MAAM,CAAC,MAAM,iBAAiB,GAA8B,CAC1D,MAAyC,EAChC,EAAE;IACX,OAAO,CACL,MAAM,KAAK,cAAc,CAAC,KAAK;QAC/B,MAAM,KAAK,cAAc,CAAC,OAAO;QACjC,MAAM,KAAK,cAAc,CAAC,qBAAqB,CAChD,CAAC;AACJ,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAW,EAAE,CAAC;AAC9C,MAAM,CAAC,MAAM,0BAA0B,GAAW,IAAI,CAAC;AAmBvD;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAA2B,CAAC,MAGtD,EAAoB,EAAE;IACrB,IAAI,MAAM,CAAC,SAAS,IAAI,mBAAmB,EAAE,CAAC;QAC5C,OAAO;YACL,cAAc,EAAE,KAAK;YACrB,OAAO,EACL,wEAAwE;SAC3E,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;QAChB,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,OAAO,EAAE,eAAe,EAAE,CAAC;IAC5D,CAAC;IAED,IAAI,mBAAmB,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3C,OAAO;YACL,cAAc,EAAE,KAAK;YACrB,OAAO,EAAE,iBAAiB,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC;gBAC3C,CAAC,CAAC,OAAO,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,iCAAiC;gBACzE,CAAC,CAAC,4BAA4B;SACjC,CAAC;IACJ,CAAC;IAED,IAAI,MAAM,CAAC,GAAG,CAAC,MAAM,KAAK,cAAc,CAAC,OAAO,EAAE,CAAC;QACjD,OAAO;YACL,cAAc,EAAE,KAAK;YACrB,OAAO,EACL,8EAA8E;SACjF,CAAC;IACJ,CAAC;IAED,OAAO;QACL,cAAc,EAAE,IAAI;QACpB,OAAO,EAAE,OAAO,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,GAAG;KACnD,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1,76 @@
1
+ /*
2
+ * A workflow run, read as the list of steps it actually took.
3
+ *
4
+ * The raw log is still there and still useful — it carries the component's own
5
+ * log lines and the warnings the runner emits — but "what did this step
6
+ * receive, what did it return, and where did it go next" is a question about
7
+ * structure, and answering it by scanning a newline-joined blob was the whole
8
+ * problem.
9
+ */
10
+ import Icon from "../Icon/Icon";
11
+ import IconProp from "../../../Types/Icon/IconProp";
12
+ import { WorkflowStepStatus, } from "../../../Types/Workflow/StepTrace";
13
+ import React, { useState } from "react";
14
+ export const formatStepDuration = (durationInMs) => {
15
+ if (durationInMs < 1000) {
16
+ return `${durationInMs}ms`;
17
+ }
18
+ if (durationInMs < 60000) {
19
+ return `${(durationInMs / 1000).toFixed(1)}s`;
20
+ }
21
+ const minutes = Math.floor(durationInMs / 60000);
22
+ const seconds = Math.round((durationInMs % 60000) / 1000);
23
+ return `${minutes}m ${seconds}s`;
24
+ };
25
+ const ValueBlock = (props) => {
26
+ const keys = Object.keys(props.values || {});
27
+ return (React.createElement("div", null,
28
+ React.createElement("p", { className: "text-[11px] font-semibold uppercase tracking-wider text-gray-500 mb-1" }, props.title),
29
+ keys.length === 0 ? (React.createElement("p", { className: "text-sm text-gray-400" }, "None")) : (React.createElement("dl", { className: "space-y-1" }, keys.map((key) => {
30
+ const value = props.values[key];
31
+ const text = typeof value === "string"
32
+ ? value
33
+ : JSON.stringify(value, null, 2);
34
+ return (React.createElement("div", { key: key, className: "text-sm" },
35
+ React.createElement("dt", { className: "text-gray-500 font-medium" }, key),
36
+ React.createElement("dd", { className: "text-gray-800 font-mono text-xs whitespace-pre-wrap break-all" }, text)));
37
+ })))));
38
+ };
39
+ const StepRow = (props) => {
40
+ const [isOpen, setIsOpen] = useState(props.step.status === WorkflowStepStatus.Error);
41
+ const isError = props.step.status === WorkflowStepStatus.Error;
42
+ return (React.createElement("div", { className: `rounded-md border ${isError ? "border-red-200 bg-red-50" : "border-gray-200 bg-white"}` },
43
+ React.createElement("button", { type: "button", "aria-expanded": isOpen, className: "w-full text-left p-3 flex items-center gap-3 cursor-pointer", onClick: () => {
44
+ setIsOpen(!isOpen);
45
+ } },
46
+ React.createElement("span", { className: "text-xs text-gray-400 w-5 shrink-0" }, props.index + 1),
47
+ React.createElement(Icon, { icon: isError ? IconProp.Alert : IconProp.CheckCircle, className: `h-4 w-4 shrink-0 ${isError ? "text-red-500" : "text-green-500"}` }),
48
+ React.createElement("span", { className: "flex-1 min-w-0" },
49
+ React.createElement("span", { className: "block text-sm font-medium text-gray-900 truncate" }, props.step.title),
50
+ React.createElement("span", { className: "block text-xs text-gray-500 truncate" }, props.step.componentId)),
51
+ React.createElement("span", { className: "text-xs text-gray-500 shrink-0" }, formatStepDuration(props.step.durationInMs)),
52
+ props.step.executedPort && (React.createElement("span", { className: "text-xs text-gray-500 shrink-0 hidden sm:inline" },
53
+ "\u2192 ",
54
+ props.step.executedPort))),
55
+ isOpen && (React.createElement("div", { className: "border-t border-gray-200 p-3 space-y-3" },
56
+ props.step.errorMessage && (React.createElement("p", { className: "text-sm text-red-700" }, props.step.errorMessage)),
57
+ React.createElement(ValueBlock, { title: "Received", values: props.step.argumentValues }),
58
+ React.createElement(ValueBlock, { title: "Returned", values: props.step.returnValues })))));
59
+ };
60
+ const StepTraceViewer = (props) => {
61
+ var _a;
62
+ const steps = ((_a = props.trace) === null || _a === void 0 ? void 0 : _a.steps) || [];
63
+ if (steps.length === 0) {
64
+ return (React.createElement("p", { className: "text-sm text-gray-500" }, "This run has no recorded steps. Runs from before step recording was added show only the log below."));
65
+ }
66
+ return (React.createElement("div", { className: "space-y-2" },
67
+ props.trace.truncated && (React.createElement("p", { className: "text-sm text-amber-700" },
68
+ "Only the last ",
69
+ steps.length,
70
+ " steps of this run were kept.")),
71
+ steps.map((step, index) => {
72
+ return React.createElement(StepRow, { key: index, step: step, index: index });
73
+ })));
74
+ };
75
+ export default StepTraceViewer;
76
+ //# sourceMappingURL=StepTraceViewer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StepTraceViewer.js","sourceRoot":"","sources":["../../../../../UI/Components/Workflow/StepTraceViewer.tsx"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import FormFieldSchemaType from "../Forms/Types/FormFieldSchemaType";
2
2
  import IconProp from "../../../Types/Icon/IconProp";
3
+ import JSONFunctions from "../../../Types/JSONFunctions";
3
4
  import { ComponentInputType, } from "../../../Types/Workflow/Component";
4
5
  import Components, { Categories } from "../../../Types/Workflow/Components";
5
6
  import BaseModelComponentFactory from "../../../Types/Workflow/Components/BaseModel";
@@ -19,6 +20,63 @@ export const loadComponentsAndCategories = () => {
19
20
  }
20
21
  return { components: initComponents, categories: initCategories };
21
22
  };
23
+ /**
24
+ * The key/value view of a StringDictionary argument, or null when the value
25
+ * cannot be shown that way and belongs in the JSON editor instead.
26
+ *
27
+ * Editable as rows:
28
+ * - nothing yet (a new component)
29
+ * - an object of primitives, whether stored as an object (written by the row
30
+ * editor) or as a JSON string (written by the old JSON editor, and by
31
+ * every workflow that already exists)
32
+ *
33
+ * Not editable as rows, so left in the JSON editor:
34
+ * - a whole-field template such as {{local.components.x.returnValues.headers}},
35
+ * which substitutes an entire object at run time and is not JSON as written
36
+ * - text that does not parse, which is exactly the case where the builder
37
+ * most needs to see and fix what they typed
38
+ * - nested objects or arrays, which the row editor cannot represent and would
39
+ * therefore quietly discard
40
+ */
41
+ export const parseStringDictionaryValue = (argValue) => {
42
+ if (argValue === null || argValue === undefined || argValue === "") {
43
+ return {};
44
+ }
45
+ let candidate = argValue;
46
+ if (typeof candidate === "string") {
47
+ if (candidate.trim() === "") {
48
+ return {};
49
+ }
50
+ /*
51
+ * JSONFunctions.parse is JSON5, which is what the components themselves use
52
+ * on these values (ApiComponentUtils.sanitizeArgs). Parsing more strictly
53
+ * here than the runtime does would push a value that works today into the
54
+ * JSON editor for no reason.
55
+ */
56
+ try {
57
+ candidate = JSONFunctions.parse(candidate);
58
+ }
59
+ catch (_a) {
60
+ return null;
61
+ }
62
+ }
63
+ if (typeof candidate !== "object" ||
64
+ candidate === null ||
65
+ Array.isArray(candidate)) {
66
+ return null;
67
+ }
68
+ const entries = candidate;
69
+ for (const key of Object.keys(entries)) {
70
+ const value = entries[key];
71
+ const isPrimitive = typeof value === "string" ||
72
+ typeof value === "number" ||
73
+ typeof value === "boolean";
74
+ if (!isPrimitive) {
75
+ return null;
76
+ }
77
+ }
78
+ return entries;
79
+ };
22
80
  export const componentInputTypeToFormFieldType = (componentInputType, argValue) => {
23
81
  // first priority.
24
82
  if (componentInputType === ComponentInputType.BaseModel) {
@@ -61,9 +119,23 @@ export const componentInputTypeToFormFieldType = (componentInputType, argValue)
61
119
  fieldType: FormFieldSchemaType.JSON,
62
120
  };
63
121
  }
122
+ /*
123
+ * A dictionary of strings is a list of key/value pairs — request headers,
124
+ * query params — and asking someone to hand-write the braces and commas
125
+ * for that is where a good share of workflow JSON mistakes come from. Give
126
+ * it the key/value row editor instead.
127
+ *
128
+ * Values written before this change are JSON strings, and a value can also
129
+ * be something the row editor cannot represent (a whole-field
130
+ * {{...}} substitution, or nested objects). parseStringDictionaryValue
131
+ * decides; anything it cannot represent stays in the JSON editor, so no
132
+ * existing value is ever silently dropped on the floor.
133
+ */
64
134
  if (componentInputType === ComponentInputType.StringDictionary) {
65
135
  return {
66
- fieldType: FormFieldSchemaType.JSON,
136
+ fieldType: parseStringDictionaryValue(argValue) === null
137
+ ? FormFieldSchemaType.JSON
138
+ : FormFieldSchemaType.Dictionary,
67
139
  };
68
140
  }
69
141
  if (componentInputType === ComponentInputType.LongText) {
@@ -1 +1 @@
1
- {"version":3,"file":"Utils.js","sourceRoot":"","sources":["../../../../../UI/Components/Workflow/Utils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Utils.js","sourceRoot":"","sources":["../../../../../UI/Components/Workflow/Utils.ts"],"names":[],"mappings":"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"}
@@ -2,11 +2,12 @@ import WorkflowComponent from "./Component";
2
2
  import ComponentSettingsModal from "./ComponentSettingsModal";
3
3
  import ComponentsModal from "./ComponentsModal";
4
4
  import RunModal from "./RunModal";
5
+ import { lintWorkflowGraph, } from "./GraphLint";
5
6
  import { loadComponentsAndCategories } from "./Utils";
6
7
  import IconProp from "../../../Types/Icon/IconProp";
7
8
  import ObjectID from "../../../Types/ObjectID";
8
9
  import { ComponentType, NodeType, } from "../../../Types/Workflow/Component";
9
- import React, { useCallback, useEffect, useRef, useState, } from "react";
10
+ import React, { useCallback, useEffect, useMemo, useRef, useState, } from "react";
10
11
  import ReactFlow, { Background, BackgroundVariant, Controls, MarkerType, MiniMap, addEdge, getConnectedEdges, updateEdge, useEdgesState, useNodesState, } from "reactflow";
11
12
  // 👇 you need to import the reactflow styles
12
13
  import "reactflow/dist/style.css";
@@ -146,6 +147,35 @@ const Workflow = (props) => {
146
147
  props.onWorkflowUpdated(nodes, edges);
147
148
  }
148
149
  }, [nodes, edges]);
150
+ /*
151
+ * Static checks over the graph, recomputed as it is edited.
152
+ *
153
+ * The results are deliberately NOT written back into node state. Node data is
154
+ * what gets persisted (Builder.saveGraph sends node.data verbatim, minus
155
+ * metadata), so storing lint output there would save today's warnings into
156
+ * the workflow itself and show them again on reload even once they were
157
+ * fixed. Deriving a separate array for rendering keeps the saved graph clean.
158
+ */
159
+ const lintResult = useMemo(() => {
160
+ return lintWorkflowGraph({
161
+ nodes: nodes,
162
+ edges: edges,
163
+ });
164
+ }, [nodes, edges]);
165
+ useEffect(() => {
166
+ var _a;
167
+ (_a = props.onLintResultChange) === null || _a === void 0 ? void 0 : _a.call(props, lintResult);
168
+ }, [lintResult]);
169
+ const nodesToRender = useMemo(() => {
170
+ return nodes.map((node) => {
171
+ const error = lintResult.errorsByNodeId[node.id] || "";
172
+ // Same object when there is nothing to say, so react-flow can bail early.
173
+ if (!error && !node.data.error) {
174
+ return node;
175
+ }
176
+ return Object.assign(Object.assign({}, node), { data: Object.assign(Object.assign({}, node.data), { error: error }) });
177
+ });
178
+ }, [nodes, lintResult]);
149
179
  const proOptions = { hideAttribution: true };
150
180
  const onConnect = useCallback((params) => {
151
181
  return setEdges((eds) => {
@@ -309,7 +339,7 @@ const Workflow = (props) => {
309
339
  stroke-dasharray: 5 5 !important;
310
340
  }
311
341
  `),
312
- React.createElement(ReactFlow, { nodes: nodes, edges: edges, fitView: true, onEdgeClick: () => {
342
+ React.createElement(ReactFlow, { nodes: nodesToRender, edges: edges, fitView: true, onEdgeClick: () => {
313
343
  refreshEdges();
314
344
  }, onNodeClick: () => {
315
345
  refreshEdges();
@@ -355,16 +385,31 @@ const Workflow = (props) => {
355
385
  ? selectedNodeData.metadata.title
356
386
  : "Component Properties", onDelete: (component) => {
357
387
  deleteNode(component.id);
358
- }, description: selectedNodeData && selectedNodeData.metadata.description
388
+ },
389
+ /*
390
+ * Triggers have nothing to run on their own — they are the thing
391
+ * that starts a run, so "run just this step" is meaningless for one.
392
+ */
393
+ onRunStep: props.onRunStep &&
394
+ selectedNodeData.componentType !== ComponentType.Trigger
395
+ ? props.onRunStep
396
+ : undefined, description: selectedNodeData && selectedNodeData.metadata.description
359
397
  ? selectedNodeData.metadata.description
360
398
  : "Edit Component Properties and variables here.", onClose: () => {
361
399
  setShowComponentSettingsModal(false);
362
400
  }, onSave: (componentData) => {
363
- // Update the node.
401
+ /*
402
+ * The settings modal was opened from the rendered node, so what
403
+ * comes back carries whatever lint message was on it. Clear that
404
+ * before it reaches node state — state is what gets saved, and a
405
+ * message about today's mistake has no business being written into
406
+ * the workflow.
407
+ */
408
+ const dataToStore = Object.assign(Object.assign({}, componentData), { error: "" });
364
409
  setNodes((nds) => {
365
410
  return nds.map((n) => {
366
- if (n.data.internalId === componentData.internalId) {
367
- n.data = componentData;
411
+ if (n.data.internalId === dataToStore.internalId) {
412
+ n.data = dataToStore;
368
413
  }
369
414
  return n;
370
415
  });