Flowfile 0.5.3__py3-none-any.whl → 0.5.6__py3-none-any.whl
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.
- flowfile/__init__.py +16 -0
- flowfile/__main__.py +94 -1
- flowfile/web/static/assets/{AdminView-49392a9a.js → AdminView-c2c7942b.js} +1 -1
- flowfile/web/static/assets/{CloudConnectionView-f13f202b.js → CloudConnectionView-7a3042c6.js} +4 -4
- flowfile/web/static/assets/{CloudConnectionView-36bcd6df.css → CloudConnectionView-cf85f943.css} +17 -17
- flowfile/web/static/assets/{CloudStorageReader-0023d4a5.js → CloudStorageReader-709c4037.js} +8 -8
- flowfile/web/static/assets/{CloudStorageWriter-8e781e11.js → CloudStorageWriter-604c51a8.js} +8 -8
- flowfile/web/static/assets/ColumnActionInput-c44b7aee.css +159 -0
- flowfile/web/static/assets/ColumnActionInput-d63d6746.js +330 -0
- flowfile/web/static/assets/{ColumnSelector-8ad68ea9.js → ColumnSelector-0c8cd1cd.js} +1 -1
- flowfile/web/static/assets/ContextMenu-366bf1b4.js +9 -0
- flowfile/web/static/assets/ContextMenu-85cf5b44.js +9 -0
- flowfile/web/static/assets/ContextMenu-9d28ae6d.js +9 -0
- flowfile/web/static/assets/ContextMenu.vue_vue_type_script_setup_true_lang-774c517c.js +59 -0
- flowfile/web/static/assets/{CrossJoin-03df6938.js → CrossJoin-38e5b99a.js} +9 -9
- flowfile/web/static/assets/{CustomNode-8479239b.js → CustomNode-76e8f3f5.js} +27 -20
- flowfile/web/static/assets/CustomNode-edb9b939.css +42 -0
- flowfile/web/static/assets/{DatabaseConnectionSettings-869e3efd.js → DatabaseConnectionSettings-38155669.js} +4 -4
- flowfile/web/static/assets/{DatabaseConnectionSettings-e91df89a.css → DatabaseConnectionSettings-c20a1e16.css} +22 -20
- flowfile/web/static/assets/{DatabaseReader-c58b9552.js → DatabaseReader-2e549c8f.js} +13 -13
- flowfile/web/static/assets/{DatabaseReader-36898a00.css → DatabaseReader-5bf8c75b.css} +39 -44
- flowfile/web/static/assets/{DatabaseView-d26a9140.js → DatabaseView-dc877c29.js} +2 -2
- flowfile/web/static/assets/{DatabaseWriter-217a99f1.css → DatabaseWriter-bdcf2c8b.css} +27 -25
- flowfile/web/static/assets/{DatabaseWriter-4d05ddc7.js → DatabaseWriter-ffb91864.js} +12 -12
- flowfile/web/static/assets/{DesignerView-a6d0ee84.css → DesignerView-71d4e9a1.css} +429 -376
- flowfile/web/static/assets/{DesignerView-e6f5c0e8.js → DesignerView-a4466dab.js} +338 -183
- flowfile/web/static/assets/{DocumentationView-2e78ef1b.js → DocumentationView-979afc84.js} +3 -3
- flowfile/web/static/assets/{DocumentationView-fd46c656.css → DocumentationView-9ea6e871.css} +9 -9
- flowfile/web/static/assets/{ExploreData-7b54caca.js → ExploreData-e4b92aaf.js} +7 -7
- flowfile/web/static/assets/{ExternalSource-47ab05a3.css → ExternalSource-7ac7373f.css} +17 -17
- flowfile/web/static/assets/{ExternalSource-3fa399b2.js → ExternalSource-d08e7227.js} +9 -9
- flowfile/web/static/assets/{Filter-8cbbdbf3.js → Filter-7add806d.js} +9 -9
- flowfile/web/static/assets/{Formula-aac42b1e.js → Formula-36ab24d2.js} +9 -9
- flowfile/web/static/assets/{FuzzyMatch-cd9bbfca.js → FuzzyMatch-cc01bb04.js} +10 -10
- flowfile/web/static/assets/{GraphSolver-c24dec17.css → GraphSolver-4b4d7db9.css} +4 -4
- flowfile/web/static/assets/{GraphSolver-c7e6780e.js → GraphSolver-4fb98f3b.js} +11 -11
- flowfile/web/static/assets/GroupBy-5792782d.css +9 -0
- flowfile/web/static/assets/{GroupBy-93c5d22b.js → GroupBy-b3c8f429.js} +9 -9
- flowfile/web/static/assets/{Join-a19b2de2.js → Join-096b7b26.js} +10 -10
- flowfile/web/static/assets/{LoginView-0df4ed0a.js → LoginView-c33a246a.js} +1 -1
- flowfile/web/static/assets/{ManualInput-3702e677.css → ManualInput-39111f19.css} +48 -48
- flowfile/web/static/assets/{ManualInput-8d3374b2.js → ManualInput-7307e9b1.js} +55 -13
- flowfile/web/static/assets/{MultiSelect-ad1b6243.js → MultiSelect-14822c48.js} +2 -2
- flowfile/web/static/assets/{MultiSelect.vue_vue_type_script_setup_true_lang-e278950d.js → MultiSelect.vue_vue_type_script_setup_true_lang-90c4d340.js} +1 -1
- flowfile/web/static/assets/{NodeDesigner-40b647c9.js → NodeDesigner-5036c392.js} +171 -69
- flowfile/web/static/assets/{NodeDesigner-5f53be3f.css → NodeDesigner-94cd4dd3.css} +190 -190
- flowfile/web/static/assets/{NumericInput-7100234c.js → NumericInput-15cf3b72.js} +2 -2
- flowfile/web/static/assets/{NumericInput.vue_vue_type_script_setup_true_lang-5130219f.js → NumericInput.vue_vue_type_script_setup_true_lang-91e679d7.js} +1 -1
- flowfile/web/static/assets/{Output-f5efd2aa.js → Output-1f8ed42c.js} +13 -12
- flowfile/web/static/assets/{Output-35e97000.css → Output-692dd25d.css} +10 -10
- flowfile/web/static/assets/{Pivot-d981d23c.js → Pivot-0e153f4e.js} +10 -10
- flowfile/web/static/assets/{PivotValidation-63de1f73.js → PivotValidation-5a4f7c79.js} +1 -1
- flowfile/web/static/assets/{PivotValidation-39386e95.js → PivotValidation-81ec2a33.js} +1 -1
- flowfile/web/static/assets/{PolarsCode-f9d69217.js → PolarsCode-a39f15ac.js} +7 -7
- flowfile/web/static/assets/PopOver-ddcfe4f6.js +138 -0
- flowfile/web/static/assets/{Read-aec2e377.js → Read-39b63932.js} +15 -14
- flowfile/web/static/assets/{Read-36e7bd51.css → Read-90f366bc.css} +13 -13
- flowfile/web/static/assets/{RecordCount-78ed6845.js → RecordCount-e9048ccd.js} +6 -6
- flowfile/web/static/assets/{RecordId-2156e890.js → RecordId-ad02521d.js} +9 -9
- flowfile/web/static/assets/{SQLQueryComponent-48c72f5b.js → SQLQueryComponent-2eeecf0b.js} +3 -3
- flowfile/web/static/assets/SQLQueryComponent-edb90b98.css +29 -0
- flowfile/web/static/assets/{Sample-1352ca74.js → Sample-9a68c23d.js} +6 -6
- flowfile/web/static/assets/{SecretSelector-22b5ff89.js → SecretSelector-2429f35a.js} +2 -2
- flowfile/web/static/assets/{SecretsView-17df66ee.js → SecretsView-c6afc915.js} +2 -2
- flowfile/web/static/assets/{Select-0aee4c54.js → Select-fcd002b6.js} +9 -9
- flowfile/web/static/assets/{SettingsSection-cd341bb6.js → SettingsSection-5ce15962.js} +1 -1
- flowfile/web/static/assets/{SettingsSection-0784e157.js → SettingsSection-c6b1362c.js} +1 -1
- flowfile/web/static/assets/{SettingsSection-f2002a6d.js → SettingsSection-cebb91d5.js} +1 -1
- flowfile/web/static/assets/SetupView-2d12e01f.js +160 -0
- flowfile/web/static/assets/SetupView-ec26f76a.css +230 -0
- flowfile/web/static/assets/{SingleSelect-460cc0ea.js → SingleSelect-b67de4eb.js} +2 -2
- flowfile/web/static/assets/{SingleSelect.vue_vue_type_script_setup_true_lang-30741bb2.js → SingleSelect.vue_vue_type_script_setup_true_lang-eedb70eb.js} +1 -1
- flowfile/web/static/assets/{SliderInput-5d926864.js → SliderInput-fd8134ac.js} +1 -1
- flowfile/web/static/assets/Sort-4abb7fae.css +9 -0
- flowfile/web/static/assets/{Sort-3cdc971b.js → Sort-c005a573.js} +9 -9
- flowfile/web/static/assets/{TextInput-a2d0bfbd.js → TextInput-1bb31dab.js} +2 -2
- flowfile/web/static/assets/{TextInput.vue_vue_type_script_setup_true_lang-abad1ca2.js → TextInput.vue_vue_type_script_setup_true_lang-a51fe730.js} +1 -1
- flowfile/web/static/assets/{TextToRows-918945f7.js → TextToRows-4f363753.js} +9 -9
- flowfile/web/static/assets/{ToggleSwitch-f0ef5196.js → ToggleSwitch-ca0f2e5e.js} +2 -2
- flowfile/web/static/assets/{ToggleSwitch.vue_vue_type_script_setup_true_lang-5605c793.js → ToggleSwitch.vue_vue_type_script_setup_true_lang-49aa41d8.js} +1 -1
- flowfile/web/static/assets/{UnavailableFields-54d2f518.css → UnavailableFields-394a1f78.css} +13 -13
- flowfile/web/static/assets/{UnavailableFields-bdad6144.js → UnavailableFields-f6147968.js} +4 -4
- flowfile/web/static/assets/{Union-e8ab8c86.js → Union-c65f17b7.js} +6 -6
- flowfile/web/static/assets/Unique-2b705521.css +3 -0
- flowfile/web/static/assets/{Unique-8cd4f976.js → Unique-a1d96fb2.js} +12 -12
- flowfile/web/static/assets/{Unpivot-710a2948.css → Unpivot-b6ad6427.css} +6 -6
- flowfile/web/static/assets/{Unpivot-8da14095.js → Unpivot-c2657ff3.js} +11 -11
- flowfile/web/static/assets/{UnpivotValidation-6f7d89ff.js → UnpivotValidation-28e29a3b.js} +1 -1
- flowfile/web/static/assets/{VueGraphicWalker-3fb312e1.js → VueGraphicWalker-2fc3ddd4.js} +1 -1
- flowfile/web/static/assets/{api-24483f0d.js → api-df48ec50.js} +1 -1
- flowfile/web/static/assets/{api-8b81fa73.js → api-ee542cf7.js} +1 -1
- flowfile/web/static/assets/{dropDown-3d8dc5fa.css → dropDown-1d6acbd9.css} +26 -26
- flowfile/web/static/assets/{dropDown-ac0fda9d.js → dropDown-7576a76a.js} +3 -3
- flowfile/web/static/assets/{fullEditor-5497a84a.js → fullEditor-7583bef5.js} +3 -3
- flowfile/web/static/assets/{fullEditor-a0be62b3.css → fullEditor-fe9f7e18.css} +3 -3
- flowfile/web/static/assets/{genericNodeSettings-99014e1d.js → genericNodeSettings-0155288b.js} +2 -3
- flowfile/web/static/assets/{index-3ba44389.js → index-057d770d.js} +2 -2
- flowfile/web/static/assets/{index-07dda503.js → index-aeec439d.js} +1 -1
- flowfile/web/static/assets/{index-fb6493ae.js → index-ca6799de.js} +2293 -196
- flowfile/web/static/assets/{index-e6289dd0.css → index-d60c9dd4.css} +560 -10
- flowfile/web/static/assets/nodeInput-d478b9ac.js +2 -0
- flowfile/web/static/assets/{outputCsv-8f8ba42d.js → outputCsv-c492b15e.js} +3 -3
- flowfile/web/static/assets/outputCsv-cc84e09f.css +2499 -0
- flowfile/web/static/assets/{outputExcel-393f4fef.js → outputExcel-13bfa10f.js} +1 -1
- flowfile/web/static/assets/{outputParquet-07c81f65.js → outputParquet-9be1523a.js} +1 -1
- flowfile/web/static/assets/{readCsv-07f6d9ad.js → readCsv-5a49a8c9.js} +1 -1
- flowfile/web/static/assets/{readExcel-ed69bc8f.js → readExcel-27c30ad8.js} +3 -3
- flowfile/web/static/assets/{readParquet-e3ed4528.js → readParquet-446bde68.js} +1 -1
- flowfile/web/static/assets/{secrets.api-002e7d7e.js → secrets.api-34431884.js} +1 -1
- flowfile/web/static/assets/{selectDynamic-80b92899.js → selectDynamic-5754a2b1.js} +2 -3
- flowfile/web/static/assets/{vue-codemirror.esm-0965f39f.js → vue-codemirror.esm-8f46fb36.js} +1 -1
- flowfile/web/static/assets/{vue-content-loader.es-c506ad97.js → vue-content-loader.es-808fe33a.js} +1 -1
- flowfile/web/static/index.html +2 -2
- {flowfile-0.5.3.dist-info → flowfile-0.5.6.dist-info}/METADATA +2 -2
- {flowfile-0.5.3.dist-info → flowfile-0.5.6.dist-info}/RECORD +139 -134
- flowfile_core/auth/secrets.py +56 -13
- flowfile_core/fileExplorer/funcs.py +26 -4
- flowfile_core/flowfile/code_generator/__init__.py +11 -0
- flowfile_core/flowfile/code_generator/code_generator.py +347 -2
- flowfile_core/flowfile/flow_data_engine/flow_data_engine.py +13 -1
- flowfile_core/flowfile/flow_data_engine/subprocess_operations/subprocess_operations.py +12 -0
- flowfile_core/flowfile/flow_graph.py +2 -0
- flowfile_core/flowfile/flow_node/flow_node.py +52 -28
- flowfile_core/flowfile/node_designer/__init__.py +4 -0
- flowfile_core/flowfile/node_designer/ui_components.py +144 -1
- flowfile_core/main.py +2 -4
- flowfile_core/routes/public.py +43 -1
- flowfile_core/schemas/cloud_storage_schemas.py +39 -15
- flowfile_core/secret_manager/secret_manager.py +107 -6
- flowfile_frame/__init__.py +11 -0
- flowfile_frame/database/__init__.py +36 -0
- flowfile_frame/database/connection_manager.py +205 -0
- flowfile_frame/database/frame_helpers.py +249 -0
- flowfile_worker/configs.py +31 -15
- flowfile_worker/secrets.py +105 -15
- flowfile_worker/spawner.py +10 -6
- flowfile/web/static/assets/ContextMenu-26d4dd27.css +0 -26
- flowfile/web/static/assets/ContextMenu-31ee57f0.js +0 -41
- flowfile/web/static/assets/ContextMenu-69a74055.js +0 -41
- flowfile/web/static/assets/ContextMenu-8e2051c6.js +0 -41
- flowfile/web/static/assets/ContextMenu-8ec1729e.css +0 -26
- flowfile/web/static/assets/ContextMenu-9b310c60.css +0 -26
- flowfile/web/static/assets/CustomNode-59e99a86.css +0 -32
- flowfile/web/static/assets/GroupBy-be7ac0bf.css +0 -51
- flowfile/web/static/assets/PopOver-b22f049e.js +0 -939
- flowfile/web/static/assets/SQLQueryComponent-1c2f26b4.css +0 -27
- flowfile/web/static/assets/Sort-8a871341.css +0 -51
- flowfile/web/static/assets/Unique-9fb2f567.css +0 -51
- flowfile/web/static/assets/nodeInput-0eb13f1a.js +0 -2
- flowfile/web/static/assets/outputCsv-b9a072af.css +0 -2499
- {flowfile-0.5.3.dist-info → flowfile-0.5.6.dist-info}/WHEEL +0 -0
- {flowfile-0.5.3.dist-info → flowfile-0.5.6.dist-info}/entry_points.txt +0 -0
- {flowfile-0.5.3.dist-info → flowfile-0.5.6.dist-info}/licenses/LICENSE +0 -0
|
@@ -10552,12 +10552,12 @@ const _export_sfc = (sfc, props) => {
|
|
|
10552
10552
|
}
|
|
10553
10553
|
return target;
|
|
10554
10554
|
};
|
|
10555
|
-
const _sfc_main$
|
|
10556
|
-
const _hoisted_1$
|
|
10555
|
+
const _sfc_main$a = {};
|
|
10556
|
+
const _hoisted_1$_ = { class: "logo" };
|
|
10557
10557
|
function _sfc_render$1(_ctx, _cache) {
|
|
10558
|
-
return openBlock(), createElementBlock("div", _hoisted_1$
|
|
10558
|
+
return openBlock(), createElementBlock("div", _hoisted_1$_);
|
|
10559
10559
|
}
|
|
10560
|
-
const Header = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
10560
|
+
const Header = /* @__PURE__ */ _export_sfc(_sfc_main$a, [["render", _sfc_render$1]]);
|
|
10561
10561
|
const NavigationRoutes = {
|
|
10562
10562
|
root: {
|
|
10563
10563
|
name: "/",
|
|
@@ -15633,7 +15633,7 @@ if (__INTLIFY_PROD_DEVTOOLS__) {
|
|
|
15633
15633
|
target.__INTLIFY__ = true;
|
|
15634
15634
|
setDevToolsHook(target.__INTLIFY_DEVTOOLS_GLOBAL_HOOK__);
|
|
15635
15635
|
}
|
|
15636
|
-
const _sfc_main$
|
|
15636
|
+
const _sfc_main$9 = /* @__PURE__ */ defineComponent({
|
|
15637
15637
|
__name: "MenuAccordion",
|
|
15638
15638
|
props: {
|
|
15639
15639
|
items: { default: () => [] },
|
|
@@ -15742,14 +15742,14 @@ const _sfc_main$6 = /* @__PURE__ */ defineComponent({
|
|
|
15742
15742
|
}
|
|
15743
15743
|
});
|
|
15744
15744
|
const MenuAccordion_vue_vue_type_style_index_0_scoped_04b48d7c_lang = "";
|
|
15745
|
-
const MenuAccordion = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
15745
|
+
const MenuAccordion = /* @__PURE__ */ _export_sfc(_sfc_main$9, [["__scopeId", "data-v-04b48d7c"]]);
|
|
15746
15746
|
const _imports_1 = "/images/flowfile.svg";
|
|
15747
|
-
const _hoisted_1$
|
|
15748
|
-
const _hoisted_2$
|
|
15747
|
+
const _hoisted_1$Z = ["alt"];
|
|
15748
|
+
const _hoisted_2$P = {
|
|
15749
15749
|
key: 0,
|
|
15750
15750
|
class: "app-name"
|
|
15751
15751
|
};
|
|
15752
|
-
const _sfc_main$
|
|
15752
|
+
const _sfc_main$8 = /* @__PURE__ */ defineComponent({
|
|
15753
15753
|
__name: "Logo",
|
|
15754
15754
|
props: {
|
|
15755
15755
|
width: {
|
|
@@ -15793,14 +15793,14 @@ const _sfc_main$5 = /* @__PURE__ */ defineComponent({
|
|
|
15793
15793
|
src: _imports_1,
|
|
15794
15794
|
alt: __props.altText,
|
|
15795
15795
|
style: normalizeStyle({ width: __props.width, height: __props.height })
|
|
15796
|
-
}, null, 12, _hoisted_1$
|
|
15797
|
-
__props.appName ? (openBlock(), createElementBlock("span", _hoisted_2$
|
|
15796
|
+
}, null, 12, _hoisted_1$Z),
|
|
15797
|
+
__props.appName ? (openBlock(), createElementBlock("span", _hoisted_2$P, toDisplayString$1(__props.appName), 1)) : createCommentVNode("", true)
|
|
15798
15798
|
], 2);
|
|
15799
15799
|
};
|
|
15800
15800
|
}
|
|
15801
15801
|
});
|
|
15802
15802
|
const Logo_vue_vue_type_style_index_0_scoped_a736f53d_lang = "";
|
|
15803
|
-
const Logo = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
15803
|
+
const Logo = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["__scopeId", "data-v-a736f53d"]]);
|
|
15804
15804
|
const THEME_STORAGE_KEY = "flowfile-theme-preference";
|
|
15805
15805
|
function getSystemPreference() {
|
|
15806
15806
|
if (typeof window !== "undefined" && window.matchMedia) {
|
|
@@ -15908,16 +15908,16 @@ function useTheme() {
|
|
|
15908
15908
|
toggleTheme
|
|
15909
15909
|
};
|
|
15910
15910
|
}
|
|
15911
|
-
const _hoisted_1$
|
|
15912
|
-
const _hoisted_2$
|
|
15911
|
+
const _hoisted_1$Y = ["title"];
|
|
15912
|
+
const _hoisted_2$O = {
|
|
15913
15913
|
key: 0,
|
|
15914
15914
|
class: "fas fa-sun"
|
|
15915
15915
|
};
|
|
15916
|
-
const _hoisted_3$
|
|
15916
|
+
const _hoisted_3$H = {
|
|
15917
15917
|
key: 1,
|
|
15918
15918
|
class: "fas fa-moon"
|
|
15919
15919
|
};
|
|
15920
|
-
const _sfc_main$
|
|
15920
|
+
const _sfc_main$7 = /* @__PURE__ */ defineComponent({
|
|
15921
15921
|
__name: "ThemeToggle",
|
|
15922
15922
|
setup(__props) {
|
|
15923
15923
|
const { isDark, toggleTheme } = useTheme();
|
|
@@ -15928,13 +15928,13 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
|
|
|
15928
15928
|
onClick: _cache[0] || (_cache[0] = //@ts-ignore
|
|
15929
15929
|
(...args) => unref(toggleTheme) && unref(toggleTheme)(...args))
|
|
15930
15930
|
}, [
|
|
15931
|
-
unref(isDark) ? (openBlock(), createElementBlock("i", _hoisted_2$
|
|
15932
|
-
], 8, _hoisted_1$
|
|
15931
|
+
unref(isDark) ? (openBlock(), createElementBlock("i", _hoisted_2$O)) : (openBlock(), createElementBlock("i", _hoisted_3$H))
|
|
15932
|
+
], 8, _hoisted_1$Y);
|
|
15933
15933
|
};
|
|
15934
15934
|
}
|
|
15935
15935
|
});
|
|
15936
15936
|
const ThemeToggle_vue_vue_type_style_index_0_scoped_c436efe9_lang = "";
|
|
15937
|
-
const ThemeToggle = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
15937
|
+
const ThemeToggle = /* @__PURE__ */ _export_sfc(_sfc_main$7, [["__scopeId", "data-v-c436efe9"]]);
|
|
15938
15938
|
function bind(fn2, thisArg) {
|
|
15939
15939
|
return function wrap() {
|
|
15940
15940
|
return fn2.apply(thisArg, arguments);
|
|
@@ -18325,12 +18325,26 @@ class AuthService {
|
|
|
18325
18325
|
__publicField(this, "token", ref(null));
|
|
18326
18326
|
__publicField(this, "tokenExpiration", ref(null));
|
|
18327
18327
|
__publicField(this, "isElectronMode", ref(false));
|
|
18328
|
+
__publicField(this, "modeInitialized", false);
|
|
18328
18329
|
__publicField(this, "refreshPromise", null);
|
|
18329
18330
|
__publicField(this, "currentUsername", ref(null));
|
|
18330
18331
|
this.isElectronMode.value = this.detectElectronMode();
|
|
18331
18332
|
this.clearStoredTokens();
|
|
18332
18333
|
this.loadStoredToken();
|
|
18333
18334
|
}
|
|
18335
|
+
/**
|
|
18336
|
+
* Update electron mode based on backend status.
|
|
18337
|
+
* This is called when we get the mode from /health/status endpoint.
|
|
18338
|
+
* In "flowfile run ui" mode, electronAPI won't exist but backend mode is "electron".
|
|
18339
|
+
*/
|
|
18340
|
+
setModeFromBackend(mode) {
|
|
18341
|
+
if (!this.modeInitialized) {
|
|
18342
|
+
if (!this.detectElectronMode()) {
|
|
18343
|
+
this.isElectronMode.value = mode === "electron";
|
|
18344
|
+
}
|
|
18345
|
+
this.modeInitialized = true;
|
|
18346
|
+
}
|
|
18347
|
+
}
|
|
18334
18348
|
loadStoredToken() {
|
|
18335
18349
|
const savedToken = localStorage.getItem("auth_token");
|
|
18336
18350
|
const savedExpiration = localStorage.getItem("auth_token_expiration");
|
|
@@ -18487,6 +18501,7 @@ class AuthService {
|
|
|
18487
18501
|
localStorage.removeItem("auth_username");
|
|
18488
18502
|
}
|
|
18489
18503
|
}
|
|
18504
|
+
const authService = new AuthService();
|
|
18490
18505
|
axios$1.interceptors.response.use(
|
|
18491
18506
|
(response) => response,
|
|
18492
18507
|
async (error) => {
|
|
@@ -18496,13 +18511,11 @@ axios$1.interceptors.response.use(
|
|
|
18496
18511
|
const isAuthRequest = requestUrl.includes("/auth/token") || requestUrl.includes("/auth/");
|
|
18497
18512
|
if (((_a = error.response) == null ? void 0 : _a.status) === 401 && !originalRequest._retry && !isAuthRequest) {
|
|
18498
18513
|
originalRequest._retry = true;
|
|
18499
|
-
|
|
18500
|
-
if (isElectron) {
|
|
18514
|
+
if (authService.isInElectronMode()) {
|
|
18501
18515
|
localStorage.removeItem("auth_token");
|
|
18502
18516
|
localStorage.removeItem("auth_token_expiration");
|
|
18503
|
-
|
|
18504
|
-
await
|
|
18505
|
-
const newToken = await authInstance.getToken();
|
|
18517
|
+
await authService.initialize();
|
|
18518
|
+
const newToken = await authService.getToken();
|
|
18506
18519
|
if (newToken) {
|
|
18507
18520
|
originalRequest.headers["Authorization"] = `Bearer ${newToken}`;
|
|
18508
18521
|
return axios$1(originalRequest);
|
|
@@ -18519,7 +18532,6 @@ axios$1.interceptors.response.use(
|
|
|
18519
18532
|
return Promise.reject(error);
|
|
18520
18533
|
}
|
|
18521
18534
|
);
|
|
18522
|
-
const authService = new AuthService();
|
|
18523
18535
|
const useAuthStore = /* @__PURE__ */ defineStore("auth", {
|
|
18524
18536
|
state: () => ({
|
|
18525
18537
|
user: null,
|
|
@@ -18608,20 +18620,20 @@ const useAuthStore = /* @__PURE__ */ defineStore("auth", {
|
|
|
18608
18620
|
}
|
|
18609
18621
|
}
|
|
18610
18622
|
});
|
|
18611
|
-
const _hoisted_1$
|
|
18612
|
-
const _hoisted_2$
|
|
18613
|
-
const _hoisted_3$
|
|
18614
|
-
const _hoisted_4$
|
|
18615
|
-
const _hoisted_5$
|
|
18623
|
+
const _hoisted_1$X = { class: "sidebar" };
|
|
18624
|
+
const _hoisted_2$N = { class: "center-container" };
|
|
18625
|
+
const _hoisted_3$G = { class: "sidebar-container" };
|
|
18626
|
+
const _hoisted_4$x = { class: "sidebar-footer" };
|
|
18627
|
+
const _hoisted_5$s = {
|
|
18616
18628
|
class: "footer-btn-wrapper",
|
|
18617
18629
|
"data-tooltip": "Toggle theme"
|
|
18618
18630
|
};
|
|
18619
|
-
const _hoisted_6$
|
|
18631
|
+
const _hoisted_6$n = {
|
|
18620
18632
|
key: 0,
|
|
18621
18633
|
class: "footer-btn-wrapper",
|
|
18622
18634
|
"data-tooltip": "Sign out"
|
|
18623
18635
|
};
|
|
18624
|
-
const _sfc_main$
|
|
18636
|
+
const _sfc_main$6 = /* @__PURE__ */ defineComponent({
|
|
18625
18637
|
__name: "Sidebar",
|
|
18626
18638
|
props: {
|
|
18627
18639
|
isCollapse: {
|
|
@@ -18648,25 +18660,25 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({
|
|
|
18648
18660
|
router2.push({ name: "login" });
|
|
18649
18661
|
};
|
|
18650
18662
|
return (_ctx, _cache) => {
|
|
18651
|
-
return openBlock(), createElementBlock("div", _hoisted_1$
|
|
18652
|
-
createBaseVNode("div", _hoisted_2$
|
|
18663
|
+
return openBlock(), createElementBlock("div", _hoisted_1$X, [
|
|
18664
|
+
createBaseVNode("div", _hoisted_2$N, [
|
|
18653
18665
|
createVNode(Logo, {
|
|
18654
18666
|
width: "50px",
|
|
18655
18667
|
"app-name": "",
|
|
18656
18668
|
"position-app-name": "left"
|
|
18657
18669
|
})
|
|
18658
18670
|
]),
|
|
18659
|
-
createBaseVNode("div", _hoisted_3$
|
|
18671
|
+
createBaseVNode("div", _hoisted_3$G, [
|
|
18660
18672
|
createVNode(MenuAccordion, {
|
|
18661
18673
|
items: items.value,
|
|
18662
18674
|
"is-collapse": true
|
|
18663
18675
|
}, null, 8, ["items"])
|
|
18664
18676
|
]),
|
|
18665
|
-
createBaseVNode("div", _hoisted_4$
|
|
18666
|
-
createBaseVNode("div", _hoisted_5$
|
|
18677
|
+
createBaseVNode("div", _hoisted_4$x, [
|
|
18678
|
+
createBaseVNode("div", _hoisted_5$s, [
|
|
18667
18679
|
createVNode(ThemeToggle)
|
|
18668
18680
|
]),
|
|
18669
|
-
showLogout.value ? (openBlock(), createElementBlock("div", _hoisted_6$
|
|
18681
|
+
showLogout.value ? (openBlock(), createElementBlock("div", _hoisted_6$n, [
|
|
18670
18682
|
createBaseVNode("button", {
|
|
18671
18683
|
class: "logout-button",
|
|
18672
18684
|
onClick: handleLogout
|
|
@@ -18680,23 +18692,23 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({
|
|
|
18680
18692
|
}
|
|
18681
18693
|
});
|
|
18682
18694
|
const Sidebar_vue_vue_type_style_index_0_lang = "";
|
|
18683
|
-
const _hoisted_1$
|
|
18684
|
-
const _hoisted_2$
|
|
18685
|
-
const _hoisted_3$
|
|
18686
|
-
const _hoisted_4$
|
|
18687
|
-
const _hoisted_5$
|
|
18695
|
+
const _hoisted_1$W = { class: "modal-container" };
|
|
18696
|
+
const _hoisted_2$M = { class: "modal-header" };
|
|
18697
|
+
const _hoisted_3$F = { class: "modal-title" };
|
|
18698
|
+
const _hoisted_4$w = { class: "modal-content" };
|
|
18699
|
+
const _hoisted_5$r = {
|
|
18688
18700
|
key: 0,
|
|
18689
18701
|
class: "warning-text"
|
|
18690
18702
|
};
|
|
18691
|
-
const _hoisted_6$
|
|
18692
|
-
const _hoisted_7$
|
|
18693
|
-
const _hoisted_8$
|
|
18694
|
-
const _hoisted_9$
|
|
18703
|
+
const _hoisted_6$m = { class: "form-field" };
|
|
18704
|
+
const _hoisted_7$e = { class: "password-field" };
|
|
18705
|
+
const _hoisted_8$a = ["type"];
|
|
18706
|
+
const _hoisted_9$9 = {
|
|
18695
18707
|
key: 0,
|
|
18696
18708
|
class: "form-error"
|
|
18697
18709
|
};
|
|
18698
|
-
const _hoisted_10$
|
|
18699
|
-
const _hoisted_11$
|
|
18710
|
+
const _hoisted_10$9 = { class: "form-field" };
|
|
18711
|
+
const _hoisted_11$6 = { class: "password-field" };
|
|
18700
18712
|
const _hoisted_12$5 = ["type"];
|
|
18701
18713
|
const _hoisted_13$3 = {
|
|
18702
18714
|
key: 0,
|
|
@@ -18721,7 +18733,7 @@ const _hoisted_23$1 = {
|
|
|
18721
18733
|
key: 0,
|
|
18722
18734
|
class: "fa-solid fa-spinner fa-spin"
|
|
18723
18735
|
};
|
|
18724
|
-
const _sfc_main$
|
|
18736
|
+
const _sfc_main$5 = /* @__PURE__ */ defineComponent({
|
|
18725
18737
|
__name: "ChangePasswordModal",
|
|
18726
18738
|
props: {
|
|
18727
18739
|
show: { type: Boolean },
|
|
@@ -18833,9 +18845,9 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
|
|
|
18833
18845
|
class: "modal-overlay",
|
|
18834
18846
|
onClick: withModifiers(handleBackdropClick, ["self"])
|
|
18835
18847
|
}, [
|
|
18836
|
-
createBaseVNode("div", _hoisted_1$
|
|
18837
|
-
createBaseVNode("div", _hoisted_2$
|
|
18838
|
-
createBaseVNode("h3", _hoisted_3$
|
|
18848
|
+
createBaseVNode("div", _hoisted_1$W, [
|
|
18849
|
+
createBaseVNode("div", _hoisted_2$M, [
|
|
18850
|
+
createBaseVNode("h3", _hoisted_3$F, [
|
|
18839
18851
|
_cache[6] || (_cache[6] = createBaseVNode("i", { class: "fa-solid fa-key" }, null, -1)),
|
|
18840
18852
|
createTextVNode(" " + toDisplayString$1(_ctx.isForced ? "Password Change Required" : "Change Password"), 1)
|
|
18841
18853
|
]),
|
|
@@ -18848,18 +18860,18 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
|
|
|
18848
18860
|
createBaseVNode("i", { class: "fa-solid fa-times" }, null, -1)
|
|
18849
18861
|
]))) : createCommentVNode("", true)
|
|
18850
18862
|
]),
|
|
18851
|
-
createBaseVNode("div", _hoisted_4$
|
|
18852
|
-
_ctx.isForced ? (openBlock(), createElementBlock("p", _hoisted_5$
|
|
18863
|
+
createBaseVNode("div", _hoisted_4$w, [
|
|
18864
|
+
_ctx.isForced ? (openBlock(), createElementBlock("p", _hoisted_5$r, " You must change your password before continuing. This is required for security purposes. ")) : createCommentVNode("", true),
|
|
18853
18865
|
createBaseVNode("form", {
|
|
18854
18866
|
class: "form",
|
|
18855
18867
|
onSubmit: withModifiers(handleSubmit, ["prevent"])
|
|
18856
18868
|
}, [
|
|
18857
|
-
createBaseVNode("div", _hoisted_6$
|
|
18869
|
+
createBaseVNode("div", _hoisted_6$m, [
|
|
18858
18870
|
_cache[8] || (_cache[8] = createBaseVNode("label", {
|
|
18859
18871
|
for: "current-password",
|
|
18860
18872
|
class: "form-label"
|
|
18861
18873
|
}, "Current Password", -1)),
|
|
18862
|
-
createBaseVNode("div", _hoisted_7$
|
|
18874
|
+
createBaseVNode("div", _hoisted_7$e, [
|
|
18863
18875
|
withDirectives(createBaseVNode("input", {
|
|
18864
18876
|
id: "current-password",
|
|
18865
18877
|
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => formData.value.currentPassword = $event),
|
|
@@ -18867,7 +18879,7 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
|
|
|
18867
18879
|
class: normalizeClass(["form-input", { "is-error": errors.value.currentPassword }]),
|
|
18868
18880
|
placeholder: "Enter current password",
|
|
18869
18881
|
required: ""
|
|
18870
|
-
}, null, 10, _hoisted_8$
|
|
18882
|
+
}, null, 10, _hoisted_8$a), [
|
|
18871
18883
|
[vModelDynamic, formData.value.currentPassword]
|
|
18872
18884
|
]),
|
|
18873
18885
|
createBaseVNode("button", {
|
|
@@ -18881,14 +18893,14 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
|
|
|
18881
18893
|
}, null, 2)
|
|
18882
18894
|
])
|
|
18883
18895
|
]),
|
|
18884
|
-
errors.value.currentPassword ? (openBlock(), createElementBlock("span", _hoisted_9$
|
|
18896
|
+
errors.value.currentPassword ? (openBlock(), createElementBlock("span", _hoisted_9$9, toDisplayString$1(errors.value.currentPassword), 1)) : createCommentVNode("", true)
|
|
18885
18897
|
]),
|
|
18886
|
-
createBaseVNode("div", _hoisted_10$
|
|
18898
|
+
createBaseVNode("div", _hoisted_10$9, [
|
|
18887
18899
|
_cache[12] || (_cache[12] = createBaseVNode("label", {
|
|
18888
18900
|
for: "new-password",
|
|
18889
18901
|
class: "form-label"
|
|
18890
18902
|
}, "New Password", -1)),
|
|
18891
|
-
createBaseVNode("div", _hoisted_11$
|
|
18903
|
+
createBaseVNode("div", _hoisted_11$6, [
|
|
18892
18904
|
withDirectives(createBaseVNode("input", {
|
|
18893
18905
|
id: "new-password",
|
|
18894
18906
|
"onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => formData.value.newPassword = $event),
|
|
@@ -18994,7 +19006,2041 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
|
|
|
18994
19006
|
}
|
|
18995
19007
|
});
|
|
18996
19008
|
const ChangePasswordModal_vue_vue_type_style_index_0_scoped_79657dc0_lang = "";
|
|
18997
|
-
const ChangePasswordModal = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
19009
|
+
const ChangePasswordModal = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["__scopeId", "data-v-79657dc0"]]);
|
|
19010
|
+
const useTutorialStore = /* @__PURE__ */ defineStore("tutorial", () => {
|
|
19011
|
+
const isActive = ref(false);
|
|
19012
|
+
const currentTutorial = ref(null);
|
|
19013
|
+
const currentStepIndex = ref(0);
|
|
19014
|
+
const isTransitioning = ref(false);
|
|
19015
|
+
const completedTutorials = ref(/* @__PURE__ */ new Set());
|
|
19016
|
+
const tutorialPaused = ref(false);
|
|
19017
|
+
const currentStep = computed(() => {
|
|
19018
|
+
if (!currentTutorial.value || currentStepIndex.value < 0)
|
|
19019
|
+
return null;
|
|
19020
|
+
return currentTutorial.value.steps[currentStepIndex.value] || null;
|
|
19021
|
+
});
|
|
19022
|
+
const totalSteps = computed(() => {
|
|
19023
|
+
var _a;
|
|
19024
|
+
return ((_a = currentTutorial.value) == null ? void 0 : _a.steps.length) ?? 0;
|
|
19025
|
+
});
|
|
19026
|
+
const progress = computed(() => {
|
|
19027
|
+
if (totalSteps.value === 0)
|
|
19028
|
+
return 0;
|
|
19029
|
+
return (currentStepIndex.value + 1) / totalSteps.value * 100;
|
|
19030
|
+
});
|
|
19031
|
+
const isFirstStep = computed(() => currentStepIndex.value === 0);
|
|
19032
|
+
const isLastStep = computed(() => currentStepIndex.value === totalSteps.value - 1);
|
|
19033
|
+
const hasNextStep = computed(() => currentStepIndex.value < totalSteps.value - 1);
|
|
19034
|
+
const hasPrevStep = computed(() => currentStepIndex.value > 0);
|
|
19035
|
+
async function startTutorial(tutorial) {
|
|
19036
|
+
currentTutorial.value = tutorial;
|
|
19037
|
+
currentStepIndex.value = 0;
|
|
19038
|
+
isActive.value = true;
|
|
19039
|
+
tutorialPaused.value = false;
|
|
19040
|
+
const step = currentTutorial.value.steps[0];
|
|
19041
|
+
if (step == null ? void 0 : step.onEnter) {
|
|
19042
|
+
await step.onEnter();
|
|
19043
|
+
}
|
|
19044
|
+
}
|
|
19045
|
+
async function nextStep() {
|
|
19046
|
+
if (!currentTutorial.value || isTransitioning.value)
|
|
19047
|
+
return;
|
|
19048
|
+
if (currentStepIndex.value >= totalSteps.value - 1) {
|
|
19049
|
+
await completeTutorial();
|
|
19050
|
+
return;
|
|
19051
|
+
}
|
|
19052
|
+
isTransitioning.value = true;
|
|
19053
|
+
const currentStepObj = currentStep.value;
|
|
19054
|
+
if (currentStepObj == null ? void 0 : currentStepObj.onExit) {
|
|
19055
|
+
await currentStepObj.onExit();
|
|
19056
|
+
}
|
|
19057
|
+
currentStepIndex.value++;
|
|
19058
|
+
const nextStepObj = currentStep.value;
|
|
19059
|
+
if (nextStepObj == null ? void 0 : nextStepObj.onEnter) {
|
|
19060
|
+
await nextStepObj.onEnter();
|
|
19061
|
+
}
|
|
19062
|
+
isTransitioning.value = false;
|
|
19063
|
+
}
|
|
19064
|
+
async function prevStep() {
|
|
19065
|
+
if (!currentTutorial.value || isTransitioning.value || currentStepIndex.value <= 0)
|
|
19066
|
+
return;
|
|
19067
|
+
isTransitioning.value = true;
|
|
19068
|
+
const currentStepObj = currentStep.value;
|
|
19069
|
+
if (currentStepObj == null ? void 0 : currentStepObj.onExit) {
|
|
19070
|
+
await currentStepObj.onExit();
|
|
19071
|
+
}
|
|
19072
|
+
currentStepIndex.value--;
|
|
19073
|
+
const prevStepObj = currentStep.value;
|
|
19074
|
+
if (prevStepObj == null ? void 0 : prevStepObj.onEnter) {
|
|
19075
|
+
await prevStepObj.onEnter();
|
|
19076
|
+
}
|
|
19077
|
+
isTransitioning.value = false;
|
|
19078
|
+
}
|
|
19079
|
+
async function goToStep(index2) {
|
|
19080
|
+
if (!currentTutorial.value || isTransitioning.value)
|
|
19081
|
+
return;
|
|
19082
|
+
if (index2 < 0 || index2 >= totalSteps.value)
|
|
19083
|
+
return;
|
|
19084
|
+
isTransitioning.value = true;
|
|
19085
|
+
const currentStepObj = currentStep.value;
|
|
19086
|
+
if (currentStepObj == null ? void 0 : currentStepObj.onExit) {
|
|
19087
|
+
await currentStepObj.onExit();
|
|
19088
|
+
}
|
|
19089
|
+
currentStepIndex.value = index2;
|
|
19090
|
+
const newStepObj = currentStep.value;
|
|
19091
|
+
if (newStepObj == null ? void 0 : newStepObj.onEnter) {
|
|
19092
|
+
await newStepObj.onEnter();
|
|
19093
|
+
}
|
|
19094
|
+
isTransitioning.value = false;
|
|
19095
|
+
}
|
|
19096
|
+
async function completeTutorial() {
|
|
19097
|
+
if (currentTutorial.value) {
|
|
19098
|
+
completedTutorials.value.add(currentTutorial.value.id);
|
|
19099
|
+
const lastStep = currentStep.value;
|
|
19100
|
+
if (lastStep == null ? void 0 : lastStep.onExit) {
|
|
19101
|
+
await lastStep.onExit();
|
|
19102
|
+
}
|
|
19103
|
+
}
|
|
19104
|
+
endTutorial();
|
|
19105
|
+
}
|
|
19106
|
+
function endTutorial() {
|
|
19107
|
+
isActive.value = false;
|
|
19108
|
+
currentTutorial.value = null;
|
|
19109
|
+
currentStepIndex.value = 0;
|
|
19110
|
+
isTransitioning.value = false;
|
|
19111
|
+
tutorialPaused.value = false;
|
|
19112
|
+
}
|
|
19113
|
+
function pauseTutorial() {
|
|
19114
|
+
tutorialPaused.value = true;
|
|
19115
|
+
}
|
|
19116
|
+
function resumeTutorial() {
|
|
19117
|
+
tutorialPaused.value = false;
|
|
19118
|
+
}
|
|
19119
|
+
function isTutorialCompleted(tutorialId) {
|
|
19120
|
+
return completedTutorials.value.has(tutorialId);
|
|
19121
|
+
}
|
|
19122
|
+
function resetCompletedTutorials() {
|
|
19123
|
+
completedTutorials.value.clear();
|
|
19124
|
+
}
|
|
19125
|
+
async function onActionCompleted() {
|
|
19126
|
+
if (!currentStep.value)
|
|
19127
|
+
return;
|
|
19128
|
+
if (currentStep.value.action && currentStep.value.action !== "observe") {
|
|
19129
|
+
await nextStep();
|
|
19130
|
+
}
|
|
19131
|
+
}
|
|
19132
|
+
return {
|
|
19133
|
+
// State
|
|
19134
|
+
isActive,
|
|
19135
|
+
currentTutorial,
|
|
19136
|
+
currentStepIndex,
|
|
19137
|
+
isTransitioning,
|
|
19138
|
+
completedTutorials,
|
|
19139
|
+
tutorialPaused,
|
|
19140
|
+
// Computed
|
|
19141
|
+
currentStep,
|
|
19142
|
+
totalSteps,
|
|
19143
|
+
progress,
|
|
19144
|
+
isFirstStep,
|
|
19145
|
+
isLastStep,
|
|
19146
|
+
hasNextStep,
|
|
19147
|
+
hasPrevStep,
|
|
19148
|
+
// Actions
|
|
19149
|
+
startTutorial,
|
|
19150
|
+
nextStep,
|
|
19151
|
+
prevStep,
|
|
19152
|
+
goToStep,
|
|
19153
|
+
completeTutorial,
|
|
19154
|
+
endTutorial,
|
|
19155
|
+
pauseTutorial,
|
|
19156
|
+
resumeTutorial,
|
|
19157
|
+
isTutorialCompleted,
|
|
19158
|
+
resetCompletedTutorials,
|
|
19159
|
+
onActionCompleted
|
|
19160
|
+
};
|
|
19161
|
+
});
|
|
19162
|
+
const FLOW_ID_STORAGE_KEY = "last_flow_id";
|
|
19163
|
+
const useFlowStore = /* @__PURE__ */ defineStore("flow", {
|
|
19164
|
+
state: () => {
|
|
19165
|
+
const savedFlowId = sessionStorage.getItem(FLOW_ID_STORAGE_KEY);
|
|
19166
|
+
const initialFlowId = savedFlowId ? parseInt(savedFlowId) : -1;
|
|
19167
|
+
return {
|
|
19168
|
+
flowId: initialFlowId,
|
|
19169
|
+
vueFlowInstance: null
|
|
19170
|
+
};
|
|
19171
|
+
},
|
|
19172
|
+
getters: {
|
|
19173
|
+
currentFlowId: (state) => state.flowId
|
|
19174
|
+
},
|
|
19175
|
+
actions: {
|
|
19176
|
+
setFlowId(flowId) {
|
|
19177
|
+
this.flowId = flowId;
|
|
19178
|
+
try {
|
|
19179
|
+
sessionStorage.setItem(FLOW_ID_STORAGE_KEY, flowId.toString());
|
|
19180
|
+
} catch (error) {
|
|
19181
|
+
console.warn("Failed to store flow ID in session storage:", error);
|
|
19182
|
+
}
|
|
19183
|
+
},
|
|
19184
|
+
setVueFlowInstance(vueFlowInstance) {
|
|
19185
|
+
this.vueFlowInstance = vueFlowInstance;
|
|
19186
|
+
},
|
|
19187
|
+
getVueFlowInstance() {
|
|
19188
|
+
return this.vueFlowInstance;
|
|
19189
|
+
}
|
|
19190
|
+
}
|
|
19191
|
+
});
|
|
19192
|
+
const flowfileCorebaseURL = "http://localhost:63578/";
|
|
19193
|
+
axios$1.defaults.baseURL = flowfileCorebaseURL;
|
|
19194
|
+
axios$1.defaults.withCredentials = true;
|
|
19195
|
+
axios$1.interceptors.request.use(
|
|
19196
|
+
async (config) => {
|
|
19197
|
+
if (config.headers && config.headers["X-Skip-Auth-Header"]) {
|
|
19198
|
+
delete config.headers["X-Skip-Auth-Header"];
|
|
19199
|
+
return config;
|
|
19200
|
+
}
|
|
19201
|
+
try {
|
|
19202
|
+
const token = await authService.getToken();
|
|
19203
|
+
if (token) {
|
|
19204
|
+
config.headers = config.headers || {};
|
|
19205
|
+
config.headers.Authorization = `Bearer ${token}`;
|
|
19206
|
+
}
|
|
19207
|
+
return config;
|
|
19208
|
+
} catch (error) {
|
|
19209
|
+
console.error("Error in request interceptor:", error);
|
|
19210
|
+
return config;
|
|
19211
|
+
}
|
|
19212
|
+
},
|
|
19213
|
+
(error) => {
|
|
19214
|
+
return Promise.reject(error);
|
|
19215
|
+
}
|
|
19216
|
+
);
|
|
19217
|
+
axios$1.interceptors.response.use(
|
|
19218
|
+
(response) => {
|
|
19219
|
+
return response;
|
|
19220
|
+
},
|
|
19221
|
+
async (error) => {
|
|
19222
|
+
var _a;
|
|
19223
|
+
const originalRequest = error.config;
|
|
19224
|
+
if (((_a = error.response) == null ? void 0 : _a.status) === 401 && !originalRequest._retry) {
|
|
19225
|
+
originalRequest._retry = true;
|
|
19226
|
+
try {
|
|
19227
|
+
await authService.getToken();
|
|
19228
|
+
return axios$1(originalRequest);
|
|
19229
|
+
} catch (refreshError) {
|
|
19230
|
+
console.error("Token refresh failed:", refreshError);
|
|
19231
|
+
authService.logout();
|
|
19232
|
+
return Promise.reject(error);
|
|
19233
|
+
}
|
|
19234
|
+
}
|
|
19235
|
+
return Promise.reject(error);
|
|
19236
|
+
}
|
|
19237
|
+
);
|
|
19238
|
+
class NodeApi {
|
|
19239
|
+
/**
|
|
19240
|
+
* Get node data for a specific node
|
|
19241
|
+
*/
|
|
19242
|
+
static async getNodeData(flowId, nodeId) {
|
|
19243
|
+
const response = await axios$1.get("/node", {
|
|
19244
|
+
params: { flow_id: flowId, node_id: nodeId },
|
|
19245
|
+
headers: { accept: "application/json" }
|
|
19246
|
+
});
|
|
19247
|
+
return response.data;
|
|
19248
|
+
}
|
|
19249
|
+
/**
|
|
19250
|
+
* Get table example/preview data for a node
|
|
19251
|
+
*/
|
|
19252
|
+
static async getTableExample(flowId, nodeId) {
|
|
19253
|
+
const response = await axios$1.get("/node/data", {
|
|
19254
|
+
params: { flow_id: flowId, node_id: nodeId },
|
|
19255
|
+
headers: { accept: "application/json" }
|
|
19256
|
+
});
|
|
19257
|
+
return response.data;
|
|
19258
|
+
}
|
|
19259
|
+
/**
|
|
19260
|
+
* Get downstream node IDs for a given node
|
|
19261
|
+
*/
|
|
19262
|
+
static async getDownstreamNodeIds(flowId, nodeId) {
|
|
19263
|
+
const response = await axios$1.get("/node/downstream_node_ids", {
|
|
19264
|
+
params: { flow_id: flowId, node_id: nodeId },
|
|
19265
|
+
headers: { accept: "application/json" }
|
|
19266
|
+
});
|
|
19267
|
+
return response.data;
|
|
19268
|
+
}
|
|
19269
|
+
/**
|
|
19270
|
+
* Get node description
|
|
19271
|
+
*/
|
|
19272
|
+
static async getNodeDescription(flowId, nodeId) {
|
|
19273
|
+
const response = await axios$1.get("/node/description", {
|
|
19274
|
+
params: { node_id: nodeId, flow_id: flowId }
|
|
19275
|
+
});
|
|
19276
|
+
return response.data;
|
|
19277
|
+
}
|
|
19278
|
+
/**
|
|
19279
|
+
* Set/update node description
|
|
19280
|
+
*/
|
|
19281
|
+
static async setNodeDescription(flowId, nodeId, description) {
|
|
19282
|
+
const response = await axios$1.post("/node/description/", JSON.stringify(description), {
|
|
19283
|
+
params: { flow_id: flowId, node_id: nodeId },
|
|
19284
|
+
headers: { "Content-Type": "application/json" }
|
|
19285
|
+
});
|
|
19286
|
+
return response.data;
|
|
19287
|
+
}
|
|
19288
|
+
/**
|
|
19289
|
+
* Update node settings directly
|
|
19290
|
+
*/
|
|
19291
|
+
static async updateSettingsDirectly(nodeType, inputData) {
|
|
19292
|
+
const response = await axios$1.post("/update_settings/", inputData, {
|
|
19293
|
+
params: { node_type: nodeType }
|
|
19294
|
+
});
|
|
19295
|
+
return response.data;
|
|
19296
|
+
}
|
|
19297
|
+
/**
|
|
19298
|
+
* Update user-defined node settings
|
|
19299
|
+
*/
|
|
19300
|
+
static async updateUserDefinedSettings(nodeType, inputData) {
|
|
19301
|
+
const response = await axios$1.post(
|
|
19302
|
+
"/user_defined_components/update_user_defined_node/",
|
|
19303
|
+
inputData,
|
|
19304
|
+
{
|
|
19305
|
+
params: { node_type: nodeType }
|
|
19306
|
+
}
|
|
19307
|
+
);
|
|
19308
|
+
return response.data;
|
|
19309
|
+
}
|
|
19310
|
+
}
|
|
19311
|
+
class ExpressionsApi {
|
|
19312
|
+
/**
|
|
19313
|
+
* Fetch all available expressions overview/documentation
|
|
19314
|
+
*/
|
|
19315
|
+
static async getExpressionsOverview() {
|
|
19316
|
+
const response = await axios$1.get("/editor/expression_doc");
|
|
19317
|
+
return response.data;
|
|
19318
|
+
}
|
|
19319
|
+
}
|
|
19320
|
+
const useResultsStore = /* @__PURE__ */ defineStore("results", {
|
|
19321
|
+
state: () => ({
|
|
19322
|
+
runResults: {},
|
|
19323
|
+
runNodeResults: {},
|
|
19324
|
+
runNodeValidations: {},
|
|
19325
|
+
currentRunResult: null,
|
|
19326
|
+
resultVersion: 0
|
|
19327
|
+
}),
|
|
19328
|
+
getters: {
|
|
19329
|
+
getCurrentRunResult: (state) => state.currentRunResult
|
|
19330
|
+
},
|
|
19331
|
+
actions: {
|
|
19332
|
+
// ========== Result Cache Management ==========
|
|
19333
|
+
initializeResultCache(flowId) {
|
|
19334
|
+
if (!this.runNodeResults[flowId]) {
|
|
19335
|
+
this.runNodeResults[flowId] = {};
|
|
19336
|
+
}
|
|
19337
|
+
},
|
|
19338
|
+
setNodeResult(flowId, nodeId, result) {
|
|
19339
|
+
this.initializeResultCache(flowId);
|
|
19340
|
+
this.runNodeResults[flowId][nodeId] = result;
|
|
19341
|
+
},
|
|
19342
|
+
getNodeResult(flowId, nodeId) {
|
|
19343
|
+
var _a;
|
|
19344
|
+
return (_a = this.runNodeResults[flowId]) == null ? void 0 : _a[nodeId];
|
|
19345
|
+
},
|
|
19346
|
+
resetNodeResult() {
|
|
19347
|
+
console.log("Clearing node results");
|
|
19348
|
+
this.runNodeResults = {};
|
|
19349
|
+
},
|
|
19350
|
+
clearFlowResults(flowId) {
|
|
19351
|
+
if (this.runNodeResults[flowId]) {
|
|
19352
|
+
delete this.runNodeResults[flowId];
|
|
19353
|
+
}
|
|
19354
|
+
},
|
|
19355
|
+
// ========== Validation Cache Management ==========
|
|
19356
|
+
initializeValidationCache(flowId) {
|
|
19357
|
+
if (!this.runNodeValidations[flowId]) {
|
|
19358
|
+
this.runNodeValidations[flowId] = {};
|
|
19359
|
+
}
|
|
19360
|
+
},
|
|
19361
|
+
setNodeValidation(flowId, nodeId, nodeValidationInput) {
|
|
19362
|
+
if (typeof nodeId === "string") {
|
|
19363
|
+
nodeId = parseInt(nodeId);
|
|
19364
|
+
}
|
|
19365
|
+
this.initializeValidationCache(flowId);
|
|
19366
|
+
const nodeValidation = {
|
|
19367
|
+
...nodeValidationInput,
|
|
19368
|
+
validationTime: Date.now() / 1e3
|
|
19369
|
+
};
|
|
19370
|
+
this.runNodeValidations[flowId][nodeId] = nodeValidation;
|
|
19371
|
+
},
|
|
19372
|
+
resetNodeValidation() {
|
|
19373
|
+
this.runNodeValidations = {};
|
|
19374
|
+
},
|
|
19375
|
+
getNodeValidation(flowId, nodeId) {
|
|
19376
|
+
var _a;
|
|
19377
|
+
return ((_a = this.runNodeValidations[flowId]) == null ? void 0 : _a[nodeId]) || {
|
|
19378
|
+
isValid: true,
|
|
19379
|
+
error: "",
|
|
19380
|
+
validationTime: 0
|
|
19381
|
+
};
|
|
19382
|
+
},
|
|
19383
|
+
// ========== Run Results Management ==========
|
|
19384
|
+
insertRunResult(runResult) {
|
|
19385
|
+
this.currentRunResult = runResult;
|
|
19386
|
+
this.runResults[runResult.flow_id] = runResult;
|
|
19387
|
+
this.initializeResultCache(runResult.flow_id);
|
|
19388
|
+
runResult.node_step_result.forEach((nodeResult) => {
|
|
19389
|
+
this.runNodeResults[runResult.flow_id][nodeResult.node_id] = nodeResult;
|
|
19390
|
+
});
|
|
19391
|
+
this.resultVersion++;
|
|
19392
|
+
},
|
|
19393
|
+
resetRunResults() {
|
|
19394
|
+
this.runNodeResults = {};
|
|
19395
|
+
this.runResults = {};
|
|
19396
|
+
this.currentRunResult = null;
|
|
19397
|
+
},
|
|
19398
|
+
getRunResult(flowId) {
|
|
19399
|
+
return this.runResults[flowId] || null;
|
|
19400
|
+
}
|
|
19401
|
+
}
|
|
19402
|
+
});
|
|
19403
|
+
const useEditorStore = /* @__PURE__ */ defineStore("editor", {
|
|
19404
|
+
state: () => ({
|
|
19405
|
+
// Drawer state
|
|
19406
|
+
isDrawerOpen: false,
|
|
19407
|
+
isAnalysisOpen: false,
|
|
19408
|
+
activeDrawerComponent: shallowRef(null),
|
|
19409
|
+
drawerProps: ref({}),
|
|
19410
|
+
drawCloseFunction: null,
|
|
19411
|
+
// Editor state
|
|
19412
|
+
initialEditorData: "",
|
|
19413
|
+
inputCode: "",
|
|
19414
|
+
// Log viewer state
|
|
19415
|
+
hideLogViewerForThisRun: false,
|
|
19416
|
+
isShowingLogViewer: false,
|
|
19417
|
+
isStreamingLogs: false,
|
|
19418
|
+
displayLogViewer: true,
|
|
19419
|
+
// Code generator state
|
|
19420
|
+
showCodeGenerator: false,
|
|
19421
|
+
// Run state
|
|
19422
|
+
isRunning: false,
|
|
19423
|
+
showFlowResult: false,
|
|
19424
|
+
tableVisible: false
|
|
19425
|
+
}),
|
|
19426
|
+
getters: {
|
|
19427
|
+
drawerOpen() {
|
|
19428
|
+
return !!this.activeDrawerComponent;
|
|
19429
|
+
}
|
|
19430
|
+
},
|
|
19431
|
+
actions: {
|
|
19432
|
+
// ========== Drawer Management ==========
|
|
19433
|
+
async executeDrawCloseFunction() {
|
|
19434
|
+
console.log("Executing draw close function");
|
|
19435
|
+
if (this.drawCloseFunction) {
|
|
19436
|
+
this.drawCloseFunction();
|
|
19437
|
+
}
|
|
19438
|
+
},
|
|
19439
|
+
setCloseFunction(f2) {
|
|
19440
|
+
this.drawCloseFunction = f2;
|
|
19441
|
+
},
|
|
19442
|
+
openDrawer(component2, nodeTitleInfo, props = {}) {
|
|
19443
|
+
this.activeDrawerComponent = component2;
|
|
19444
|
+
this.drawerProps = { ...nodeTitleInfo, ...props };
|
|
19445
|
+
this.isDrawerOpen = true;
|
|
19446
|
+
},
|
|
19447
|
+
closeDrawer() {
|
|
19448
|
+
this.activeDrawerComponent = null;
|
|
19449
|
+
if (this.drawCloseFunction)
|
|
19450
|
+
;
|
|
19451
|
+
},
|
|
19452
|
+
toggleDrawer() {
|
|
19453
|
+
if (this.isDrawerOpen && this.drawCloseFunction) {
|
|
19454
|
+
this.pushNodeData();
|
|
19455
|
+
}
|
|
19456
|
+
this.isDrawerOpen = !this.isDrawerOpen;
|
|
19457
|
+
},
|
|
19458
|
+
pushNodeData() {
|
|
19459
|
+
if (this.drawCloseFunction && !this.isRunning) {
|
|
19460
|
+
this.drawCloseFunction();
|
|
19461
|
+
this.drawCloseFunction = null;
|
|
19462
|
+
}
|
|
19463
|
+
},
|
|
19464
|
+
openAnalysisDrawer(closeFunction) {
|
|
19465
|
+
console.log("openAnalysisDrawer in editor-store.ts");
|
|
19466
|
+
if (this.isAnalysisOpen) {
|
|
19467
|
+
this.pushNodeData();
|
|
19468
|
+
}
|
|
19469
|
+
if (closeFunction) {
|
|
19470
|
+
this.drawCloseFunction = closeFunction;
|
|
19471
|
+
}
|
|
19472
|
+
this.isAnalysisOpen = true;
|
|
19473
|
+
},
|
|
19474
|
+
closeAnalysisDrawer() {
|
|
19475
|
+
this.isAnalysisOpen = false;
|
|
19476
|
+
if (this.drawCloseFunction) {
|
|
19477
|
+
console.log("closeDrawer in editor-store.ts");
|
|
19478
|
+
this.pushNodeData();
|
|
19479
|
+
}
|
|
19480
|
+
},
|
|
19481
|
+
// ========== Code Generator ==========
|
|
19482
|
+
toggleCodeGenerator() {
|
|
19483
|
+
this.showCodeGenerator = !this.showCodeGenerator;
|
|
19484
|
+
},
|
|
19485
|
+
setCodeGeneratorVisibility(visible) {
|
|
19486
|
+
this.showCodeGenerator = visible;
|
|
19487
|
+
},
|
|
19488
|
+
// ========== Log Viewer ==========
|
|
19489
|
+
showLogViewer() {
|
|
19490
|
+
console.log("triggered show log viewer");
|
|
19491
|
+
this.isShowingLogViewer = this.displayLogViewer;
|
|
19492
|
+
},
|
|
19493
|
+
hideLogViewer() {
|
|
19494
|
+
this.isShowingLogViewer = false;
|
|
19495
|
+
},
|
|
19496
|
+
toggleLogViewer() {
|
|
19497
|
+
console.log("triggered toggle log viewer");
|
|
19498
|
+
this.isShowingLogViewer = !this.isShowingLogViewer;
|
|
19499
|
+
},
|
|
19500
|
+
updateLogViewerVisibility(showResult) {
|
|
19501
|
+
this.isShowingLogViewer = this.displayLogViewer && showResult && !this.hideLogViewerForThisRun;
|
|
19502
|
+
},
|
|
19503
|
+
// ========== Editor Data ==========
|
|
19504
|
+
setInitialEditorData(editorDataString) {
|
|
19505
|
+
this.initialEditorData = editorDataString;
|
|
19506
|
+
},
|
|
19507
|
+
getInitialEditorData() {
|
|
19508
|
+
return this.initialEditorData;
|
|
19509
|
+
},
|
|
19510
|
+
setInputCode(newCode) {
|
|
19511
|
+
this.inputCode = newCode;
|
|
19512
|
+
},
|
|
19513
|
+
// ========== Flow Result Display ==========
|
|
19514
|
+
setShowFlowResult(show) {
|
|
19515
|
+
this.showFlowResult = show;
|
|
19516
|
+
},
|
|
19517
|
+
setTableVisible(visible) {
|
|
19518
|
+
this.tableVisible = visible;
|
|
19519
|
+
},
|
|
19520
|
+
setIsRunning(running) {
|
|
19521
|
+
this.isRunning = running;
|
|
19522
|
+
}
|
|
19523
|
+
}
|
|
19524
|
+
});
|
|
19525
|
+
const useNodeStore = /* @__PURE__ */ defineStore("node", {
|
|
19526
|
+
state: () => ({
|
|
19527
|
+
nodeId: -1,
|
|
19528
|
+
previousNodeId: -1,
|
|
19529
|
+
nodeValidateFuncs: /* @__PURE__ */ new Map(),
|
|
19530
|
+
nodeData: null,
|
|
19531
|
+
nodeExists: false,
|
|
19532
|
+
isLoaded: false,
|
|
19533
|
+
sizeDataPreview: 300,
|
|
19534
|
+
dataTypes: ["String", "Datetime", "Int64", "Int32", "Int16", "Float64", "Float32", "Boolean"],
|
|
19535
|
+
nodeDescriptions: {},
|
|
19536
|
+
allExpressions: null
|
|
19537
|
+
}),
|
|
19538
|
+
getters: {
|
|
19539
|
+
currentNodeId: (state) => state.nodeId,
|
|
19540
|
+
currentNodeData: (state) => state.nodeData,
|
|
19541
|
+
// Backward compatibility: read-only getters (use snake_case for legacy)
|
|
19542
|
+
/** @deprecated Use `nodeId` (camelCase) instead. This getter is read-only. */
|
|
19543
|
+
node_id: (state) => state.nodeId,
|
|
19544
|
+
/** @deprecated Use `isLoaded` (camelCase) instead. This getter is read-only. */
|
|
19545
|
+
is_loaded: (state) => state.isLoaded,
|
|
19546
|
+
// Proxy getters to other stores
|
|
19547
|
+
/** @deprecated Use `useFlowStore().flowId` directly. This getter is read-only. */
|
|
19548
|
+
flow_id() {
|
|
19549
|
+
return useFlowStore().flowId;
|
|
19550
|
+
},
|
|
19551
|
+
/** @deprecated Use `useFlowStore().vueFlowInstance` directly. This getter is read-only. */
|
|
19552
|
+
vueFlowInstance() {
|
|
19553
|
+
return useFlowStore().vueFlowInstance;
|
|
19554
|
+
},
|
|
19555
|
+
/** @deprecated Use `useEditorStore().isRunning` directly. This getter is read-only. */
|
|
19556
|
+
isRunning() {
|
|
19557
|
+
var _a;
|
|
19558
|
+
return ((_a = useEditorStore()) == null ? void 0 : _a.isRunning) || false;
|
|
19559
|
+
},
|
|
19560
|
+
/** @deprecated Use `useEditorStore().isDrawerOpen` directly. This getter is read-only. */
|
|
19561
|
+
isDrawerOpen() {
|
|
19562
|
+
var _a;
|
|
19563
|
+
return ((_a = useEditorStore()) == null ? void 0 : _a.isDrawerOpen) || false;
|
|
19564
|
+
},
|
|
19565
|
+
/** @deprecated Use `useEditorStore().activeDrawerComponent` directly. This getter is read-only. */
|
|
19566
|
+
activeDrawerComponent() {
|
|
19567
|
+
var _a;
|
|
19568
|
+
return (_a = useEditorStore()) == null ? void 0 : _a.activeDrawerComponent;
|
|
19569
|
+
},
|
|
19570
|
+
/** @deprecated Use `useEditorStore().drawerProps` directly. This getter is read-only. */
|
|
19571
|
+
drawerProps() {
|
|
19572
|
+
var _a;
|
|
19573
|
+
return ((_a = useEditorStore()) == null ? void 0 : _a.drawerProps) || {};
|
|
19574
|
+
},
|
|
19575
|
+
/** @deprecated Use `useEditorStore().showCodeGenerator` directly. This getter is read-only. */
|
|
19576
|
+
showCodeGenerator() {
|
|
19577
|
+
var _a;
|
|
19578
|
+
return ((_a = useEditorStore()) == null ? void 0 : _a.showCodeGenerator) || false;
|
|
19579
|
+
},
|
|
19580
|
+
/** @deprecated Use `useEditorStore().showFlowResult` directly. This getter is read-only. */
|
|
19581
|
+
showFlowResult() {
|
|
19582
|
+
var _a;
|
|
19583
|
+
return ((_a = useEditorStore()) == null ? void 0 : _a.showFlowResult) || false;
|
|
19584
|
+
},
|
|
19585
|
+
/** @deprecated Use `useEditorStore().isShowingLogViewer` directly. This getter is read-only. */
|
|
19586
|
+
isShowingLogViewer() {
|
|
19587
|
+
var _a;
|
|
19588
|
+
return ((_a = useEditorStore()) == null ? void 0 : _a.isShowingLogViewer) || false;
|
|
19589
|
+
},
|
|
19590
|
+
/** @deprecated Use `useEditorStore().hideLogViewerForThisRun` directly. This getter is read-only. */
|
|
19591
|
+
hideLogViewerForThisRun() {
|
|
19592
|
+
var _a;
|
|
19593
|
+
return ((_a = useEditorStore()) == null ? void 0 : _a.hideLogViewerForThisRun) || false;
|
|
19594
|
+
},
|
|
19595
|
+
/** @deprecated Use `useEditorStore().displayLogViewer` directly. This getter is read-only. */
|
|
19596
|
+
displayLogViewer() {
|
|
19597
|
+
const editorStore = useEditorStore();
|
|
19598
|
+
return (editorStore == null ? void 0 : editorStore.displayLogViewer) !== void 0 ? editorStore.displayLogViewer : true;
|
|
19599
|
+
},
|
|
19600
|
+
/** @deprecated Use `useEditorStore().inputCode` directly. This getter is read-only. */
|
|
19601
|
+
inputCode() {
|
|
19602
|
+
var _a;
|
|
19603
|
+
return ((_a = useEditorStore()) == null ? void 0 : _a.inputCode) || "";
|
|
19604
|
+
},
|
|
19605
|
+
/** @deprecated Use `useResultsStore().currentRunResult` directly. This getter is read-only. */
|
|
19606
|
+
currentRunResult() {
|
|
19607
|
+
var _a;
|
|
19608
|
+
return (_a = useResultsStore()) == null ? void 0 : _a.currentRunResult;
|
|
19609
|
+
},
|
|
19610
|
+
/** @deprecated Use `useResultsStore().runResults` directly. This getter is read-only. */
|
|
19611
|
+
runResults() {
|
|
19612
|
+
var _a;
|
|
19613
|
+
return ((_a = useResultsStore()) == null ? void 0 : _a.runResults) || {};
|
|
19614
|
+
}
|
|
19615
|
+
},
|
|
19616
|
+
actions: {
|
|
19617
|
+
// ========== Node Data Management ==========
|
|
19618
|
+
async getNodeData(nodeId, useCache2 = true) {
|
|
19619
|
+
const flowStore = useFlowStore();
|
|
19620
|
+
if (this.nodeId === nodeId && useCache2) {
|
|
19621
|
+
if (this.nodeData) {
|
|
19622
|
+
this.isLoaded = true;
|
|
19623
|
+
return this.nodeData;
|
|
19624
|
+
}
|
|
19625
|
+
}
|
|
19626
|
+
try {
|
|
19627
|
+
console.log("Getting node data");
|
|
19628
|
+
const data = await NodeApi.getNodeData(flowStore.flowId, nodeId);
|
|
19629
|
+
this.nodeData = data;
|
|
19630
|
+
this.isLoaded = true;
|
|
19631
|
+
this.nodeExists = true;
|
|
19632
|
+
return this.nodeData;
|
|
19633
|
+
} catch (error) {
|
|
19634
|
+
console.error("Error fetching node data:", error);
|
|
19635
|
+
this.nodeData = null;
|
|
19636
|
+
this.isLoaded = false;
|
|
19637
|
+
this.nodeExists = false;
|
|
19638
|
+
return null;
|
|
19639
|
+
}
|
|
19640
|
+
},
|
|
19641
|
+
async reloadCurrentNodeData() {
|
|
19642
|
+
return this.getNodeData(this.nodeId, false);
|
|
19643
|
+
},
|
|
19644
|
+
getCurrentNodeData() {
|
|
19645
|
+
return this.nodeData;
|
|
19646
|
+
},
|
|
19647
|
+
async getTableExample(flowId, nodeId) {
|
|
19648
|
+
try {
|
|
19649
|
+
return await NodeApi.getTableExample(flowId, nodeId);
|
|
19650
|
+
} catch (error) {
|
|
19651
|
+
console.error("Error fetching table example:", error);
|
|
19652
|
+
return null;
|
|
19653
|
+
}
|
|
19654
|
+
},
|
|
19655
|
+
// ========== Node ID Management ==========
|
|
19656
|
+
setFlowIdAndNodeId(flowId, nodeId) {
|
|
19657
|
+
const flowStore = useFlowStore();
|
|
19658
|
+
if (this.nodeId === nodeId && flowStore.flowId === flowId) {
|
|
19659
|
+
return;
|
|
19660
|
+
}
|
|
19661
|
+
console.log("Automatically pushing the node data");
|
|
19662
|
+
if (flowStore.flowId !== flowId) {
|
|
19663
|
+
flowStore.setFlowId(flowId);
|
|
19664
|
+
}
|
|
19665
|
+
this.nodeId = nodeId;
|
|
19666
|
+
},
|
|
19667
|
+
doReset() {
|
|
19668
|
+
this.isLoaded = false;
|
|
19669
|
+
},
|
|
19670
|
+
// ========== Node Validation ==========
|
|
19671
|
+
setNodeValidateFunc(nodeId, func) {
|
|
19672
|
+
if (typeof nodeId === "string") {
|
|
19673
|
+
nodeId = parseInt(nodeId);
|
|
19674
|
+
}
|
|
19675
|
+
this.nodeValidateFuncs.set(nodeId, func);
|
|
19676
|
+
},
|
|
19677
|
+
async validateNode(nodeId) {
|
|
19678
|
+
if (typeof nodeId === "string") {
|
|
19679
|
+
nodeId = parseInt(nodeId);
|
|
19680
|
+
}
|
|
19681
|
+
const func = this.nodeValidateFuncs.get(nodeId);
|
|
19682
|
+
if (func) {
|
|
19683
|
+
func();
|
|
19684
|
+
}
|
|
19685
|
+
},
|
|
19686
|
+
// ========== Node Descriptions ==========
|
|
19687
|
+
initializeDescriptionCache(flowId) {
|
|
19688
|
+
if (!this.nodeDescriptions[flowId]) {
|
|
19689
|
+
this.nodeDescriptions[flowId] = {};
|
|
19690
|
+
}
|
|
19691
|
+
},
|
|
19692
|
+
cacheNodeDescriptionDict(flowId, nodeId, description) {
|
|
19693
|
+
this.initializeDescriptionCache(flowId);
|
|
19694
|
+
this.nodeDescriptions[flowId][nodeId] = description;
|
|
19695
|
+
if (this.nodeData && this.nodeData.node_id === nodeId && this.nodeData.setting_input) {
|
|
19696
|
+
this.nodeData.setting_input.description = description;
|
|
19697
|
+
}
|
|
19698
|
+
},
|
|
19699
|
+
clearNodeDescriptionCache(flowId, nodeId) {
|
|
19700
|
+
if (this.nodeDescriptions[flowId] && this.nodeDescriptions[flowId][nodeId]) {
|
|
19701
|
+
delete this.nodeDescriptions[flowId][nodeId];
|
|
19702
|
+
}
|
|
19703
|
+
},
|
|
19704
|
+
clearFlowDescriptionCache(flowId) {
|
|
19705
|
+
if (this.nodeDescriptions[flowId]) {
|
|
19706
|
+
delete this.nodeDescriptions[flowId];
|
|
19707
|
+
}
|
|
19708
|
+
},
|
|
19709
|
+
clearAllDescriptionCaches() {
|
|
19710
|
+
this.nodeDescriptions = {};
|
|
19711
|
+
},
|
|
19712
|
+
async getNodeDescription(nodeId, forceRefresh = false) {
|
|
19713
|
+
var _a, _b;
|
|
19714
|
+
const flowStore = useFlowStore();
|
|
19715
|
+
this.initializeDescriptionCache(flowStore.flowId);
|
|
19716
|
+
if (!forceRefresh && ((_a = this.nodeDescriptions[flowStore.flowId]) == null ? void 0 : _a[nodeId])) {
|
|
19717
|
+
return this.nodeDescriptions[flowStore.flowId][nodeId];
|
|
19718
|
+
}
|
|
19719
|
+
try {
|
|
19720
|
+
const description = await NodeApi.getNodeDescription(flowStore.flowId, nodeId);
|
|
19721
|
+
this.cacheNodeDescriptionDict(flowStore.flowId, nodeId, description);
|
|
19722
|
+
return description;
|
|
19723
|
+
} catch (error) {
|
|
19724
|
+
console.info("Error fetching node description:", error);
|
|
19725
|
+
if ((_b = this.nodeDescriptions[flowStore.flowId]) == null ? void 0 : _b[nodeId]) {
|
|
19726
|
+
console.warn("Using cached description due to API error");
|
|
19727
|
+
return this.nodeDescriptions[flowStore.flowId][nodeId];
|
|
19728
|
+
}
|
|
19729
|
+
return "";
|
|
19730
|
+
}
|
|
19731
|
+
},
|
|
19732
|
+
async setNodeDescription(nodeId, description) {
|
|
19733
|
+
const flowStore = useFlowStore();
|
|
19734
|
+
try {
|
|
19735
|
+
this.cacheNodeDescriptionDict(flowStore.flowId, nodeId, description);
|
|
19736
|
+
const result = await NodeApi.setNodeDescription(flowStore.flowId, nodeId, description);
|
|
19737
|
+
if (result === true) {
|
|
19738
|
+
console.log("Description updated successfully");
|
|
19739
|
+
} else {
|
|
19740
|
+
console.warn("Unexpected response:", result);
|
|
19741
|
+
}
|
|
19742
|
+
} catch (error) {
|
|
19743
|
+
if (error.response) {
|
|
19744
|
+
console.error("API error:", error.response.data.message);
|
|
19745
|
+
} else if (error.request) {
|
|
19746
|
+
console.error("The request was made but no response was received");
|
|
19747
|
+
} else {
|
|
19748
|
+
console.error("Error", error.message);
|
|
19749
|
+
}
|
|
19750
|
+
throw error;
|
|
19751
|
+
}
|
|
19752
|
+
},
|
|
19753
|
+
updateNodeDescription(nodeId, description) {
|
|
19754
|
+
const flowStore = useFlowStore();
|
|
19755
|
+
this.cacheNodeDescriptionDict(flowStore.flowId, nodeId, description);
|
|
19756
|
+
},
|
|
19757
|
+
// ========== Node Settings Updates ==========
|
|
19758
|
+
async updateSettingsDirectly(inputData) {
|
|
19759
|
+
var _a, _b;
|
|
19760
|
+
const flowStore = useFlowStore();
|
|
19761
|
+
try {
|
|
19762
|
+
const node = (_a = flowStore.vueFlowInstance) == null ? void 0 : _a.findNode(String(inputData.node_id));
|
|
19763
|
+
inputData.pos_x = node.position.x;
|
|
19764
|
+
inputData.pos_y = node.position.y;
|
|
19765
|
+
const response = await NodeApi.updateSettingsDirectly(
|
|
19766
|
+
node.data.nodeTemplate.item,
|
|
19767
|
+
inputData
|
|
19768
|
+
);
|
|
19769
|
+
const downstreamNodeIds = await NodeApi.getDownstreamNodeIds(
|
|
19770
|
+
flowStore.flowId,
|
|
19771
|
+
inputData.node_id
|
|
19772
|
+
);
|
|
19773
|
+
downstreamNodeIds.map((nodeId) => {
|
|
19774
|
+
this.validateNode(nodeId);
|
|
19775
|
+
});
|
|
19776
|
+
return response;
|
|
19777
|
+
} catch (error) {
|
|
19778
|
+
console.error("Error updating settings directly:", (_b = error.response) == null ? void 0 : _b.data);
|
|
19779
|
+
throw error;
|
|
19780
|
+
}
|
|
19781
|
+
},
|
|
19782
|
+
async updateUserDefinedSettings(inputData) {
|
|
19783
|
+
var _a, _b;
|
|
19784
|
+
const flowStore = useFlowStore();
|
|
19785
|
+
try {
|
|
19786
|
+
const node = (_a = flowStore.vueFlowInstance) == null ? void 0 : _a.findNode(String(inputData.value.node_id));
|
|
19787
|
+
const nodeType = node.data.nodeTemplate.item;
|
|
19788
|
+
inputData.value.pos_x = node.position.x;
|
|
19789
|
+
inputData.value.pos_y = node.position.y;
|
|
19790
|
+
const response = await NodeApi.updateUserDefinedSettings(nodeType, inputData.value);
|
|
19791
|
+
const downstreamNodeIds = await NodeApi.getDownstreamNodeIds(
|
|
19792
|
+
flowStore.flowId,
|
|
19793
|
+
inputData.value.node_id
|
|
19794
|
+
);
|
|
19795
|
+
downstreamNodeIds.map((nodeId) => {
|
|
19796
|
+
this.validateNode(nodeId);
|
|
19797
|
+
});
|
|
19798
|
+
return response;
|
|
19799
|
+
} catch (error) {
|
|
19800
|
+
console.error("Error updating settings:", (_b = error.response) == null ? void 0 : _b.data);
|
|
19801
|
+
throw error;
|
|
19802
|
+
}
|
|
19803
|
+
},
|
|
19804
|
+
async updateSettings(inputData, inputNodeType) {
|
|
19805
|
+
var _a, _b;
|
|
19806
|
+
const flowStore = useFlowStore();
|
|
19807
|
+
try {
|
|
19808
|
+
const node = (_a = flowStore.vueFlowInstance) == null ? void 0 : _a.findNode(String(inputData.value.node_id));
|
|
19809
|
+
const nodeType = inputNodeType ?? node.data.nodeTemplate.item;
|
|
19810
|
+
inputData.value.pos_x = node.position.x;
|
|
19811
|
+
inputData.value.pos_y = node.position.y;
|
|
19812
|
+
const response = await NodeApi.updateSettingsDirectly(nodeType, inputData.value);
|
|
19813
|
+
const downstreamNodeIds = await NodeApi.getDownstreamNodeIds(
|
|
19814
|
+
flowStore.flowId,
|
|
19815
|
+
inputData.value.node_id
|
|
19816
|
+
);
|
|
19817
|
+
downstreamNodeIds.map((nodeId) => {
|
|
19818
|
+
this.validateNode(nodeId);
|
|
19819
|
+
});
|
|
19820
|
+
return response;
|
|
19821
|
+
} catch (error) {
|
|
19822
|
+
console.error("Error updating settings:", (_b = error.response) == null ? void 0 : _b.data);
|
|
19823
|
+
throw error;
|
|
19824
|
+
}
|
|
19825
|
+
},
|
|
19826
|
+
// ========== Expressions ==========
|
|
19827
|
+
async fetchExpressionsOverview() {
|
|
19828
|
+
try {
|
|
19829
|
+
const expressions = await ExpressionsApi.getExpressionsOverview();
|
|
19830
|
+
this.allExpressions = expressions;
|
|
19831
|
+
return this.allExpressions;
|
|
19832
|
+
} catch (error) {
|
|
19833
|
+
console.error("Error fetching expressions overview:", error);
|
|
19834
|
+
return [];
|
|
19835
|
+
}
|
|
19836
|
+
},
|
|
19837
|
+
async getExpressionsOverview() {
|
|
19838
|
+
if (this.allExpressions) {
|
|
19839
|
+
return this.allExpressions;
|
|
19840
|
+
} else {
|
|
19841
|
+
return await this.fetchExpressionsOverview();
|
|
19842
|
+
}
|
|
19843
|
+
},
|
|
19844
|
+
// ========== Utilities ==========
|
|
19845
|
+
getDataTypes() {
|
|
19846
|
+
return this.dataTypes;
|
|
19847
|
+
},
|
|
19848
|
+
getSizeDataPreview() {
|
|
19849
|
+
return this.sizeDataPreview;
|
|
19850
|
+
},
|
|
19851
|
+
setSizeDataPreview(newHeight) {
|
|
19852
|
+
this.sizeDataPreview = newHeight;
|
|
19853
|
+
},
|
|
19854
|
+
getEditorNodeData() {
|
|
19855
|
+
var _a;
|
|
19856
|
+
const flowStore = useFlowStore();
|
|
19857
|
+
if (this.nodeId) {
|
|
19858
|
+
return (_a = flowStore.vueFlowInstance) == null ? void 0 : _a.findNode(String(this.nodeId));
|
|
19859
|
+
}
|
|
19860
|
+
return null;
|
|
19861
|
+
},
|
|
19862
|
+
// ========== Backward Compatibility Actions (Proxy to other stores) ==========
|
|
19863
|
+
/** @deprecated Use `useFlowStore().setFlowId()` directly instead. */
|
|
19864
|
+
setFlowId(flowId) {
|
|
19865
|
+
const flowStore = useFlowStore();
|
|
19866
|
+
flowStore.setFlowId(flowId);
|
|
19867
|
+
},
|
|
19868
|
+
/** @deprecated Use `useFlowStore().setVueFlowInstance()` directly instead. */
|
|
19869
|
+
setVueFlowInstance(vueFlowInstance) {
|
|
19870
|
+
const flowStore = useFlowStore();
|
|
19871
|
+
flowStore.setVueFlowInstance(vueFlowInstance);
|
|
19872
|
+
},
|
|
19873
|
+
/** @deprecated Use `useFlowStore().getVueFlowInstance()` directly instead. */
|
|
19874
|
+
getVueFlowInstance() {
|
|
19875
|
+
const flowStore = useFlowStore();
|
|
19876
|
+
return flowStore.getVueFlowInstance();
|
|
19877
|
+
},
|
|
19878
|
+
/** @deprecated Use `useResultsStore().setNodeResult()` directly instead. */
|
|
19879
|
+
setNodeResult(nodeId, result) {
|
|
19880
|
+
const flowStore = useFlowStore();
|
|
19881
|
+
const resultsStore = useResultsStore();
|
|
19882
|
+
resultsStore.setNodeResult(flowStore.flowId, nodeId, result);
|
|
19883
|
+
},
|
|
19884
|
+
/** @deprecated Use `useResultsStore().getNodeResult()` directly instead. */
|
|
19885
|
+
getNodeResult(nodeId) {
|
|
19886
|
+
const flowStore = useFlowStore();
|
|
19887
|
+
const resultsStore = useResultsStore();
|
|
19888
|
+
return resultsStore.getNodeResult(flowStore.flowId, nodeId);
|
|
19889
|
+
},
|
|
19890
|
+
/** @deprecated Use `useResultsStore().resetNodeResult()` directly instead. */
|
|
19891
|
+
resetNodeResult() {
|
|
19892
|
+
const resultsStore = useResultsStore();
|
|
19893
|
+
resultsStore.resetNodeResult();
|
|
19894
|
+
},
|
|
19895
|
+
/** @deprecated Use `useResultsStore().clearFlowResults()` directly instead. */
|
|
19896
|
+
clearFlowResults(flowId) {
|
|
19897
|
+
const resultsStore = useResultsStore();
|
|
19898
|
+
resultsStore.clearFlowResults(flowId);
|
|
19899
|
+
},
|
|
19900
|
+
/** @deprecated Use `useResultsStore().setNodeValidation()` directly instead. */
|
|
19901
|
+
setNodeValidation(nodeId, nodeValidationInput) {
|
|
19902
|
+
const flowStore = useFlowStore();
|
|
19903
|
+
const resultsStore = useResultsStore();
|
|
19904
|
+
resultsStore.setNodeValidation(flowStore.flowId, nodeId, nodeValidationInput);
|
|
19905
|
+
},
|
|
19906
|
+
/** @deprecated Use `useResultsStore().resetNodeValidation()` directly instead. */
|
|
19907
|
+
resetNodeValidation() {
|
|
19908
|
+
const resultsStore = useResultsStore();
|
|
19909
|
+
resultsStore.resetNodeValidation();
|
|
19910
|
+
},
|
|
19911
|
+
/** @deprecated Use `useResultsStore().getNodeValidation()` directly instead. */
|
|
19912
|
+
getNodeValidation(nodeId) {
|
|
19913
|
+
const flowStore = useFlowStore();
|
|
19914
|
+
const resultsStore = useResultsStore();
|
|
19915
|
+
return resultsStore.getNodeValidation(flowStore.flowId, nodeId);
|
|
19916
|
+
},
|
|
19917
|
+
/** @deprecated Use `useResultsStore().insertRunResult()` directly instead. */
|
|
19918
|
+
insertRunResult(runResult) {
|
|
19919
|
+
const resultsStore = useResultsStore();
|
|
19920
|
+
resultsStore.insertRunResult(runResult);
|
|
19921
|
+
},
|
|
19922
|
+
/** @deprecated Use `useResultsStore().resetRunResults()` directly instead. */
|
|
19923
|
+
resetRunResults() {
|
|
19924
|
+
const resultsStore = useResultsStore();
|
|
19925
|
+
resultsStore.resetRunResults();
|
|
19926
|
+
},
|
|
19927
|
+
/** @deprecated Use `useResultsStore().getRunResult()` directly instead. */
|
|
19928
|
+
getRunResult(flowId) {
|
|
19929
|
+
const resultsStore = useResultsStore();
|
|
19930
|
+
return resultsStore.getRunResult(flowId);
|
|
19931
|
+
},
|
|
19932
|
+
/** @deprecated Use `useEditorStore().openDrawer()` directly instead. */
|
|
19933
|
+
openDrawer(component2, nodeTitleInfo, props = {}) {
|
|
19934
|
+
const editorStore = useEditorStore();
|
|
19935
|
+
editorStore.openDrawer(component2, nodeTitleInfo, props);
|
|
19936
|
+
},
|
|
19937
|
+
/** @deprecated Use `useEditorStore().closeDrawer()` directly instead. */
|
|
19938
|
+
closeDrawer() {
|
|
19939
|
+
const editorStore = useEditorStore();
|
|
19940
|
+
editorStore.closeDrawer();
|
|
19941
|
+
this.nodeId = -1;
|
|
19942
|
+
},
|
|
19943
|
+
/** @deprecated Use `useEditorStore().toggleDrawer()` directly instead. */
|
|
19944
|
+
toggleDrawer() {
|
|
19945
|
+
const editorStore = useEditorStore();
|
|
19946
|
+
editorStore.toggleDrawer();
|
|
19947
|
+
},
|
|
19948
|
+
/** @deprecated Use `useEditorStore().pushNodeData()` directly instead. */
|
|
19949
|
+
pushNodeData() {
|
|
19950
|
+
const editorStore = useEditorStore();
|
|
19951
|
+
editorStore.pushNodeData();
|
|
19952
|
+
},
|
|
19953
|
+
/** @deprecated Use `useEditorStore().setCloseFunction()` directly instead. */
|
|
19954
|
+
setCloseFunction(f2) {
|
|
19955
|
+
const editorStore = useEditorStore();
|
|
19956
|
+
editorStore.setCloseFunction(f2);
|
|
19957
|
+
},
|
|
19958
|
+
/** @deprecated Use `useEditorStore().executeDrawCloseFunction()` directly instead. */
|
|
19959
|
+
executeDrawCloseFunction() {
|
|
19960
|
+
const editorStore = useEditorStore();
|
|
19961
|
+
return editorStore.executeDrawCloseFunction();
|
|
19962
|
+
},
|
|
19963
|
+
/** @deprecated Use `useEditorStore().toggleCodeGenerator()` directly instead. */
|
|
19964
|
+
toggleCodeGenerator() {
|
|
19965
|
+
const editorStore = useEditorStore();
|
|
19966
|
+
editorStore.toggleCodeGenerator();
|
|
19967
|
+
},
|
|
19968
|
+
/** @deprecated Use `useEditorStore().setCodeGeneratorVisibility()` directly instead. */
|
|
19969
|
+
setCodeGeneratorVisibility(visible) {
|
|
19970
|
+
const editorStore = useEditorStore();
|
|
19971
|
+
editorStore.setCodeGeneratorVisibility(visible);
|
|
19972
|
+
},
|
|
19973
|
+
/** @deprecated Use `useEditorStore().showLogViewer()` directly instead. */
|
|
19974
|
+
showLogViewer() {
|
|
19975
|
+
const editorStore = useEditorStore();
|
|
19976
|
+
editorStore.showLogViewer();
|
|
19977
|
+
},
|
|
19978
|
+
/** @deprecated Use `useEditorStore().hideLogViewer()` directly instead. */
|
|
19979
|
+
hideLogViewer() {
|
|
19980
|
+
const editorStore = useEditorStore();
|
|
19981
|
+
editorStore.hideLogViewer();
|
|
19982
|
+
},
|
|
19983
|
+
/** @deprecated Use `useEditorStore().toggleLogViewer()` directly instead. */
|
|
19984
|
+
toggleLogViewer() {
|
|
19985
|
+
const editorStore = useEditorStore();
|
|
19986
|
+
editorStore.toggleLogViewer();
|
|
19987
|
+
},
|
|
19988
|
+
/** @deprecated Use `useEditorStore().setInputCode()` directly instead. */
|
|
19989
|
+
setInputCode(newCode) {
|
|
19990
|
+
const editorStore = useEditorStore();
|
|
19991
|
+
editorStore.setInputCode(newCode);
|
|
19992
|
+
},
|
|
19993
|
+
/** @deprecated Use `useEditorStore().setInitialEditorData()` directly instead. */
|
|
19994
|
+
setInitialEditorData(editorDataString) {
|
|
19995
|
+
const editorStore = useEditorStore();
|
|
19996
|
+
editorStore.setInitialEditorData(editorDataString);
|
|
19997
|
+
},
|
|
19998
|
+
/** @deprecated Use `useEditorStore().getInitialEditorData()` directly instead. */
|
|
19999
|
+
getInitialEditorData() {
|
|
20000
|
+
const editorStore = useEditorStore();
|
|
20001
|
+
return editorStore.getInitialEditorData();
|
|
20002
|
+
}
|
|
20003
|
+
}
|
|
20004
|
+
});
|
|
20005
|
+
const _hoisted_1$V = { class: "tooltip-progress" };
|
|
20006
|
+
const _hoisted_2$L = { class: "progress-bar" };
|
|
20007
|
+
const _hoisted_3$E = { class: "progress-text" };
|
|
20008
|
+
const _hoisted_4$v = { class: "tooltip-content" };
|
|
20009
|
+
const _hoisted_5$q = { class: "tooltip-title" };
|
|
20010
|
+
const _hoisted_6$l = ["innerHTML"];
|
|
20011
|
+
const _hoisted_7$d = {
|
|
20012
|
+
key: 0,
|
|
20013
|
+
class: "tooltip-action-hint"
|
|
20014
|
+
};
|
|
20015
|
+
const _hoisted_8$9 = { class: "tooltip-navigation" };
|
|
20016
|
+
const _hoisted_9$8 = { class: "nav-main" };
|
|
20017
|
+
const _hoisted_10$8 = {
|
|
20018
|
+
key: 0,
|
|
20019
|
+
class: "material-icons"
|
|
20020
|
+
};
|
|
20021
|
+
const _hoisted_11$5 = {
|
|
20022
|
+
key: 1,
|
|
20023
|
+
class: "material-icons"
|
|
20024
|
+
};
|
|
20025
|
+
const _sfc_main$4 = /* @__PURE__ */ defineComponent({
|
|
20026
|
+
__name: "TutorialTooltip",
|
|
20027
|
+
props: {
|
|
20028
|
+
step: {},
|
|
20029
|
+
position: {},
|
|
20030
|
+
isCenterMode: { type: Boolean },
|
|
20031
|
+
currentStepIndex: {},
|
|
20032
|
+
totalSteps: {},
|
|
20033
|
+
progress: {}
|
|
20034
|
+
},
|
|
20035
|
+
emits: ["next", "prev", "skip", "complete"],
|
|
20036
|
+
setup(__props, { emit: __emit }) {
|
|
20037
|
+
const props = __props;
|
|
20038
|
+
const emit2 = __emit;
|
|
20039
|
+
const tooltipRef = ref(null);
|
|
20040
|
+
const tooltipRect = ref(null);
|
|
20041
|
+
function updateTooltipRect() {
|
|
20042
|
+
if (tooltipRef.value) {
|
|
20043
|
+
tooltipRect.value = tooltipRef.value.getBoundingClientRect();
|
|
20044
|
+
}
|
|
20045
|
+
}
|
|
20046
|
+
watch(
|
|
20047
|
+
() => props.step,
|
|
20048
|
+
() => {
|
|
20049
|
+
setTimeout(updateTooltipRect, 50);
|
|
20050
|
+
},
|
|
20051
|
+
{ immediate: true }
|
|
20052
|
+
);
|
|
20053
|
+
onMounted(() => {
|
|
20054
|
+
setTimeout(updateTooltipRect, 50);
|
|
20055
|
+
window.addEventListener("resize", updateTooltipRect);
|
|
20056
|
+
});
|
|
20057
|
+
onUnmounted(() => {
|
|
20058
|
+
window.removeEventListener("resize", updateTooltipRect);
|
|
20059
|
+
});
|
|
20060
|
+
const tooltipStyle = computed(() => {
|
|
20061
|
+
var _a, _b;
|
|
20062
|
+
if (props.isCenterMode) {
|
|
20063
|
+
if (props.step.centerInScreen) {
|
|
20064
|
+
return {
|
|
20065
|
+
position: "fixed",
|
|
20066
|
+
left: "50%",
|
|
20067
|
+
top: "50%",
|
|
20068
|
+
right: "auto",
|
|
20069
|
+
bottom: "auto",
|
|
20070
|
+
transform: "translate(-50%, -50%)"
|
|
20071
|
+
};
|
|
20072
|
+
}
|
|
20073
|
+
return {
|
|
20074
|
+
position: "fixed",
|
|
20075
|
+
right: "24px",
|
|
20076
|
+
bottom: "24px",
|
|
20077
|
+
left: "auto",
|
|
20078
|
+
top: "auto",
|
|
20079
|
+
transform: "none"
|
|
20080
|
+
};
|
|
20081
|
+
}
|
|
20082
|
+
const tooltipWidth = ((_a = tooltipRect.value) == null ? void 0 : _a.width) || 350;
|
|
20083
|
+
const tooltipHeight = ((_b = tooltipRect.value) == null ? void 0 : _b.height) || 200;
|
|
20084
|
+
const padding = 20;
|
|
20085
|
+
const position = props.step.position || "bottom";
|
|
20086
|
+
let x2 = props.position.x;
|
|
20087
|
+
let y = props.position.y;
|
|
20088
|
+
let transform2 = "";
|
|
20089
|
+
switch (position) {
|
|
20090
|
+
case "top":
|
|
20091
|
+
x2 = props.position.x;
|
|
20092
|
+
y = props.position.y;
|
|
20093
|
+
transform2 = "translate(-50%, -100%)";
|
|
20094
|
+
break;
|
|
20095
|
+
case "bottom":
|
|
20096
|
+
x2 = props.position.x;
|
|
20097
|
+
y = props.position.y;
|
|
20098
|
+
transform2 = "translate(-50%, 0)";
|
|
20099
|
+
break;
|
|
20100
|
+
case "left":
|
|
20101
|
+
x2 = props.position.x;
|
|
20102
|
+
y = props.position.y;
|
|
20103
|
+
transform2 = "translate(-100%, -50%)";
|
|
20104
|
+
break;
|
|
20105
|
+
case "right":
|
|
20106
|
+
x2 = props.position.x;
|
|
20107
|
+
y = props.position.y;
|
|
20108
|
+
transform2 = "translate(0, -50%)";
|
|
20109
|
+
break;
|
|
20110
|
+
}
|
|
20111
|
+
let finalX = x2;
|
|
20112
|
+
let finalY = y;
|
|
20113
|
+
let effectiveX = x2;
|
|
20114
|
+
let effectiveY = y;
|
|
20115
|
+
if (transform2.includes("-50%, 0")) {
|
|
20116
|
+
effectiveX = x2 - tooltipWidth / 2;
|
|
20117
|
+
} else if (transform2.includes("-50%, -100%)")) {
|
|
20118
|
+
effectiveX = x2 - tooltipWidth / 2;
|
|
20119
|
+
effectiveY = y - tooltipHeight;
|
|
20120
|
+
} else if (transform2.includes("-100%, -50%")) {
|
|
20121
|
+
effectiveX = x2 - tooltipWidth;
|
|
20122
|
+
effectiveY = y - tooltipHeight / 2;
|
|
20123
|
+
} else if (transform2.includes("0, -50%")) {
|
|
20124
|
+
effectiveY = y - tooltipHeight / 2;
|
|
20125
|
+
}
|
|
20126
|
+
if (effectiveX < padding) {
|
|
20127
|
+
finalX = x2 + (padding - effectiveX);
|
|
20128
|
+
}
|
|
20129
|
+
if (effectiveX + tooltipWidth > window.innerWidth - padding) {
|
|
20130
|
+
finalX = x2 - (effectiveX + tooltipWidth - window.innerWidth + padding);
|
|
20131
|
+
}
|
|
20132
|
+
if (effectiveY < padding) {
|
|
20133
|
+
finalY = y + (padding - effectiveY);
|
|
20134
|
+
}
|
|
20135
|
+
if (effectiveY + tooltipHeight > window.innerHeight - padding) {
|
|
20136
|
+
finalY = y - (effectiveY + tooltipHeight - window.innerHeight + padding);
|
|
20137
|
+
}
|
|
20138
|
+
return {
|
|
20139
|
+
position: "fixed",
|
|
20140
|
+
left: `${finalX}px`,
|
|
20141
|
+
top: `${finalY}px`,
|
|
20142
|
+
transform: transform2
|
|
20143
|
+
};
|
|
20144
|
+
});
|
|
20145
|
+
const isLastStep = computed(() => props.currentStepIndex === props.totalSteps - 1);
|
|
20146
|
+
const showNextButton = computed(() => props.step.showNextButton !== false);
|
|
20147
|
+
const showPrevButton = computed(
|
|
20148
|
+
() => props.step.showPrevButton !== false && props.currentStepIndex > 0
|
|
20149
|
+
);
|
|
20150
|
+
const canSkip = computed(() => props.step.canSkip !== false);
|
|
20151
|
+
const actionHint = computed(() => {
|
|
20152
|
+
switch (props.step.action) {
|
|
20153
|
+
case "click":
|
|
20154
|
+
return "Click the highlighted element to continue";
|
|
20155
|
+
case "drag":
|
|
20156
|
+
return "Drag the highlighted element to the target area";
|
|
20157
|
+
case "input":
|
|
20158
|
+
return "Enter the required information";
|
|
20159
|
+
case "wait":
|
|
20160
|
+
return "Please wait...";
|
|
20161
|
+
default:
|
|
20162
|
+
return null;
|
|
20163
|
+
}
|
|
20164
|
+
});
|
|
20165
|
+
function handleNext() {
|
|
20166
|
+
if (isLastStep.value) {
|
|
20167
|
+
emit2("complete");
|
|
20168
|
+
} else {
|
|
20169
|
+
emit2("next");
|
|
20170
|
+
}
|
|
20171
|
+
}
|
|
20172
|
+
return (_ctx, _cache) => {
|
|
20173
|
+
return openBlock(), createElementBlock("div", {
|
|
20174
|
+
ref_key: "tooltipRef",
|
|
20175
|
+
ref: tooltipRef,
|
|
20176
|
+
class: "tutorial-tooltip",
|
|
20177
|
+
style: normalizeStyle(tooltipStyle.value)
|
|
20178
|
+
}, [
|
|
20179
|
+
createBaseVNode("div", _hoisted_1$V, [
|
|
20180
|
+
createBaseVNode("div", _hoisted_2$L, [
|
|
20181
|
+
createBaseVNode("div", {
|
|
20182
|
+
class: "progress-fill",
|
|
20183
|
+
style: normalizeStyle({ width: `${_ctx.progress}%` })
|
|
20184
|
+
}, null, 4)
|
|
20185
|
+
]),
|
|
20186
|
+
createBaseVNode("span", _hoisted_3$E, toDisplayString$1(_ctx.currentStepIndex + 1) + " / " + toDisplayString$1(_ctx.totalSteps), 1)
|
|
20187
|
+
]),
|
|
20188
|
+
createBaseVNode("div", _hoisted_4$v, [
|
|
20189
|
+
createBaseVNode("h3", _hoisted_5$q, toDisplayString$1(_ctx.step.title), 1),
|
|
20190
|
+
createBaseVNode("p", {
|
|
20191
|
+
class: "tooltip-description",
|
|
20192
|
+
innerHTML: _ctx.step.content
|
|
20193
|
+
}, null, 8, _hoisted_6$l),
|
|
20194
|
+
actionHint.value && _ctx.step.action !== "observe" ? (openBlock(), createElementBlock("p", _hoisted_7$d, [
|
|
20195
|
+
_cache[2] || (_cache[2] = createBaseVNode("span", { class: "action-icon material-icons" }, "touch_app", -1)),
|
|
20196
|
+
createTextVNode(" " + toDisplayString$1(actionHint.value), 1)
|
|
20197
|
+
])) : createCommentVNode("", true)
|
|
20198
|
+
]),
|
|
20199
|
+
createBaseVNode("div", _hoisted_8$9, [
|
|
20200
|
+
canSkip.value ? (openBlock(), createElementBlock("button", {
|
|
20201
|
+
key: 0,
|
|
20202
|
+
class: "nav-btn skip-btn",
|
|
20203
|
+
onClick: _cache[0] || (_cache[0] = ($event) => emit2("skip"))
|
|
20204
|
+
}, "Skip Tutorial")) : createCommentVNode("", true),
|
|
20205
|
+
createBaseVNode("div", _hoisted_9$8, [
|
|
20206
|
+
showPrevButton.value ? (openBlock(), createElementBlock("button", {
|
|
20207
|
+
key: 0,
|
|
20208
|
+
class: "nav-btn prev-btn",
|
|
20209
|
+
onClick: _cache[1] || (_cache[1] = ($event) => emit2("prev"))
|
|
20210
|
+
}, _cache[3] || (_cache[3] = [
|
|
20211
|
+
createBaseVNode("span", { class: "material-icons" }, "arrow_back", -1),
|
|
20212
|
+
createTextVNode(" Back ")
|
|
20213
|
+
]))) : createCommentVNode("", true),
|
|
20214
|
+
showNextButton.value ? (openBlock(), createElementBlock("button", {
|
|
20215
|
+
key: 1,
|
|
20216
|
+
class: "nav-btn next-btn",
|
|
20217
|
+
onClick: handleNext
|
|
20218
|
+
}, [
|
|
20219
|
+
createTextVNode(toDisplayString$1(isLastStep.value ? "Finish" : "Next") + " ", 1),
|
|
20220
|
+
!isLastStep.value ? (openBlock(), createElementBlock("span", _hoisted_10$8, "arrow_forward")) : (openBlock(), createElementBlock("span", _hoisted_11$5, "check"))
|
|
20221
|
+
])) : createCommentVNode("", true)
|
|
20222
|
+
])
|
|
20223
|
+
])
|
|
20224
|
+
], 4);
|
|
20225
|
+
};
|
|
20226
|
+
}
|
|
20227
|
+
});
|
|
20228
|
+
const TutorialTooltip_vue_vue_type_style_index_0_scoped_4c5588cd_lang = "";
|
|
20229
|
+
const TutorialTooltip = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["__scopeId", "data-v-4c5588cd"]]);
|
|
20230
|
+
const _hoisted_1$U = {
|
|
20231
|
+
key: 0,
|
|
20232
|
+
class: "tutorial-overlay"
|
|
20233
|
+
};
|
|
20234
|
+
const _hoisted_2$K = {
|
|
20235
|
+
key: 0,
|
|
20236
|
+
class: "tutorial-backdrop"
|
|
20237
|
+
};
|
|
20238
|
+
const _hoisted_3$D = {
|
|
20239
|
+
class: "tutorial-mask",
|
|
20240
|
+
width: "100%",
|
|
20241
|
+
height: "100%"
|
|
20242
|
+
};
|
|
20243
|
+
const _hoisted_4$u = { id: "spotlight-mask" };
|
|
20244
|
+
const _hoisted_5$p = ["x", "y", "width", "height", "rx"];
|
|
20245
|
+
const _hoisted_6$k = {
|
|
20246
|
+
key: 1,
|
|
20247
|
+
class: "tutorial-backdrop tutorial-backdrop-full"
|
|
20248
|
+
};
|
|
20249
|
+
const _sfc_main$3 = /* @__PURE__ */ defineComponent({
|
|
20250
|
+
__name: "TutorialOverlay",
|
|
20251
|
+
setup(__props) {
|
|
20252
|
+
const tutorialStore = useTutorialStore();
|
|
20253
|
+
const nodeStore = useFlowStore();
|
|
20254
|
+
const route = useRoute();
|
|
20255
|
+
const isDesignerPage = computed(() => route.name === "designer");
|
|
20256
|
+
const targetRect = ref(null);
|
|
20257
|
+
const tooltipPosition = ref({ x: 0, y: 0 });
|
|
20258
|
+
const previousNodeCount = ref(0);
|
|
20259
|
+
const spotlightStyle = computed(() => {
|
|
20260
|
+
var _a;
|
|
20261
|
+
if (!targetRect.value || !((_a = tutorialStore.currentStep) == null ? void 0 : _a.target)) {
|
|
20262
|
+
return null;
|
|
20263
|
+
}
|
|
20264
|
+
const padding = tutorialStore.currentStep.highlightPadding ?? 8;
|
|
20265
|
+
const rect = targetRect.value;
|
|
20266
|
+
return {
|
|
20267
|
+
left: `${rect.left - padding}px`,
|
|
20268
|
+
top: `${rect.top - padding}px`,
|
|
20269
|
+
width: `${rect.width + padding * 2}px`,
|
|
20270
|
+
height: `${rect.height + padding * 2}px`,
|
|
20271
|
+
borderRadius: tutorialStore.currentStep.spotlightShape === "circle" ? "50%" : "8px"
|
|
20272
|
+
};
|
|
20273
|
+
});
|
|
20274
|
+
const isCenterMode = computed(() => {
|
|
20275
|
+
var _a;
|
|
20276
|
+
return !((_a = tutorialStore.currentStep) == null ? void 0 : _a.target);
|
|
20277
|
+
});
|
|
20278
|
+
function calculateTooltipPosition() {
|
|
20279
|
+
if (!tutorialStore.currentStep)
|
|
20280
|
+
return;
|
|
20281
|
+
const position = tutorialStore.currentStep.position || "bottom";
|
|
20282
|
+
if (isCenterMode.value || position === "center") {
|
|
20283
|
+
tooltipPosition.value = {
|
|
20284
|
+
x: window.innerWidth / 2,
|
|
20285
|
+
y: window.innerHeight / 2
|
|
20286
|
+
};
|
|
20287
|
+
return;
|
|
20288
|
+
}
|
|
20289
|
+
if (!targetRect.value)
|
|
20290
|
+
return;
|
|
20291
|
+
const rect = targetRect.value;
|
|
20292
|
+
const padding = 16;
|
|
20293
|
+
switch (position) {
|
|
20294
|
+
case "top":
|
|
20295
|
+
tooltipPosition.value = {
|
|
20296
|
+
x: rect.left + rect.width / 2,
|
|
20297
|
+
y: rect.top - padding
|
|
20298
|
+
};
|
|
20299
|
+
break;
|
|
20300
|
+
case "bottom":
|
|
20301
|
+
tooltipPosition.value = {
|
|
20302
|
+
x: rect.left + rect.width / 2,
|
|
20303
|
+
y: rect.bottom + padding
|
|
20304
|
+
};
|
|
20305
|
+
break;
|
|
20306
|
+
case "left":
|
|
20307
|
+
tooltipPosition.value = {
|
|
20308
|
+
x: rect.left - padding - 30,
|
|
20309
|
+
// Extra offset to avoid modal overlap
|
|
20310
|
+
y: rect.top + rect.height / 2
|
|
20311
|
+
};
|
|
20312
|
+
break;
|
|
20313
|
+
case "right":
|
|
20314
|
+
tooltipPosition.value = {
|
|
20315
|
+
x: rect.right + padding,
|
|
20316
|
+
y: rect.top + rect.height / 2
|
|
20317
|
+
};
|
|
20318
|
+
break;
|
|
20319
|
+
}
|
|
20320
|
+
}
|
|
20321
|
+
function updateTargetPosition() {
|
|
20322
|
+
var _a;
|
|
20323
|
+
if (!((_a = tutorialStore.currentStep) == null ? void 0 : _a.target)) {
|
|
20324
|
+
targetRect.value = null;
|
|
20325
|
+
calculateTooltipPosition();
|
|
20326
|
+
return;
|
|
20327
|
+
}
|
|
20328
|
+
const targetElement = document.querySelector(tutorialStore.currentStep.target);
|
|
20329
|
+
if (targetElement) {
|
|
20330
|
+
targetRect.value = targetElement.getBoundingClientRect();
|
|
20331
|
+
calculateTooltipPosition();
|
|
20332
|
+
} else {
|
|
20333
|
+
targetRect.value = null;
|
|
20334
|
+
}
|
|
20335
|
+
}
|
|
20336
|
+
watch(
|
|
20337
|
+
() => tutorialStore.currentStep,
|
|
20338
|
+
async (newStep) => {
|
|
20339
|
+
if (!newStep)
|
|
20340
|
+
return;
|
|
20341
|
+
if (newStep.waitForElement) {
|
|
20342
|
+
const maxAttempts = 50;
|
|
20343
|
+
let attempts = 0;
|
|
20344
|
+
while (attempts < maxAttempts) {
|
|
20345
|
+
const element = document.querySelector(newStep.waitForElement);
|
|
20346
|
+
if (element)
|
|
20347
|
+
break;
|
|
20348
|
+
await new Promise((resolve2) => setTimeout(resolve2, 100));
|
|
20349
|
+
attempts++;
|
|
20350
|
+
}
|
|
20351
|
+
}
|
|
20352
|
+
await nextTick();
|
|
20353
|
+
updateTargetPosition();
|
|
20354
|
+
},
|
|
20355
|
+
{ immediate: true }
|
|
20356
|
+
);
|
|
20357
|
+
watch(
|
|
20358
|
+
() => nodeStore.flowId,
|
|
20359
|
+
(newFlowId, oldFlowId) => {
|
|
20360
|
+
var _a;
|
|
20361
|
+
if (!tutorialStore.isActive)
|
|
20362
|
+
return;
|
|
20363
|
+
const currentStepId = (_a = tutorialStore.currentStep) == null ? void 0 : _a.id;
|
|
20364
|
+
if (currentStepId === "confirm-create-flow" && newFlowId && newFlowId > 0 && (!oldFlowId || oldFlowId <= 0)) {
|
|
20365
|
+
setTimeout(() => {
|
|
20366
|
+
tutorialStore.nextStep();
|
|
20367
|
+
}, 500);
|
|
20368
|
+
}
|
|
20369
|
+
}
|
|
20370
|
+
);
|
|
20371
|
+
const nodeSettingsWasVisible = ref(false);
|
|
20372
|
+
function checkForNodeSettings() {
|
|
20373
|
+
var _a;
|
|
20374
|
+
if (!tutorialStore.isActive)
|
|
20375
|
+
return;
|
|
20376
|
+
const currentStepId = (_a = tutorialStore.currentStep) == null ? void 0 : _a.id;
|
|
20377
|
+
const nodeSettings = document.querySelector("#nodeSettings");
|
|
20378
|
+
const nodeSettingsIsVisible = nodeSettings !== null;
|
|
20379
|
+
if (currentStepId === "configure-manual-input" && nodeSettingsIsVisible && !nodeSettingsWasVisible.value) {
|
|
20380
|
+
setTimeout(() => {
|
|
20381
|
+
tutorialStore.nextStep();
|
|
20382
|
+
}, 300);
|
|
20383
|
+
}
|
|
20384
|
+
nodeSettingsWasVisible.value = nodeSettingsIsVisible;
|
|
20385
|
+
}
|
|
20386
|
+
function checkForNewNodes() {
|
|
20387
|
+
var _a;
|
|
20388
|
+
if (!tutorialStore.isActive)
|
|
20389
|
+
return;
|
|
20390
|
+
const currentStepId = (_a = tutorialStore.currentStep) == null ? void 0 : _a.id;
|
|
20391
|
+
const nodes = document.querySelectorAll(".vue-flow__node");
|
|
20392
|
+
const currentNodeCount = nodes.length;
|
|
20393
|
+
if (currentStepId === "drag-manual-input" && currentNodeCount > previousNodeCount.value) {
|
|
20394
|
+
setTimeout(() => {
|
|
20395
|
+
tutorialStore.nextStep();
|
|
20396
|
+
}, 300);
|
|
20397
|
+
}
|
|
20398
|
+
if (currentStepId === "drag-group-by" && currentNodeCount > previousNodeCount.value) {
|
|
20399
|
+
setTimeout(() => {
|
|
20400
|
+
tutorialStore.nextStep();
|
|
20401
|
+
}, 300);
|
|
20402
|
+
}
|
|
20403
|
+
if (currentStepId === "drag-write-data" && currentNodeCount > previousNodeCount.value) {
|
|
20404
|
+
setTimeout(() => {
|
|
20405
|
+
tutorialStore.nextStep();
|
|
20406
|
+
}, 300);
|
|
20407
|
+
}
|
|
20408
|
+
previousNodeCount.value = currentNodeCount;
|
|
20409
|
+
}
|
|
20410
|
+
function handleResize() {
|
|
20411
|
+
updateTargetPosition();
|
|
20412
|
+
}
|
|
20413
|
+
function handleScroll2() {
|
|
20414
|
+
updateTargetPosition();
|
|
20415
|
+
}
|
|
20416
|
+
let mutationObserver = null;
|
|
20417
|
+
function setupMutationObserver() {
|
|
20418
|
+
mutationObserver = new MutationObserver(() => {
|
|
20419
|
+
updateTargetPosition();
|
|
20420
|
+
checkForNodeSettings();
|
|
20421
|
+
checkForNewNodes();
|
|
20422
|
+
});
|
|
20423
|
+
mutationObserver.observe(document.body, {
|
|
20424
|
+
childList: true,
|
|
20425
|
+
subtree: true,
|
|
20426
|
+
attributes: true,
|
|
20427
|
+
attributeFilter: ["class", "style"]
|
|
20428
|
+
});
|
|
20429
|
+
}
|
|
20430
|
+
onMounted(() => {
|
|
20431
|
+
window.addEventListener("resize", handleResize);
|
|
20432
|
+
window.addEventListener("scroll", handleScroll2, true);
|
|
20433
|
+
setupMutationObserver();
|
|
20434
|
+
updateTargetPosition();
|
|
20435
|
+
previousNodeCount.value = document.querySelectorAll(".vue-flow__node").length;
|
|
20436
|
+
});
|
|
20437
|
+
onUnmounted(() => {
|
|
20438
|
+
window.removeEventListener("resize", handleResize);
|
|
20439
|
+
window.removeEventListener("scroll", handleScroll2, true);
|
|
20440
|
+
if (mutationObserver) {
|
|
20441
|
+
mutationObserver.disconnect();
|
|
20442
|
+
}
|
|
20443
|
+
});
|
|
20444
|
+
return (_ctx, _cache) => {
|
|
20445
|
+
return openBlock(), createBlock(Teleport, { to: "body" }, [
|
|
20446
|
+
createVNode(Transition, { name: "tutorial-fade" }, {
|
|
20447
|
+
default: withCtx(() => {
|
|
20448
|
+
var _a;
|
|
20449
|
+
return [
|
|
20450
|
+
isDesignerPage.value && unref(tutorialStore).isActive && !unref(tutorialStore).tutorialPaused ? (openBlock(), createElementBlock("div", _hoisted_1$U, [
|
|
20451
|
+
spotlightStyle.value ? (openBlock(), createElementBlock("div", _hoisted_2$K, [
|
|
20452
|
+
(openBlock(), createElementBlock("svg", _hoisted_3$D, [
|
|
20453
|
+
createBaseVNode("defs", null, [
|
|
20454
|
+
createBaseVNode("mask", _hoisted_4$u, [
|
|
20455
|
+
_cache[0] || (_cache[0] = createBaseVNode("rect", {
|
|
20456
|
+
width: "100%",
|
|
20457
|
+
height: "100%",
|
|
20458
|
+
fill: "white"
|
|
20459
|
+
}, null, -1)),
|
|
20460
|
+
spotlightStyle.value ? (openBlock(), createElementBlock("rect", {
|
|
20461
|
+
key: 0,
|
|
20462
|
+
x: parseInt(spotlightStyle.value.left),
|
|
20463
|
+
y: parseInt(spotlightStyle.value.top),
|
|
20464
|
+
width: parseInt(spotlightStyle.value.width),
|
|
20465
|
+
height: parseInt(spotlightStyle.value.height),
|
|
20466
|
+
rx: spotlightStyle.value.borderRadius === "50%" ? parseInt(spotlightStyle.value.width) / 2 : 8,
|
|
20467
|
+
fill: "black"
|
|
20468
|
+
}, null, 8, _hoisted_5$p)) : createCommentVNode("", true)
|
|
20469
|
+
])
|
|
20470
|
+
]),
|
|
20471
|
+
_cache[1] || (_cache[1] = createBaseVNode("rect", {
|
|
20472
|
+
width: "100%",
|
|
20473
|
+
height: "100%",
|
|
20474
|
+
fill: "rgba(0, 0, 0, 0.7)",
|
|
20475
|
+
mask: "url(#spotlight-mask)"
|
|
20476
|
+
}, null, -1))
|
|
20477
|
+
]))
|
|
20478
|
+
])) : ((_a = unref(tutorialStore).currentStep) == null ? void 0 : _a.centerInScreen) ? (openBlock(), createElementBlock("div", _hoisted_6$k)) : createCommentVNode("", true),
|
|
20479
|
+
spotlightStyle.value ? (openBlock(), createElementBlock("div", {
|
|
20480
|
+
key: 2,
|
|
20481
|
+
class: "tutorial-spotlight",
|
|
20482
|
+
style: normalizeStyle(spotlightStyle.value)
|
|
20483
|
+
}, _cache[2] || (_cache[2] = [
|
|
20484
|
+
createBaseVNode("div", { class: "spotlight-border" }, null, -1)
|
|
20485
|
+
]), 4)) : createCommentVNode("", true),
|
|
20486
|
+
unref(tutorialStore).currentStep ? (openBlock(), createBlock(TutorialTooltip, {
|
|
20487
|
+
key: 3,
|
|
20488
|
+
step: unref(tutorialStore).currentStep,
|
|
20489
|
+
position: tooltipPosition.value,
|
|
20490
|
+
"is-center-mode": isCenterMode.value,
|
|
20491
|
+
"current-step-index": unref(tutorialStore).currentStepIndex,
|
|
20492
|
+
"total-steps": unref(tutorialStore).totalSteps,
|
|
20493
|
+
progress: unref(tutorialStore).progress,
|
|
20494
|
+
onNext: unref(tutorialStore).nextStep,
|
|
20495
|
+
onPrev: unref(tutorialStore).prevStep,
|
|
20496
|
+
onSkip: unref(tutorialStore).endTutorial,
|
|
20497
|
+
onComplete: unref(tutorialStore).completeTutorial
|
|
20498
|
+
}, null, 8, ["step", "position", "is-center-mode", "current-step-index", "total-steps", "progress", "onNext", "onPrev", "onSkip", "onComplete"])) : createCommentVNode("", true)
|
|
20499
|
+
])) : createCommentVNode("", true)
|
|
20500
|
+
];
|
|
20501
|
+
}),
|
|
20502
|
+
_: 1
|
|
20503
|
+
})
|
|
20504
|
+
]);
|
|
20505
|
+
};
|
|
20506
|
+
}
|
|
20507
|
+
});
|
|
20508
|
+
const TutorialOverlay_vue_vue_type_style_index_0_scoped_cfeb3afc_lang = "";
|
|
20509
|
+
const TutorialOverlay = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["__scopeId", "data-v-cfeb3afc"]]);
|
|
20510
|
+
const gettingStartedTutorial = {
|
|
20511
|
+
id: "getting-started",
|
|
20512
|
+
name: "Getting Started with Flowfile",
|
|
20513
|
+
description: "Learn how to create your first data flow - from input to output",
|
|
20514
|
+
steps: [
|
|
20515
|
+
// Step 1: Welcome
|
|
20516
|
+
{
|
|
20517
|
+
id: "welcome",
|
|
20518
|
+
title: "Welcome to Flowfile!",
|
|
20519
|
+
content: `
|
|
20520
|
+
<p>In this tutorial, you'll learn how to build your first data flow.</p>
|
|
20521
|
+
<p>We'll cover:</p>
|
|
20522
|
+
<ul style="margin: 12px 0; padding-left: 20px;">
|
|
20523
|
+
<li>Creating a new flow</li>
|
|
20524
|
+
<li>Adding data with Manual Input</li>
|
|
20525
|
+
<li>Transforming data with Group By</li>
|
|
20526
|
+
<li>Writing results to a CSV file</li>
|
|
20527
|
+
<li>Running your flow</li>
|
|
20528
|
+
<li>Saving as YAML</li>
|
|
20529
|
+
</ul>
|
|
20530
|
+
<p>Let's get started!</p>
|
|
20531
|
+
`,
|
|
20532
|
+
position: "center",
|
|
20533
|
+
action: "observe",
|
|
20534
|
+
showNextButton: true,
|
|
20535
|
+
showPrevButton: false
|
|
20536
|
+
},
|
|
20537
|
+
// Step 2: Click Quick Create button
|
|
20538
|
+
{
|
|
20539
|
+
id: "click-quick-create",
|
|
20540
|
+
title: "Create a New Flow",
|
|
20541
|
+
content: `
|
|
20542
|
+
<p>First, let's create a new flow.</p>
|
|
20543
|
+
<p>Click the <strong>Quick Create</strong> button to open the flow creation dialog.</p>
|
|
20544
|
+
`,
|
|
20545
|
+
target: "[data-tutorial='quick-create-btn']",
|
|
20546
|
+
position: "bottom",
|
|
20547
|
+
action: "click",
|
|
20548
|
+
showNextButton: false,
|
|
20549
|
+
highlightPadding: 4
|
|
20550
|
+
},
|
|
20551
|
+
// Step 3: Click Create Flow in modal (no highlight - tooltip stays in corner)
|
|
20552
|
+
{
|
|
20553
|
+
id: "confirm-create-flow",
|
|
20554
|
+
title: "Confirm Flow Creation",
|
|
20555
|
+
content: `
|
|
20556
|
+
<p>A dialog appeared where you can optionally name your flow.</p>
|
|
20557
|
+
<p>Click <strong>Create Flow</strong> in the dialog to continue.</p>
|
|
20558
|
+
`,
|
|
20559
|
+
position: "center",
|
|
20560
|
+
action: "observe",
|
|
20561
|
+
showNextButton: false
|
|
20562
|
+
},
|
|
20563
|
+
// Step 4: Explore the canvas
|
|
20564
|
+
{
|
|
20565
|
+
id: "explore-canvas",
|
|
20566
|
+
title: "Your Flow Canvas",
|
|
20567
|
+
content: `
|
|
20568
|
+
<p>This is your <strong>flow canvas</strong> - the workspace where you'll build your data pipelines.</p>
|
|
20569
|
+
<p>On the left, you'll see the <strong>Data Actions</strong> panel with all available nodes organized by category.</p>
|
|
20570
|
+
`,
|
|
20571
|
+
target: ".vue-flow",
|
|
20572
|
+
position: "center",
|
|
20573
|
+
action: "observe",
|
|
20574
|
+
showNextButton: true,
|
|
20575
|
+
highlightPadding: 0
|
|
20576
|
+
},
|
|
20577
|
+
// Step 5: Explore the node list
|
|
20578
|
+
{
|
|
20579
|
+
id: "node-list",
|
|
20580
|
+
title: "Available Nodes",
|
|
20581
|
+
content: `
|
|
20582
|
+
<p>The <strong>Data Actions</strong> panel contains all the nodes you can use:</p>
|
|
20583
|
+
<ul style="margin: 12px 0; padding-left: 20px;">
|
|
20584
|
+
<li><strong>Input Sources</strong> - Load data from files, databases, or manual input</li>
|
|
20585
|
+
<li><strong>Transformations</strong> - Filter, select, sort, and modify data</li>
|
|
20586
|
+
<li><strong>Combine Operations</strong> - Join and merge datasets</li>
|
|
20587
|
+
<li><strong>Aggregations</strong> - Group and summarize data</li>
|
|
20588
|
+
<li><strong>Output Operations</strong> - Write results to files or databases</li>
|
|
20589
|
+
</ul>
|
|
20590
|
+
`,
|
|
20591
|
+
target: "[data-tutorial='node-list']",
|
|
20592
|
+
position: "right",
|
|
20593
|
+
action: "observe",
|
|
20594
|
+
showNextButton: true,
|
|
20595
|
+
highlightPadding: 4
|
|
20596
|
+
},
|
|
20597
|
+
// Step 5: Find Manual Input
|
|
20598
|
+
{
|
|
20599
|
+
id: "find-manual-input",
|
|
20600
|
+
title: "Input Sources",
|
|
20601
|
+
content: `
|
|
20602
|
+
<p>Let's add some data to work with!</p>
|
|
20603
|
+
<p>The <strong>Input Sources</strong> category contains nodes for bringing data into your flow:</p>
|
|
20604
|
+
<ul style="margin: 12px 0; padding-left: 20px;">
|
|
20605
|
+
<li><strong>Read</strong> - Load CSV, Parquet, or other files</li>
|
|
20606
|
+
<li><strong>Manual Input</strong> - Enter sample data directly</li>
|
|
20607
|
+
<li><strong>Database Reader</strong> - Query databases</li>
|
|
20608
|
+
<li><strong>External Source</strong> - Connect to APIs</li>
|
|
20609
|
+
</ul>
|
|
20610
|
+
`,
|
|
20611
|
+
target: "[data-tutorial-category='input']",
|
|
20612
|
+
position: "right",
|
|
20613
|
+
action: "observe",
|
|
20614
|
+
showNextButton: true,
|
|
20615
|
+
highlightPadding: 4
|
|
20616
|
+
},
|
|
20617
|
+
// Step 6: Highlight Manual Input node
|
|
20618
|
+
{
|
|
20619
|
+
id: "drag-manual-input",
|
|
20620
|
+
title: "Drag Manual Input to Canvas",
|
|
20621
|
+
content: `
|
|
20622
|
+
<p>Find <strong>Manual Input</strong> and <strong>drag it</strong> onto the canvas.</p>
|
|
20623
|
+
<p>This node lets you define sample data directly in the flow - perfect for testing!</p>
|
|
20624
|
+
`,
|
|
20625
|
+
target: "[data-tutorial-node='manual_input']",
|
|
20626
|
+
position: "right",
|
|
20627
|
+
action: "drag",
|
|
20628
|
+
actionTarget: ".vue-flow",
|
|
20629
|
+
showNextButton: true,
|
|
20630
|
+
highlightPadding: 4
|
|
20631
|
+
},
|
|
20632
|
+
// Step 7: Node added - click to configure
|
|
20633
|
+
{
|
|
20634
|
+
id: "configure-manual-input",
|
|
20635
|
+
title: "Configure Your Data",
|
|
20636
|
+
content: `
|
|
20637
|
+
<p>Once you've added the node, <strong>click on it</strong> to open its settings.</p>
|
|
20638
|
+
<p>The settings panel will appear on the right where you can define your data columns and values.</p>
|
|
20639
|
+
`,
|
|
20640
|
+
target: ".vue-flow__node",
|
|
20641
|
+
position: "left",
|
|
20642
|
+
action: "click",
|
|
20643
|
+
waitForElement: ".vue-flow__node",
|
|
20644
|
+
showNextButton: true,
|
|
20645
|
+
highlightPadding: 8
|
|
20646
|
+
},
|
|
20647
|
+
// Step 8: Show node settings with sample data suggestion
|
|
20648
|
+
{
|
|
20649
|
+
id: "node-settings",
|
|
20650
|
+
title: "Add Sample Data",
|
|
20651
|
+
content: `
|
|
20652
|
+
<p>The <strong>Node Settings</strong> panel lets you configure your data.</p>
|
|
20653
|
+
<p><strong>Quick option:</strong> Click <strong>Edit JSON</strong> button, paste this sample data, then click <strong>Apply JSON to table</strong>:</p>
|
|
20654
|
+
<div style="background: var(--color-background-muted); padding: 8px; border-radius: 4px; margin: 8px 0; font-family: monospace; font-size: 11px; max-height: 120px; overflow: auto;">
|
|
20655
|
+
[{"country":"USA","product":"Widget","revenue":1000},<br>
|
|
20656
|
+
{"country":"Germany","product":"Gadget","revenue":2500},<br>
|
|
20657
|
+
{"country":"France","product":"Widget","revenue":1800},<br>
|
|
20658
|
+
{"country":"USA","product":"Gadget","revenue":3200},<br>
|
|
20659
|
+
{"country":"Germany","product":"Widget","revenue":1500},<br>
|
|
20660
|
+
{"country":"France","product":"Gadget","revenue":2100}]
|
|
20661
|
+
</div>
|
|
20662
|
+
<p style="font-size: 12px; color: var(--color-text-secondary);">Or manually add columns (country, product, revenue) and rows. Make sure to change the data type of revenue to "integer".</p>
|
|
20663
|
+
`,
|
|
20664
|
+
target: "#nodeSettings",
|
|
20665
|
+
position: "left",
|
|
20666
|
+
action: "observe",
|
|
20667
|
+
waitForElement: "#nodeSettings",
|
|
20668
|
+
showNextButton: true,
|
|
20669
|
+
highlightPadding: 4,
|
|
20670
|
+
onExit: () => {
|
|
20671
|
+
const nodeStore = useNodeStore();
|
|
20672
|
+
nodeStore.nodeId = -1;
|
|
20673
|
+
}
|
|
20674
|
+
},
|
|
20675
|
+
// Step 9: Explore transformations
|
|
20676
|
+
{
|
|
20677
|
+
id: "transformations-overview",
|
|
20678
|
+
title: "Transformation Nodes",
|
|
20679
|
+
content: `
|
|
20680
|
+
<p>Now let's explore the <strong>transformation</strong> options available:</p>
|
|
20681
|
+
<ul style="margin: 12px 0; padding-left: 20px;">
|
|
20682
|
+
<li><strong>Filter</strong> - Keep only rows matching conditions</li>
|
|
20683
|
+
<li><strong>Select</strong> - Choose and rename columns</li>
|
|
20684
|
+
<li><strong>Sort</strong> - Order rows by column values</li>
|
|
20685
|
+
<li><strong>Formula</strong> - Create calculated columns</li>
|
|
20686
|
+
<li><strong>Polars Code</strong> - Write custom Polars code</li>
|
|
20687
|
+
</ul>
|
|
20688
|
+
`,
|
|
20689
|
+
target: "[data-tutorial-category='transform']",
|
|
20690
|
+
position: "right",
|
|
20691
|
+
action: "observe",
|
|
20692
|
+
showNextButton: true,
|
|
20693
|
+
highlightPadding: 4
|
|
20694
|
+
},
|
|
20695
|
+
// Step 10: Aggregations - More prominent Group By explanation
|
|
20696
|
+
{
|
|
20697
|
+
id: "aggregations-overview",
|
|
20698
|
+
title: "Let's Aggregate Your Data!",
|
|
20699
|
+
content: `
|
|
20700
|
+
<p style="font-size: 15px; margin-bottom: 16px;"><strong>Grouping</strong> is one of the most powerful data operations. It lets you summarize data by categories.</p>
|
|
20701
|
+
<p><strong>Example:</strong> With your sales data, you can answer questions like:</p>
|
|
20702
|
+
<ul style="margin: 12px 0; padding-left: 20px;">
|
|
20703
|
+
<li>"What is the <strong>total revenue per country</strong>?"</li>
|
|
20704
|
+
<li>"How many products were sold in each region?"</li>
|
|
20705
|
+
<li>"What's the average order value by product type?"</li>
|
|
20706
|
+
</ul>
|
|
20707
|
+
`,
|
|
20708
|
+
target: "[data-tutorial-category='aggregate']",
|
|
20709
|
+
position: "right",
|
|
20710
|
+
action: "observe",
|
|
20711
|
+
showNextButton: true,
|
|
20712
|
+
highlightPadding: 4
|
|
20713
|
+
},
|
|
20714
|
+
// Step 11: Drag Group By node
|
|
20715
|
+
{
|
|
20716
|
+
id: "drag-group-by",
|
|
20717
|
+
title: "Add Group By Node",
|
|
20718
|
+
content: `
|
|
20719
|
+
<p style="font-size: 15px; padding: 12px; background: var(--color-accent-subtle); color: #1a1a1a; border-radius: 6px; margin-bottom: 12px;">
|
|
20720
|
+
<strong style="color: inherit;">Drag the Group By node</strong> onto the canvas now!
|
|
20721
|
+
</p>
|
|
20722
|
+
<p>This will let you calculate the <strong>total revenue per country</strong> from your sales data.</p>
|
|
20723
|
+
`,
|
|
20724
|
+
target: "[data-tutorial-node='group_by']",
|
|
20725
|
+
position: "right",
|
|
20726
|
+
action: "drag",
|
|
20727
|
+
actionTarget: ".vue-flow",
|
|
20728
|
+
showNextButton: true,
|
|
20729
|
+
highlightPadding: 4
|
|
20730
|
+
},
|
|
20731
|
+
// Step 12: Connect nodes with grouping context
|
|
20732
|
+
{
|
|
20733
|
+
id: "connect-nodes",
|
|
20734
|
+
title: "Connect Your Nodes",
|
|
20735
|
+
content: `
|
|
20736
|
+
<p>To make data flow between nodes, you need to <strong>connect them</strong>.</p>
|
|
20737
|
+
<p>Look for the small circles (handles) on each node:</p>
|
|
20738
|
+
<ul style="margin: 12px 0; padding-left: 20px;">
|
|
20739
|
+
<li><strong>Right side</strong> - Output handle (data goes out)</li>
|
|
20740
|
+
<li><strong>Left side</strong> - Input handle (data comes in)</li>
|
|
20741
|
+
</ul>
|
|
20742
|
+
<p><strong>Click and drag</strong> from Manual Input's output to Group By's input.</p>
|
|
20743
|
+
<p style="margin-top: 12px;">Once connected, click on Group By to configure it - select <strong>country</strong> as the group column and <strong>sum of revenue</strong> as the aggregation!</p>
|
|
20744
|
+
`,
|
|
20745
|
+
target: ".vue-flow",
|
|
20746
|
+
position: "center",
|
|
20747
|
+
action: "observe",
|
|
20748
|
+
showNextButton: true,
|
|
20749
|
+
highlightPadding: 0,
|
|
20750
|
+
onExit: () => {
|
|
20751
|
+
const nodeStore = useNodeStore();
|
|
20752
|
+
nodeStore.nodeId = -1;
|
|
20753
|
+
}
|
|
20754
|
+
},
|
|
20755
|
+
// Step 13: Write data (output operations)
|
|
20756
|
+
{
|
|
20757
|
+
id: "output-overview",
|
|
20758
|
+
title: "Write Your Results",
|
|
20759
|
+
content: `
|
|
20760
|
+
<p>The <strong>Output Operations</strong> section lets you save your results:</p>
|
|
20761
|
+
<ul style="margin: 12px 0; padding-left: 20px;">
|
|
20762
|
+
<li><strong>Write data</strong> - Save to CSV, Parquet, or Excel files</li>
|
|
20763
|
+
<li><strong>Database Writer</strong> - Save to a database</li>
|
|
20764
|
+
<li><strong>Cloud Storage</strong> - Upload to S3, GCS, etc.</li>
|
|
20765
|
+
</ul>
|
|
20766
|
+
`,
|
|
20767
|
+
target: "[data-tutorial-category='output']",
|
|
20768
|
+
position: "right",
|
|
20769
|
+
action: "observe",
|
|
20770
|
+
showNextButton: true,
|
|
20771
|
+
highlightPadding: 4
|
|
20772
|
+
},
|
|
20773
|
+
// Step 13: Drag Write data node
|
|
20774
|
+
{
|
|
20775
|
+
id: "drag-write-data",
|
|
20776
|
+
title: "Add Write Data Node",
|
|
20777
|
+
content: `
|
|
20778
|
+
<p>Now <strong>drag the Write data node</strong> onto the canvas.</p>
|
|
20779
|
+
<p>This will let you save your aggregated revenue per country to a CSV file!</p>
|
|
20780
|
+
<p>After adding it, connect it to the Group By node's output.</p>
|
|
20781
|
+
`,
|
|
20782
|
+
target: "[data-tutorial-node='output']",
|
|
20783
|
+
position: "right",
|
|
20784
|
+
action: "drag",
|
|
20785
|
+
actionTarget: ".vue-flow",
|
|
20786
|
+
showNextButton: true,
|
|
20787
|
+
highlightPadding: 4
|
|
20788
|
+
},
|
|
20789
|
+
// Step 14: Connect and configure nodes
|
|
20790
|
+
{
|
|
20791
|
+
id: "configure-write-data",
|
|
20792
|
+
title: "Connect and Configure Your Nodes",
|
|
20793
|
+
content: `
|
|
20794
|
+
<p>Now it's time to wire everything together!</p>
|
|
20795
|
+
<p><strong>Steps to complete:</strong></p>
|
|
20796
|
+
<ol style="margin: 12px 0; padding-left: 20px;">
|
|
20797
|
+
<li>Connect <strong>Group By → Write data</strong></li>
|
|
20798
|
+
<li>Click on <strong>Write data</strong> to set the output file path</li>
|
|
20799
|
+
</ol>
|
|
20800
|
+
<p style="font-size: 12px; color: var(--color-text-secondary);">Drag from output handles (right side) to input handles (left side) to connect nodes.</p>
|
|
20801
|
+
`,
|
|
20802
|
+
position: "center",
|
|
20803
|
+
action: "observe",
|
|
20804
|
+
showNextButton: true,
|
|
20805
|
+
onExit: () => {
|
|
20806
|
+
const nodeStore = useNodeStore();
|
|
20807
|
+
nodeStore.nodeId = -1;
|
|
20808
|
+
}
|
|
20809
|
+
},
|
|
20810
|
+
// Step 15: Execution settings
|
|
20811
|
+
{
|
|
20812
|
+
id: "execution-settings",
|
|
20813
|
+
title: "Configure Execution Mode",
|
|
20814
|
+
content: `
|
|
20815
|
+
<p>Before running, let's check the <strong>execution settings</strong>.</p>
|
|
20816
|
+
<p>Click the <strong>Settings</strong> button to open execution options.</p>
|
|
20817
|
+
<p>Make sure <strong>Development</strong> mode is selected - this gives you detailed feedback and is perfect for building and testing flows!</p>
|
|
20818
|
+
`,
|
|
20819
|
+
target: "[data-tutorial='settings-btn']",
|
|
20820
|
+
position: "bottom",
|
|
20821
|
+
action: "observe",
|
|
20822
|
+
showNextButton: true,
|
|
20823
|
+
highlightPadding: 4
|
|
20824
|
+
},
|
|
20825
|
+
// Step 16: Run the flow
|
|
20826
|
+
{
|
|
20827
|
+
id: "run-flow",
|
|
20828
|
+
title: "Run Your Flow",
|
|
20829
|
+
content: `
|
|
20830
|
+
<p>Now click <strong>Run</strong> to execute your flow!</p>
|
|
20831
|
+
<p>Flowfile will process your data through each node in sequence.</p>
|
|
20832
|
+
<p>Watch the nodes change color as they execute:</p>
|
|
20833
|
+
<ul style="margin: 12px 0; padding-left: 20px;">
|
|
20834
|
+
<li><strong>Blue</strong> - Currently running</li>
|
|
20835
|
+
<li><strong>Green</strong> - Completed successfully</li>
|
|
20836
|
+
<li><strong>Red</strong> - Error occurred</li>
|
|
20837
|
+
</ul>
|
|
20838
|
+
`,
|
|
20839
|
+
target: "[data-tutorial='run-btn']",
|
|
20840
|
+
position: "bottom",
|
|
20841
|
+
action: "observe",
|
|
20842
|
+
showNextButton: true,
|
|
20843
|
+
highlightPadding: 4
|
|
20844
|
+
},
|
|
20845
|
+
// Step 16: View results and explore pipeline
|
|
20846
|
+
{
|
|
20847
|
+
id: "view-results",
|
|
20848
|
+
title: "Explore Your Results",
|
|
20849
|
+
content: `
|
|
20850
|
+
<p style="font-size: 15px;">Wait for the success message and then your flow has finished running!</p>
|
|
20851
|
+
<p><strong>Click on any node</strong> to see its output in the Table Preview below.</p>
|
|
20852
|
+
<p>Try clicking on different nodes:</p>
|
|
20853
|
+
<ul style="margin: 12px 0; padding-left: 20px;">
|
|
20854
|
+
<li><strong>Manual Input</strong> - Your raw sales data</li>
|
|
20855
|
+
<li><strong>Group By</strong> - Total revenue per country</li>
|
|
20856
|
+
<li><strong>Write data</strong> - Final output to be saved</li>
|
|
20857
|
+
</ul>
|
|
20858
|
+
<p style="font-size: 12px; color: var(--color-text-secondary);"><strong>Tip:</strong> If you don't see any data, make sure you have set up the flow to run in Development mode.</p>
|
|
20859
|
+
`,
|
|
20860
|
+
position: "center",
|
|
20861
|
+
action: "observe",
|
|
20862
|
+
showNextButton: true
|
|
20863
|
+
},
|
|
20864
|
+
// Step 17: Save the flow
|
|
20865
|
+
{
|
|
20866
|
+
id: "save-flow",
|
|
20867
|
+
title: "Save Your Flow",
|
|
20868
|
+
content: `
|
|
20869
|
+
<p>Let's save your flow so you can use it again!</p>
|
|
20870
|
+
<p>Click the <strong>Save</strong> button to choose where to save your flow file.</p>
|
|
20871
|
+
`,
|
|
20872
|
+
target: "[data-tutorial='save-btn']",
|
|
20873
|
+
position: "bottom",
|
|
20874
|
+
action: "observe",
|
|
20875
|
+
showNextButton: true,
|
|
20876
|
+
highlightPadding: 4
|
|
20877
|
+
},
|
|
20878
|
+
// Step 18: YAML format explanation
|
|
20879
|
+
{
|
|
20880
|
+
id: "yaml-format",
|
|
20881
|
+
title: "Flows are Saved as YAML",
|
|
20882
|
+
content: `
|
|
20883
|
+
<p>Flowfile saves your flows in <strong>YAML format</strong> (.yaml or .yml).</p>
|
|
20884
|
+
<p>This means your flows are:</p>
|
|
20885
|
+
<ul style="margin: 12px 0; padding-left: 20px;">
|
|
20886
|
+
<li><strong>Human-readable</strong> - Open and edit in any text editor</li>
|
|
20887
|
+
<li><strong>Version-control friendly</strong> - Track changes with Git</li>
|
|
20888
|
+
<li><strong>Portable</strong> - Share flows with your team</li>
|
|
20889
|
+
<li><strong>Scriptable</strong> - Run from command line</li>
|
|
20890
|
+
</ul>
|
|
20891
|
+
<p>You can even edit your flows manually if needed!</p>
|
|
20892
|
+
`,
|
|
20893
|
+
position: "center",
|
|
20894
|
+
action: "observe",
|
|
20895
|
+
showNextButton: true,
|
|
20896
|
+
centerInScreen: true
|
|
20897
|
+
},
|
|
20898
|
+
// Step 19: Generate code
|
|
20899
|
+
{
|
|
20900
|
+
id: "generate-code",
|
|
20901
|
+
title: "Generate Python Code",
|
|
20902
|
+
content: `
|
|
20903
|
+
<p>Want to use your flow in Python?</p>
|
|
20904
|
+
<p>Click <strong>Generate Code</strong> to export your flow as Python/Polars code!</p>
|
|
20905
|
+
<p>This is great for:</p>
|
|
20906
|
+
<ul style="margin: 12px 0; padding-left: 20px;">
|
|
20907
|
+
<li>Integrating with Python projects</li>
|
|
20908
|
+
<li>Learning how Polars works</li>
|
|
20909
|
+
<li>Creating production pipelines</li>
|
|
20910
|
+
</ul>
|
|
20911
|
+
`,
|
|
20912
|
+
target: "[data-tutorial='generate-code-btn']",
|
|
20913
|
+
position: "bottom",
|
|
20914
|
+
action: "click",
|
|
20915
|
+
showNextButton: true,
|
|
20916
|
+
highlightPadding: 4
|
|
20917
|
+
},
|
|
20918
|
+
// Step 20: Code preview
|
|
20919
|
+
{
|
|
20920
|
+
id: "code-preview",
|
|
20921
|
+
title: "Your Python Code",
|
|
20922
|
+
content: `
|
|
20923
|
+
<p>Here's your flow as <strong>Python/Polars code</strong>!</p>
|
|
20924
|
+
<p>You can:</p>
|
|
20925
|
+
<ul style="margin: 12px 0; padding-left: 20px;">
|
|
20926
|
+
<li>Click <strong>Export Code</strong> to save as a .py file</li>
|
|
20927
|
+
<li>Copy the code directly from the editor</li>
|
|
20928
|
+
<li>Click <strong>Refresh</strong> to regenerate after changes</li>
|
|
20929
|
+
</ul>
|
|
20930
|
+
<p>The code is fully functional and can run standalone!</p>
|
|
20931
|
+
`,
|
|
20932
|
+
position: "center",
|
|
20933
|
+
action: "observe",
|
|
20934
|
+
showNextButton: true
|
|
20935
|
+
},
|
|
20936
|
+
// Step 21: Keyboard shortcuts
|
|
20937
|
+
{
|
|
20938
|
+
id: "keyboard-shortcuts",
|
|
20939
|
+
title: "Keyboard Shortcuts",
|
|
20940
|
+
content: `
|
|
20941
|
+
<p>Speed up your workflow with keyboard shortcuts:</p>
|
|
20942
|
+
<ul style="margin: 12px 0; padding-left: 20px;">
|
|
20943
|
+
<li><strong>Ctrl+S</strong> - Save flow</li>
|
|
20944
|
+
<li><strong>Ctrl+E</strong> - Run flow</li>
|
|
20945
|
+
<li><strong>Ctrl+G</strong> - Generate code</li>
|
|
20946
|
+
<li><strong>Ctrl+N</strong> - Quick create new flow</li>
|
|
20947
|
+
<li><strong>Ctrl+C/V</strong> - Copy/paste nodes</li>
|
|
20948
|
+
<li><strong>Delete</strong> - Remove selected node</li>
|
|
20949
|
+
</ul>
|
|
20950
|
+
`,
|
|
20951
|
+
position: "center",
|
|
20952
|
+
action: "observe",
|
|
20953
|
+
showNextButton: true
|
|
20954
|
+
},
|
|
20955
|
+
// Step 22: Completion
|
|
20956
|
+
{
|
|
20957
|
+
id: "completion",
|
|
20958
|
+
title: "Congratulations!",
|
|
20959
|
+
content: `
|
|
20960
|
+
<p>You've completed the Getting Started tutorial!</p>
|
|
20961
|
+
<p>You now know how to:</p>
|
|
20962
|
+
<ul style="margin: 12px 0; padding-left: 20px;">
|
|
20963
|
+
<li>Create a new flow</li>
|
|
20964
|
+
<li>Add and configure nodes</li>
|
|
20965
|
+
<li>Connect nodes to build pipelines</li>
|
|
20966
|
+
<li>Run your flow and preview data</li>
|
|
20967
|
+
<li>Save and export your work</li>
|
|
20968
|
+
</ul>
|
|
20969
|
+
<p style="margin-top: 16px;">
|
|
20970
|
+
<strong>Learn more:</strong> Visit our
|
|
20971
|
+
<a href="https://edwardvaneechoud.github.io/Flowfile/" target="_blank" style="color: var(--color-accent); text-decoration: underline;">documentation</a>
|
|
20972
|
+
for advanced features and more tutorials.
|
|
20973
|
+
</p>
|
|
20974
|
+
`,
|
|
20975
|
+
position: "center",
|
|
20976
|
+
action: "observe",
|
|
20977
|
+
showNextButton: true,
|
|
20978
|
+
showPrevButton: false,
|
|
20979
|
+
canSkip: false,
|
|
20980
|
+
centerInScreen: true
|
|
20981
|
+
}
|
|
20982
|
+
]
|
|
20983
|
+
};
|
|
20984
|
+
const _hoisted_1$T = {
|
|
20985
|
+
key: 0,
|
|
20986
|
+
class: "tutorial-start-container"
|
|
20987
|
+
};
|
|
20988
|
+
const DISMISSED_KEY = "flowfile-tutorial-dismissed";
|
|
20989
|
+
const _sfc_main$2 = /* @__PURE__ */ defineComponent({
|
|
20990
|
+
__name: "TutorialStartButton",
|
|
20991
|
+
setup(__props) {
|
|
20992
|
+
const tutorialStore = useTutorialStore();
|
|
20993
|
+
const nodeStore = useNodeStore();
|
|
20994
|
+
const route = useRoute();
|
|
20995
|
+
const isDismissed = ref(false);
|
|
20996
|
+
onMounted(() => {
|
|
20997
|
+
isDismissed.value = localStorage.getItem(DISMISSED_KEY) === "true";
|
|
20998
|
+
});
|
|
20999
|
+
const showButton = computed(() => {
|
|
21000
|
+
const isDesignerPage = route.name === "designer";
|
|
21001
|
+
const hasNoFlow = !nodeStore.flow_id || nodeStore.flow_id <= 0;
|
|
21002
|
+
return isDesignerPage && hasNoFlow && !tutorialStore.isActive && !isDismissed.value;
|
|
21003
|
+
});
|
|
21004
|
+
function startTutorial() {
|
|
21005
|
+
tutorialStore.startTutorial(gettingStartedTutorial);
|
|
21006
|
+
}
|
|
21007
|
+
function dismissButton() {
|
|
21008
|
+
isDismissed.value = true;
|
|
21009
|
+
localStorage.setItem(DISMISSED_KEY, "true");
|
|
21010
|
+
}
|
|
21011
|
+
return (_ctx, _cache) => {
|
|
21012
|
+
return openBlock(), createBlock(Teleport, { to: "body" }, [
|
|
21013
|
+
createVNode(Transition, { name: "float-in" }, {
|
|
21014
|
+
default: withCtx(() => [
|
|
21015
|
+
showButton.value ? (openBlock(), createElementBlock("div", _hoisted_1$T, [
|
|
21016
|
+
createBaseVNode("button", {
|
|
21017
|
+
class: "tutorial-dismiss-btn",
|
|
21018
|
+
title: "Dismiss",
|
|
21019
|
+
onClick: dismissButton
|
|
21020
|
+
}, _cache[0] || (_cache[0] = [
|
|
21021
|
+
createBaseVNode("span", { class: "material-icons" }, "close", -1)
|
|
21022
|
+
])),
|
|
21023
|
+
createBaseVNode("button", {
|
|
21024
|
+
class: "tutorial-start-btn",
|
|
21025
|
+
onClick: startTutorial
|
|
21026
|
+
}, _cache[1] || (_cache[1] = [
|
|
21027
|
+
createBaseVNode("span", { class: "btn-icon material-icons" }, "school", -1),
|
|
21028
|
+
createBaseVNode("div", { class: "btn-content" }, [
|
|
21029
|
+
createBaseVNode("span", { class: "btn-title" }, "New to Flowfile?"),
|
|
21030
|
+
createBaseVNode("span", { class: "btn-subtitle" }, "Start the interactive tutorial")
|
|
21031
|
+
], -1),
|
|
21032
|
+
createBaseVNode("span", { class: "btn-arrow material-icons" }, "arrow_forward", -1)
|
|
21033
|
+
]))
|
|
21034
|
+
])) : createCommentVNode("", true)
|
|
21035
|
+
]),
|
|
21036
|
+
_: 1
|
|
21037
|
+
})
|
|
21038
|
+
]);
|
|
21039
|
+
};
|
|
21040
|
+
}
|
|
21041
|
+
});
|
|
21042
|
+
const TutorialStartButton_vue_vue_type_style_index_0_scoped_36f83d99_lang = "";
|
|
21043
|
+
const TutorialStartButton = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-36f83d99"]]);
|
|
18998
21044
|
const _hoisted_1$S = { class: "app-layout" };
|
|
18999
21045
|
const _hoisted_2$J = { class: "app-layout__content" };
|
|
19000
21046
|
const _hoisted_3$C = { class: "app-layout__page" };
|
|
@@ -19031,7 +21077,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
19031
21077
|
createBaseVNode("div", {
|
|
19032
21078
|
class: normalizeClass(["app-layout__sidebar-wrapper", { minimized: isCollapse.value }])
|
|
19033
21079
|
}, [
|
|
19034
|
-
createVNode(_sfc_main$
|
|
21080
|
+
createVNode(_sfc_main$6, {
|
|
19035
21081
|
"is-collapse": isCollapse.value,
|
|
19036
21082
|
onToggleCollapse: toggleCollapse
|
|
19037
21083
|
}, null, 8, ["is-collapse"])
|
|
@@ -19045,21 +21091,82 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
19045
21091
|
"is-forced": true,
|
|
19046
21092
|
onClose: _cache[0] || (_cache[0] = ($event) => showPasswordModal.value = false),
|
|
19047
21093
|
onSuccess: handlePasswordChanged
|
|
19048
|
-
}, null, 8, ["show"])
|
|
21094
|
+
}, null, 8, ["show"]),
|
|
21095
|
+
createVNode(TutorialOverlay),
|
|
21096
|
+
createVNode(TutorialStartButton)
|
|
19049
21097
|
]);
|
|
19050
21098
|
};
|
|
19051
21099
|
}
|
|
19052
21100
|
});
|
|
19053
21101
|
const AppLayout_vue_vue_type_style_index_0_lang = "";
|
|
21102
|
+
class SetupService {
|
|
21103
|
+
constructor() {
|
|
21104
|
+
__publicField(this, "cachedStatus", null);
|
|
21105
|
+
__publicField(this, "statusPromise", null);
|
|
21106
|
+
}
|
|
21107
|
+
async getSetupStatus(forceRefresh = false) {
|
|
21108
|
+
if (!forceRefresh && this.cachedStatus) {
|
|
21109
|
+
return this.cachedStatus;
|
|
21110
|
+
}
|
|
21111
|
+
if (this.statusPromise) {
|
|
21112
|
+
return this.statusPromise;
|
|
21113
|
+
}
|
|
21114
|
+
this.statusPromise = this.fetchStatus();
|
|
21115
|
+
try {
|
|
21116
|
+
this.cachedStatus = await this.statusPromise;
|
|
21117
|
+
return this.cachedStatus;
|
|
21118
|
+
} finally {
|
|
21119
|
+
this.statusPromise = null;
|
|
21120
|
+
}
|
|
21121
|
+
}
|
|
21122
|
+
async fetchStatus() {
|
|
21123
|
+
const maxRetries = 5;
|
|
21124
|
+
const retryDelay = 1e3;
|
|
21125
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
21126
|
+
try {
|
|
21127
|
+
const response = await axios$1.get("/health/status", {
|
|
21128
|
+
headers: { "X-Skip-Auth-Header": "true" },
|
|
21129
|
+
timeout: 5e3
|
|
21130
|
+
});
|
|
21131
|
+
return response.data;
|
|
21132
|
+
} catch {
|
|
21133
|
+
if (attempt < maxRetries) {
|
|
21134
|
+
await new Promise((resolve2) => setTimeout(resolve2, retryDelay));
|
|
21135
|
+
}
|
|
21136
|
+
}
|
|
21137
|
+
}
|
|
21138
|
+
return {
|
|
21139
|
+
setup_required: true,
|
|
21140
|
+
master_key_configured: false,
|
|
21141
|
+
mode: "unknown"
|
|
21142
|
+
};
|
|
21143
|
+
}
|
|
21144
|
+
async generateKey() {
|
|
21145
|
+
const response = await axios$1.post("/setup/generate-key", null, {
|
|
21146
|
+
headers: { "X-Skip-Auth-Header": "true" }
|
|
21147
|
+
});
|
|
21148
|
+
return response.data;
|
|
21149
|
+
}
|
|
21150
|
+
clearCache() {
|
|
21151
|
+
this.cachedStatus = null;
|
|
21152
|
+
}
|
|
21153
|
+
}
|
|
21154
|
+
const setupService = new SetupService();
|
|
19054
21155
|
const routes = [
|
|
19055
21156
|
{
|
|
19056
21157
|
path: "/",
|
|
19057
21158
|
redirect: "/main"
|
|
19058
21159
|
},
|
|
21160
|
+
{
|
|
21161
|
+
path: "/setup",
|
|
21162
|
+
name: "setup",
|
|
21163
|
+
component: () => __vitePreload(() => import("./SetupView-2d12e01f.js"), true ? ["assets/SetupView-2d12e01f.js","assets/SetupView-ec26f76a.css"] : void 0),
|
|
21164
|
+
meta: { requiresAuth: false, isSetupPage: true }
|
|
21165
|
+
},
|
|
19059
21166
|
{
|
|
19060
21167
|
path: "/login",
|
|
19061
21168
|
name: "login",
|
|
19062
|
-
component: () => __vitePreload(() => import("./LoginView-
|
|
21169
|
+
component: () => __vitePreload(() => import("./LoginView-c33a246a.js"), true ? ["assets/LoginView-c33a246a.js","assets/LoginView-d325d632.css"] : void 0),
|
|
19063
21170
|
meta: { requiresAuth: false }
|
|
19064
21171
|
},
|
|
19065
21172
|
{
|
|
@@ -19075,42 +21182,42 @@ const routes = [
|
|
|
19075
21182
|
{
|
|
19076
21183
|
path: "designer",
|
|
19077
21184
|
name: "designer",
|
|
19078
|
-
component: () => __vitePreload(() => import("./DesignerView-
|
|
21185
|
+
component: () => __vitePreload(() => import("./DesignerView-a4466dab.js").then((n) => n.D), true ? ["assets/DesignerView-a4466dab.js","assets/PopOver-ddcfe4f6.js","assets/PopOver-d96599db.css","assets/index-057d770d.js","assets/vue-codemirror.esm-8f46fb36.js","assets/DesignerView-71d4e9a1.css"] : void 0)
|
|
19079
21186
|
},
|
|
19080
21187
|
{
|
|
19081
21188
|
name: "nodeData",
|
|
19082
21189
|
path: "nodeData",
|
|
19083
|
-
component: () => __vitePreload(() => import("./fullEditor-
|
|
21190
|
+
component: () => __vitePreload(() => import("./fullEditor-7583bef5.js"), true ? ["assets/fullEditor-7583bef5.js","assets/PopOver-ddcfe4f6.js","assets/PopOver-d96599db.css","assets/vue-codemirror.esm-8f46fb36.js","assets/fullEditor-fe9f7e18.css"] : void 0)
|
|
19084
21191
|
},
|
|
19085
21192
|
{
|
|
19086
21193
|
name: "documentation",
|
|
19087
21194
|
path: "documentation",
|
|
19088
|
-
component: () => __vitePreload(() => import("./DocumentationView-
|
|
21195
|
+
component: () => __vitePreload(() => import("./DocumentationView-979afc84.js"), true ? ["assets/DocumentationView-979afc84.js","assets/DocumentationView-9ea6e871.css"] : void 0)
|
|
19089
21196
|
},
|
|
19090
21197
|
{
|
|
19091
21198
|
name: "databaseManager",
|
|
19092
21199
|
path: "databaseManager",
|
|
19093
|
-
component: () => __vitePreload(() => import("./DatabaseView-
|
|
21200
|
+
component: () => __vitePreload(() => import("./DatabaseView-dc877c29.js"), true ? ["assets/DatabaseView-dc877c29.js","assets/api-df48ec50.js","assets/DatabaseView-6655afd6.css"] : void 0)
|
|
19094
21201
|
},
|
|
19095
21202
|
{
|
|
19096
21203
|
name: "cloudConnectionManager",
|
|
19097
21204
|
path: "cloudConnectionManager",
|
|
19098
|
-
component: () => __vitePreload(() => import("./CloudConnectionView-
|
|
21205
|
+
component: () => __vitePreload(() => import("./CloudConnectionView-7a3042c6.js"), true ? ["assets/CloudConnectionView-7a3042c6.js","assets/api-ee542cf7.js","assets/CloudConnectionView-cf85f943.css"] : void 0)
|
|
19099
21206
|
},
|
|
19100
21207
|
{
|
|
19101
21208
|
name: "secretManager",
|
|
19102
21209
|
path: "secretManager",
|
|
19103
|
-
component: () => __vitePreload(() => import("./SecretsView-
|
|
21210
|
+
component: () => __vitePreload(() => import("./SecretsView-c6afc915.js"), true ? ["assets/SecretsView-c6afc915.js","assets/secrets.api-34431884.js","assets/SecretsView-aa291340.css"] : void 0)
|
|
19104
21211
|
},
|
|
19105
21212
|
{
|
|
19106
21213
|
name: "nodeDesigner",
|
|
19107
21214
|
path: "nodeDesigner",
|
|
19108
|
-
component: () => __vitePreload(() => import("./NodeDesigner-
|
|
21215
|
+
component: () => __vitePreload(() => import("./NodeDesigner-5036c392.js"), true ? ["assets/NodeDesigner-5036c392.js","assets/vue-codemirror.esm-8f46fb36.js","assets/index-057d770d.js","assets/NodeDesigner-94cd4dd3.css"] : void 0)
|
|
19109
21216
|
},
|
|
19110
21217
|
{
|
|
19111
21218
|
name: "admin",
|
|
19112
21219
|
path: "admin",
|
|
19113
|
-
component: () => __vitePreload(() => import("./AdminView-
|
|
21220
|
+
component: () => __vitePreload(() => import("./AdminView-c2c7942b.js"), true ? ["assets/AdminView-c2c7942b.js","assets/AdminView-f53bad23.css"] : void 0),
|
|
19114
21221
|
meta: { requiresAdmin: true, hideInElectron: true }
|
|
19115
21222
|
}
|
|
19116
21223
|
]
|
|
@@ -19124,10 +21231,39 @@ const router = createRouter({
|
|
|
19124
21231
|
history: createWebHashHistory("/"),
|
|
19125
21232
|
routes
|
|
19126
21233
|
});
|
|
21234
|
+
let setupChecked = false;
|
|
21235
|
+
let setupRequired = false;
|
|
19127
21236
|
router.beforeEach(async (to, _from, next) => {
|
|
19128
21237
|
const authStore = useAuthStore();
|
|
19129
21238
|
const requiresAuth = to.matched.some((record) => record.meta.requiresAuth !== false);
|
|
19130
21239
|
const hideInElectron = to.matched.some((record) => record.meta.hideInElectron);
|
|
21240
|
+
const isSetupPage = to.matched.some((record) => record.meta.isSetupPage);
|
|
21241
|
+
if (!setupChecked || isSetupPage) {
|
|
21242
|
+
try {
|
|
21243
|
+
const status = await setupService.getSetupStatus(isSetupPage);
|
|
21244
|
+
authService.setModeFromBackend(status.mode);
|
|
21245
|
+
setupRequired = status.setup_required;
|
|
21246
|
+
setupChecked = status.mode !== "unknown";
|
|
21247
|
+
} catch {
|
|
21248
|
+
setupRequired = true;
|
|
21249
|
+
setupChecked = false;
|
|
21250
|
+
}
|
|
21251
|
+
}
|
|
21252
|
+
if (!authService.isInElectronMode()) {
|
|
21253
|
+
if (setupRequired && !isSetupPage) {
|
|
21254
|
+
next({ name: "setup" });
|
|
21255
|
+
return;
|
|
21256
|
+
}
|
|
21257
|
+
if (!setupRequired && isSetupPage) {
|
|
21258
|
+
next({ name: "login" });
|
|
21259
|
+
return;
|
|
21260
|
+
}
|
|
21261
|
+
} else {
|
|
21262
|
+
if (isSetupPage) {
|
|
21263
|
+
next({ name: "designer" });
|
|
21264
|
+
return;
|
|
21265
|
+
}
|
|
21266
|
+
}
|
|
19131
21267
|
if (authService.isAuthenticated() && !authStore.user) {
|
|
19132
21268
|
await authStore.initialize();
|
|
19133
21269
|
}
|
|
@@ -60499,52 +62635,6 @@ const i18n = createI18n({
|
|
|
60499
62635
|
});
|
|
60500
62636
|
const all2 = "";
|
|
60501
62637
|
const main = "";
|
|
60502
|
-
const flowfileCorebaseURL = "http://localhost:63578/";
|
|
60503
|
-
axios$1.defaults.baseURL = flowfileCorebaseURL;
|
|
60504
|
-
axios$1.defaults.withCredentials = true;
|
|
60505
|
-
axios$1.interceptors.request.use(
|
|
60506
|
-
async (config) => {
|
|
60507
|
-
if (config.headers && config.headers["X-Skip-Auth-Header"]) {
|
|
60508
|
-
delete config.headers["X-Skip-Auth-Header"];
|
|
60509
|
-
return config;
|
|
60510
|
-
}
|
|
60511
|
-
try {
|
|
60512
|
-
const token = await authService.getToken();
|
|
60513
|
-
if (token) {
|
|
60514
|
-
config.headers = config.headers || {};
|
|
60515
|
-
config.headers.Authorization = `Bearer ${token}`;
|
|
60516
|
-
}
|
|
60517
|
-
return config;
|
|
60518
|
-
} catch (error) {
|
|
60519
|
-
console.error("Error in request interceptor:", error);
|
|
60520
|
-
return config;
|
|
60521
|
-
}
|
|
60522
|
-
},
|
|
60523
|
-
(error) => {
|
|
60524
|
-
return Promise.reject(error);
|
|
60525
|
-
}
|
|
60526
|
-
);
|
|
60527
|
-
axios$1.interceptors.response.use(
|
|
60528
|
-
(response) => {
|
|
60529
|
-
return response;
|
|
60530
|
-
},
|
|
60531
|
-
async (error) => {
|
|
60532
|
-
var _a;
|
|
60533
|
-
const originalRequest = error.config;
|
|
60534
|
-
if (((_a = error.response) == null ? void 0 : _a.status) === 401 && !originalRequest._retry) {
|
|
60535
|
-
originalRequest._retry = true;
|
|
60536
|
-
try {
|
|
60537
|
-
await authService.getToken();
|
|
60538
|
-
return axios$1(originalRequest);
|
|
60539
|
-
} catch (refreshError) {
|
|
60540
|
-
console.error("Token refresh failed:", refreshError);
|
|
60541
|
-
authService.logout();
|
|
60542
|
-
return Promise.reject(error);
|
|
60543
|
-
}
|
|
60544
|
-
}
|
|
60545
|
-
return Promise.reject(error);
|
|
60546
|
-
}
|
|
60547
|
-
);
|
|
60548
62638
|
const app = createApp(App);
|
|
60549
62639
|
app.directive("click-outside", ClickOutsideDirective);
|
|
60550
62640
|
app.use(stores);
|
|
@@ -60572,92 +62662,99 @@ authService.initialize().then((authenticated) => {
|
|
|
60572
62662
|
}
|
|
60573
62663
|
});
|
|
60574
62664
|
export {
|
|
60575
|
-
|
|
60576
|
-
|
|
60577
|
-
|
|
60578
|
-
|
|
60579
|
-
|
|
62665
|
+
isRef as $,
|
|
62666
|
+
withCtx as A,
|
|
62667
|
+
unref as B,
|
|
62668
|
+
createBlock as C,
|
|
62669
|
+
defineStore as D,
|
|
60580
62670
|
ElNotification as E,
|
|
60581
|
-
|
|
60582
|
-
|
|
60583
|
-
|
|
60584
|
-
|
|
60585
|
-
|
|
60586
|
-
|
|
60587
|
-
|
|
60588
|
-
|
|
60589
|
-
|
|
60590
|
-
|
|
60591
|
-
|
|
60592
|
-
|
|
60593
|
-
|
|
60594
|
-
|
|
60595
|
-
|
|
60596
|
-
|
|
60597
|
-
|
|
60598
|
-
|
|
60599
|
-
|
|
60600
|
-
|
|
60601
|
-
|
|
62671
|
+
getDefaultExportFromCjs as F,
|
|
62672
|
+
computed as G,
|
|
62673
|
+
watch as H,
|
|
62674
|
+
onActivated as I,
|
|
62675
|
+
onMounted as J,
|
|
62676
|
+
Fragment as K,
|
|
62677
|
+
renderList as L,
|
|
62678
|
+
withKeys as M,
|
|
62679
|
+
ElMessage as N,
|
|
62680
|
+
ElMessageBox as O,
|
|
62681
|
+
inject as P,
|
|
62682
|
+
effectScope as Q,
|
|
62683
|
+
provide as R,
|
|
62684
|
+
getCurrentInstance as S,
|
|
62685
|
+
getCurrentScope as T,
|
|
62686
|
+
onScopeDispose as U,
|
|
62687
|
+
createPropsRestProxy as V,
|
|
62688
|
+
toRef as W,
|
|
62689
|
+
renderSlot as X,
|
|
62690
|
+
reactive as Y,
|
|
62691
|
+
useSlots as Z,
|
|
60602
62692
|
_imports_1 as _,
|
|
60603
|
-
|
|
60604
|
-
|
|
60605
|
-
|
|
60606
|
-
|
|
60607
|
-
|
|
60608
|
-
|
|
60609
|
-
|
|
60610
|
-
|
|
60611
|
-
|
|
60612
|
-
|
|
60613
|
-
|
|
60614
|
-
|
|
60615
|
-
|
|
60616
|
-
|
|
60617
|
-
|
|
60618
|
-
|
|
60619
|
-
|
|
60620
|
-
|
|
60621
|
-
|
|
60622
|
-
|
|
60623
|
-
|
|
60624
|
-
|
|
60625
|
-
|
|
60626
|
-
|
|
60627
|
-
|
|
60628
|
-
|
|
60629
|
-
|
|
60630
|
-
|
|
60631
|
-
|
|
60632
|
-
|
|
60633
|
-
|
|
60634
|
-
|
|
60635
|
-
|
|
60636
|
-
|
|
60637
|
-
|
|
60638
|
-
|
|
62693
|
+
createBaseVNode as a,
|
|
62694
|
+
toRefs as a0,
|
|
62695
|
+
customRef as a1,
|
|
62696
|
+
nextTick as a2,
|
|
62697
|
+
onBeforeMount as a3,
|
|
62698
|
+
normalizeStyle as a4,
|
|
62699
|
+
onBeforeUnmount as a5,
|
|
62700
|
+
isMemoSame as a6,
|
|
62701
|
+
toValue as a7,
|
|
62702
|
+
shallowRef as a8,
|
|
62703
|
+
h$1 as a9,
|
|
62704
|
+
useThemeStore as aA,
|
|
62705
|
+
debounce$2 as aB,
|
|
62706
|
+
ElPopover as aC,
|
|
62707
|
+
ElOption$1 as aD,
|
|
62708
|
+
ElSelect as aE,
|
|
62709
|
+
markRaw as aa,
|
|
62710
|
+
readonly as ab,
|
|
62711
|
+
useAttrs$1 as ac,
|
|
62712
|
+
mergeProps as ad,
|
|
62713
|
+
resolveDynamicComponent as ae,
|
|
62714
|
+
watchEffect as af,
|
|
62715
|
+
normalizeProps as ag,
|
|
62716
|
+
defineAsyncComponent as ah,
|
|
62717
|
+
onErrorCaptured as ai,
|
|
62718
|
+
__vitePreload as aj,
|
|
62719
|
+
useFlowStore as ak,
|
|
62720
|
+
Teleport as al,
|
|
62721
|
+
guardReactiveProps as am,
|
|
62722
|
+
Transition as an,
|
|
62723
|
+
render$$ as ao,
|
|
62724
|
+
vShow as ap,
|
|
62725
|
+
authService as aq,
|
|
62726
|
+
flowfileCorebaseURL as ar,
|
|
62727
|
+
useCssVars as as,
|
|
62728
|
+
vModelSelect as at,
|
|
62729
|
+
vModelCheckbox as au,
|
|
62730
|
+
ElDialog as av,
|
|
62731
|
+
ElButton as aw,
|
|
62732
|
+
toRaw as ax,
|
|
62733
|
+
ElIcon as ay,
|
|
62734
|
+
ElRadio as az,
|
|
62735
|
+
createStaticVNode as b,
|
|
60639
62736
|
createElementBlock as c,
|
|
60640
62737
|
defineComponent as d,
|
|
60641
|
-
|
|
60642
|
-
|
|
60643
|
-
|
|
60644
|
-
|
|
60645
|
-
|
|
60646
|
-
|
|
60647
|
-
|
|
60648
|
-
|
|
60649
|
-
|
|
62738
|
+
createCommentVNode as e,
|
|
62739
|
+
createTextVNode as f,
|
|
62740
|
+
_export_sfc as g,
|
|
62741
|
+
useAuthStore as h,
|
|
62742
|
+
withDirectives as i,
|
|
62743
|
+
vModelDynamic as j,
|
|
62744
|
+
axios$1 as k,
|
|
62745
|
+
useNodeStore as l,
|
|
62746
|
+
useEditorStore as m,
|
|
60650
62747
|
normalizeClass as n,
|
|
60651
62748
|
openBlock as o,
|
|
60652
|
-
|
|
60653
|
-
|
|
62749
|
+
useResultsStore as p,
|
|
62750
|
+
onUnmounted as q,
|
|
60654
62751
|
ref as r,
|
|
60655
|
-
|
|
62752
|
+
setupService as s,
|
|
60656
62753
|
toDisplayString$1 as t,
|
|
60657
62754
|
useRouter as u,
|
|
60658
62755
|
vModelText as v,
|
|
60659
62756
|
withModifiers as w,
|
|
60660
|
-
|
|
60661
|
-
|
|
60662
|
-
|
|
62757
|
+
useTutorialStore as x,
|
|
62758
|
+
resolveComponent as y,
|
|
62759
|
+
createVNode as z
|
|
60663
62760
|
};
|