@integry/sdk 4.7.39 → 4.7.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/index.csm.js +1 -1
- package/dist/umd/index.umd.js +1 -1
- package/package.json +6 -1
- package/.eslintignore +0 -1
- package/.vscode/launch.json +0 -17
- package/CHANGELOG_INTERNAL.md +0 -134
- package/README_INTERNAL.md +0 -176
- package/THIRD_PARTY_LICENSES +0 -525
- package/generateTests.js +0 -80
- package/jest.config.cjs +0 -10
- package/src/components/AddTagButton/index.ts +0 -23
- package/src/components/BasicSelect/index.ts +0 -123
- package/src/components/BasicSelect/styles.module.scss +0 -44
- package/src/components/Button/index.ts +0 -97
- package/src/components/Button/styles.module.scss +0 -152
- package/src/components/CheckboxGroup/Checkbox.ts +0 -104
- package/src/components/CheckboxGroup/index.ts +0 -190
- package/src/components/CheckboxGroup/styles.module.scss +0 -63
- package/src/components/CollapsedMenu/index.ts +0 -104
- package/src/components/CollapsedMenu/styles.module.scss +0 -46
- package/src/components/ConfigureFieldWrapper/index.ts +0 -85
- package/src/components/ConfigureFieldWrapper/styles.module.scss +0 -57
- package/src/components/EditableText/index.ts +0 -121
- package/src/components/EditableText/styles.module.scss +0 -38
- package/src/components/EditableTextArea/index.ts +0 -143
- package/src/components/EditableTextArea/styles.module.scss +0 -91
- package/src/components/ErrorMessage/index.ts +0 -16
- package/src/components/ErrorMessage/styles.module.scss +0 -19
- package/src/components/ErrorPage/index.ts +0 -42
- package/src/components/ErrorPage/styles.module.scss +0 -26
- package/src/components/Footer/index.ts +0 -41
- package/src/components/Footer/styles.module.scss +0 -40
- package/src/components/HTMLContent/index.tsx +0 -205
- package/src/components/HTMLContent/styles.module.scss +0 -3
- package/src/components/InfoBox/index.ts +0 -48
- package/src/components/InfoBox/styles.module.scss +0 -21
- package/src/components/Input/BaseInput/index.ts +0 -170
- package/src/components/Input/BaseInput/styles.module.scss +0 -95
- package/src/components/Input/DateInput/index.ts +0 -103
- package/src/components/Input/DateInput/styles.module.scss +0 -50
- package/src/components/Input/Input/index.ts +0 -225
- package/src/components/Input/Input/styles.module.scss +0 -16
- package/src/components/Input/PasswordInput/index.ts +0 -164
- package/src/components/Input/PasswordInput/styles.module.scss +0 -37
- package/src/components/Input/index.ts +0 -7
- package/src/components/Label/index.ts +0 -61
- package/src/components/Label/styles.module.scss +0 -41
- package/src/components/LargeLoader/index.ts +0 -25
- package/src/components/LargeLoader/styles.module.scss +0 -16
- package/src/components/Listbox/ListBoxItem.ts +0 -57
- package/src/components/Listbox/index.ts +0 -488
- package/src/components/Listbox/styles.module.scss +0 -197
- package/src/components/Loader/index.ts +0 -25
- package/src/components/Loader/styles.module.scss +0 -16
- package/src/components/MediaGallery/MediaGalleryModal.ts +0 -82
- package/src/components/MediaGallery/MediaSlider.ts +0 -76
- package/src/components/MediaGallery/index.ts +0 -92
- package/src/components/MediaGallery/styles.module.scss +0 -156
- package/src/components/MediaUpload/index.ts +0 -233
- package/src/components/MediaUpload/styles.module.scss +0 -118
- package/src/components/Modal/index.ts +0 -87
- package/src/components/Modal/styles.module.scss +0 -441
- package/src/components/MultipurposeField/Dropdown/ListBoxItem.tsx +0 -59
- package/src/components/MultipurposeField/Dropdown/index.tsx +0 -1202
- package/src/components/MultipurposeField/Dropdown/styles.module.scss +0 -215
- package/src/components/MultipurposeField/TagMenu/index.ts +0 -536
- package/src/components/MultipurposeField/TagMenu/styles.module.scss +0 -175
- package/src/components/MultipurposeField/TagOptions/index.tsx +0 -83
- package/src/components/MultipurposeField/TagOptions/styles.module.scss +0 -95
- package/src/components/MultipurposeField/index.tsx +0 -944
- package/src/components/MultipurposeField/styles.module.scss +0 -77
- package/src/components/NewModal/index.ts +0 -69
- package/src/components/NewModal/styles.module.scss +0 -70
- package/src/components/OverflowTooltip/index.tsx +0 -59
- package/src/components/PopUp/ConfirmationPopUp/index.ts +0 -58
- package/src/components/PopUp/ConfirmationPopUp/styles.module.scss +0 -49
- package/src/components/PopUp/SuccessPopUp/index.ts +0 -62
- package/src/components/PopUp/SuccessPopUp/styles.module.scss +0 -38
- package/src/components/RadioGroup/Radio.ts +0 -128
- package/src/components/RadioGroup/index.ts +0 -169
- package/src/components/RadioGroup/styles.module.scss +0 -81
- package/src/components/Search/index.ts +0 -69
- package/src/components/Search/styles.module.scss +0 -149
- package/src/components/TabBar/Tab.ts +0 -33
- package/src/components/TabBar/index.ts +0 -64
- package/src/components/TabBar/styles.module.scss +0 -43
- package/src/components/Tag/index.ts +0 -29
- package/src/components/Tag/styles.module.scss +0 -57
- package/src/components/TagsMenu/index.ts +0 -1697
- package/src/components/TagsMenu/styles.module.scss +0 -350
- package/src/components/TestComponent/index.ts +0 -71
- package/src/components/TestComponent/styles.module.scss +0 -152
- package/src/components/TextArea/index.ts +0 -172
- package/src/components/TextArea/styles.module.scss +0 -72
- package/src/components/TextContent/index.tsx +0 -128
- package/src/components/TextContent/styles.module.scss +0 -6
- package/src/components/ThreeDotLoader/index.ts +0 -39
- package/src/components/ThreeDotLoader/styles.module.scss +0 -41
- package/src/components/TimeInput/index.ts +0 -129
- package/src/components/TimeInput/styles.module.scss +0 -16
- package/src/components/Toggle/index.ts +0 -34
- package/src/components/Toggle/styles.module.scss +0 -56
- package/src/components/Toggle-v2/index.ts +0 -40
- package/src/components/Toggle-v2/styles.module.scss +0 -86
- package/src/components/Tooltip/index.ts +0 -271
- package/src/components/Tooltip/styles.module.scss +0 -105
- package/src/components/form/FunctionField/index.ts +0 -816
- package/src/components/form/FunctionField/styles.module.scss +0 -478
- package/src/components/form/ObjectField/__snapshots__/index.ts.test.tsx.snap +0 -3
- package/src/components/form/ObjectField/index.ts +0 -593
- package/src/components/form/ObjectField/index.ts.test.tsx +0 -213
- package/src/components/form/ObjectField/styles.module.scss +0 -103
- package/src/components/form/index.ts +0 -4
- package/src/contexts/AppContext.ts +0 -12
- package/src/declaration.d.ts +0 -7
- package/src/extensions/HMAC.ts +0 -25
- package/src/extensions/IntegryAPIError.ts +0 -19
- package/src/features/common/AccountDropdown/index.ts +0 -291
- package/src/features/common/AccountDropdown/styles.module.scss +0 -19
- package/src/features/common/ActionForm/index.ts +0 -2602
- package/src/features/common/ActionForm/styles.module.scss +0 -35
- package/src/features/common/AppCard/index.ts +0 -207
- package/src/features/common/AppCard/styles.module.scss +0 -117
- package/src/features/common/AppCardCompact/index.ts +0 -189
- package/src/features/common/AppCardCompact/styles.module.scss +0 -141
- package/src/features/common/AuthSelector/index.ts +0 -537
- package/src/features/common/AuthSelector/styles.module.scss +0 -161
- package/src/features/common/AuthSelectorCompact/index.ts +0 -706
- package/src/features/common/AuthSelectorCompact/styles.module.scss +0 -219
- package/src/features/common/AuthSelectorDropdown/index.ts +0 -704
- package/src/features/common/AuthSelectorDropdown/styles.module.scss +0 -361
- package/src/features/common/AuthSelectorV2/index.ts +0 -336
- package/src/features/common/AuthSelectorV2/styles.module.scss +0 -235
- package/src/features/common/DynamicField/index.ts +0 -402
- package/src/features/common/DynamicField/styles.module.scss +0 -266
- package/src/features/common/DynamicTypedField/index.ts +0 -504
- package/src/features/common/DynamicTypedField/styles.module.scss +0 -135
- package/src/features/common/FunctionForm/index.ts +0 -1095
- package/src/features/common/FunctionForm/styles.module.scss +0 -225
- package/src/features/common/MappingUI/index.ts +0 -649
- package/src/features/common/MappingUI/styles.module.scss +0 -121
- package/src/features/common/MarketplaceAppCard/index.ts +0 -279
- package/src/features/common/MarketplaceAppCard/styles.module.scss +0 -231
- package/src/features/common/MarketplaceAppCardCompact/index.ts +0 -283
- package/src/features/common/MarketplaceAppCardCompact/styles.module.scss +0 -255
- package/src/features/common/NewMappingUI/index.ts +0 -515
- package/src/features/common/NewMappingUI/styles.module.scss +0 -113
- package/src/features/common/RequestAppWidget/RequestAppModal/index.ts +0 -67
- package/src/features/common/RequestAppWidget/RequestAppModal/styles.module.scss +0 -23
- package/src/features/common/RequestAppWidget/index.ts +0 -48
- package/src/features/common/RequestAppWidget/request-app-form.ts +0 -89
- package/src/features/common/RequestAppWidget/styles.module.scss +0 -43
- package/src/features/common/SectionField/index.ts +0 -272
- package/src/features/common/SectionField/styles.module.scss +0 -67
- package/src/features/common/Step/index.ts +0 -827
- package/src/features/common/Step/styles.module.scss +0 -12
- package/src/features/common/StepNavigation/CollapsedSteps.ts +0 -131
- package/src/features/common/StepNavigation/NavItem.ts +0 -111
- package/src/features/common/StepNavigation/index.ts +0 -261
- package/src/features/common/StepNavigation/styles.module.scss +0 -117
- package/src/features/common/Steps/index.ts +0 -1140
- package/src/features/common/Steps/styles.module.scss +0 -314
- package/src/features/containers/AppFlowContainer/AppFlowListing/compactStyles.module.scss +0 -404
- package/src/features/containers/AppFlowContainer/AppFlowListing/flow-instance.tsx +0 -367
- package/src/features/containers/AppFlowContainer/AppFlowListing/flowCard.test.tsx +0 -58
- package/src/features/containers/AppFlowContainer/AppFlowListing/flowCard.tsx +0 -208
- package/src/features/containers/AppFlowContainer/AppFlowListing/flowCardCompact.test.tsx +0 -49
- package/src/features/containers/AppFlowContainer/AppFlowListing/flowCardCompact.tsx +0 -421
- package/src/features/containers/AppFlowContainer/AppFlowListing/flowInstanceCompact.tsx +0 -577
- package/src/features/containers/AppFlowContainer/AppFlowListing/index.tsx +0 -83
- package/src/features/containers/AppFlowContainer/AppFlowListing/styles.module.scss +0 -233
- package/src/features/containers/AppFlowContainer/AppFlowWrap/app-page-loader.tsx +0 -45
- package/src/features/containers/AppFlowContainer/AppFlowWrap/index.tsx +0 -1085
- package/src/features/containers/AppFlowContainer/AppFlowWrap/styles.module.scss +0 -465
- package/src/features/containers/AppFlowContainer/Authentication/index.ts +0 -610
- package/src/features/containers/AppFlowContainer/Authentication/styles.module.scss +0 -468
- package/src/features/containers/AppFlowContainer/index.ts +0 -114
- package/src/features/containers/AppPageContainer/AppPage/index.tsx +0 -262
- package/src/features/containers/AppPageContainer/AppPage/styles.module.scss +0 -120
- package/src/features/containers/AppPageContainer/IntegrationCard/index.ts +0 -165
- package/src/features/containers/AppPageContainer/IntegrationCard/styles.module.scss +0 -81
- package/src/features/containers/AppPageContainer/index.tsx +0 -93
- package/src/features/containers/AppPageContainer/styles.module.scss +0 -0
- package/src/features/containers/AppsForFlows/index.ts +0 -161
- package/src/features/containers/AppsForFlows/styles.module.scss +0 -280
- package/src/features/containers/AppsForFlowsCompact/index.ts +0 -161
- package/src/features/containers/AppsForFlowsCompact/styles.module.scss +0 -279
- package/src/features/containers/AuthSetupContainer/AppSelection.ts +0 -73
- package/src/features/containers/AuthSetupContainer/AuthTypeSelection.ts +0 -67
- package/src/features/containers/AuthSetupContainer/Footer.ts +0 -32
- package/src/features/containers/AuthSetupContainer/Header.ts +0 -39
- package/src/features/containers/AuthSetupContainer/PostAdditionPopup.ts +0 -27
- package/src/features/containers/AuthSetupContainer/index.ts +0 -349
- package/src/features/containers/AuthSetupContainer/styles.module.scss +0 -229
- package/src/features/containers/FlowSetupContainer/index.ts +0 -391
- package/src/features/containers/FlowSetupContainer/styles.module.scss +0 -18
- package/src/features/containers/MarkeplaceApps/index.ts +0 -583
- package/src/features/containers/MarkeplaceApps/styles.module.scss +0 -558
- package/src/features/containers/MarketplaceAppsCompact/index.ts +0 -585
- package/src/features/containers/MarketplaceAppsCompact/styles.module.scss +0 -563
- package/src/features/containers/MarketplaceAppsContainer/index.ts +0 -91
- package/src/features/containers/MarketplaceContainer/AppCard/index.ts +0 -91
- package/src/features/containers/MarketplaceContainer/AppCard/styles.module.scss +0 -66
- package/src/features/containers/MarketplaceContainer/AppListing/index.ts +0 -34
- package/src/features/containers/MarketplaceContainer/AppListing/styles.module.scss +0 -10
- package/src/features/containers/MarketplaceContainer/MarketplaceContentWrap/index.ts +0 -132
- package/src/features/containers/MarketplaceContainer/MarketplaceContentWrap/styles.module.scss +0 -117
- package/src/features/containers/MarketplaceContainer/index.ts +0 -242
- package/src/features/containers/MarketplaceContainer/styles.module.scss +0 -84
- package/src/features/containers/SDKContainer/index.ts +0 -817
- package/src/features/containers/SDKContainer/styles.module.scss +0 -266
- package/src/features/containers/SDKDebugContainer/index.ts +0 -137
- package/src/features/containers/SDKDebugContainer/styles.module.scss +0 -37
- package/src/features/containers/SDKFailedContainer/index.ts +0 -117
- package/src/features/containers/SDKFailedContainer/styles.module.scss +0 -57
- package/src/features/integrations/IntegrationRow/Icons.ts +0 -77
- package/src/features/integrations/IntegrationRow/index.ts +0 -129
- package/src/features/integrations/IntegrationRow/styles.module.scss +0 -62
- package/src/features/integrations/IntegrationsHeader/index.ts +0 -34
- package/src/features/integrations/IntegrationsHeader/styles.module.scss +0 -47
- package/src/features/integrations/IntegrationsList/index.ts +0 -252
- package/src/features/integrations/IntegrationsList/styles.module.scss +0 -67
- package/src/features/templates/Template/index.ts +0 -295
- package/src/features/templates/Template/styles.module.scss +0 -226
- package/src/features/templates/TemplatesView/index.ts +0 -368
- package/src/features/templates/TemplatesView/styles.module.scss +0 -71
- package/src/features/templates/TemplatesViewCompact/index.ts +0 -364
- package/src/features/templates/TemplatesViewCompact/styles.module.scss +0 -141
- package/src/hooks/useAutosizeTextArea.ts +0 -22
- package/src/hooks/useCustomRef.ts +0 -13
- package/src/hooks/useDebounce.ts +0 -17
- package/src/hooks/useElementResize.ts +0 -40
- package/src/hooks/useEventListener.ts +0 -42
- package/src/hooks/useHover.ts +0 -40
- package/src/hooks/useOnClickOutside.ts +0 -32
- package/src/index.ts +0 -2244
- package/src/index.umd.ts +0 -13
- package/src/interfaces/index.ts +0 -938
- package/src/modules/api/index.ts +0 -1325
- package/src/modules/api/responseHandler.ts +0 -38
- package/src/modules/event-emitter/index.ts +0 -72
- package/src/modules/event-emitter/runners/abstract.ts +0 -21
- package/src/modules/event-emitter/runners/default.ts +0 -11
- package/src/modules/event-emitter/runners/ntimes.ts +0 -28
- package/src/modules/event-emitter/types.ts +0 -34
- package/src/store/actionFunctions.ts +0 -1578
- package/src/store/index.ts +0 -17
- package/src/store/initialState.ts +0 -58
- package/src/types/index.ts +0 -320
- package/src/types/preact-compat.d.ts +0 -4
- package/src/types/store.ts +0 -366
- package/src/types/utils.ts +0 -19
- package/src/utils/ActivityOutputUtils.ts +0 -176
- package/src/utils/common.ts +0 -20
- package/src/utils/copyToClipboard.ts +0 -24
- package/src/utils/datetime.ts +0 -101
- package/src/utils/getUrlParam.ts +0 -11
- package/src/utils/isAuthMessage.ts +0 -16
- package/src/utils/isBrowser.ts +0 -1
- package/src/utils/jsonEncodeDecode.ts +0 -15
- package/src/utils/objectUtils.ts +0 -117
- package/src/utils/popup.ts +0 -30
- package/src/utils/searchJson.ts +0 -51
- package/src/utils/stepUtils.ts +0 -45
- package/src/utils/truncate.ts +0 -6
- package/test/setup.ts +0 -1
- package/vitest.config.ts +0 -16
|
@@ -1,1697 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import { html } from 'htm/preact';
|
|
4
|
-
import { useState, useEffect } from 'preact/hooks';
|
|
5
|
-
import { Hint } from '@/components/Tooltip';
|
|
6
|
-
import styles from './styles.module.scss';
|
|
7
|
-
|
|
8
|
-
// Update the TagNode interface to better handle various types
|
|
9
|
-
interface TagNode {
|
|
10
|
-
name?: string; // Step name or field name
|
|
11
|
-
machineName?: string; // Machine-readable name for the step
|
|
12
|
-
appIcon?: string; // URL for the step's app icon
|
|
13
|
-
output?: Record<string, unknown> | unknown[]; // JSON data for step output
|
|
14
|
-
tags?: Record<string, TagNode>; // Nested tags or fields
|
|
15
|
-
ignoreParentKey?: boolean; // If true, omit parent key from final tag path
|
|
16
|
-
[key: string]: unknown; // Allow for additional properties
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
// Define the structure of the entire data object
|
|
20
|
-
interface TagData {
|
|
21
|
-
[key: string]: TagNode;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
// Add this interface for the Values tab items
|
|
25
|
-
interface ValueItem {
|
|
26
|
-
id: number;
|
|
27
|
-
value: string;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// Define the props for the TagMenu component
|
|
31
|
-
interface TagMenuProps {
|
|
32
|
-
data: TagData;
|
|
33
|
-
onSelect: (tag: TagNode | Record<string, unknown>) => void;
|
|
34
|
-
onOptionClick?: (option: Record<string, unknown>) => void;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
interface TagListProps {
|
|
38
|
-
tags: Record<string, unknown> | unknown[];
|
|
39
|
-
searchTerm: string;
|
|
40
|
-
level?: number;
|
|
41
|
-
path?: string;
|
|
42
|
-
globalSearchMode?: boolean;
|
|
43
|
-
onSelect?: (tag: Record<string, unknown>) => void;
|
|
44
|
-
activeTab?: string;
|
|
45
|
-
parentAppIcon?: string; // Add parent app icon to props
|
|
46
|
-
ignoreParentKey?: boolean; // whether parent key should be ignored in tag path
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
interface TagsMenuProps {
|
|
50
|
-
tagsTree: Record<string, unknown>;
|
|
51
|
-
onSelect: (tag: Record<string, unknown>) => void;
|
|
52
|
-
renderValuesTab?: boolean;
|
|
53
|
-
options?: Record<string, unknown>;
|
|
54
|
-
onOptionClick?: (option: Record<string, unknown>) => void;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// Helper function to convert nested tags arrays to objects
|
|
58
|
-
function convertNestedTagsToObject(tags: TagNode[]): Record<string, TagNode> {
|
|
59
|
-
const result: Record<string, TagNode> = {};
|
|
60
|
-
|
|
61
|
-
tags.forEach((tag, index) => {
|
|
62
|
-
const tagKey = tag.machineName || `[${index}]`;
|
|
63
|
-
|
|
64
|
-
if (tag.tags && Array.isArray(tag.tags)) {
|
|
65
|
-
result[tagKey] = {
|
|
66
|
-
...tag,
|
|
67
|
-
tags: convertNestedTagsToObject(tag.tags),
|
|
68
|
-
};
|
|
69
|
-
} else {
|
|
70
|
-
result[tagKey] = tag;
|
|
71
|
-
}
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
return result;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// Add a type guard function to check if a value is a TagNode
|
|
78
|
-
function isTagNode(value: unknown): value is TagNode {
|
|
79
|
-
return (
|
|
80
|
-
value !== null &&
|
|
81
|
-
typeof value === 'object' &&
|
|
82
|
-
!Array.isArray(value) &&
|
|
83
|
-
Object.prototype.hasOwnProperty.call(value, 'machineName')
|
|
84
|
-
);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// Update the arrayToObject function with proper typing
|
|
88
|
-
const arrayToObject = (arr: unknown[]): Record<string, unknown> =>
|
|
89
|
-
arr.reduce<Record<string, unknown>>((obj, item, index) => {
|
|
90
|
-
const newObj = { ...obj };
|
|
91
|
-
newObj[`[${index}]`] = item;
|
|
92
|
-
return newObj;
|
|
93
|
-
}, {});
|
|
94
|
-
|
|
95
|
-
// Check if output data matches the search term
|
|
96
|
-
const outputMatchesSearch = (output: unknown, term: string): boolean => {
|
|
97
|
-
if (!term || !output) return false;
|
|
98
|
-
const lowerTerm = term.toLowerCase();
|
|
99
|
-
|
|
100
|
-
if (typeof output === 'string') {
|
|
101
|
-
return output.toLowerCase().includes(lowerTerm);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
if (Array.isArray(output)) {
|
|
105
|
-
return output.some(
|
|
106
|
-
(item) =>
|
|
107
|
-
(typeof item === 'string' && item.toLowerCase().includes(lowerTerm)) ||
|
|
108
|
-
(typeof item === 'object' &&
|
|
109
|
-
item !== null &&
|
|
110
|
-
outputMatchesSearch(item, lowerTerm)),
|
|
111
|
-
);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
if (typeof output === 'object' && output !== null) {
|
|
115
|
-
return Object.entries(output as Record<string, unknown>).some(
|
|
116
|
-
([key, val]) => {
|
|
117
|
-
if (key.toLowerCase().includes(lowerTerm)) return true;
|
|
118
|
-
|
|
119
|
-
if (typeof val === 'string') {
|
|
120
|
-
return val.toLowerCase().includes(lowerTerm);
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
if (typeof val === 'object' && val !== null) {
|
|
124
|
-
return outputMatchesSearch(val, lowerTerm);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
return false;
|
|
128
|
-
},
|
|
129
|
-
);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
return false;
|
|
133
|
-
};
|
|
134
|
-
|
|
135
|
-
// Function to count matches in a generic object
|
|
136
|
-
const countMatchesInObject = (obj: unknown, term: string): number => {
|
|
137
|
-
if (!obj || typeof obj !== 'object') return 0;
|
|
138
|
-
|
|
139
|
-
let count = 0;
|
|
140
|
-
|
|
141
|
-
// Handle arrays specifically
|
|
142
|
-
if (Array.isArray(obj)) {
|
|
143
|
-
obj.forEach((item) => {
|
|
144
|
-
if (typeof item === 'string' && item.toLowerCase().includes(term)) {
|
|
145
|
-
count += 1;
|
|
146
|
-
} else if (typeof item === 'object' && item !== null) {
|
|
147
|
-
count += countMatchesInObject(item, term);
|
|
148
|
-
}
|
|
149
|
-
});
|
|
150
|
-
return count;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
Object.entries(obj as Record<string, unknown>).forEach(([key, value]) => {
|
|
154
|
-
if (key.toLowerCase().includes(term)) {
|
|
155
|
-
count += 1;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
if (typeof value === 'string' && value.toLowerCase().includes(term)) {
|
|
159
|
-
count += 1;
|
|
160
|
-
} else if (typeof value === 'object' && value !== null) {
|
|
161
|
-
count += countMatchesInObject(value, term);
|
|
162
|
-
}
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
return count;
|
|
166
|
-
};
|
|
167
|
-
|
|
168
|
-
// Count matches in a nested structure
|
|
169
|
-
const countSearchMatches = (
|
|
170
|
-
tags: Record<string, TagNode>,
|
|
171
|
-
term: string,
|
|
172
|
-
): number => {
|
|
173
|
-
let count = 0;
|
|
174
|
-
|
|
175
|
-
Object.entries(tags).forEach(([key, value]) => {
|
|
176
|
-
// Check if the key, name, or machineName matches
|
|
177
|
-
if (
|
|
178
|
-
key.toLowerCase().includes(term) ||
|
|
179
|
-
(isTagNode(value) &&
|
|
180
|
-
value.name &&
|
|
181
|
-
value.name.toLowerCase().includes(term)) ||
|
|
182
|
-
(isTagNode(value) &&
|
|
183
|
-
value.machineName &&
|
|
184
|
-
value.machineName.toLowerCase().includes(term))
|
|
185
|
-
) {
|
|
186
|
-
count += 1;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
// Check output data for matches
|
|
190
|
-
if (value.output) {
|
|
191
|
-
count += countMatchesInObject(value.output, term);
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
// Check nested tags
|
|
195
|
-
if (value.tags) {
|
|
196
|
-
count += countSearchMatches(value.tags, term);
|
|
197
|
-
}
|
|
198
|
-
});
|
|
199
|
-
|
|
200
|
-
return count;
|
|
201
|
-
};
|
|
202
|
-
|
|
203
|
-
// Type icon component to render different icons based on data type
|
|
204
|
-
const TypeIcon = ({ value }: { value: unknown }) => {
|
|
205
|
-
// Determine the type of value
|
|
206
|
-
const getTypeIcon = (iconValue: unknown) => {
|
|
207
|
-
if (iconValue === null || iconValue === undefined) {
|
|
208
|
-
return html`
|
|
209
|
-
<svg
|
|
210
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
211
|
-
width="24"
|
|
212
|
-
height="24"
|
|
213
|
-
viewBox="0 0 24 24"
|
|
214
|
-
fill="none"
|
|
215
|
-
stroke="currentColor"
|
|
216
|
-
strokeWidth="2"
|
|
217
|
-
strokeLinecap="round"
|
|
218
|
-
strokeLinejoin="round"
|
|
219
|
-
class="lucide lucide-ban h-4 w-4"
|
|
220
|
-
>
|
|
221
|
-
<circle cx="12" cy="12" r="10"></circle>
|
|
222
|
-
<path d="m4.93 4.93 14.14 14.14"></path>
|
|
223
|
-
</svg>
|
|
224
|
-
`;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
if (typeof iconValue === 'string') {
|
|
228
|
-
return html`
|
|
229
|
-
<img
|
|
230
|
-
src="data:image/svg+xml,%3csvg%20width='23'%20height='15'%20viewBox='0%200%2023%2015'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20fill-rule='evenodd'%20clip-rule='evenodd'%20d='M4.12408%2010.2498H9.09622L9.5856%2011.7004H9.08601C8.59375%2011.7004%208.24266%2011.8106%208.03275%2012.0311C7.82284%2012.2516%207.71835%2012.536%207.71835%2012.8844C7.71835%2013.24%207.82284%2013.5289%208.03275%2013.7493C8.24266%2013.9698%208.59375%2014.08%209.08601%2014.08H11.8424C12.3347%2014.08%2012.6839%2013.9698%2012.8902%2013.7493C13.0964%2013.5289%2013.2%2013.2444%2013.2%2012.896C13.2%2012.4782%2013.0469%2012.1413%2012.7408%2011.8862C12.5877%2011.7627%2012.2714%2011.7004%2011.792%2011.7004L7.71839%200.0115555L3.29537%200C2.80219%200%202.45111%200.110217%202.2412%200.330662C2.03221%200.551119%201.92679%200.840001%201.92679%201.19556C1.92679%201.55111%202.0322%201.84001%202.2412%202.06045C2.45111%202.28089%202.80219%202.39112%203.29537%202.39112H4.63279L1.41807%2011.7004C0.912084%2011.6853%200.549076%2011.7893%200.329075%2012.0142C0.110001%2012.2382%200%2012.5289%200%2012.8844C0%2013.24%200.104491%2013.5289%200.314408%2013.7493C0.524319%2013.9698%200.875405%2014.08%201.36767%2014.08H4.12408C4.61634%2014.08%204.96743%2013.9698%205.17734%2013.7493C5.38725%2013.5289%205.49175%2013.2444%205.49175%2012.896C5.49175%2012.5404%205.38725%2012.2515%205.17734%2012.0311C4.96743%2011.8107%204.61634%2011.7004%204.12408%2011.7004H3.62449L4.12408%2010.2498ZM6.60013%203.1573L8.24738%207.87022H4.94279L6.60013%203.1573Z'%20fill='%23999999'/%3e%3cpath%20fill-rule='evenodd'%20clip-rule='evenodd'%20d='M19.523%2013.1856V13.7089L21.6596%2013.7089C22.0995%2013.7089%2022.4124%2013.6051%2022.5991%2013.3983C22.7866%2013.1916%2022.88%2012.9248%2022.88%2012.597C22.88%2012.2633%2022.7866%2011.9922%2022.5991%2011.7855C22.4124%2011.5787%2022.0995%2011.4749%2021.6596%2011.4749H21.3485V6.87643C21.3485%205.83759%2021.0347%205.01831%2020.409%204.41862C19.7823%203.8198%2018.9025%203.51953%2017.7685%203.51953C17.3883%203.51953%2016.9639%203.565%2016.4946%203.65594C16.0262%203.74688%2015.5655%203.86871%2015.1143%204.02141C14.7764%204.13723%2014.5534%204.23761%2014.4471%204.32082C14.34%204.40404%2014.257%204.51471%2014.1974%204.65283C14.1377%204.79095%2014.1083%204.95481%2014.1083%205.14355C14.1083%205.47813%2014.193%205.75181%2014.3624%205.96628C14.531%206.18075%2014.7375%206.28799%2014.9813%206.28799C15.1593%206.28799%2015.4082%206.2408%2015.7289%206.14643C16.5897%205.88477%2017.2906%205.75351%2017.8308%205.75351C18.4894%205.75351%2018.9362%205.85903%2019.1713%206.07007C19.4055%206.28027%2019.523%206.55309%2019.523%206.88681V7.42128C18.7988%207.27544%2018.1601%207.20337%2017.6078%207.20337C16.231%207.20337%2015.1515%207.60489%2014.3711%208.40702C13.5906%209.21007%2013.2%2010.08%2013.2%2011.0177C13.2%2011.7872%2013.5059%2012.4907%2014.1169%2013.1264C14.7288%2013.7621%2015.524%2014.0795%2016.5041%2014.0795C16.9552%2014.0795%2017.4565%2014.0049%2018.0088%2013.8565C18.561%2013.7072%2019.0658%2013.4842%2019.523%2013.1856ZM17.5015%209.4477C18.1185%209.4477%2018.7927%209.53521%2019.523%209.70936V10.6685C19.0891%2011.0322%2018.5948%2011.3188%2018.0399%2011.5298C17.485%2011.74%2016.9872%2011.8455%2016.5482%2011.8455C16.0322%2011.8455%2015.6251%2011.7254%2015.3287%2011.4861C15.1679%2011.3548%2015.0875%2011.1841%2015.0875%2010.9739C15.0875%2010.6831%2015.2543%2010.3965%2015.5862%2010.1126C16.1212%209.66989%2016.759%209.4477%2017.5015%209.4477Z'%20fill='%23999999'/%3e%3c/svg%3e"
|
|
231
|
-
alt="alt-icon"
|
|
232
|
-
class="type-icon"
|
|
233
|
-
/>
|
|
234
|
-
`;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
if (typeof iconValue === 'number') {
|
|
238
|
-
return html`
|
|
239
|
-
<img
|
|
240
|
-
src="data:image/svg+xml,%3csvg%20width='15'%20height='8'%20viewBox='0%200%2015%208'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M3.37681%207.86147H1.83754V1.92808L0%202.49799V1.24633L3.2117%200.0958716H3.37681V7.86147Z'%20fill='%23999999'/%3e%3cpath%20d='M9.39897%207.86147H4.08342V6.80688L6.59206%204.13313C6.93649%203.75675%207.19037%203.4283%207.35371%203.14778C7.5206%202.86727%207.60404%202.60096%207.60404%202.34885C7.60404%202.00443%207.51704%201.73457%207.34305%201.53927C7.16907%201.34043%206.92051%201.241%206.59739%201.241C6.24941%201.241%205.97422%201.36173%205.77183%201.60319C5.57298%201.84109%205.47356%202.15534%205.47356%202.54592H3.92896C3.92896%202.07367%204.04081%201.64225%204.26451%201.25166C4.49176%200.861069%204.81133%200.5557%205.22323%200.335551C5.63512%200.11185%206.10205%200%206.62402%200C7.42295%200%208.04256%200.191743%208.48286%200.57523C8.92671%200.958716%209.14864%201.50021%209.14864%202.19972C9.14864%202.58321%209.04921%202.9738%208.85037%203.37148C8.65152%203.76917%208.31065%204.23255%207.82774%204.76162L6.06477%206.62047H9.39897V7.86147Z'%20fill='%23999999'/%3e%3cpath%20d='M11.3675%203.30224H12.1878C12.5784%203.30224%2012.8677%203.2046%2013.0559%203.0093C13.2441%202.81401%2013.3382%202.5548%2013.3382%202.23168C13.3382%201.91921%2013.2441%201.67598%2013.0559%201.50199C12.8713%201.328%2012.6156%201.241%2012.289%201.241C11.9942%201.241%2011.7475%201.32267%2011.5486%201.48601C11.3498%201.6458%2011.2504%201.85529%2011.2504%202.1145H9.71108C9.71108%201.70971%209.81938%201.34753%2010.036%201.02796C10.2561%200.704834%2010.5615%200.452727%2010.9521%200.271636C11.3462%200.0905454%2011.7794%200%2012.2517%200C13.0719%200%2013.7146%200.197069%2014.1798%200.591208C14.6449%200.981796%2014.8775%201.52152%2014.8775%202.21037C14.8775%202.56545%2014.7692%202.89213%2014.5526%203.19039C14.336%203.48866%2014.0519%203.71769%2013.7004%203.87747C14.1372%204.03371%2014.4621%204.26806%2014.6751%204.58053C14.8917%204.893%2015%205.26229%2015%205.68838C15%206.37724%2014.7479%206.92939%2014.2437%207.34483C13.743%207.76027%2013.079%207.968%2012.2517%207.968C11.4776%207.968%2010.8438%207.76382%2010.3502%207.35548C9.86022%206.94714%209.61521%206.40742%209.61521%205.73632H11.1545C11.1545%206.02748%2011.2628%206.26539%2011.4794%206.45003C11.6995%206.63467%2011.9694%206.72699%2012.289%206.72699C12.6547%206.72699%2012.9405%206.63112%2013.1465%206.43938C13.356%206.24408%2013.4607%205.98665%2013.4607%205.66708C13.4607%204.893%2013.0346%204.50597%2012.1824%204.50597H11.3675V3.30224Z'%20fill='%23999999'/%3e%3c/svg%3e"
|
|
241
|
-
alt="alt-icon"
|
|
242
|
-
class="type-icon"
|
|
243
|
-
/>
|
|
244
|
-
`;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
if (typeof iconValue === 'boolean') {
|
|
248
|
-
// Single icon for all boolean values
|
|
249
|
-
return html`
|
|
250
|
-
<svg
|
|
251
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
252
|
-
width="24"
|
|
253
|
-
height="24"
|
|
254
|
-
viewBox="0 0 24 24"
|
|
255
|
-
fill="none"
|
|
256
|
-
stroke="#71717a"
|
|
257
|
-
strokeWidth="2"
|
|
258
|
-
strokeLinecap="round"
|
|
259
|
-
strokeLinejoin="round"
|
|
260
|
-
class="lucide lucide-toggle-right h-4 w-4"
|
|
261
|
-
>
|
|
262
|
-
<rect width="20" height="12" x="2" y="6" rx="6" ry="6"></rect>
|
|
263
|
-
<circle cx="16" cy="12" r="2"></circle>
|
|
264
|
-
</svg>
|
|
265
|
-
`;
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
if (Array.isArray(iconValue)) {
|
|
269
|
-
return html`
|
|
270
|
-
<svg
|
|
271
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
272
|
-
width="24"
|
|
273
|
-
height="24"
|
|
274
|
-
viewBox="0 0 24 24"
|
|
275
|
-
fill="none"
|
|
276
|
-
stroke="#71717a"
|
|
277
|
-
stroke-width="2"
|
|
278
|
-
stroke-linecap="round"
|
|
279
|
-
stroke-linejoin="round"
|
|
280
|
-
class="lucide lucide-layers"
|
|
281
|
-
>
|
|
282
|
-
<path
|
|
283
|
-
d="M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z"
|
|
284
|
-
/>
|
|
285
|
-
<path
|
|
286
|
-
d="M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12"
|
|
287
|
-
/>
|
|
288
|
-
<path
|
|
289
|
-
d="M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17"
|
|
290
|
-
/>
|
|
291
|
-
</svg>
|
|
292
|
-
`;
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
if (typeof iconValue === 'object') {
|
|
296
|
-
return html`
|
|
297
|
-
<img
|
|
298
|
-
src="data:image/svg+xml,%3csvg%20width='14'%20height='15'%20viewBox='0%200%2014%2015'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M12.8419%203.40522L7.78708%200.494922C7.3822%200.269922%206.88708%200.269922%206.49684%200.494922L1.44199%203.40522C1.03711%203.63022%200.796875%204.06498%200.796875%204.53022V10.3649C0.796875%2010.8302%201.05175%2011.2497%201.44199%2011.4899L6.49684%2014.3996C6.69197%2014.5197%206.91696%2014.5795%207.14196%2014.5795C7.36696%2014.5795%207.59196%2014.5197%207.78708%2014.3996L12.8419%2011.4746C13.2468%2011.2496%2013.4871%2010.8149%2013.4871%2010.3496V4.53007C13.4871%204.06483%2013.2322%203.63007%2012.8419%203.40507V3.40522ZM7.00723%201.38022C7.05235%201.35034%207.09747%201.35034%207.142%201.35034C7.18712%201.35034%207.23223%201.36557%207.27677%201.38022L11.9421%204.08022L7.14207%206.83992L2.34207%204.08022L7.00723%201.38022ZM1.96693%2010.5899C1.89193%2010.5448%201.83217%2010.4552%201.83217%2010.3649V4.96492L6.63217%207.73992V13.2746L1.96693%2010.5899ZM12.3169%2010.5899L7.65163%2013.2899V7.73992L12.4516%204.96492V10.3496C12.4516%2010.4551%2012.4071%2010.5301%2012.3169%2010.5899L12.3169%2010.5899Z'%20fill='%23999999'/%3e%3c/svg%3e"
|
|
299
|
-
alt="alt-icon"
|
|
300
|
-
class="type-icon"
|
|
301
|
-
/>
|
|
302
|
-
`;
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
// Default tag icon for any other type
|
|
306
|
-
return html`
|
|
307
|
-
<svg
|
|
308
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
309
|
-
width="24"
|
|
310
|
-
height="24"
|
|
311
|
-
viewBox="0 0 24 24"
|
|
312
|
-
fill="none"
|
|
313
|
-
stroke="currentColor"
|
|
314
|
-
strokeWidth="2"
|
|
315
|
-
strokeLinecap="round"
|
|
316
|
-
strokeLinejoin="round"
|
|
317
|
-
class="lucide lucide-tag h-4 w-4"
|
|
318
|
-
>
|
|
319
|
-
<path
|
|
320
|
-
d="M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z"
|
|
321
|
-
></path>
|
|
322
|
-
<circle cx="7.5" cy="7.5" r=".5" fill="currentColor"></circle>
|
|
323
|
-
</svg>
|
|
324
|
-
`;
|
|
325
|
-
};
|
|
326
|
-
|
|
327
|
-
return html`<span class="${styles.tagIcon}">${getTypeIcon(value)}</span>`;
|
|
328
|
-
};
|
|
329
|
-
|
|
330
|
-
// Add a new component to render the flat list of values
|
|
331
|
-
const ValuesList = ({
|
|
332
|
-
values,
|
|
333
|
-
onSelect,
|
|
334
|
-
onOptionClick,
|
|
335
|
-
}: {
|
|
336
|
-
values: ValueItem[];
|
|
337
|
-
onSelect: (item: Record<string, unknown>) => void;
|
|
338
|
-
onOptionClick: (option: Record<string, unknown>) => void;
|
|
339
|
-
}) =>
|
|
340
|
-
html`
|
|
341
|
-
<div class="${styles.valuesList}">
|
|
342
|
-
<ul>
|
|
343
|
-
${values.map(
|
|
344
|
-
(item) => html`
|
|
345
|
-
<li
|
|
346
|
-
key=${item.id}
|
|
347
|
-
class="${styles.valueItem}"
|
|
348
|
-
onClick=${() =>
|
|
349
|
-
onOptionClick({
|
|
350
|
-
id: item.id,
|
|
351
|
-
value: item.value,
|
|
352
|
-
})}
|
|
353
|
-
>
|
|
354
|
-
<span class="${styles.valueText}">${item.value}</span>
|
|
355
|
-
</li>
|
|
356
|
-
`,
|
|
357
|
-
)}
|
|
358
|
-
</ul>
|
|
359
|
-
</div>
|
|
360
|
-
`;
|
|
361
|
-
|
|
362
|
-
// Update the TagList component to pass parent app icon and include it in selections
|
|
363
|
-
const TagList = ({
|
|
364
|
-
tags,
|
|
365
|
-
searchTerm,
|
|
366
|
-
level = 0,
|
|
367
|
-
path = '',
|
|
368
|
-
globalSearchMode = false,
|
|
369
|
-
onSelect = (tag: Record<string, unknown>): void => {
|
|
370
|
-
/* Default empty implementation */
|
|
371
|
-
},
|
|
372
|
-
activeTab = '',
|
|
373
|
-
parentAppIcon = undefined, // Add parent app icon parameter
|
|
374
|
-
ignoreParentKey = false,
|
|
375
|
-
}: TagListProps) => {
|
|
376
|
-
// Track which nodes are expanded to show nested steps
|
|
377
|
-
const [expandedNodes, setExpandedNodes] = useState<Record<string, boolean>>(
|
|
378
|
-
{},
|
|
379
|
-
);
|
|
380
|
-
|
|
381
|
-
// Track which steps have their output expanded
|
|
382
|
-
const [expandedOutputs, setExpandedOutputs] = useState<
|
|
383
|
-
Record<string, boolean>
|
|
384
|
-
>({});
|
|
385
|
-
|
|
386
|
-
// Track which node is being hovered
|
|
387
|
-
const [hoveredNode, setHoveredNode] = useState<string | null>(null);
|
|
388
|
-
|
|
389
|
-
// Handle arrays by converting them to objects with indices as keys
|
|
390
|
-
const processedTags = Array.isArray(tags)
|
|
391
|
-
? arrayToObject(tags)
|
|
392
|
-
: (tags as Record<string, unknown>);
|
|
393
|
-
|
|
394
|
-
// Update the nodeMatchesSearch function with proper type checking
|
|
395
|
-
const nodeMatchesSearch = (
|
|
396
|
-
key: string,
|
|
397
|
-
node: unknown,
|
|
398
|
-
term: string,
|
|
399
|
-
): boolean => {
|
|
400
|
-
if (!term) return false;
|
|
401
|
-
const lowerTerm = term.toLowerCase();
|
|
402
|
-
|
|
403
|
-
return (
|
|
404
|
-
key?.toLowerCase().includes(lowerTerm) ||
|
|
405
|
-
(isTagNode(node) &&
|
|
406
|
-
node.name &&
|
|
407
|
-
node.name.toLowerCase().includes(lowerTerm)) ||
|
|
408
|
-
(isTagNode(node) &&
|
|
409
|
-
node.machineName &&
|
|
410
|
-
node.machineName.toLowerCase().includes(lowerTerm)) ||
|
|
411
|
-
false
|
|
412
|
-
);
|
|
413
|
-
};
|
|
414
|
-
|
|
415
|
-
// Update the childrenMatchSearch function with proper type checking
|
|
416
|
-
const childrenMatchSearch = (node: unknown, term: string): boolean => {
|
|
417
|
-
if (!term) return false;
|
|
418
|
-
|
|
419
|
-
// Check if node is an array
|
|
420
|
-
if (Array.isArray(node)) {
|
|
421
|
-
return node.some(
|
|
422
|
-
(item) =>
|
|
423
|
-
(typeof item === 'string' && item.toLowerCase().includes(term)) ||
|
|
424
|
-
(typeof item === 'object' &&
|
|
425
|
-
item !== null &&
|
|
426
|
-
outputMatchesSearch(item, term)),
|
|
427
|
-
);
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
// Check if node has tags
|
|
431
|
-
if (isTagNode(node) && node.tags) {
|
|
432
|
-
return Object.entries(node.tags).some(
|
|
433
|
-
([childKey, childNode]) =>
|
|
434
|
-
nodeMatchesSearch(childKey, childNode, term) ||
|
|
435
|
-
childrenMatchSearch(childNode, term) ||
|
|
436
|
-
(isTagNode(childNode) &&
|
|
437
|
-
childNode.output &&
|
|
438
|
-
outputMatchesSearch(childNode.output, term)),
|
|
439
|
-
);
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
return false;
|
|
443
|
-
};
|
|
444
|
-
|
|
445
|
-
// Add the isExpandable function with proper type checking
|
|
446
|
-
const isExpandable = (value: unknown): boolean => {
|
|
447
|
-
if (value === null || value === undefined) return false;
|
|
448
|
-
|
|
449
|
-
// Arrays with items are expandable
|
|
450
|
-
if (Array.isArray(value)) return value.length > 0;
|
|
451
|
-
|
|
452
|
-
// Objects with properties are expandable
|
|
453
|
-
if (typeof value === 'object') {
|
|
454
|
-
// Check if it's a TagNode with tags
|
|
455
|
-
if (isTagNode(value)) {
|
|
456
|
-
// Check if it has tags
|
|
457
|
-
if (value.tags && Object.keys(value.tags).length > 0) {
|
|
458
|
-
return true;
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
// Check if it has output that is expandable
|
|
462
|
-
if (value.output) {
|
|
463
|
-
if (Array.isArray(value.output) && value.output.length > 0) {
|
|
464
|
-
return true;
|
|
465
|
-
}
|
|
466
|
-
if (
|
|
467
|
-
typeof value.output === 'object' &&
|
|
468
|
-
value.output !== null &&
|
|
469
|
-
Object.keys(value.output as Record<string, unknown>).length > 0
|
|
470
|
-
) {
|
|
471
|
-
return true;
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
// Regular object with properties
|
|
477
|
-
return Object.keys(value as Record<string, unknown>).length > 0;
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
return false;
|
|
481
|
-
};
|
|
482
|
-
|
|
483
|
-
// Initialize expandedNodes for steps with nested steps and handle search expansion
|
|
484
|
-
useEffect(() => {
|
|
485
|
-
const initialExpanded: Record<string, boolean> = {};
|
|
486
|
-
const initialOutputs: Record<string, boolean> = {};
|
|
487
|
-
|
|
488
|
-
Object.entries(processedTags).forEach(([key, value]) => {
|
|
489
|
-
// Auto-expand steps that have nested steps
|
|
490
|
-
if (
|
|
491
|
-
isTagNode(value) &&
|
|
492
|
-
value.tags &&
|
|
493
|
-
Object.keys(value.tags).length > 0
|
|
494
|
-
) {
|
|
495
|
-
initialExpanded[key] = true;
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
// If in search mode, check if this node or its children match the search
|
|
499
|
-
if (
|
|
500
|
-
searchTerm &&
|
|
501
|
-
(nodeMatchesSearch(key, value, searchTerm) ||
|
|
502
|
-
childrenMatchSearch(value, searchTerm))
|
|
503
|
-
) {
|
|
504
|
-
initialExpanded[key] = true;
|
|
505
|
-
|
|
506
|
-
// If the node has output and the output matches the search, expand the output too
|
|
507
|
-
if (
|
|
508
|
-
isTagNode(value) &&
|
|
509
|
-
value.output &&
|
|
510
|
-
outputMatchesSearch(value.output, searchTerm)
|
|
511
|
-
) {
|
|
512
|
-
initialOutputs[key] = true;
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
});
|
|
516
|
-
|
|
517
|
-
setExpandedNodes((prev) => ({ ...prev, ...initialExpanded }));
|
|
518
|
-
setExpandedOutputs((prev) => ({ ...prev, ...initialOutputs }));
|
|
519
|
-
}, [processedTags, searchTerm]);
|
|
520
|
-
|
|
521
|
-
// Update the toggleExpand function with proper type checking
|
|
522
|
-
const toggleExpand = (key: string, event?: Event) => {
|
|
523
|
-
if (event) {
|
|
524
|
-
event.stopPropagation(); // Prevent event bubbling
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
// Get the node that we want to toggle
|
|
528
|
-
const node = processedTags[key];
|
|
529
|
-
|
|
530
|
-
if (isTagNode(node)) {
|
|
531
|
-
// If it's a TagNode with tags, toggle output expansion
|
|
532
|
-
if (node.tags && Object.keys(node.tags).length > 0) {
|
|
533
|
-
// Toggle the output expansion
|
|
534
|
-
setExpandedOutputs((prev) => ({
|
|
535
|
-
...prev,
|
|
536
|
-
[key]: !prev[key],
|
|
537
|
-
}));
|
|
538
|
-
return;
|
|
539
|
-
}
|
|
540
|
-
|
|
541
|
-
// If it's a TagNode with expandable output, toggle node expansion
|
|
542
|
-
if (node.output && isExpandable(node.output)) {
|
|
543
|
-
setExpandedNodes((prev) => ({
|
|
544
|
-
...prev,
|
|
545
|
-
[key]: !prev[key],
|
|
546
|
-
}));
|
|
547
|
-
return;
|
|
548
|
-
}
|
|
549
|
-
}
|
|
550
|
-
|
|
551
|
-
// For arrays, objects, or steps without nested tags - toggle normal expansion
|
|
552
|
-
setExpandedNodes((prev) => {
|
|
553
|
-
const newExpandedNodes = { ...prev };
|
|
554
|
-
// Toggle the value
|
|
555
|
-
newExpandedNodes[key] = !prev[key];
|
|
556
|
-
return newExpandedNodes;
|
|
557
|
-
});
|
|
558
|
-
};
|
|
559
|
-
|
|
560
|
-
const toggleOutputExpand = (key: string, e: Event) => {
|
|
561
|
-
e.stopPropagation(); // Prevent the click from affecting the parent
|
|
562
|
-
setExpandedOutputs((prev) => ({
|
|
563
|
-
...prev,
|
|
564
|
-
[key]: !prev[key],
|
|
565
|
-
}));
|
|
566
|
-
};
|
|
567
|
-
|
|
568
|
-
const escapeHTMLIfNeeded = (input: any) => {
|
|
569
|
-
if (typeof input !== 'string') {
|
|
570
|
-
return input;
|
|
571
|
-
}
|
|
572
|
-
const isHTML = /<\/?[a-z][\s\S]*>/i.test(input);
|
|
573
|
-
|
|
574
|
-
const output = isHTML
|
|
575
|
-
? input
|
|
576
|
-
.replace(/&/g, '&')
|
|
577
|
-
.replace(/</g, '<')
|
|
578
|
-
.replace(/>/g, '>')
|
|
579
|
-
.replace(/"/g, '"')
|
|
580
|
-
.replace(/'/g, ''')
|
|
581
|
-
: input;
|
|
582
|
-
|
|
583
|
-
return output.length > 200 ? `${output.slice(0, 200)}...` : output;
|
|
584
|
-
};
|
|
585
|
-
|
|
586
|
-
const highlightSearchTerm = (text: string, term: string) => {
|
|
587
|
-
const textModified = escapeHTMLIfNeeded(text);
|
|
588
|
-
if (!term) return textModified;
|
|
589
|
-
const regex = new RegExp(`(${term})`, 'gi');
|
|
590
|
-
return textModified.replace(regex, '<mark>$1</mark>');
|
|
591
|
-
};
|
|
592
|
-
|
|
593
|
-
const extractStepsFromOutputPath = (pathToExtract: string) => {
|
|
594
|
-
const parts = pathToExtract.split('.'); // Split the string by dots
|
|
595
|
-
|
|
596
|
-
// Find the first occurrence of 'output'
|
|
597
|
-
const firstOutputIndex = parts.indexOf('output');
|
|
598
|
-
|
|
599
|
-
if (firstOutputIndex === -1 || firstOutputIndex === 0) {
|
|
600
|
-
return ''; // Return empty if 'output' is not found or it's at the start
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
// Get the step name (part before the first 'output')
|
|
604
|
-
const stepName = parts[firstOutputIndex - 1];
|
|
605
|
-
|
|
606
|
-
// Get all parts after the first 'output', including any other 'output' keys
|
|
607
|
-
const remainingParts = parts.slice(firstOutputIndex + 1);
|
|
608
|
-
|
|
609
|
-
// If there are remaining parts, combine the step name with them
|
|
610
|
-
if (remainingParts.length > 0) {
|
|
611
|
-
return `${stepName}.${remainingParts.join('.')}`;
|
|
612
|
-
}
|
|
613
|
-
|
|
614
|
-
// If there are no remaining parts, just return the step name
|
|
615
|
-
return stepName;
|
|
616
|
-
};
|
|
617
|
-
|
|
618
|
-
// Modified function to handle selecting a tag with parent app icon
|
|
619
|
-
const handleSelectTag = (
|
|
620
|
-
key: string,
|
|
621
|
-
value: unknown,
|
|
622
|
-
currentPath: string,
|
|
623
|
-
nodeAppIcon?: string,
|
|
624
|
-
ignoreKey = false,
|
|
625
|
-
) => {
|
|
626
|
-
const basePath = extractStepsFromOutputPath(currentPath);
|
|
627
|
-
const tagPath = ignoreKey ? basePath : `${activeTab}.${basePath}`;
|
|
628
|
-
|
|
629
|
-
// Determine which app icon to use - prioritize node's own icon, then parent icon
|
|
630
|
-
const appIconToUse = nodeAppIcon || parentAppIcon;
|
|
631
|
-
|
|
632
|
-
onSelect({
|
|
633
|
-
currentPath: tagPath
|
|
634
|
-
.replace(/\bparameters\.parameters\b/g, 'parameters')
|
|
635
|
-
.replace(/\bauthorization\.authorization\b/g, 'authorization'),
|
|
636
|
-
key,
|
|
637
|
-
value: escapeHTMLIfNeeded(value),
|
|
638
|
-
parentAppIcon: appIconToUse, // Include parent app icon in the response
|
|
639
|
-
});
|
|
640
|
-
};
|
|
641
|
-
|
|
642
|
-
// Update the filterTags function with proper type checking
|
|
643
|
-
const filterTags = (
|
|
644
|
-
tagsToFilter: Record<string, unknown> | unknown[],
|
|
645
|
-
termToSearch: string,
|
|
646
|
-
pathPrefix: string,
|
|
647
|
-
): Record<string, unknown> | unknown[] => {
|
|
648
|
-
if (!termToSearch) return tagsToFilter;
|
|
649
|
-
|
|
650
|
-
// Handle arrays
|
|
651
|
-
if (Array.isArray(tagsToFilter)) {
|
|
652
|
-
const filteredArray = tagsToFilter.filter((item, index) => {
|
|
653
|
-
const currentPath = pathPrefix
|
|
654
|
-
? `${pathPrefix}[${index}]`
|
|
655
|
-
: `[${index}]`;
|
|
656
|
-
|
|
657
|
-
// Check if this item matches the search
|
|
658
|
-
if (
|
|
659
|
-
typeof item === 'string' &&
|
|
660
|
-
item.toLowerCase().includes(termToSearch.toLowerCase())
|
|
661
|
-
) {
|
|
662
|
-
return true;
|
|
663
|
-
}
|
|
664
|
-
|
|
665
|
-
// Check if this is an object that matches
|
|
666
|
-
if (typeof item === 'object' && item !== null) {
|
|
667
|
-
const filteredItem = filterTags(
|
|
668
|
-
item as Record<string, unknown>,
|
|
669
|
-
termToSearch,
|
|
670
|
-
currentPath,
|
|
671
|
-
);
|
|
672
|
-
return (
|
|
673
|
-
(typeof filteredItem === 'object' &&
|
|
674
|
-
Object.keys(filteredItem as Record<string, unknown>).length >
|
|
675
|
-
0) ||
|
|
676
|
-
outputMatchesSearch(item, termToSearch)
|
|
677
|
-
);
|
|
678
|
-
}
|
|
679
|
-
|
|
680
|
-
return false;
|
|
681
|
-
});
|
|
682
|
-
|
|
683
|
-
return filteredArray.length > 0 ? arrayToObject(filteredArray) : {};
|
|
684
|
-
}
|
|
685
|
-
|
|
686
|
-
const filteredTags: Record<string, unknown> = {};
|
|
687
|
-
const lowerTerm = termToSearch.toLowerCase();
|
|
688
|
-
|
|
689
|
-
Object.entries(tagsToFilter).forEach(([key, value]) => {
|
|
690
|
-
const currentPath = pathPrefix ? `${pathPrefix}.${key}` : key;
|
|
691
|
-
|
|
692
|
-
// Check if this node matches the search
|
|
693
|
-
const nodeMatches = nodeMatchesSearch(key, value, lowerTerm);
|
|
694
|
-
|
|
695
|
-
// Check if output matches the search
|
|
696
|
-
const outputMatches =
|
|
697
|
-
isTagNode(value) &&
|
|
698
|
-
value.output &&
|
|
699
|
-
outputMatchesSearch(value.output, lowerTerm);
|
|
700
|
-
|
|
701
|
-
// Check if children match the search
|
|
702
|
-
let filteredChildren: Record<string, unknown> = {};
|
|
703
|
-
|
|
704
|
-
// Handle array in output
|
|
705
|
-
if (isTagNode(value) && value.output && Array.isArray(value.output)) {
|
|
706
|
-
const filteredOutput = filterTags(
|
|
707
|
-
value.output,
|
|
708
|
-
termToSearch,
|
|
709
|
-
`${currentPath}.output`,
|
|
710
|
-
);
|
|
711
|
-
const outputMatch =
|
|
712
|
-
typeof filteredOutput === 'object' &&
|
|
713
|
-
Object.keys(filteredOutput as Record<string, unknown>).length > 0;
|
|
714
|
-
if (outputMatch) {
|
|
715
|
-
const clonedNode = { ...value };
|
|
716
|
-
clonedNode.output = value.output; // Keep original array for proper rendering
|
|
717
|
-
filteredTags[key] = clonedNode;
|
|
718
|
-
return;
|
|
719
|
-
}
|
|
720
|
-
}
|
|
721
|
-
|
|
722
|
-
// Handle regular tags
|
|
723
|
-
if (isTagNode(value) && value.tags) {
|
|
724
|
-
filteredChildren = filterTags(
|
|
725
|
-
value.tags,
|
|
726
|
-
termToSearch,
|
|
727
|
-
currentPath,
|
|
728
|
-
) as Record<string, unknown>;
|
|
729
|
-
}
|
|
730
|
-
|
|
731
|
-
const childrenMatch =
|
|
732
|
-
typeof filteredChildren === 'object' &&
|
|
733
|
-
Object.keys(filteredChildren).length > 0;
|
|
734
|
-
|
|
735
|
-
// Include this node if it matches or has matching children
|
|
736
|
-
if (nodeMatches || outputMatches || childrenMatch) {
|
|
737
|
-
// Clone the node to avoid modifying the original
|
|
738
|
-
const clonedNode = isTagNode(value) ? { ...value } : value;
|
|
739
|
-
|
|
740
|
-
// If children match, include the filtered children
|
|
741
|
-
if (childrenMatch && isTagNode(clonedNode)) {
|
|
742
|
-
clonedNode.tags = filteredChildren as Record<string, TagNode>;
|
|
743
|
-
}
|
|
744
|
-
|
|
745
|
-
filteredTags[key] = clonedNode;
|
|
746
|
-
}
|
|
747
|
-
});
|
|
748
|
-
|
|
749
|
-
return filteredTags;
|
|
750
|
-
};
|
|
751
|
-
|
|
752
|
-
// Only filter if in global search mode, otherwise show all
|
|
753
|
-
const filteredTags = globalSearchMode
|
|
754
|
-
? filterTags(processedTags, searchTerm, path)
|
|
755
|
-
: processedTags;
|
|
756
|
-
|
|
757
|
-
// Simplified rendering to fix syntax issues
|
|
758
|
-
return html`
|
|
759
|
-
<ul style="padding-left: ${1 * 20}px;">
|
|
760
|
-
${Object.entries(filteredTags as Record<string, unknown>).map(
|
|
761
|
-
([key, value]) => {
|
|
762
|
-
const isStep = isTagNode(value);
|
|
763
|
-
// We don't use isOutput but keep it for future reference
|
|
764
|
-
const isArrayItem = key.startsWith('[') && key.endsWith(']');
|
|
765
|
-
const hasNestedSteps =
|
|
766
|
-
isStep &&
|
|
767
|
-
isTagNode(value) &&
|
|
768
|
-
value.tags &&
|
|
769
|
-
Object.keys(value.tags).length > 0;
|
|
770
|
-
const hasOutput =
|
|
771
|
-
isTagNode(value) &&
|
|
772
|
-
value.output &&
|
|
773
|
-
typeof value.output === 'object';
|
|
774
|
-
// Determine if this item has children that can be expanded
|
|
775
|
-
let hasChildren = hasNestedSteps || hasOutput;
|
|
776
|
-
|
|
777
|
-
// Check if this is an array or object (even if it's inside a step's output)
|
|
778
|
-
// This will allow us to show expand/collapse icons for arrays and objects
|
|
779
|
-
const isArray = Array.isArray(value);
|
|
780
|
-
const isObject =
|
|
781
|
-
!isArray &&
|
|
782
|
-
typeof value === 'object' &&
|
|
783
|
-
value !== null &&
|
|
784
|
-
Object.keys(value as Record<string, unknown>).length > 0;
|
|
785
|
-
|
|
786
|
-
// If this is an array or object (not a step), mark it as having children
|
|
787
|
-
if (!isStep && (isArray || isObject)) {
|
|
788
|
-
hasChildren = true;
|
|
789
|
-
}
|
|
790
|
-
|
|
791
|
-
// If this is a step with output that is an array or object, also mark it as having children
|
|
792
|
-
if (isStep && isTagNode(value) && value.output) {
|
|
793
|
-
// The output could be any data type - check if it's an array or object with content
|
|
794
|
-
const outputIsArray =
|
|
795
|
-
Array.isArray(value.output) && value.output.length > 0;
|
|
796
|
-
const outputIsObject =
|
|
797
|
-
!outputIsArray &&
|
|
798
|
-
typeof value.output === 'object' &&
|
|
799
|
-
value.output !== null &&
|
|
800
|
-
Object.keys(value.output as Record<string, unknown>).length > 0;
|
|
801
|
-
|
|
802
|
-
if (outputIsArray || outputIsObject) {
|
|
803
|
-
hasChildren = true;
|
|
804
|
-
}
|
|
805
|
-
}
|
|
806
|
-
const isExpanded = expandedNodes[key];
|
|
807
|
-
const isOutputExpanded = expandedOutputs[key];
|
|
808
|
-
let currentPath: string;
|
|
809
|
-
if (path) {
|
|
810
|
-
if (key.startsWith('[') && key.endsWith(']')) {
|
|
811
|
-
currentPath = `${path}${key}`;
|
|
812
|
-
} else {
|
|
813
|
-
currentPath = `${path}.${key}`;
|
|
814
|
-
}
|
|
815
|
-
} else {
|
|
816
|
-
currentPath = key;
|
|
817
|
-
}
|
|
818
|
-
const nodeMatches =
|
|
819
|
-
searchTerm && nodeMatchesSearch(key, value, searchTerm);
|
|
820
|
-
let text: string;
|
|
821
|
-
|
|
822
|
-
if (isArrayItem) {
|
|
823
|
-
text = key;
|
|
824
|
-
} else if (isTagNode(value) && value.name) {
|
|
825
|
-
text = value.name;
|
|
826
|
-
} else {
|
|
827
|
-
text = key;
|
|
828
|
-
}
|
|
829
|
-
|
|
830
|
-
let tagsParam: unknown = {};
|
|
831
|
-
|
|
832
|
-
if (isTagNode(value)) {
|
|
833
|
-
// If the output exists, use it directly regardless of its type
|
|
834
|
-
if (value.output !== undefined) {
|
|
835
|
-
tagsParam = value.output;
|
|
836
|
-
}
|
|
837
|
-
}
|
|
838
|
-
|
|
839
|
-
let tagsParamForOutput: unknown;
|
|
840
|
-
|
|
841
|
-
if (Array.isArray(value)) {
|
|
842
|
-
tagsParamForOutput = value;
|
|
843
|
-
} else if (isTagNode(value) && value.tags) {
|
|
844
|
-
tagsParamForOutput = value.tags;
|
|
845
|
-
} else {
|
|
846
|
-
tagsParamForOutput = value as Record<string, unknown>;
|
|
847
|
-
}
|
|
848
|
-
|
|
849
|
-
// Determine the app icon to pass down - use current node's icon or parent's icon
|
|
850
|
-
const currentNodeAppIcon = isTagNode(value)
|
|
851
|
-
? value.appIcon
|
|
852
|
-
: undefined;
|
|
853
|
-
const appIconToPass = currentNodeAppIcon || parentAppIcon;
|
|
854
|
-
const childIgnoreParentKey =
|
|
855
|
-
ignoreParentKey || (isTagNode(value) && value.ignoreParentKey === true);
|
|
856
|
-
|
|
857
|
-
const handleMenuRowClcik = (e: Event) => {
|
|
858
|
-
if (isStep && hasOutput) {
|
|
859
|
-
// For step nodes with output, toggle output expansion
|
|
860
|
-
setExpandedOutputs((prev) => ({
|
|
861
|
-
...prev,
|
|
862
|
-
[key]: !prev[key],
|
|
863
|
-
}));
|
|
864
|
-
} else if (hasChildren) {
|
|
865
|
-
// For array/object nodes, toggle node expansion
|
|
866
|
-
toggleExpand(key);
|
|
867
|
-
toggleOutputExpand(key, e);
|
|
868
|
-
} else {
|
|
869
|
-
// For leaf nodes, select the value
|
|
870
|
-
handleSelectTag(
|
|
871
|
-
key,
|
|
872
|
-
value,
|
|
873
|
-
currentPath,
|
|
874
|
-
currentNodeAppIcon,
|
|
875
|
-
childIgnoreParentKey,
|
|
876
|
-
);
|
|
877
|
-
}
|
|
878
|
-
};
|
|
879
|
-
|
|
880
|
-
// Check if this is an edge node (leaf node with no children)
|
|
881
|
-
const isEdgeNode = !hasChildren;
|
|
882
|
-
|
|
883
|
-
// Determine if we should show the add tag button
|
|
884
|
-
// Don't show for step name nodes, only for non-edge nodes that aren't step names
|
|
885
|
-
const shouldShowAddButton =
|
|
886
|
-
!isEdgeNode && hoveredNode === key && !isStep;
|
|
887
|
-
|
|
888
|
-
return html`
|
|
889
|
-
<li key=${key} class="${nodeMatches ? styles.searchMatch : ''}">
|
|
890
|
-
<div
|
|
891
|
-
onClick=${(e: Event) => {
|
|
892
|
-
if (isStep && hasOutput) {
|
|
893
|
-
// For step nodes with output, toggle output expansion
|
|
894
|
-
setExpandedOutputs((prev) => ({
|
|
895
|
-
...prev,
|
|
896
|
-
[key]: !prev[key],
|
|
897
|
-
}));
|
|
898
|
-
} else if (hasChildren) {
|
|
899
|
-
// For array/object nodes, toggle node expansion
|
|
900
|
-
toggleExpand(key);
|
|
901
|
-
toggleOutputExpand(key, e);
|
|
902
|
-
} else {
|
|
903
|
-
// For leaf nodes, select the value
|
|
904
|
-
handleSelectTag(
|
|
905
|
-
key,
|
|
906
|
-
value,
|
|
907
|
-
currentPath,
|
|
908
|
-
currentNodeAppIcon,
|
|
909
|
-
childIgnoreParentKey,
|
|
910
|
-
);
|
|
911
|
-
}
|
|
912
|
-
}}
|
|
913
|
-
class="${styles.listItemContent}"
|
|
914
|
-
onMouseEnter=${() => setHoveredNode(key)}
|
|
915
|
-
onMouseLeave=${() => setHoveredNode(null)}
|
|
916
|
-
>
|
|
917
|
-
${!isStep ? html`<${TypeIcon} value=${value} />` : ''}
|
|
918
|
-
${isTagNode(value) && value.appIcon
|
|
919
|
-
? html`<img src=${value.appIcon} alt="App Icon" />`
|
|
920
|
-
: ''}
|
|
921
|
-
|
|
922
|
-
<span
|
|
923
|
-
class="${styles.key}"
|
|
924
|
-
dangerouslySetInnerHTML=${{
|
|
925
|
-
__html: highlightSearchTerm(text, searchTerm),
|
|
926
|
-
}}
|
|
927
|
-
></span>
|
|
928
|
-
|
|
929
|
-
${!hasChildren &&
|
|
930
|
-
value !== undefined &&
|
|
931
|
-
(typeof value === 'string' ||
|
|
932
|
-
typeof value === 'number' ||
|
|
933
|
-
typeof value === 'boolean')
|
|
934
|
-
? html`<${Hint}
|
|
935
|
-
dismissOnClick=${false}
|
|
936
|
-
position="top"
|
|
937
|
-
deltaY=${0}
|
|
938
|
-
className=${styles.hint}
|
|
939
|
-
><span class="${styles.value}">
|
|
940
|
-
${value ? ' ' : ''}
|
|
941
|
-
<span
|
|
942
|
-
data-hint=${value ? String(value) : ''}
|
|
943
|
-
dangerouslySetInnerHTML=${{
|
|
944
|
-
__html: highlightSearchTerm(
|
|
945
|
-
String(value),
|
|
946
|
-
searchTerm,
|
|
947
|
-
),
|
|
948
|
-
}}
|
|
949
|
-
></span> </span
|
|
950
|
-
><//>`
|
|
951
|
-
: ''}
|
|
952
|
-
${isStep &&
|
|
953
|
-
value !== undefined &&
|
|
954
|
-
isTagNode(value) &&
|
|
955
|
-
value.machineName
|
|
956
|
-
? html`<span class="${styles.value}">
|
|
957
|
-
${' '}
|
|
958
|
-
<span
|
|
959
|
-
dangerouslySetInnerHTML=${{
|
|
960
|
-
__html: highlightSearchTerm(
|
|
961
|
-
value.machineName,
|
|
962
|
-
searchTerm,
|
|
963
|
-
),
|
|
964
|
-
}}
|
|
965
|
-
></span>
|
|
966
|
-
</span>`
|
|
967
|
-
: ''}
|
|
968
|
-
${isArrayItem && typeof value === 'object' && !isStep
|
|
969
|
-
? html`<span class="${styles.value}">
|
|
970
|
-
${' '}
|
|
971
|
-
<span>
|
|
972
|
-
${Array.isArray(value)
|
|
973
|
-
? `Array(${value.length})`
|
|
974
|
-
: `Object${
|
|
975
|
-
value && typeof value === 'object'
|
|
976
|
-
? ` (${
|
|
977
|
-
Object.keys(
|
|
978
|
-
value as Record<string, unknown>,
|
|
979
|
-
).length
|
|
980
|
-
} keys)`
|
|
981
|
-
: ''
|
|
982
|
-
}`}
|
|
983
|
-
</span>
|
|
984
|
-
</span>`
|
|
985
|
-
: ''}
|
|
986
|
-
|
|
987
|
-
<!-- Add Tag button for non-edge nodes that aren't step names -->
|
|
988
|
-
${shouldShowAddButton
|
|
989
|
-
? html`
|
|
990
|
-
<button
|
|
991
|
-
class="${styles.addTagButton}"
|
|
992
|
-
onClick=${(e: Event) => {
|
|
993
|
-
e.stopPropagation();
|
|
994
|
-
handleSelectTag(
|
|
995
|
-
key,
|
|
996
|
-
value,
|
|
997
|
-
currentPath,
|
|
998
|
-
currentNodeAppIcon,
|
|
999
|
-
childIgnoreParentKey,
|
|
1000
|
-
);
|
|
1001
|
-
}}
|
|
1002
|
-
title="Add this tag"
|
|
1003
|
-
>
|
|
1004
|
-
<svg
|
|
1005
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
1006
|
-
width="16"
|
|
1007
|
-
height="16"
|
|
1008
|
-
viewBox="0 0 24 24"
|
|
1009
|
-
fill="none"
|
|
1010
|
-
stroke="currentColor"
|
|
1011
|
-
strokeWidth="2"
|
|
1012
|
-
strokeLinecap="round"
|
|
1013
|
-
strokeLinejoin="round"
|
|
1014
|
-
>
|
|
1015
|
-
<path d="M12 5v14"></path>
|
|
1016
|
-
<path d="M5 12h14"></path>
|
|
1017
|
-
</svg>
|
|
1018
|
-
</button>
|
|
1019
|
-
`
|
|
1020
|
-
: ''}
|
|
1021
|
-
|
|
1022
|
-
<!-- Expand/collapse icon for arrays -->
|
|
1023
|
-
${Array.isArray(value) && value.length > 0
|
|
1024
|
-
? html`<span
|
|
1025
|
-
class="${styles.outputIndicator} ${styles.objectExpandIcon}"
|
|
1026
|
-
onClick=${(e: Event) => handleMenuRowClcik(e)}
|
|
1027
|
-
title="Toggle expand output"
|
|
1028
|
-
>
|
|
1029
|
-
<svg
|
|
1030
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
1031
|
-
width="24"
|
|
1032
|
-
height="24"
|
|
1033
|
-
viewBox="0 0 24 24"
|
|
1034
|
-
fill="none"
|
|
1035
|
-
stroke="currentColor"
|
|
1036
|
-
strokeWidth="2"
|
|
1037
|
-
strokeLinecap="round"
|
|
1038
|
-
strokeLinejoin="round"
|
|
1039
|
-
style="transform: ${isOutputExpanded
|
|
1040
|
-
? 'rotate(180deg)'
|
|
1041
|
-
: 'rotate(0deg)'};
|
|
1042
|
-
transition: transform 0.2s;"
|
|
1043
|
-
>
|
|
1044
|
-
<path d="m6 9 6 6 6-6"></path>
|
|
1045
|
-
</svg>
|
|
1046
|
-
</span>`
|
|
1047
|
-
: ''}
|
|
1048
|
-
|
|
1049
|
-
<!-- Expand/collapse icon for objects -->
|
|
1050
|
-
${!isStep &&
|
|
1051
|
-
!Array.isArray(value) &&
|
|
1052
|
-
typeof value === 'object' &&
|
|
1053
|
-
value !== null &&
|
|
1054
|
-
Object.keys(value as Record<string, unknown>).length > 0
|
|
1055
|
-
? html`<span
|
|
1056
|
-
class="${styles.outputIndicator} ${styles.objectExpandIcon}"
|
|
1057
|
-
onClick=${(e: Event) => {
|
|
1058
|
-
handleMenuRowClcik(e);
|
|
1059
|
-
}}
|
|
1060
|
-
title="Toggle expand output"
|
|
1061
|
-
>
|
|
1062
|
-
<svg
|
|
1063
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
1064
|
-
width="24"
|
|
1065
|
-
height="24"
|
|
1066
|
-
viewBox="0 0 24 24"
|
|
1067
|
-
fill="none"
|
|
1068
|
-
stroke="currentColor"
|
|
1069
|
-
strokeWidth="2"
|
|
1070
|
-
strokeLinecap="round"
|
|
1071
|
-
strokeLinejoin="round"
|
|
1072
|
-
style="transform: ${isOutputExpanded
|
|
1073
|
-
? 'rotate(180deg)'
|
|
1074
|
-
: 'rotate(0deg)'};
|
|
1075
|
-
transition: transform 0.2s;"
|
|
1076
|
-
>
|
|
1077
|
-
<path d="m6 9 6 6 6-6"></path>
|
|
1078
|
-
</svg>
|
|
1079
|
-
</span>`
|
|
1080
|
-
: ''}
|
|
1081
|
-
|
|
1082
|
-
<!-- Expand/collapse icon for step output that contains arrays or objects -->
|
|
1083
|
-
${isStep &&
|
|
1084
|
-
isTagNode(value) &&
|
|
1085
|
-
value.output &&
|
|
1086
|
-
((Array.isArray(value.output) && value.output.length > 0) ||
|
|
1087
|
-
(!Array.isArray(value.output) &&
|
|
1088
|
-
typeof value.output === 'object' &&
|
|
1089
|
-
value.output !== null &&
|
|
1090
|
-
Object.keys(value.output as Record<string, unknown>)
|
|
1091
|
-
.length > 0))
|
|
1092
|
-
? html`<span
|
|
1093
|
-
class="${styles.outputIndicator} ${styles.objectExpandIcon}"
|
|
1094
|
-
onClick=${(e: Event) => toggleOutputExpand(key, e)}
|
|
1095
|
-
title="Toggle expand output"
|
|
1096
|
-
>
|
|
1097
|
-
<svg
|
|
1098
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
1099
|
-
width="24"
|
|
1100
|
-
height="24"
|
|
1101
|
-
viewBox="0 0 24 24"
|
|
1102
|
-
fill="none"
|
|
1103
|
-
stroke="currentColor"
|
|
1104
|
-
strokeWidth="2"
|
|
1105
|
-
strokeLinecap="round"
|
|
1106
|
-
strokeLinejoin="round"
|
|
1107
|
-
style="transform: ${isOutputExpanded
|
|
1108
|
-
? 'rotate(180deg)'
|
|
1109
|
-
: 'rotate(0deg)'};
|
|
1110
|
-
transition: transform 0.2s;"
|
|
1111
|
-
>
|
|
1112
|
-
<path d="m6 9 6 6 6-6"></path>
|
|
1113
|
-
</svg>
|
|
1114
|
-
</span>`
|
|
1115
|
-
: ''}
|
|
1116
|
-
</div>
|
|
1117
|
-
|
|
1118
|
-
${isStep && hasOutput && isOutputExpanded
|
|
1119
|
-
? html`<div class="${styles.outputSection}">
|
|
1120
|
-
<div style="position: relative;">
|
|
1121
|
-
<!-- SPECIAL CASE: Force array handling -->
|
|
1122
|
-
${(() => {
|
|
1123
|
-
// For arrays specifically, render them directly
|
|
1124
|
-
if (Array.isArray(tagsParam)) {
|
|
1125
|
-
// Create a wrapper div to show each array item
|
|
1126
|
-
return html`
|
|
1127
|
-
<div class="${styles.arrayOutput}">
|
|
1128
|
-
<ul>
|
|
1129
|
-
${tagsParam.map(
|
|
1130
|
-
(item, index) => html`
|
|
1131
|
-
<li key=${index}>
|
|
1132
|
-
<div class="${styles.listItemContent}">
|
|
1133
|
-
<span class="${styles.key}"
|
|
1134
|
-
>[${index}]</span
|
|
1135
|
-
>
|
|
1136
|
-
${typeof item === 'object' &&
|
|
1137
|
-
item !== null
|
|
1138
|
-
? html`
|
|
1139
|
-
<span class="${styles.value}">
|
|
1140
|
-
${Array.isArray(item)
|
|
1141
|
-
? `Array(${item.length})`
|
|
1142
|
-
: `Object(${
|
|
1143
|
-
Object.keys(
|
|
1144
|
-
item as Record<
|
|
1145
|
-
string,
|
|
1146
|
-
unknown
|
|
1147
|
-
>,
|
|
1148
|
-
).length
|
|
1149
|
-
} keys)`}
|
|
1150
|
-
</span>
|
|
1151
|
-
<span
|
|
1152
|
-
class="${styles.outputIndicator} ${styles.objectExpandIcon}"
|
|
1153
|
-
onClick=${(e: Event) =>
|
|
1154
|
-
toggleOutputExpand(key, e)}
|
|
1155
|
-
title="Toggle expand output"
|
|
1156
|
-
>
|
|
1157
|
-
<svg
|
|
1158
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
1159
|
-
width="24"
|
|
1160
|
-
height="24"
|
|
1161
|
-
viewBox="0 0 24 24"
|
|
1162
|
-
fill="none"
|
|
1163
|
-
stroke="currentColor"
|
|
1164
|
-
strokeWidth="2"
|
|
1165
|
-
strokeLinecap="round"
|
|
1166
|
-
strokeLinejoin="round"
|
|
1167
|
-
style="transform: ${isOutputExpanded
|
|
1168
|
-
? 'rotate(180deg)'
|
|
1169
|
-
: 'rotate(0deg)'};
|
|
1170
|
-
transition: transform 0.2s;"
|
|
1171
|
-
>
|
|
1172
|
-
<path d="m6 9 6 6 6-6"></path>
|
|
1173
|
-
</svg>
|
|
1174
|
-
</span>
|
|
1175
|
-
`
|
|
1176
|
-
: html`
|
|
1177
|
-
<span class="${styles.value}">
|
|
1178
|
-
${String(item)}
|
|
1179
|
-
</span>
|
|
1180
|
-
`}
|
|
1181
|
-
</div>
|
|
1182
|
-
</li>
|
|
1183
|
-
`,
|
|
1184
|
-
)}
|
|
1185
|
-
</ul>
|
|
1186
|
-
</div>
|
|
1187
|
-
`;
|
|
1188
|
-
}
|
|
1189
|
-
|
|
1190
|
-
// For objects, render keys and values
|
|
1191
|
-
if (
|
|
1192
|
-
typeof tagsParam === 'object' &&
|
|
1193
|
-
tagsParam !== null
|
|
1194
|
-
) {
|
|
1195
|
-
return html`
|
|
1196
|
-
<${TagList}
|
|
1197
|
-
tags=${tagsParam as Record<string, unknown>}
|
|
1198
|
-
searchTerm=${searchTerm}
|
|
1199
|
-
level=${level + 1}
|
|
1200
|
-
path=${`${currentPath}.output`}
|
|
1201
|
-
globalSearchMode=${globalSearchMode}
|
|
1202
|
-
onSelect=${onSelect}
|
|
1203
|
-
activeTab=${activeTab}
|
|
1204
|
-
parentAppIcon=${appIconToPass}
|
|
1205
|
-
ignoreParentKey=${childIgnoreParentKey}
|
|
1206
|
-
/>
|
|
1207
|
-
`;
|
|
1208
|
-
}
|
|
1209
|
-
|
|
1210
|
-
// For primitive values, just show the string representation
|
|
1211
|
-
return html`
|
|
1212
|
-
<div style="padding: 4px; color: #666;">
|
|
1213
|
-
${String(tagsParam)}
|
|
1214
|
-
</div>
|
|
1215
|
-
`;
|
|
1216
|
-
})()}
|
|
1217
|
-
</div>
|
|
1218
|
-
</div>`
|
|
1219
|
-
: ''}
|
|
1220
|
-
${hasNestedSteps && isExpanded
|
|
1221
|
-
? html`<${TagList}
|
|
1222
|
-
tags=${isTagNode(value) ? value.tags || {} : {}}
|
|
1223
|
-
searchTerm=${searchTerm}
|
|
1224
|
-
level=${level + 1}
|
|
1225
|
-
path=${currentPath}
|
|
1226
|
-
globalSearchMode=${globalSearchMode}
|
|
1227
|
-
onSelect=${onSelect}
|
|
1228
|
-
activeTab=${activeTab}
|
|
1229
|
-
parentAppIcon=${appIconToPass}
|
|
1230
|
-
ignoreParentKey=${value.ignoreParentKey || ignoreParentKey}
|
|
1231
|
-
/>`
|
|
1232
|
-
: ''}
|
|
1233
|
-
<!-- Display expanded array content with additional debug info -->
|
|
1234
|
-
${Array.isArray(value) && value.length > 0 && isExpanded
|
|
1235
|
-
? html`<div class="${styles.outputSection}">
|
|
1236
|
-
<${TagList}
|
|
1237
|
-
tags=${value}
|
|
1238
|
-
searchTerm=${searchTerm}
|
|
1239
|
-
level=${level + 1}
|
|
1240
|
-
path=${currentPath}
|
|
1241
|
-
globalSearchMode=${globalSearchMode}
|
|
1242
|
-
onSelect=${onSelect}
|
|
1243
|
-
activeTab=${activeTab}
|
|
1244
|
-
parentAppIcon=${appIconToPass}
|
|
1245
|
-
ignoreParentKey=${childIgnoreParentKey}
|
|
1246
|
-
/>
|
|
1247
|
-
</div>`
|
|
1248
|
-
: ''}
|
|
1249
|
-
|
|
1250
|
-
<!-- Display expanded object content with additional debug info -->
|
|
1251
|
-
${!isStep &&
|
|
1252
|
-
!Array.isArray(value) &&
|
|
1253
|
-
typeof value === 'object' &&
|
|
1254
|
-
value !== null &&
|
|
1255
|
-
Object.keys(value as Record<string, unknown>).length > 0 &&
|
|
1256
|
-
isExpanded
|
|
1257
|
-
? html`<div class="${styles.outputSection}">
|
|
1258
|
-
<${TagList}
|
|
1259
|
-
tags=${value as Record<string, unknown>}
|
|
1260
|
-
searchTerm=${searchTerm}
|
|
1261
|
-
level=${level + 1}
|
|
1262
|
-
path=${currentPath}
|
|
1263
|
-
globalSearchMode=${globalSearchMode}
|
|
1264
|
-
onSelect=${onSelect}
|
|
1265
|
-
activeTab=${activeTab}
|
|
1266
|
-
parentAppIcon=${appIconToPass}
|
|
1267
|
-
ignoreParentKey=${childIgnoreParentKey}
|
|
1268
|
-
/>
|
|
1269
|
-
</div>`
|
|
1270
|
-
: ''}
|
|
1271
|
-
</li>
|
|
1272
|
-
`;
|
|
1273
|
-
},
|
|
1274
|
-
)}
|
|
1275
|
-
</ul>
|
|
1276
|
-
`;
|
|
1277
|
-
};
|
|
1278
|
-
|
|
1279
|
-
// Update the TabMenu component to search across all tabs and pass data to TagList
|
|
1280
|
-
const TabMenu = ({ data, onSelect, onOptionClick }: TagMenuProps) => {
|
|
1281
|
-
const [activeTab, setActiveTab] = useState<string>(Object.keys(data)[0]);
|
|
1282
|
-
const [searchTerm, setSearchTerm] = useState<string>('');
|
|
1283
|
-
const [searchResults, setSearchResults] = useState<Record<string, number>>(
|
|
1284
|
-
{},
|
|
1285
|
-
);
|
|
1286
|
-
const [globalSearchMode, setGlobalSearchMode] = useState<boolean>(false);
|
|
1287
|
-
|
|
1288
|
-
// Search across all tabs and count matches
|
|
1289
|
-
useEffect(() => {
|
|
1290
|
-
if (!searchTerm) {
|
|
1291
|
-
setSearchResults({});
|
|
1292
|
-
setGlobalSearchMode(false);
|
|
1293
|
-
return;
|
|
1294
|
-
}
|
|
1295
|
-
|
|
1296
|
-
const results: Record<string, number> = {};
|
|
1297
|
-
|
|
1298
|
-
Object.keys(data).forEach((tabKey) => {
|
|
1299
|
-
// Skip counting for Values tab - handle it differently
|
|
1300
|
-
if (tabKey === 'Values') {
|
|
1301
|
-
const valuesData = (data[tabKey] as unknown) as { values: ValueItem[] };
|
|
1302
|
-
if (valuesData.values) {
|
|
1303
|
-
const matches = valuesData.values.filter((item) =>
|
|
1304
|
-
item.value.toLowerCase().includes(searchTerm.toLowerCase()),
|
|
1305
|
-
).length;
|
|
1306
|
-
results[tabKey] = matches;
|
|
1307
|
-
}
|
|
1308
|
-
return;
|
|
1309
|
-
}
|
|
1310
|
-
|
|
1311
|
-
const matches = countSearchMatches(
|
|
1312
|
-
data[tabKey].tags || {},
|
|
1313
|
-
searchTerm.toLowerCase(),
|
|
1314
|
-
);
|
|
1315
|
-
results[tabKey] = matches;
|
|
1316
|
-
});
|
|
1317
|
-
|
|
1318
|
-
setSearchResults(results);
|
|
1319
|
-
setGlobalSearchMode(searchTerm.length > 0);
|
|
1320
|
-
}, [searchTerm, data]);
|
|
1321
|
-
|
|
1322
|
-
const getTabIcon = (tabName: string) => {
|
|
1323
|
-
const name = tabName.toLowerCase();
|
|
1324
|
-
|
|
1325
|
-
if (name === 'values') {
|
|
1326
|
-
return html`
|
|
1327
|
-
<svg
|
|
1328
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
1329
|
-
width="16"
|
|
1330
|
-
height="16"
|
|
1331
|
-
viewBox="0 0 24 24"
|
|
1332
|
-
fill="none"
|
|
1333
|
-
stroke="currentColor"
|
|
1334
|
-
strokeWidth="2"
|
|
1335
|
-
strokeLinecap="round"
|
|
1336
|
-
strokeLinejoin="round"
|
|
1337
|
-
class="mr-1"
|
|
1338
|
-
>
|
|
1339
|
-
<path d="M8 3H5a2 2 0 0 0-2 2v3"></path>
|
|
1340
|
-
<path d="M21 8V5a2 2 0 0 0-2-2h-3"></path>
|
|
1341
|
-
<path d="M3 16v3a2 2 0 0 0 2 2h3"></path>
|
|
1342
|
-
<path d="M16 21h3a2 2 0 0 0 2-2v-3"></path>
|
|
1343
|
-
<rect width="10" height="10" x="7" y="7" rx="2"></rect>
|
|
1344
|
-
</svg>
|
|
1345
|
-
`;
|
|
1346
|
-
}
|
|
1347
|
-
|
|
1348
|
-
if (name.includes('trigger')) {
|
|
1349
|
-
return html`
|
|
1350
|
-
<svg
|
|
1351
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
1352
|
-
width="16"
|
|
1353
|
-
height="16"
|
|
1354
|
-
viewBox="0 0 24 24"
|
|
1355
|
-
fill="none"
|
|
1356
|
-
stroke="currentColor"
|
|
1357
|
-
strokeWidth="2"
|
|
1358
|
-
strokeLinecap="round"
|
|
1359
|
-
strokeLinejoin="round"
|
|
1360
|
-
class="mr-1"
|
|
1361
|
-
>
|
|
1362
|
-
<path d="M13 2 3 14h9l-1 8 10-12h-9l1-8z"></path>
|
|
1363
|
-
</svg>
|
|
1364
|
-
`;
|
|
1365
|
-
}
|
|
1366
|
-
|
|
1367
|
-
if (name.includes('storage') || name.includes('variable')) {
|
|
1368
|
-
return html`
|
|
1369
|
-
<svg
|
|
1370
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
1371
|
-
width="16"
|
|
1372
|
-
height="16"
|
|
1373
|
-
viewBox="0 0 24 24"
|
|
1374
|
-
fill="none"
|
|
1375
|
-
stroke="currentColor"
|
|
1376
|
-
strokeWidth="2"
|
|
1377
|
-
strokeLinecap="round"
|
|
1378
|
-
strokeLinejoin="round"
|
|
1379
|
-
class="mr-1"
|
|
1380
|
-
>
|
|
1381
|
-
<ellipse cx="12" cy="5" rx="9" ry="3"></ellipse>
|
|
1382
|
-
<path d="M21 12c0 1.66-4 3-9 3s-9-1.34-9-3"></path>
|
|
1383
|
-
<path d="M3 5v14c0 1.66 4 3 9 3s9-1.34 9-3V5"></path>
|
|
1384
|
-
</svg>
|
|
1385
|
-
`;
|
|
1386
|
-
}
|
|
1387
|
-
|
|
1388
|
-
if (name.includes('form') || name.includes('setup')) {
|
|
1389
|
-
return html`
|
|
1390
|
-
<svg
|
|
1391
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
1392
|
-
width="16"
|
|
1393
|
-
height="16"
|
|
1394
|
-
viewBox="0 0 24 24"
|
|
1395
|
-
fill="none"
|
|
1396
|
-
stroke="currentColor"
|
|
1397
|
-
strokeWidth="2"
|
|
1398
|
-
strokeLinecap="round"
|
|
1399
|
-
strokeLinejoin="round"
|
|
1400
|
-
class="mr-1"
|
|
1401
|
-
>
|
|
1402
|
-
<rect width="18" height="18" x="3" y="3" rx="2"></rect>
|
|
1403
|
-
<path d="M9 9h6"></path>
|
|
1404
|
-
<path d="M9 13h6"></path>
|
|
1405
|
-
<path d="M9 17h6"></path>
|
|
1406
|
-
</svg>
|
|
1407
|
-
`;
|
|
1408
|
-
}
|
|
1409
|
-
|
|
1410
|
-
if (name.includes('auth') || name.includes('authorization')) {
|
|
1411
|
-
return html`
|
|
1412
|
-
<svg
|
|
1413
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
1414
|
-
width="16"
|
|
1415
|
-
height="16"
|
|
1416
|
-
viewBox="0 0 24 24"
|
|
1417
|
-
fill="none"
|
|
1418
|
-
stroke="currentColor"
|
|
1419
|
-
strokeWidth="2"
|
|
1420
|
-
strokeLinecap="round"
|
|
1421
|
-
strokeLinejoin="round"
|
|
1422
|
-
class="mr-1"
|
|
1423
|
-
>
|
|
1424
|
-
<rect width="18" height="11" x="3" y="11" rx="2" ry="2"></rect>
|
|
1425
|
-
<path d="M7 11V7a5 5 0 0 1 10 0v4"></path>
|
|
1426
|
-
<path d="M12 16v3"></path>
|
|
1427
|
-
</svg>
|
|
1428
|
-
`;
|
|
1429
|
-
}
|
|
1430
|
-
|
|
1431
|
-
if (name.includes('parameter')) {
|
|
1432
|
-
return html`
|
|
1433
|
-
<svg
|
|
1434
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
1435
|
-
width="20"
|
|
1436
|
-
height="20"
|
|
1437
|
-
viewBox="0 0 24 24"
|
|
1438
|
-
fill="none"
|
|
1439
|
-
stroke="currentColor"
|
|
1440
|
-
stroke-width="2"
|
|
1441
|
-
stroke-linecap="round"
|
|
1442
|
-
stroke-linejoin="round"
|
|
1443
|
-
class="lucide lucide-variable"
|
|
1444
|
-
>
|
|
1445
|
-
<path d="M8 21s-4-3-4-9 4-9 4-9" />
|
|
1446
|
-
<path d="M16 3s4 3 4 9-4 9-4 9" />
|
|
1447
|
-
<line x1="15" x2="9" y1="9" y2="15" />
|
|
1448
|
-
<line x1="9" x2="15" y1="9" y2="15" />
|
|
1449
|
-
</svg>
|
|
1450
|
-
`;
|
|
1451
|
-
}
|
|
1452
|
-
|
|
1453
|
-
// Default icon
|
|
1454
|
-
return html`
|
|
1455
|
-
<svg
|
|
1456
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
1457
|
-
width="16"
|
|
1458
|
-
height="16"
|
|
1459
|
-
viewBox="0 0 24 24"
|
|
1460
|
-
fill="none"
|
|
1461
|
-
stroke="currentColor"
|
|
1462
|
-
strokeWidth="2"
|
|
1463
|
-
strokeLinecap="round"
|
|
1464
|
-
strokeLinejoin="round"
|
|
1465
|
-
class="mr-1"
|
|
1466
|
-
>
|
|
1467
|
-
<path
|
|
1468
|
-
d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"
|
|
1469
|
-
></path>
|
|
1470
|
-
</svg>
|
|
1471
|
-
`;
|
|
1472
|
-
};
|
|
1473
|
-
|
|
1474
|
-
const renderTabs = () =>
|
|
1475
|
-
html`
|
|
1476
|
-
<div class="${styles.tabsWrapper}">
|
|
1477
|
-
${Object.keys(data).map(
|
|
1478
|
-
(key) => html`
|
|
1479
|
-
<div
|
|
1480
|
-
class="${styles.tab} ${activeTab === key
|
|
1481
|
-
? styles.activeTab
|
|
1482
|
-
: ''} ${searchResults[key] > 0 ? styles.tabWithResults : ''}"
|
|
1483
|
-
onClick=${() => setActiveTab(key)}
|
|
1484
|
-
>
|
|
1485
|
-
${getTabIcon(data[key].name || key)} ${data[key].name || key}
|
|
1486
|
-
${searchResults[key] > 0
|
|
1487
|
-
? html`<span class="${styles.resultBadge}"
|
|
1488
|
-
>${searchResults[key]}</span
|
|
1489
|
-
>`
|
|
1490
|
-
: ''}
|
|
1491
|
-
</div>
|
|
1492
|
-
`,
|
|
1493
|
-
)}
|
|
1494
|
-
</div>
|
|
1495
|
-
`;
|
|
1496
|
-
|
|
1497
|
-
const renderContent = () => {
|
|
1498
|
-
// Special handling for Values tab
|
|
1499
|
-
if (activeTab === 'Values') {
|
|
1500
|
-
const valuesData = (data[activeTab] as unknown) as {
|
|
1501
|
-
values: ValueItem[];
|
|
1502
|
-
};
|
|
1503
|
-
const filteredValues = searchTerm
|
|
1504
|
-
? valuesData.values.filter((item) =>
|
|
1505
|
-
item.value.toLowerCase().includes(searchTerm.toLowerCase()),
|
|
1506
|
-
)
|
|
1507
|
-
: valuesData.values;
|
|
1508
|
-
|
|
1509
|
-
return html`
|
|
1510
|
-
<div class="${styles.tabContent}">
|
|
1511
|
-
<div class="${styles.searchWrapper}">
|
|
1512
|
-
<input
|
|
1513
|
-
type="text"
|
|
1514
|
-
placeholder="Search values..."
|
|
1515
|
-
value=${searchTerm}
|
|
1516
|
-
onInput=${(e: Event) =>
|
|
1517
|
-
setSearchTerm((e.target as HTMLInputElement).value)}
|
|
1518
|
-
/>
|
|
1519
|
-
${searchTerm
|
|
1520
|
-
? html`
|
|
1521
|
-
<button
|
|
1522
|
-
class="${styles.clearSearch}"
|
|
1523
|
-
onClick=${() => setSearchTerm('')}
|
|
1524
|
-
title="Clear search"
|
|
1525
|
-
>
|
|
1526
|
-
<svg
|
|
1527
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
1528
|
-
width="16"
|
|
1529
|
-
height="16"
|
|
1530
|
-
viewBox="0 0 24 24"
|
|
1531
|
-
fill="none"
|
|
1532
|
-
stroke="currentColor"
|
|
1533
|
-
strokeWidth="2"
|
|
1534
|
-
strokeLinecap="round"
|
|
1535
|
-
strokeLinejoin="round"
|
|
1536
|
-
>
|
|
1537
|
-
<line x1="18" y1="6" x2="6" y2="18"></line>
|
|
1538
|
-
<line x1="6" y1="6" x2="18" y2="18"></line>
|
|
1539
|
-
</svg>
|
|
1540
|
-
</button>
|
|
1541
|
-
`
|
|
1542
|
-
: ''}
|
|
1543
|
-
</div>
|
|
1544
|
-
<div class="${styles.tagsListWrapper}">
|
|
1545
|
-
<${ValuesList}
|
|
1546
|
-
values=${filteredValues}
|
|
1547
|
-
onSelect=${onSelect}
|
|
1548
|
-
onOptionClick=${onOptionClick}
|
|
1549
|
-
/>
|
|
1550
|
-
</div>
|
|
1551
|
-
</div>
|
|
1552
|
-
`;
|
|
1553
|
-
}
|
|
1554
|
-
|
|
1555
|
-
// Regular tab handling
|
|
1556
|
-
const activeData = data[activeTab];
|
|
1557
|
-
const steps = activeData.tags || [];
|
|
1558
|
-
const hasSingleEmptyStep =
|
|
1559
|
-
!Array.isArray(steps) && // Handle the case where steps is an object
|
|
1560
|
-
Object.keys(steps).length === 1 &&
|
|
1561
|
-
isTagNode(Object.values(steps)[0]) &&
|
|
1562
|
-
Object.keys((Object.values(steps)[0] as TagNode).output || {}).length ===
|
|
1563
|
-
0;
|
|
1564
|
-
return html`
|
|
1565
|
-
<div class="${styles.tabContent}">
|
|
1566
|
-
<div class="${styles.searchWrapper}">
|
|
1567
|
-
<input
|
|
1568
|
-
type="text"
|
|
1569
|
-
placeholder="Search across all steps and fields..."
|
|
1570
|
-
value=${searchTerm}
|
|
1571
|
-
onInput=${(e: Event) =>
|
|
1572
|
-
setSearchTerm((e.target as HTMLInputElement).value)}
|
|
1573
|
-
/>
|
|
1574
|
-
${searchTerm
|
|
1575
|
-
? html`
|
|
1576
|
-
<button
|
|
1577
|
-
class="${styles.clearSearch}"
|
|
1578
|
-
onClick=${() => setSearchTerm('')}
|
|
1579
|
-
title="Clear search"
|
|
1580
|
-
>
|
|
1581
|
-
<svg
|
|
1582
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
1583
|
-
width="16"
|
|
1584
|
-
height="16"
|
|
1585
|
-
viewBox="0 0 24 24"
|
|
1586
|
-
fill="none"
|
|
1587
|
-
stroke="currentColor"
|
|
1588
|
-
strokeWidth="2"
|
|
1589
|
-
strokeLinecap="round"
|
|
1590
|
-
strokeLinejoin="round"
|
|
1591
|
-
>
|
|
1592
|
-
<line x1="18" y1="6" x2="6" y2="18"></line>
|
|
1593
|
-
<line x1="6" y1="6" x2="18" y2="18"></line>
|
|
1594
|
-
</svg>
|
|
1595
|
-
</button>
|
|
1596
|
-
`
|
|
1597
|
-
: ''}
|
|
1598
|
-
</div>
|
|
1599
|
-
${hasSingleEmptyStep
|
|
1600
|
-
? html`<div class="${styles.emptyStep}">
|
|
1601
|
-
<span>No tags found</span>
|
|
1602
|
-
</div>`
|
|
1603
|
-
: html` <div class="${styles.tagsListWrapper}">
|
|
1604
|
-
<${TagList}
|
|
1605
|
-
tags=${activeData.tags}
|
|
1606
|
-
searchTerm=${searchTerm}
|
|
1607
|
-
globalSearchMode=${globalSearchMode}
|
|
1608
|
-
onSelect=${onSelect}
|
|
1609
|
-
activeTab=${data[activeTab].machineName || activeTab}
|
|
1610
|
-
parentAppIcon=${isTagNode(activeData)
|
|
1611
|
-
? activeData.appIcon
|
|
1612
|
-
: undefined}
|
|
1613
|
-
ignoreParentKey=${false}
|
|
1614
|
-
/>
|
|
1615
|
-
</div>`}
|
|
1616
|
-
</div>
|
|
1617
|
-
`;
|
|
1618
|
-
};
|
|
1619
|
-
|
|
1620
|
-
return html`<div>${renderTabs()} ${renderContent()}</div>`;
|
|
1621
|
-
};
|
|
1622
|
-
|
|
1623
|
-
// Function to convert TagData to include the Values tab
|
|
1624
|
-
function convertTagsToObject(tagData: Record<string, unknown>): TagData {
|
|
1625
|
-
const result: TagData = {};
|
|
1626
|
-
|
|
1627
|
-
Object.keys(tagData).forEach((key) => {
|
|
1628
|
-
const section = tagData[key] as TagNode;
|
|
1629
|
-
const newSection: TagNode = {
|
|
1630
|
-
...section,
|
|
1631
|
-
};
|
|
1632
|
-
|
|
1633
|
-
// Convert tags array to object if needed
|
|
1634
|
-
if (section.tags && Array.isArray(section.tags)) {
|
|
1635
|
-
const tagsObject: Record<string, TagNode> = {};
|
|
1636
|
-
|
|
1637
|
-
section.tags.forEach((tag: TagNode, index: number) => {
|
|
1638
|
-
// Use machineName as key if available, otherwise use index
|
|
1639
|
-
const tagKey = tag.machineName || `[${index}]`;
|
|
1640
|
-
|
|
1641
|
-
// Recursively convert nested tags
|
|
1642
|
-
if (tag.tags && Array.isArray(tag.tags)) {
|
|
1643
|
-
tagsObject[tagKey] = {
|
|
1644
|
-
...tag,
|
|
1645
|
-
tags: convertNestedTagsToObject(tag.tags),
|
|
1646
|
-
};
|
|
1647
|
-
} else {
|
|
1648
|
-
tagsObject[tagKey] = tag;
|
|
1649
|
-
}
|
|
1650
|
-
});
|
|
1651
|
-
|
|
1652
|
-
newSection.tags = tagsObject;
|
|
1653
|
-
}
|
|
1654
|
-
|
|
1655
|
-
result[key] = newSection;
|
|
1656
|
-
});
|
|
1657
|
-
|
|
1658
|
-
return result;
|
|
1659
|
-
}
|
|
1660
|
-
|
|
1661
|
-
// Update the TagsMenu function to add the Values tab
|
|
1662
|
-
export function TagsMenu({
|
|
1663
|
-
tagsTree,
|
|
1664
|
-
onSelect,
|
|
1665
|
-
renderValuesTab,
|
|
1666
|
-
options,
|
|
1667
|
-
onOptionClick,
|
|
1668
|
-
}: TagsMenuProps) {
|
|
1669
|
-
let modifiedData = convertTagsToObject(tagsTree);
|
|
1670
|
-
|
|
1671
|
-
if (
|
|
1672
|
-
renderValuesTab &&
|
|
1673
|
-
options &&
|
|
1674
|
-
Array.isArray(options) &&
|
|
1675
|
-
options.length > 0
|
|
1676
|
-
) {
|
|
1677
|
-
// Add the Values tab with sample data
|
|
1678
|
-
// In a real implementation, this would come from props
|
|
1679
|
-
modifiedData = {
|
|
1680
|
-
Values: {
|
|
1681
|
-
name: 'Values',
|
|
1682
|
-
machineName: 'values',
|
|
1683
|
-
values: options,
|
|
1684
|
-
} as TagNode,
|
|
1685
|
-
...modifiedData, // Spread the remaining tabs after "Values"
|
|
1686
|
-
};
|
|
1687
|
-
}
|
|
1688
|
-
return html`
|
|
1689
|
-
<div class="${styles.tagsMenuWrapper}">
|
|
1690
|
-
<${TabMenu}
|
|
1691
|
-
data=${modifiedData}
|
|
1692
|
-
onSelect=${onSelect}
|
|
1693
|
-
onOptionClick=${onOptionClick}
|
|
1694
|
-
/>
|
|
1695
|
-
</div>
|
|
1696
|
-
`;
|
|
1697
|
-
}
|