@orchestrator-ui/orchestrator-ui-components 5.9.0 → 6.0.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 (57) hide show
  1. package/.turbo/turbo-build.log +8 -8
  2. package/.turbo/turbo-lint.log +10 -1
  3. package/.turbo/turbo-test.log +8 -8
  4. package/CHANGELOG.md +6 -0
  5. package/__mocks__/@copilotkit/react-core.js +9 -0
  6. package/__mocks__/@copilotkit/react-ui.js +11 -0
  7. package/dist/index.d.ts +1429 -2
  8. package/dist/index.js +2977 -19
  9. package/dist/index.js.map +1 -1
  10. package/package.json +5 -1
  11. package/src/components/WfoAgent/FilterDisplay/FilterDisplay.tsx +182 -0
  12. package/src/components/WfoAgent/FilterDisplay/index.ts +1 -0
  13. package/src/components/WfoAgent/FilterDisplay/styles.ts +62 -0
  14. package/src/components/WfoAgent/WfoAgent/WfoAgent.tsx +100 -0
  15. package/src/components/WfoAgent/WfoAgent/index.ts +1 -0
  16. package/src/components/WfoAgent/index.ts +2 -0
  17. package/src/components/WfoSearchPage/WfoConditionRow/WfoConditionRow.tsx +388 -0
  18. package/src/components/WfoSearchPage/WfoConditionRow/WfoFieldSelector.tsx +43 -0
  19. package/src/components/WfoSearchPage/WfoConditionRow/WfoOperatorSelector.tsx +100 -0
  20. package/src/components/WfoSearchPage/WfoConditionRow/WfoPathChips.tsx +193 -0
  21. package/src/components/WfoSearchPage/WfoConditionRow/WfoPathSelector.tsx +54 -0
  22. package/src/components/WfoSearchPage/WfoConditionRow/WfoRenderFunctions.tsx +107 -0
  23. package/src/components/WfoSearchPage/WfoConditionRow/WfoSelectedPathDisplay.tsx +75 -0
  24. package/src/components/WfoSearchPage/WfoConditionRow/index.ts +11 -0
  25. package/src/components/WfoSearchPage/WfoConditionRow/types.ts +84 -0
  26. package/src/components/WfoSearchPage/WfoConditionRow/utils.ts +63 -0
  27. package/src/components/WfoSearchPage/WfoFilterGroup/WfoFilterGroup.tsx +238 -0
  28. package/src/components/WfoSearchPage/WfoFilterGroup/index.ts +1 -0
  29. package/src/components/WfoSearchPage/WfoSearch/WfoSearch.tsx +453 -0
  30. package/src/components/WfoSearchPage/WfoSearch/index.ts +1 -0
  31. package/src/components/WfoSearchPage/WfoSearchResults/WfoHighlightedText.tsx +63 -0
  32. package/src/components/WfoSearchPage/WfoSearchResults/WfoPathBreadcrumb.tsx +80 -0
  33. package/src/components/WfoSearchPage/WfoSearchResults/WfoSearchEmptyState.tsx +24 -0
  34. package/src/components/WfoSearchPage/WfoSearchResults/WfoSearchLoadingState.tsx +24 -0
  35. package/src/components/WfoSearchPage/WfoSearchResults/WfoSearchMetadataHeader.tsx +24 -0
  36. package/src/components/WfoSearchPage/WfoSearchResults/WfoSearchPaginationInfo.tsx +107 -0
  37. package/src/components/WfoSearchPage/WfoSearchResults/WfoSearchResultItem.tsx +157 -0
  38. package/src/components/WfoSearchPage/WfoSearchResults/WfoSearchResults.tsx +65 -0
  39. package/src/components/WfoSearchPage/WfoSearchResults/WfoSubscriptionDetailModal.tsx +55 -0
  40. package/src/components/WfoSearchPage/WfoSearchResults/index.ts +10 -0
  41. package/src/components/WfoSearchPage/WfoValueControl/WfoValueControl.tsx +247 -0
  42. package/src/components/WfoSearchPage/WfoValueControl/index.ts +1 -0
  43. package/src/components/WfoSearchPage/constants.ts +17 -0
  44. package/src/components/WfoSearchPage/index.ts +6 -0
  45. package/src/components/WfoSearchPage/utils.ts +271 -0
  46. package/src/components/index.ts +2 -0
  47. package/src/configuration/version.ts +1 -1
  48. package/src/hooks/useDebounce.ts +21 -0
  49. package/src/hooks/usePathAutoComplete.ts +133 -0
  50. package/src/hooks/useSearch.ts +83 -0
  51. package/src/hooks/useSearchPagination.ts +148 -0
  52. package/src/hooks/useUrlParams.ts +120 -0
  53. package/src/messages/en-GB.json +77 -0
  54. package/src/rtk/endpoints/index.ts +1 -0
  55. package/src/rtk/endpoints/search.ts +90 -0
  56. package/src/types/index.ts +1 -0
  57. package/src/types/search.ts +215 -0
@@ -0,0 +1,193 @@
1
+ import React, { FC } from 'react';
2
+
3
+ import { EuiIcon } from '@elastic/eui';
4
+
5
+ import { WfoBadge, WfoToolTip } from '@/components';
6
+ import { useOrchestratorTheme } from '@/hooks';
7
+
8
+ import { getTypeColor } from '../utils';
9
+
10
+ interface WfoPathChipsProps {
11
+ fullPath: string;
12
+ label: string;
13
+ fieldType?: string;
14
+ isAnyPath?: boolean;
15
+ }
16
+
17
+ export const WfoPathChips: FC<WfoPathChipsProps> = ({
18
+ fullPath,
19
+ label,
20
+ fieldType,
21
+ isAnyPath = false,
22
+ }) => {
23
+ const { theme } = useOrchestratorTheme();
24
+
25
+ // For "Any path" case, just show the label
26
+ if (isAnyPath) {
27
+ return (
28
+ <WfoToolTip tooltipContent={label}>
29
+ <div
30
+ style={{
31
+ display: 'flex',
32
+ justifyContent: 'space-between',
33
+ alignItems: 'center',
34
+ padding: `${theme.size.xs} ${theme.size.s} ${theme.size.xs} 0`,
35
+ textDecoration: 'none',
36
+ width: '100%',
37
+ boxSizing: 'border-box',
38
+ minHeight: theme.size.xl,
39
+ }}
40
+ >
41
+ <div
42
+ style={{
43
+ display: 'flex',
44
+ gap: theme.size.xs,
45
+ alignItems: 'center',
46
+ flexWrap: 'nowrap',
47
+ textDecoration: 'none',
48
+ marginRight: theme.size.s,
49
+ flex: 1,
50
+ overflow: 'visible',
51
+ }}
52
+ >
53
+ <div
54
+ style={{
55
+ textDecoration: 'none',
56
+ borderBottom: 'none',
57
+ }}
58
+ >
59
+ <WfoBadge
60
+ color="primary"
61
+ textColor={theme.colors.ghost}
62
+ size="xs"
63
+ >
64
+ <span
65
+ style={{
66
+ textDecoration: 'none',
67
+ borderBottom: 'none',
68
+ outline: 'none',
69
+ textDecorationLine: 'none',
70
+ textDecorationColor: 'transparent',
71
+ }}
72
+ >
73
+ {label}
74
+ </span>
75
+ </WfoBadge>
76
+ </div>
77
+ </div>
78
+ {fieldType && (
79
+ <div style={{ flexShrink: 0 }}>
80
+ <WfoBadge
81
+ color={getTypeColor(fieldType, theme)}
82
+ textColor={theme.colors.ink}
83
+ size="xs"
84
+ >
85
+ <span style={{ textDecoration: 'none' }}>
86
+ {fieldType}
87
+ </span>
88
+ </WfoBadge>
89
+ </div>
90
+ )}
91
+ </div>
92
+ </WfoToolTip>
93
+ );
94
+ }
95
+
96
+ // Extract the last two meaningful segments from the full path
97
+ const completePath = fullPath || label;
98
+ const allSegments = completePath
99
+ .split('.')
100
+ .filter(
101
+ (segment) =>
102
+ segment && !segment.match(/^\d+$/) && !segment.includes('('),
103
+ );
104
+
105
+ // Only show the last two segments
106
+ const pathSegments = allSegments.slice(-2);
107
+
108
+ return (
109
+ <WfoToolTip tooltipContent={completePath}>
110
+ <div
111
+ style={{
112
+ display: 'flex',
113
+ justifyContent: 'space-between',
114
+ alignItems: 'center',
115
+ padding: `${theme.size.xs} ${theme.size.s} ${theme.size.xs} 0`,
116
+ textDecoration: 'none',
117
+ width: '100%',
118
+ boxSizing: 'border-box',
119
+ minHeight: theme.size.xl,
120
+ }}
121
+ >
122
+ <div
123
+ style={{
124
+ display: 'flex',
125
+ gap: theme.size.xs,
126
+ alignItems: 'center',
127
+ flexWrap: 'nowrap',
128
+ textDecoration: 'none',
129
+ marginRight: theme.size.s,
130
+ flex: 1,
131
+ overflow: 'visible',
132
+ }}
133
+ >
134
+ {pathSegments.map((segment, index) =>
135
+ [
136
+ <div
137
+ key={`segment-${index}`}
138
+ style={{
139
+ textDecoration: 'none',
140
+ borderBottom: 'none',
141
+ }}
142
+ >
143
+ <WfoBadge
144
+ color="primary"
145
+ textColor={theme.colors.ghost}
146
+ size="xs"
147
+ >
148
+ <span
149
+ style={{
150
+ textDecoration: 'none',
151
+ borderBottom: 'none',
152
+ outline: 'none',
153
+ textDecorationLine: 'none',
154
+ textDecorationColor: 'transparent',
155
+ }}
156
+ >
157
+ {segment}
158
+ </span>
159
+ </WfoBadge>
160
+ </div>,
161
+ index < pathSegments.length - 1 && (
162
+ <EuiIcon
163
+ key={`arrow-${index}`}
164
+ type="arrowRight"
165
+ size="s"
166
+ color={theme.colors.mediumShade}
167
+ title=""
168
+ style={{
169
+ flexShrink: 0,
170
+ marginTop: '1px',
171
+ }}
172
+ />
173
+ ),
174
+ ].filter(Boolean),
175
+ )}
176
+ </div>
177
+ {fieldType && (
178
+ <div style={{ flexShrink: 0 }}>
179
+ <WfoBadge
180
+ color={getTypeColor(fieldType, theme)}
181
+ textColor={theme.colors.ink}
182
+ size="xs"
183
+ >
184
+ <span style={{ textDecoration: 'none' }}>
185
+ {fieldType}
186
+ </span>
187
+ </WfoBadge>
188
+ </div>
189
+ )}
190
+ </div>
191
+ </WfoToolTip>
192
+ );
193
+ };
@@ -0,0 +1,54 @@
1
+ import React, { FC } from 'react';
2
+
3
+ import { useTranslations } from 'next-intl';
4
+
5
+ import { EuiComboBox } from '@elastic/eui';
6
+
7
+ import { PathSelectorProps } from './types';
8
+
9
+ export const WfoPathSelector: FC<PathSelectorProps> = ({
10
+ selectedFieldName,
11
+ pathOptions,
12
+ onPathSelection,
13
+ onClear,
14
+ renderOption,
15
+ }) => {
16
+ const t = useTranslations('search.page');
17
+
18
+ return (
19
+ <EuiComboBox
20
+ placeholder={t('selectSpecificPathPlaceholder')}
21
+ options={pathOptions}
22
+ selectedOptions={[
23
+ {
24
+ label: `${selectedFieldName}:`,
25
+ value: selectedFieldName,
26
+ },
27
+ ]}
28
+ onChange={(selected) => {
29
+ if (selected[0]?.value) {
30
+ const selectedOption = pathOptions.find(
31
+ (option) => option.value === selected[0].value,
32
+ );
33
+ if (selectedOption) {
34
+ onPathSelection(selectedOption);
35
+ }
36
+ } else if (selected.length === 0) {
37
+ onClear();
38
+ }
39
+ }}
40
+ singleSelection={{ asPlainText: true }}
41
+ isClearable
42
+ renderOption={renderOption}
43
+ rowHeight={40}
44
+ autoFocus={true}
45
+ fullWidth={true}
46
+ style={{
47
+ minWidth: '500px',
48
+ maxWidth: '100%',
49
+ textDecoration: 'none',
50
+ }}
51
+ className="wfo-path-selector"
52
+ />
53
+ );
54
+ };
@@ -0,0 +1,107 @@
1
+ import React, { FC } from 'react';
2
+
3
+ import { useTranslations } from 'next-intl';
4
+
5
+ import { EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui';
6
+
7
+ import { WfoBadge, WfoToolTip } from '@/components';
8
+ import { useOrchestratorTheme } from '@/hooks';
9
+
10
+ import { getTypeColor } from '../utils';
11
+ import { PathOptionRenderProps, PathSelectionOptionRenderProps } from './types';
12
+
13
+ export const WfoRenderPathOption: FC<PathOptionRenderProps> = ({
14
+ option,
15
+ contentClassName,
16
+ paths,
17
+ }) => {
18
+ const t = useTranslations('search.page');
19
+ const { theme } = useOrchestratorTheme();
20
+ const pathInfo = option.value
21
+ ? paths.find(({ path }) => path === option.value)
22
+ : null;
23
+
24
+ if (!pathInfo) return <>{option.label}</>;
25
+
26
+ return (
27
+ <EuiFlexGroup
28
+ alignItems="center"
29
+ gutterSize="s"
30
+ responsive={false}
31
+ className={contentClassName}
32
+ title=""
33
+ >
34
+ <EuiFlexItem grow={true}>
35
+ <EuiText size="s">
36
+ {pathInfo.displayLabel || pathInfo.path}
37
+ </EuiText>
38
+ </EuiFlexItem>
39
+ <EuiFlexItem grow={false}>
40
+ <EuiFlexGroup
41
+ gutterSize="xs"
42
+ alignItems="center"
43
+ responsive={false}
44
+ >
45
+ {pathInfo.group === 'leaf' &&
46
+ pathInfo.pathCount &&
47
+ pathInfo.pathCount > 1 && (
48
+ <EuiFlexItem grow={false}>
49
+ <WfoBadge
50
+ color="default"
51
+ textColor={theme.colors.ink}
52
+ size="xs"
53
+ >
54
+ {t('pathsCount', {
55
+ count: pathInfo.pathCount,
56
+ })}
57
+ </WfoBadge>
58
+ </EuiFlexItem>
59
+ )}
60
+ {(!pathInfo.pathCount || pathInfo.pathCount <= 1) &&
61
+ pathInfo.ui_types?.map((type, index) => (
62
+ <EuiFlexItem key={index} grow={false}>
63
+ <WfoBadge
64
+ color={getTypeColor(type, theme)}
65
+ textColor={theme.colors.ink}
66
+ size="xs"
67
+ >
68
+ {type}
69
+ </WfoBadge>
70
+ </EuiFlexItem>
71
+ ))}
72
+ </EuiFlexGroup>
73
+ </EuiFlexItem>
74
+ </EuiFlexGroup>
75
+ );
76
+ };
77
+
78
+ export const WfoRenderPathSelectionOption: FC<
79
+ PathSelectionOptionRenderProps
80
+ > = ({ option, contentClassName, fieldType }) => {
81
+ const { theme } = useOrchestratorTheme();
82
+
83
+ return (
84
+ <WfoToolTip tooltipContent={option.fullPath || option.label}>
85
+ <EuiFlexGroup
86
+ alignItems="center"
87
+ gutterSize="s"
88
+ responsive={false}
89
+ className={contentClassName}
90
+ title=""
91
+ >
92
+ <EuiFlexItem grow={true}>
93
+ <EuiText size="s">{option.label}</EuiText>
94
+ </EuiFlexItem>
95
+ <EuiFlexItem grow={false}>
96
+ <WfoBadge
97
+ color={getTypeColor(fieldType, theme)}
98
+ textColor={theme.colors.ink}
99
+ size="xs"
100
+ >
101
+ {fieldType}
102
+ </WfoBadge>
103
+ </EuiFlexItem>
104
+ </EuiFlexGroup>
105
+ </WfoToolTip>
106
+ );
107
+ };
@@ -0,0 +1,75 @@
1
+ import React, { FC } from 'react';
2
+
3
+ import { EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui';
4
+
5
+ import { useOrchestratorTheme } from '@/hooks';
6
+
7
+ import { SelectedPathDisplayProps } from './types';
8
+ import { getFieldNameFromFullPath } from './utils';
9
+
10
+ export const WfoSelectedPathDisplay: FC<SelectedPathDisplayProps> = ({
11
+ condition,
12
+ onEdit,
13
+ }) => {
14
+ const { theme } = useOrchestratorTheme();
15
+
16
+ const isFullPath = condition.path.includes('.');
17
+
18
+ return (
19
+ <div
20
+ onClick={onEdit}
21
+ style={{
22
+ cursor: 'pointer',
23
+ border: `1px solid ${theme.colors.lightShade}`,
24
+ borderRadius: theme.border.radius.medium,
25
+ padding: `${theme.size.s} ${theme.size.m}`,
26
+ backgroundColor: theme.colors.emptyShade,
27
+ minHeight: '40px',
28
+ display: 'flex',
29
+ alignItems: 'center',
30
+ }}
31
+ >
32
+ <EuiFlexGroup
33
+ alignItems="center"
34
+ gutterSize="s"
35
+ responsive={false}
36
+ justifyContent="spaceBetween"
37
+ >
38
+ <EuiFlexItem grow={true}>
39
+ {isFullPath ? (
40
+ <EuiFlexGroup
41
+ gutterSize="none"
42
+ alignItems="center"
43
+ responsive={false}
44
+ >
45
+ <EuiFlexItem grow={false}>
46
+ <EuiText size="s" color={theme.colors.text}>
47
+ {getFieldNameFromFullPath(condition.path)}:
48
+ </EuiText>
49
+ </EuiFlexItem>
50
+ <EuiFlexItem grow={false}>
51
+ <EuiText
52
+ size="s"
53
+ style={{
54
+ backgroundColor:
55
+ theme.colors.lightestShade,
56
+ color: theme.colors.primary,
57
+ padding: `${theme.size.xxs} ${theme.size.xs}`,
58
+ borderRadius: theme.border.radius.small,
59
+ marginLeft: theme.size.xs,
60
+ }}
61
+ >
62
+ {condition.path}
63
+ </EuiText>
64
+ </EuiFlexItem>
65
+ </EuiFlexGroup>
66
+ ) : (
67
+ <EuiText size="s" color={theme.colors.text}>
68
+ {condition.path}
69
+ </EuiText>
70
+ )}
71
+ </EuiFlexItem>
72
+ </EuiFlexGroup>
73
+ </div>
74
+ );
75
+ };
@@ -0,0 +1,11 @@
1
+ export { ConditionRow } from './WfoConditionRow';
2
+ export { WfoFieldSelector } from './WfoFieldSelector';
3
+ export { WfoPathSelector } from './WfoPathSelector';
4
+ export { WfoSelectedPathDisplay } from './WfoSelectedPathDisplay';
5
+ export { WfoOperatorSelector } from './WfoOperatorSelector';
6
+ export {
7
+ WfoRenderPathOption,
8
+ WfoRenderPathSelectionOption,
9
+ } from './WfoRenderFunctions';
10
+ export * from './types';
11
+ export * from './utils';
@@ -0,0 +1,84 @@
1
+ import { Condition, EntityKind, PathInfo } from '@/types';
2
+
3
+ export interface ConditionRowProps {
4
+ condition: Condition;
5
+ entityType: EntityKind;
6
+ onChange: (condition: Condition) => void;
7
+ onRemove: () => void;
8
+ }
9
+
10
+ export interface FieldSelectorProps {
11
+ pathOptions: Array<{
12
+ label: string;
13
+ options: Array<{
14
+ label: string;
15
+ value: string;
16
+ 'data-type': string;
17
+ 'data-operators': string;
18
+ }>;
19
+ }>;
20
+ loading: boolean;
21
+ error: string | null;
22
+ searchValue: string;
23
+ onFieldSelection: (fieldName: string) => void;
24
+ onSearchChange: (value: string) => void;
25
+ onClear: () => void;
26
+ renderPathOption: (
27
+ option: { label: string; value?: string },
28
+ searchValue: string,
29
+ contentClassName?: string,
30
+ ) => JSX.Element;
31
+ }
32
+
33
+ export interface PathSelectorProps {
34
+ selectedFieldName: string;
35
+ pathOptions: Array<{
36
+ label: string;
37
+ value: string;
38
+ fullPath: string;
39
+ isAnyPath?: boolean;
40
+ }>;
41
+ onPathSelection: (option: {
42
+ label: string;
43
+ value: string;
44
+ fullPath: string;
45
+ isAnyPath?: boolean;
46
+ }) => void;
47
+ onClear: () => void;
48
+ renderOption?: (
49
+ option: {
50
+ label: string;
51
+ value?: string;
52
+ fullPath?: string;
53
+ isAnyPath?: boolean;
54
+ },
55
+ searchValue: string,
56
+ contentClassName?: string,
57
+ ) => JSX.Element;
58
+ }
59
+
60
+ export interface SelectedPathDisplayProps {
61
+ condition: Condition;
62
+ selectedPathInfo: PathInfo | null;
63
+ onEdit: () => void;
64
+ }
65
+
66
+ export interface OperatorSelectorProps {
67
+ selectedPathInfo: PathInfo | null;
68
+ condition: Condition;
69
+ onOperatorChange: (op: string) => void;
70
+ }
71
+
72
+ export interface PathOptionRenderProps {
73
+ option: { label: string; value?: string };
74
+ searchValue: string;
75
+ contentClassName?: string;
76
+ paths: PathInfo[];
77
+ }
78
+
79
+ export interface PathSelectionOptionRenderProps {
80
+ option: { label: string; value?: string; fullPath?: string };
81
+ searchValue: string;
82
+ contentClassName?: string;
83
+ fieldType: string;
84
+ }
@@ -0,0 +1,63 @@
1
+ import { PathInfo } from '@/types';
2
+
3
+ export const createOptionsFromPaths = (paths: PathInfo[], group: string) =>
4
+ paths
5
+ .filter(({ group: pathGroup }) => pathGroup === group)
6
+ .map(({ displayLabel, path, type, operators }) => ({
7
+ label: displayLabel || path,
8
+ value: path,
9
+ 'data-type': type,
10
+ 'data-operators': operators?.join(', ') || '',
11
+ }));
12
+
13
+ export const shouldHideValueInput = (
14
+ selectedPathInfo: PathInfo | null,
15
+ operatorSelected: boolean,
16
+ ): boolean => {
17
+ if (!selectedPathInfo || !operatorSelected) return true;
18
+
19
+ if (selectedPathInfo.group === 'component') return true;
20
+ if (selectedPathInfo.type === 'boolean') return true;
21
+
22
+ return false;
23
+ };
24
+
25
+ export const isFullPathSelected = (
26
+ path: string,
27
+ selectedPathInfo: PathInfo | null,
28
+ ): boolean => {
29
+ return !!(
30
+ path &&
31
+ (path.includes('.') ||
32
+ (selectedPathInfo && selectedPathInfo.group === 'component') ||
33
+ (!path.includes('.') && selectedPathInfo))
34
+ );
35
+ };
36
+
37
+ export const getFieldNameFromPath = (
38
+ path: string,
39
+ isComponent: boolean,
40
+ ): string => {
41
+ return isComponent ? path : path.split('.').pop() || path;
42
+ };
43
+
44
+ export const getFieldNameFromFullPath = (fullPath: string): string => {
45
+ const parts = fullPath.split('.');
46
+ return parts[parts.length - 1] || fullPath;
47
+ };
48
+
49
+ export const getPathSelectionOptions = (
50
+ selectedFieldName: string,
51
+ paths: PathInfo[],
52
+ ) => {
53
+ if (!selectedFieldName) return [];
54
+
55
+ const fieldInfo = paths.find(({ path }) => path === selectedFieldName);
56
+ if (!fieldInfo || !fieldInfo.availablePaths) return [];
57
+
58
+ return fieldInfo.availablePaths.map((fullPath) => ({
59
+ label: fullPath,
60
+ value: fullPath,
61
+ fullPath: fullPath,
62
+ }));
63
+ };