@orchestrator-ui/orchestrator-ui-components 8.4.4 → 8.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/.turbo/turbo-build.log +8 -8
  2. package/.turbo/turbo-lint.log +1 -1
  3. package/.turbo/turbo-test.log +7 -7
  4. package/CHANGELOG.md +17 -0
  5. package/dist/index.d.ts +1890 -562
  6. package/dist/index.js +3814 -2103
  7. package/dist/index.js.map +1 -1
  8. package/package.json +5 -4
  9. package/src/components/WfoPydanticForm/WfoPydanticForm.tsx +23 -1
  10. package/src/components/WfoSearchBar/WfoSearchField.tsx +0 -1
  11. package/src/components/WfoSearchPage/WfoFilterGroup/WfoFilterGroup.tsx +5 -5
  12. package/src/components/WfoSearchPage/WfoSearch/WfoSearch.tsx +12 -5
  13. package/src/components/WfoSearchPage/constants.ts +0 -4
  14. package/src/components/WfoSearchPage/utils.ts +75 -20
  15. package/src/components/WfoSubscription/WfoSubscriptionActions/WfoSubscriptionActionExpandableMenuItem.tsx +36 -18
  16. package/src/components/WfoSubscription/WfoSubscriptionActions/WfoSubscriptionActionsMenuItem.tsx +38 -2
  17. package/src/components/WfoSubscription/utils/index.ts +3 -0
  18. package/src/components/WfoSubscription/utils/utils.spec.ts +39 -4
  19. package/src/components/WfoSubscription/utils/utils.ts +10 -4
  20. package/src/components/WfoTable/WfoStructuredSearchTable/WfoAddGroupAction.tsx +19 -0
  21. package/src/components/WfoTable/WfoStructuredSearchTable/WfoAddRuleAction.tsx +23 -0
  22. package/src/components/WfoTable/WfoStructuredSearchTable/WfoCombinatorSelector.tsx +30 -0
  23. package/src/components/WfoTable/WfoStructuredSearchTable/WfoExpandingSearchRow.tsx +38 -0
  24. package/src/components/WfoTable/WfoStructuredSearchTable/WfoFieldSelector.tsx +84 -0
  25. package/src/components/WfoTable/WfoStructuredSearchTable/WfoFilterBuilder.tsx +189 -0
  26. package/src/components/WfoTable/WfoStructuredSearchTable/WfoOperatorSelector.tsx +33 -0
  27. package/src/components/WfoTable/WfoStructuredSearchTable/WfoRangeEditor.tsx +64 -0
  28. package/src/components/WfoTable/WfoStructuredSearchTable/WfoRemoveGroupAction.tsx +21 -0
  29. package/src/components/WfoTable/WfoStructuredSearchTable/WfoRemoveRuleAction.tsx +20 -0
  30. package/src/components/WfoTable/WfoStructuredSearchTable/WfoRule.tsx +16 -0
  31. package/src/components/WfoTable/WfoStructuredSearchTable/WfoRuleGroup.tsx +73 -0
  32. package/src/components/WfoTable/WfoStructuredSearchTable/WfoStructuredSearchTable.tsx +323 -0
  33. package/src/components/WfoTable/WfoStructuredSearchTable/WfoValueEditor.tsx +159 -0
  34. package/src/components/WfoTable/WfoStructuredSearchTable/index.ts +2 -0
  35. package/src/components/WfoTable/WfoStructuredSearchTable/styles.ts +146 -0
  36. package/src/components/WfoTable/WfoTable/WfoDragHandler.tsx +4 -2
  37. package/src/components/WfoTable/index.ts +2 -6
  38. package/src/components/WfoTitleWithWebsocketBadge/WfoTitleWithWebsocketBadge.tsx +14 -6
  39. package/src/components/WfoWorkflowSteps/WfoStep/WfoStep.tsx +1 -0
  40. package/src/components/WfoWorkflowSteps/WfoStepList/WfoStepList.tsx +3 -0
  41. package/src/components/WfoWorkflowSteps/WfoWorkflowStepList/WfoWorkflowStepList.tsx +32 -12
  42. package/src/components/WfoWorkflowUserGuide/WfoPageWithUserGuide.tsx +38 -0
  43. package/src/components/WfoWorkflowUserGuide/WfoWorkflowGuideExpandablePanel.tsx +151 -0
  44. package/src/components/WfoWorkflowUserGuide/index.ts +2 -0
  45. package/src/components/WfoWorkflowUserGuide/styles.ts +87 -0
  46. package/src/components/index.ts +1 -0
  47. package/src/configuration/version.ts +1 -1
  48. package/src/contexts/OrchestratorConfigContext.tsx +1 -0
  49. package/src/hooks/index.ts +1 -0
  50. package/src/hooks/usePathAutoComplete.ts +3 -4
  51. package/src/hooks/useSearch.ts +20 -15
  52. package/src/hooks/useSearchPagination.ts +11 -8
  53. package/src/hooks/useUrlParams.ts +3 -5
  54. package/src/icons/WfoTrashFilled.tsx +13 -0
  55. package/src/icons/WfoXMarkSmall.tsx +2 -2
  56. package/src/icons/index.ts +1 -0
  57. package/src/messages/en-GB.json +94 -8
  58. package/src/messages/nl-NL.json +23 -5
  59. package/src/pages/WfoSearchPocPage.tsx +402 -0
  60. package/src/pages/index.ts +1 -0
  61. package/src/pages/processes/WfoProcessDetail.tsx +10 -10
  62. package/src/pages/processes/WfoProcessDetailPage.tsx +1 -0
  63. package/src/pages/processes/WfoStartProcessPage.tsx +15 -19
  64. package/src/rtk/api.ts +1 -0
  65. package/src/rtk/endpoints/index.ts +1 -0
  66. package/src/rtk/endpoints/search.ts +45 -10
  67. package/src/rtk/endpoints/workflowGuides.ts +25 -0
  68. package/src/types/search.ts +21 -5
  69. package/src/types/types.ts +10 -1
@@ -8,18 +8,26 @@ import { useGetOrchestratorConfig } from '@/hooks';
8
8
  interface WfoTitleWithWebsocketBadgeProps {
9
9
  title: string | ReactNode;
10
10
  wsUrl?: string;
11
+ extraElement?: ReactNode;
11
12
  }
12
13
 
13
- export const WfoTitleWithWebsocketBadge = ({ title, wsUrl = undefined }: WfoTitleWithWebsocketBadgeProps) => {
14
+ export const WfoTitleWithWebsocketBadge = ({
15
+ title,
16
+ wsUrl = undefined,
17
+ extraElement,
18
+ }: WfoTitleWithWebsocketBadgeProps) => {
14
19
  const { useWebSockets } = useGetOrchestratorConfig();
15
20
 
16
21
  const pageTitle =
17
- useWebSockets ?
18
- <EuiFlexGroup alignItems="center" gutterSize="s">
22
+ useWebSockets || extraElement ?
23
+ <EuiFlexGroup alignItems="center" gutterSize="s" responsive={false}>
19
24
  <EuiFlexItem grow={false}>{title}</EuiFlexItem>
20
- <EuiFlexItem grow={false}>
21
- <WfoWebsocketStatusBadge wsUrl={wsUrl} />
22
- </EuiFlexItem>
25
+ {useWebSockets && (
26
+ <EuiFlexItem grow={false}>
27
+ <WfoWebsocketStatusBadge wsUrl={wsUrl} />
28
+ </EuiFlexItem>
29
+ )}
30
+ {extraElement && <EuiFlexItem grow={false}>{extraElement}</EuiFlexItem>}
23
31
  </EuiFlexGroup>
24
32
  : title;
25
33
 
@@ -28,6 +28,7 @@ export interface WfoStepProps {
28
28
  isTask: boolean;
29
29
  isStartStep?: boolean;
30
30
  processId?: string;
31
+ workflowName?: string;
31
32
  userPermissions: FormUserPermissions;
32
33
  }
33
34
 
@@ -20,6 +20,7 @@ export type WfoStepListProps = {
20
20
  onTriggerExpandStepListItem: (stepListItem: StepListItem) => void;
21
21
  isTask: boolean;
22
22
  processId: string;
23
+ workflowName?: string;
23
24
  userPermissions: FormUserPermissions;
24
25
  };
25
26
 
@@ -32,6 +33,7 @@ export const WfoStepList = React.forwardRef(
32
33
  onTriggerExpandStepListItem,
33
34
  isTask,
34
35
  processId,
36
+ workflowName,
35
37
  userPermissions,
36
38
  }: WfoStepListProps,
37
39
  reference: Ref<WfoStepListRef>,
@@ -97,6 +99,7 @@ export const WfoStepList = React.forwardRef(
97
99
  isStartStep={index === 0}
98
100
  isTask={isTask}
99
101
  processId={processId}
102
+ workflowName={workflowName}
100
103
  userPermissions={userPermissions}
101
104
  />
102
105
  </div>
@@ -2,7 +2,14 @@ import React, { Ref, useEffect, useState } from 'react';
2
2
 
3
3
  import { useTranslations } from 'next-intl';
4
4
 
5
- import { WfoJsonCodeBlock, WfoLoading, WfoStepList, WfoStepListHeader, WfoStepListRef } from '@/components';
5
+ import {
6
+ WfoJsonCodeBlock,
7
+ WfoLoading,
8
+ WfoPageWithUserGuide,
9
+ WfoStepList,
10
+ WfoStepListHeader,
11
+ WfoStepListRef,
12
+ } from '@/components';
6
13
  import WfoDiff, { getSubscriptionDiffTexts } from '@/components/WfoDiff/WfoDiff';
7
14
  import { WfoTraceback } from '@/components/WfoWorkflowSteps/WfoTraceback/WfoTraceback';
8
15
  import { useGetRawProcessDetailQuery } from '@/rtk/endpoints/processDetail';
@@ -21,6 +28,7 @@ export interface WfoWorkflowStepListProps {
21
28
  traceBack: string | null;
22
29
  startedAt: string;
23
30
  processId: string;
31
+ workflowName?: string;
24
32
  isTask: boolean;
25
33
  userInputForm?: InputForm;
26
34
  userPermissions: FormUserPermissions;
@@ -40,7 +48,16 @@ export const WfoProcessSubscriptionDelta = ({ processId }: { processId: string }
40
48
 
41
49
  export const WfoWorkflowStepList = React.forwardRef(
42
50
  (
43
- { steps = [], lastStatus, traceBack, processId, isTask, userInputForm, userPermissions }: WfoWorkflowStepListProps,
51
+ {
52
+ steps = [],
53
+ lastStatus,
54
+ traceBack,
55
+ processId,
56
+ workflowName,
57
+ isTask,
58
+ userInputForm,
59
+ userPermissions,
60
+ }: WfoWorkflowStepListProps,
44
61
  reference: Ref<WfoStepListRef>,
45
62
  ) => {
46
63
  const [showHiddenKeys, setShowHiddenKeys] = useState(false);
@@ -143,16 +160,19 @@ export const WfoWorkflowStepList = React.forwardRef(
143
160
  {showRaw && <WfoProcessRawData processId={processId} />}
144
161
  {showDelta && <WfoProcessSubscriptionDelta processId={processId} />}
145
162
  {!showRaw && !showDelta && (
146
- <WfoStepList
147
- ref={reference}
148
- stepListItems={stepListItems}
149
- showHiddenKeys={showHiddenKeys}
150
- isTask={isTask}
151
- onToggleExpandStepListItem={toggleExpandedStateStepListItem}
152
- processId={processId}
153
- onTriggerExpandStepListItem={handleExpandStepListItem}
154
- userPermissions={userPermissions}
155
- />
163
+ <WfoPageWithUserGuide workflowName={workflowName}>
164
+ <WfoStepList
165
+ ref={reference}
166
+ stepListItems={stepListItems}
167
+ showHiddenKeys={showHiddenKeys}
168
+ isTask={isTask}
169
+ onToggleExpandStepListItem={toggleExpandedStateStepListItem}
170
+ processId={processId}
171
+ workflowName={workflowName}
172
+ onTriggerExpandStepListItem={handleExpandStepListItem}
173
+ userPermissions={userPermissions}
174
+ />
175
+ </WfoPageWithUserGuide>
156
176
  )}
157
177
  </>
158
178
  );
@@ -0,0 +1,38 @@
1
+ import React, { ReactNode, useState } from 'react';
2
+
3
+ import { EuiFlexGroup, EuiFlexItem, useIsWithinBreakpoints } from '@elastic/eui';
4
+
5
+ import { useGetOrchestratorConfig } from '@/hooks';
6
+
7
+ import { WfoWorkflowGuideExpandablePanel } from './WfoWorkflowGuideExpandablePanel';
8
+
9
+ interface WfoFormWithUserGuideProps {
10
+ workflowName?: string;
11
+ children: ReactNode;
12
+ }
13
+
14
+ export const WfoPageWithUserGuide = ({ workflowName, children }: WfoFormWithUserGuideProps) => {
15
+ const [isExpanded, setIsExpanded] = useState(false);
16
+ const isBigScreen = useIsWithinBreakpoints(['xl', 'xxl']);
17
+ const { showWorkflowUserGuide } = useGetOrchestratorConfig();
18
+
19
+ if (!workflowName || !showWorkflowUserGuide) {
20
+ return <>{children}</>;
21
+ }
22
+
23
+ const workflowGuideExpandablePanel = (
24
+ <WfoWorkflowGuideExpandablePanel
25
+ workflowName={workflowName}
26
+ isExpanded={isExpanded}
27
+ onToggle={() => setIsExpanded((expanded) => !expanded)}
28
+ />
29
+ );
30
+
31
+ return (
32
+ <EuiFlexGroup gutterSize="s" direction={isBigScreen ? 'row' : 'column'}>
33
+ {!isBigScreen && workflowGuideExpandablePanel}
34
+ <EuiFlexItem grow={true}>{children}</EuiFlexItem>
35
+ {isBigScreen && workflowGuideExpandablePanel}
36
+ </EuiFlexGroup>
37
+ );
38
+ };
@@ -0,0 +1,151 @@
1
+ import React, { ReactNode } from 'react';
2
+
3
+ import { useTranslations } from 'next-intl';
4
+
5
+ import {
6
+ EuiFlexGroup,
7
+ EuiFlexItem,
8
+ EuiIcon,
9
+ EuiLoadingSpinner,
10
+ EuiMarkdownFormat,
11
+ EuiPanel,
12
+ EuiText,
13
+ useIsWithinBreakpoints,
14
+ } from '@elastic/eui';
15
+
16
+ import { useWithOrchestratorTheme } from '@/hooks';
17
+ import { useGetWorkflowGuideQuery } from '@/rtk';
18
+
19
+ import { getStyles } from './styles';
20
+
21
+ interface WfoWorkflowUserGuideProps {
22
+ workflowName: string;
23
+ isExpanded: boolean;
24
+ onToggle: () => void;
25
+ }
26
+
27
+ interface WfoUserGuideToggleStripProps {
28
+ onToggle: () => void;
29
+ ariaLabel: string;
30
+ isBigScreen: boolean;
31
+ noLeadingBorder?: boolean;
32
+ children: ReactNode;
33
+ }
34
+
35
+ const WfoWorkflowGuideToggleStrip = ({
36
+ onToggle,
37
+ ariaLabel,
38
+ isBigScreen,
39
+ noLeadingBorder,
40
+ children,
41
+ }: WfoUserGuideToggleStripProps) => {
42
+ const {
43
+ fullHeightStyle,
44
+ toggleStripContainerStyle,
45
+ toggleStripContainerHorizontalStyle,
46
+ toggleStripPanelStyle,
47
+ noLeftBorderStyle,
48
+ noBottomBorderStyle,
49
+ } = useWithOrchestratorTheme(getStyles);
50
+
51
+ return (
52
+ <EuiFlexItem
53
+ grow={false}
54
+ onClick={onToggle}
55
+ aria-label={ariaLabel}
56
+ css={isBigScreen ? toggleStripContainerStyle : toggleStripContainerHorizontalStyle}
57
+ >
58
+ <EuiPanel
59
+ hasShadow={false}
60
+ css={[toggleStripPanelStyle, noLeadingBorder && (isBigScreen ? noLeftBorderStyle : noBottomBorderStyle)]}
61
+ >
62
+ <EuiFlexGroup
63
+ direction={isBigScreen ? 'column' : 'row'}
64
+ alignItems="center"
65
+ gutterSize="s"
66
+ justifyContent="center"
67
+ css={fullHeightStyle}
68
+ >
69
+ {children}
70
+ </EuiFlexGroup>
71
+ </EuiPanel>
72
+ </EuiFlexItem>
73
+ );
74
+ };
75
+
76
+ const WfoWorkflowGuideMarkdown = ({ workflowName, isBigScreen }: { workflowName: string; isBigScreen: boolean }) => {
77
+ const t = useTranslations('workflowGuide');
78
+ const { guideBodyStyle, guidePanelStyle, guideStackedBodyStyle, guideStackedPanelStyle } =
79
+ useWithOrchestratorTheme(getStyles);
80
+ const { data, isLoading, isError } = useGetWorkflowGuideQuery({ workflowName });
81
+ const content = data?.content ?? '';
82
+
83
+ return (
84
+ <div css={isBigScreen ? guideBodyStyle : guideStackedBodyStyle}>
85
+ {(isLoading && <EuiLoadingSpinner size="m" />)
86
+ || ((isError || !content) && <EuiText color="subdued">{t('noGuideAvailable')}</EuiText>) || (
87
+ <EuiPanel paddingSize="m" hasShadow css={isBigScreen ? guidePanelStyle : guideStackedPanelStyle}>
88
+ <EuiMarkdownFormat>{content}</EuiMarkdownFormat>
89
+ </EuiPanel>
90
+ )}
91
+ </div>
92
+ );
93
+ };
94
+
95
+ export const WfoWorkflowGuideExpandablePanel = ({ workflowName, isExpanded, onToggle }: WfoWorkflowUserGuideProps) => {
96
+ const t = useTranslations('workflowGuide');
97
+ const { fullHeightStyle, guideExpandedItemStyle, guideExpandedFillStyle } = useWithOrchestratorTheme(getStyles);
98
+ const isBigScreen = useIsWithinBreakpoints(['xl', 'xxl']);
99
+
100
+ const OpenGuideButton = () => (
101
+ <EuiFlexItem grow={false}>
102
+ <EuiFlexGroup gutterSize="xs" alignItems="center" direction={isBigScreen ? 'column' : 'row'}>
103
+ <EuiIcon type={isBigScreen ? 'arrowLeft' : 'arrowDown'} size="xxl" color="primary" />
104
+ <EuiIcon type={'info'} size="xxl" color="primary" />
105
+ </EuiFlexGroup>
106
+ </EuiFlexItem>
107
+ );
108
+
109
+ const CloseGuideButton = () => (
110
+ <EuiFlexItem grow={false}>
111
+ <EuiIcon type={isBigScreen ? 'arrowRight' : 'arrowUp'} size="xl" color="primary" />
112
+ </EuiFlexItem>
113
+ );
114
+
115
+ if (!isExpanded) {
116
+ return (
117
+ <WfoWorkflowGuideToggleStrip onToggle={onToggle} ariaLabel={t('show')} isBigScreen={isBigScreen}>
118
+ <OpenGuideButton />
119
+ </WfoWorkflowGuideToggleStrip>
120
+ );
121
+ }
122
+
123
+ if (isBigScreen) {
124
+ return (
125
+ <EuiFlexItem grow={1} css={guideExpandedItemStyle}>
126
+ <EuiFlexGroup gutterSize="none" css={[fullHeightStyle, guideExpandedFillStyle]}>
127
+ <WfoWorkflowGuideMarkdown workflowName={workflowName} isBigScreen />
128
+ <WfoWorkflowGuideToggleStrip onToggle={onToggle} ariaLabel={t('hide')} isBigScreen noLeadingBorder>
129
+ <CloseGuideButton />
130
+ </WfoWorkflowGuideToggleStrip>
131
+ </EuiFlexGroup>
132
+ </EuiFlexItem>
133
+ );
134
+ }
135
+
136
+ return (
137
+ <EuiFlexItem grow={false}>
138
+ <EuiFlexGroup direction="column" gutterSize="none">
139
+ <WfoWorkflowGuideToggleStrip
140
+ onToggle={onToggle}
141
+ ariaLabel={t('hide')}
142
+ isBigScreen={isBigScreen}
143
+ noLeadingBorder
144
+ >
145
+ <CloseGuideButton />
146
+ </WfoWorkflowGuideToggleStrip>
147
+ <WfoWorkflowGuideMarkdown workflowName={workflowName} isBigScreen />
148
+ </EuiFlexGroup>
149
+ </EuiFlexItem>
150
+ );
151
+ };
@@ -0,0 +1,2 @@
1
+ export * from './WfoWorkflowGuideExpandablePanel';
2
+ export * from './WfoPageWithUserGuide';
@@ -0,0 +1,87 @@
1
+ import { css } from '@emotion/react';
2
+
3
+ import { WfoThemeHelpers } from '@/hooks';
4
+
5
+ export const getStyles = ({ theme }: WfoThemeHelpers) => {
6
+ const fullHeightStyle = css({
7
+ height: '100%',
8
+ });
9
+
10
+ const toggleStripContainerStyle = css({
11
+ width: theme.base * 4,
12
+ cursor: 'pointer',
13
+ });
14
+
15
+ const toggleStripContainerHorizontalStyle = css({
16
+ width: '100%',
17
+ height: theme.base * 4,
18
+ cursor: 'pointer',
19
+ });
20
+
21
+ const toggleStripPanelStyle = css({
22
+ height: '100%',
23
+ backgroundColor: theme.colors.backgroundBasePrimary,
24
+ border: `2px dashed ${theme.colors.backgroundLightPrimary}`,
25
+ transition: 'box-shadow 100ms ease-in-out, border-style 100ms ease-in-out',
26
+ '&:hover': {
27
+ borderStyle: 'solid',
28
+ boxShadow: `0 0 0 2px ${theme.colors.backgroundBasePrimary}`,
29
+ },
30
+ });
31
+
32
+ const guideExpandedItemStyle = css({
33
+ position: 'relative',
34
+ });
35
+
36
+ const guideExpandedFillStyle = css({
37
+ position: 'absolute',
38
+ inset: 0,
39
+ });
40
+
41
+ const guidePanelStyle = css({
42
+ height: '100%',
43
+ overflowY: 'auto',
44
+ border: `2px dashed ${theme.colors.backgroundLightPrimary}`,
45
+ borderRightWidth: 0,
46
+ });
47
+
48
+ const guideBodyStyle = css({
49
+ flex: 1,
50
+ minHeight: 0,
51
+ display: 'flex',
52
+ flexDirection: 'column',
53
+ });
54
+
55
+ const noLeftBorderStyle = css({
56
+ borderLeftWidth: 0,
57
+ });
58
+
59
+ const noBottomBorderStyle = css({
60
+ borderBottomWidth: 0,
61
+ });
62
+
63
+ const guideStackedBodyStyle = css({
64
+ maxHeight: '50vh',
65
+ overflowY: 'auto',
66
+ });
67
+
68
+ const guideStackedPanelStyle = css({
69
+ border: `2px dashed ${theme.colors.backgroundLightPrimary}`,
70
+ borderTopWidth: 0,
71
+ });
72
+
73
+ return {
74
+ fullHeightStyle,
75
+ toggleStripContainerStyle,
76
+ toggleStripContainerHorizontalStyle,
77
+ toggleStripPanelStyle,
78
+ noLeftBorderStyle,
79
+ noBottomBorderStyle,
80
+ guidePanelStyle,
81
+ guideBodyStyle,
82
+ guideStackedBodyStyle,
83
+ guideStackedPanelStyle,
84
+ guideExpandedItemStyle,
85
+ guideExpandedFillStyle,
86
+ };
87
+ };
@@ -38,6 +38,7 @@ export * from './WfoTableCodeBlock';
38
38
  export * from './WfoInlineEdit';
39
39
  export * from './WfoPydanticForm';
40
40
  export * from './WfoSearchPage';
41
+ export * from './WfoWorkflowUserGuide';
41
42
  export * from './WfoMonacoCodeBlock';
42
43
  export * from './WfoLogoSpinner';
43
44
  export * from './WfoPopover';
@@ -1 +1 @@
1
- export const ORCHESTRATOR_UI_LIBRARY_VERSION = '8.4.4';
1
+ export const ORCHESTRATOR_UI_LIBRARY_VERSION = '8.5.0';
@@ -13,6 +13,7 @@ export const emptyOrchestratorConfig: OrchestratorConfig = {
13
13
  useWebSockets: false,
14
14
  useThemeToggle: false,
15
15
  showWorkflowInformationLink: false,
16
+ showWorkflowUserGuide: false,
16
17
  workflowInformationLinkUrl: '',
17
18
  enableSupportMenuItem: false,
18
19
  supportMenuItemUrl: '',
@@ -13,4 +13,5 @@ export * from './useGetOrchestratorConfig';
13
13
  export * from './useBackendAvailability';
14
14
  export * from './useGetSchedulesForWorkflow';
15
15
  export * from './useGetWorkflowNameById';
16
+ export * from './usePathAutoComplete';
16
17
  export * from './useGetPydanticFormsConfig';
@@ -53,7 +53,6 @@ const FALLBACK_DEFINITIONS: Record<
53
53
  export const usePathAutocomplete = (prefix: string, entityType: EntityKind) => {
54
54
  const [paths, setPaths] = useState<PathInfo[]>([]);
55
55
  const debouncedPrefix = useDebounce(prefix, 300);
56
-
57
56
  const { data: definitions = FALLBACK_DEFINITIONS, isError: defError } = useSearchDefinitionsQuery();
58
57
 
59
58
  const {
@@ -88,7 +87,7 @@ export const usePathAutocomplete = (prefix: string, entityType: EntityKind) => {
88
87
  displayLabel: leaf.name,
89
88
  ui_types: leaf.ui_types,
90
89
  availablePaths: leaf.paths || [],
91
- pathCount: leaf.paths ? leaf.paths.length : 0,
90
+ pathCount: leaf.paths ? leaf.paths?.length : 0,
92
91
  });
93
92
  });
94
93
 
@@ -105,12 +104,12 @@ export const usePathAutocomplete = (prefix: string, entityType: EntityKind) => {
105
104
  displayLabel: component.name,
106
105
  ui_types: component.ui_types,
107
106
  availablePaths: component.paths || [],
108
- pathCount: component.paths ? component.paths.length : 0,
107
+ pathCount: component.paths ? component.paths?.length : 0,
109
108
  });
110
109
  });
111
110
 
112
111
  setPaths(enrichedPaths);
113
- }, [pathData, definitions, debouncedPrefix.length]);
112
+ }, [pathData, definitions, debouncedPrefix?.length]);
114
113
 
115
114
  const errorMessage =
116
115
  isError ? 'Failed to load paths'
@@ -2,23 +2,30 @@ import { useEffect, useState } from 'react';
2
2
 
3
3
  import { Query } from '@elastic/eui';
4
4
 
5
- import { useSearchMutation } from '@/rtk/endpoints';
6
- import { EntityKind, Group, PaginatedSearchResults, RetrieverType } from '@/types';
5
+ import { useLazySearchQuery } from '@/rtk/endpoints';
6
+ import { EntityKind, Filter, PaginatedSearchResults, RetrieverType } from '@/types';
7
+
8
+ const emptyResult: PaginatedSearchResults = {
9
+ data: [],
10
+ page_info: { has_next_page: false, next_page_cursor: null },
11
+ search_metadata: { search_type: null, description: null },
12
+ cursor: {
13
+ total_items: 0,
14
+ start_cursor: 0,
15
+ end_cursor: 0,
16
+ },
17
+ };
7
18
 
8
19
  export const useSearch = (
9
20
  query: Query | string,
10
21
  entityType: EntityKind,
11
- filterGroup?: Group,
22
+ filterGroup?: Filter,
12
23
  limit?: number,
13
24
  retriever: RetrieverType = RetrieverType.Auto,
14
25
  ) => {
15
- const [results, setResults] = useState<PaginatedSearchResults>({
16
- data: [],
17
- page_info: { has_next_page: false, next_page_cursor: null },
18
- search_metadata: { search_type: null, description: null },
19
- });
26
+ const [results, setResults] = useState<PaginatedSearchResults>({ ...emptyResult });
20
27
 
21
- const [triggerSearch, { isLoading, isError }] = useSearchMutation();
28
+ const [triggerSearch, { isLoading, isError }] = useLazySearchQuery();
22
29
 
23
30
  useEffect(() => {
24
31
  const queryText = typeof query === 'string' ? query : query.text?.trim() || '';
@@ -27,9 +34,7 @@ export const useSearch = (
27
34
 
28
35
  if (queryText.length < 2 && !hasFilters) {
29
36
  setResults({
30
- data: [],
31
- page_info: { has_next_page: false, next_page_cursor: null },
32
- search_metadata: { search_type: null, description: null },
37
+ ...emptyResult,
33
38
  });
34
39
  return;
35
40
  }
@@ -42,6 +47,7 @@ export const useSearch = (
42
47
  filters: filterGroup && filterGroup.children.length > 0 ? filterGroup : undefined,
43
48
  limit: limit,
44
49
  retriever: retriever === RetrieverType.Auto ? undefined : retriever,
50
+ response_columns: [],
45
51
  }).unwrap();
46
52
 
47
53
  setResults({
@@ -54,13 +60,12 @@ export const useSearch = (
54
60
  search_type: result.search_metadata?.search_type || null,
55
61
  description: result.search_metadata?.description || null,
56
62
  },
63
+ cursor: result.cursor,
57
64
  });
58
65
  } catch (error) {
59
66
  console.error('Search error:', error);
60
67
  setResults({
61
- data: [],
62
- page_info: { has_next_page: false, next_page_cursor: null },
63
- search_metadata: { search_type: null, description: null },
68
+ ...emptyResult,
64
69
  });
65
70
  }
66
71
  };
@@ -1,10 +1,11 @@
1
1
  import { useCallback, useState } from 'react';
2
+ import type { Dispatch, SetStateAction } from 'react';
2
3
 
3
4
  import { Query } from '@elastic/eui';
4
5
 
5
6
  import { buildSearchParams } from '@/components/WfoSearchPage/utils';
6
7
  import { useSearchWithPaginationMutation } from '@/rtk/endpoints';
7
- import { EntityKind, Group, PaginatedSearchResults, RetrieverType, SearchResult } from '@/types';
8
+ import { EntityKind, Filter, PaginatedSearchResults, RetrieverType, SearchResult } from '@/types';
8
9
 
9
10
  interface PageHistoryItem {
10
11
  page: number;
@@ -26,10 +27,10 @@ interface UseSearchPaginationReturn {
26
27
  export const useSearchPagination = (
27
28
  debouncedQuery: Query | string,
28
29
  selectedEntityTab: EntityKind,
29
- filterGroup: Group,
30
+ filterGroup: Filter,
30
31
  pageSize: number,
31
32
  results: PaginatedSearchResults,
32
- setResults: (results: PaginatedSearchResults) => void,
33
+ setResults: Dispatch<SetStateAction<PaginatedSearchResults>>,
33
34
  retriever?: RetrieverType,
34
35
  ): UseSearchPaginationReturn => {
35
36
  const [currentPage, setCurrentPage] = useState<number>(1);
@@ -50,7 +51,7 @@ export const useSearchPagination = (
50
51
  {
51
52
  page: currentPage,
52
53
  results: results.data,
53
- cursor: results.page_info.next_page_cursor,
54
+ cursor: results.cursor.start_cursor,
54
55
  },
55
56
  ]);
56
57
 
@@ -61,12 +62,12 @@ export const useSearchPagination = (
61
62
  selectedEntityTab,
62
63
  filterGroup,
63
64
  pageSize,
65
+ nextPageCursor,
64
66
  retriever === RetrieverType.Auto ? undefined : retriever,
65
67
  );
66
68
 
67
69
  const res = await triggerSearchPagination({
68
70
  ...searchParams,
69
- cursor: nextPageCursor,
70
71
  }).unwrap();
71
72
 
72
73
  setResults({
@@ -79,6 +80,7 @@ export const useSearchPagination = (
79
80
  search_type: res.search_metadata.search_type,
80
81
  description: res.search_metadata.description,
81
82
  },
83
+ cursor: res.cursor,
82
84
  });
83
85
 
84
86
  setCurrentPage((prev) => prev + 1);
@@ -94,7 +96,6 @@ export const useSearchPagination = (
94
96
  [
95
97
  currentPage,
96
98
  results.data,
97
- results.page_info.next_page_cursor,
98
99
  isLoadingMore,
99
100
  debouncedQuery,
100
101
  selectedEntityTab,
@@ -103,6 +104,7 @@ export const useSearchPagination = (
103
104
  retriever,
104
105
  setResults,
105
106
  triggerSearchPagination,
107
+ results.cursor,
106
108
  ],
107
109
  );
108
110
 
@@ -113,16 +115,17 @@ export const useSearchPagination = (
113
115
  data: previousPage.results,
114
116
  page_info: {
115
117
  has_next_page: true,
116
- next_page_cursor: previousPage.cursor,
118
+ next_page_cursor: `'${previousPage.cursor}'`,
117
119
  },
118
120
  search_metadata: results.search_metadata,
121
+ cursor: results.cursor,
119
122
  });
120
123
 
121
124
  setCurrentPage((prev) => prev - 1);
122
125
 
123
126
  setPageHistory((prev) => prev.filter((p) => p.page < currentPage));
124
127
  }
125
- }, [currentPage, pageHistory, results.search_metadata, setResults]);
128
+ }, [currentPage, pageHistory, results.search_metadata, setResults, results.cursor]);
126
129
 
127
130
  const resetPagination = useCallback(() => {
128
131
  setCurrentPage(1);
@@ -4,8 +4,6 @@ import { Query } from '@elastic/eui';
4
4
 
5
5
  import { EntityKind } from '@/types';
6
6
 
7
- import { DEFAULT_ENTITY_TAB, VALID_ENTITY_TYPES } from '../components/WfoSearchPage/constants';
8
-
9
7
  interface UseUrlParamsReturn {
10
8
  urlParams: URLSearchParams;
11
9
  query: Query | string;
@@ -34,8 +32,8 @@ export const useUrlParams = (): UseUrlParamsReturn => {
34
32
  });
35
33
 
36
34
  const [selectedEntityTab, setSelectedEntityTab] = useState<EntityKind>(() => {
37
- const tabParam = urlParams.get('tab') as EntityKind;
38
- return tabParam && VALID_ENTITY_TYPES.includes(tabParam) ? tabParam : DEFAULT_ENTITY_TAB;
35
+ const entityKind = urlParams.get('tab') as EntityKind;
36
+ return entityKind && Object.values(EntityKind).includes(entityKind) ? entityKind : EntityKind.SUBSCRIPTION;
39
37
  });
40
38
 
41
39
  const [showFilters, setShowFilters] = useState<boolean>(() => {
@@ -59,7 +57,7 @@ export const useUrlParams = (): UseUrlParamsReturn => {
59
57
  newParams.set('q', queryText);
60
58
  }
61
59
 
62
- if (selectedEntityTab !== DEFAULT_ENTITY_TAB) {
60
+ if (selectedEntityTab !== EntityKind.SUBSCRIPTION) {
63
61
  newParams.set('tab', selectedEntityTab);
64
62
  }
65
63