@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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orchestrator-ui/orchestrator-ui-components",
3
- "version": "5.9.0",
3
+ "version": "6.0.0",
4
4
  "license": "Apache-2.0",
5
5
  "description": "Library of UI Components used to display the workflow orchestrator frontend",
6
6
  "author": {
@@ -34,6 +34,10 @@
34
34
  "dev": "npm run build -- --watch"
35
35
  },
36
36
  "dependencies": {
37
+ "@ag-ui/client": "^0.0.39",
38
+ "@copilotkit/react-core": "^1.3.18",
39
+ "@copilotkit/react-ui": "^1.3.18",
40
+ "@copilotkit/runtime": "^1.3.18",
37
41
  "@elastic/eui": "101.3.0",
38
42
  "@emotion/css": "^11.11.2",
39
43
  "@emotion/react": "^11.11.4",
@@ -0,0 +1,182 @@
1
+ import React from 'react';
2
+
3
+ import { useTranslations } from 'next-intl';
4
+
5
+ import {
6
+ EuiFlexGroup,
7
+ EuiFlexItem,
8
+ EuiPanel,
9
+ EuiSpacer,
10
+ EuiText,
11
+ } from '@elastic/eui';
12
+
13
+ import { WfoBadge } from '@/components/WfoBadges';
14
+ import { WfoPathBreadcrumb } from '@/components/WfoSearchPage/WfoSearchResults/WfoPathBreadcrumb';
15
+ import {
16
+ getOperatorDisplay,
17
+ isCondition,
18
+ } from '@/components/WfoSearchPage/utils';
19
+ import { useWithOrchestratorTheme } from '@/index';
20
+ import { AnySearchParameters, Condition, Group, PathDataType } from '@/types';
21
+
22
+ import { getFilterDisplayStyles } from './styles';
23
+
24
+ const DEPTH_INDENT = 16;
25
+
26
+ type FilterDisplayProps = {
27
+ parameters: {
28
+ action?: AnySearchParameters['action'] | string;
29
+ entity_type?: AnySearchParameters['entity_type'] | string;
30
+ filters?: Group | null;
31
+ query?: string | null;
32
+ };
33
+ };
34
+
35
+ interface BetweenValue {
36
+ start?: string | number;
37
+ end?: string | number;
38
+ from?: string | number;
39
+ to?: string | number;
40
+ }
41
+
42
+ export function FilterDisplay({ parameters }: FilterDisplayProps) {
43
+ const t = useTranslations('agent.page');
44
+
45
+ const {
46
+ wrapStyle,
47
+ columnGroupWrapStyle,
48
+ chipStyle,
49
+ groupStyle,
50
+ operatorStyle,
51
+ valueStyle,
52
+ } = useWithOrchestratorTheme(getFilterDisplayStyles);
53
+ const { action, entity_type, filters, query } = parameters ?? {};
54
+
55
+ if (!parameters || Object.keys(parameters).length === 0) return null;
56
+
57
+ const sectionTitle = (text: string) => (
58
+ <EuiText size="xs" color="subdued">
59
+ <strong>{text}</strong>
60
+ </EuiText>
61
+ );
62
+
63
+ const formatFilterValue = (condition: Condition['condition']): string => {
64
+ if ('value' in condition && condition.value !== undefined) {
65
+ if (
66
+ condition.op === 'between' &&
67
+ condition.value &&
68
+ typeof condition.value === 'object'
69
+ ) {
70
+ const { start, end, from, to } =
71
+ condition.value as BetweenValue;
72
+ const fromVal = start || from;
73
+ const toVal = end || to;
74
+ return `${fromVal} … ${toVal}`;
75
+ }
76
+ return String(condition.value);
77
+ }
78
+ return '—';
79
+ };
80
+
81
+ const renderFilterGroup = (group: Group, depth = 0): React.ReactNode => {
82
+ if (!group.children || group.children.length === 0) {
83
+ return (
84
+ <EuiText size="s" color="subdued">
85
+ <em>{t('emptyGroup')}</em>
86
+ </EuiText>
87
+ );
88
+ }
89
+
90
+ const areChildrenGroups =
91
+ group.children.length > 0 && !isCondition(group.children[0]);
92
+
93
+ return (
94
+ <div css={groupStyle} style={{ marginLeft: depth * DEPTH_INDENT }}>
95
+ <div css={operatorStyle}>{group.op}</div>
96
+ <div css={areChildrenGroups ? columnGroupWrapStyle : wrapStyle}>
97
+ {group.children.map((child, i) => (
98
+ <div key={i}>
99
+ {isCondition(child) ? (
100
+ <div css={chipStyle}>
101
+ <WfoPathBreadcrumb
102
+ path={child.path}
103
+ size="s"
104
+ showArrows={true}
105
+ />
106
+ <WfoBadge
107
+ textColor="default"
108
+ color="hollow"
109
+ >
110
+ {
111
+ getOperatorDisplay(
112
+ child.condition.op,
113
+ child.value_kind
114
+ ? {
115
+ path: child.path,
116
+ type: child.value_kind as PathDataType,
117
+ operators: [],
118
+ value_schema: {},
119
+ group: 'leaf' as const,
120
+ }
121
+ : undefined,
122
+ ).symbol
123
+ }
124
+ </WfoBadge>
125
+ <span css={valueStyle}>
126
+ {formatFilterValue(child.condition)}
127
+ </span>
128
+ </div>
129
+ ) : (
130
+ renderFilterGroup(child, depth + 1)
131
+ )}
132
+ </div>
133
+ ))}
134
+ </div>
135
+ </div>
136
+ );
137
+ };
138
+
139
+ return (
140
+ <EuiPanel hasBorder paddingSize="m">
141
+ <EuiFlexGroup gutterSize="m" wrap responsive>
142
+ <EuiFlexItem grow={false}>
143
+ {sectionTitle(t('action'))}
144
+ <EuiSpacer size="xs" />
145
+ <WfoBadge textColor="default" color="hollow">
146
+ {action || 'N/A'}
147
+ </WfoBadge>
148
+ </EuiFlexItem>
149
+
150
+ <EuiFlexItem grow={false}>
151
+ {sectionTitle(t('entityType'))}
152
+ <EuiSpacer size="xs" />
153
+ <WfoBadge textColor="default" color="hollow">
154
+ {entity_type || 'N/A'}
155
+ </WfoBadge>
156
+ </EuiFlexItem>
157
+
158
+ {query ? (
159
+ <EuiFlexItem grow={false}>
160
+ {sectionTitle(t('searchQuery'))}
161
+ <EuiSpacer size="xs" />
162
+ <EuiText size="s">
163
+ <em>"{query}"</em>
164
+ </EuiText>
165
+ </EuiFlexItem>
166
+ ) : null}
167
+ </EuiFlexGroup>
168
+
169
+ <EuiSpacer size="m" />
170
+ {sectionTitle(t('activeFilters'))}
171
+ <EuiSpacer size="s" />
172
+
173
+ {filters && filters.children && filters.children.length > 0 ? (
174
+ renderFilterGroup(filters)
175
+ ) : (
176
+ <EuiText size="s" color="subdued">
177
+ <em>{t('noFiltersApplied')}</em>
178
+ </EuiText>
179
+ )}
180
+ </EuiPanel>
181
+ );
182
+ }
@@ -0,0 +1 @@
1
+ export * from './FilterDisplay';
@@ -0,0 +1,62 @@
1
+ import { css } from '@emotion/react';
2
+
3
+ import { WfoTheme } from '@/hooks';
4
+
5
+ export const getFilterDisplayStyles = ({ theme }: WfoTheme) => {
6
+ const wrapStyle = css({
7
+ display: 'flex',
8
+ flexWrap: 'wrap',
9
+ gap: theme.size.s,
10
+ });
11
+
12
+ const columnGroupWrapStyle = css({
13
+ display: 'flex',
14
+ flexDirection: 'column',
15
+ gap: theme.size.s,
16
+ alignItems: 'flex-start',
17
+ });
18
+
19
+ const chipStyle = css({
20
+ display: 'inline-flex',
21
+ alignItems: 'center',
22
+ borderRadius: theme.size.xl,
23
+ border: `1px solid ${theme.border.color}`,
24
+ backgroundColor: theme.colors.body,
25
+ padding: `${theme.size.s} ${theme.size.m}`,
26
+ lineHeight: 1.1,
27
+ gap: theme.size.s,
28
+ });
29
+
30
+ const groupStyle = css({
31
+ border: `1px solid ${theme.colors.lightShade}`,
32
+ borderRadius: theme.border.radius.medium,
33
+ padding: theme.size.s,
34
+ margin: theme.size.xs,
35
+ backgroundColor: theme.colors.body,
36
+ });
37
+
38
+ const operatorStyle = css({
39
+ fontFamily: theme.font.familyCode,
40
+ padding: `${theme.size.xs}px ${theme.size.s}px`,
41
+ borderRadius: theme.size.s,
42
+ backgroundColor: theme.colors.primary,
43
+ color: theme.colors.ghost,
44
+ fontSize: theme.size.m,
45
+ fontWeight: theme.font.weight.bold,
46
+ margin: `${theme.size.xs} 0`,
47
+ });
48
+
49
+ const valueStyle = css({
50
+ fontWeight: theme.font.weight.semiBold,
51
+ color: theme.colors.warning,
52
+ });
53
+
54
+ return {
55
+ wrapStyle,
56
+ columnGroupWrapStyle,
57
+ chipStyle,
58
+ groupStyle,
59
+ operatorStyle,
60
+ valueStyle,
61
+ };
62
+ };
@@ -0,0 +1,100 @@
1
+ import React from 'react';
2
+
3
+ import { useTranslations } from 'next-intl';
4
+
5
+ import { useCoAgent } from '@copilotkit/react-core';
6
+ import { CopilotSidebar } from '@copilotkit/react-ui';
7
+ import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiText } from '@elastic/eui';
8
+
9
+ import { WfoSearchResults } from '@/components/WfoSearchPage/WfoSearchResults';
10
+ import { AnySearchParameters, AnySearchResult, PathFilter } from '@/types';
11
+
12
+ import { FilterDisplay } from '../FilterDisplay';
13
+
14
+ type SearchState = {
15
+ parameters: AnySearchParameters;
16
+ results: AnySearchResult[];
17
+ };
18
+
19
+ const initialState: SearchState = {
20
+ parameters: {
21
+ action: 'select',
22
+ entity_type: 'SUBSCRIPTION',
23
+ filters: [] as PathFilter[],
24
+ query: null,
25
+ },
26
+ results: [],
27
+ };
28
+
29
+ export function WfoAgent() {
30
+ const t = useTranslations('agent');
31
+ const tPage = useTranslations('agent.page');
32
+
33
+ const { state } = useCoAgent<SearchState>({
34
+ name: 'query_agent',
35
+ initialState,
36
+ });
37
+ const { parameters, results } = state;
38
+
39
+ const hasStarted = !!(
40
+ state.parameters &&
41
+ Array.isArray(state.parameters.filters) &&
42
+ state.parameters.filters.length > 0
43
+ );
44
+
45
+ const isLoadingResults =
46
+ hasStarted && (!state.results || state.results.length === 0);
47
+
48
+ const displayParameters = parameters && {
49
+ ...parameters,
50
+ filters: Array.isArray(parameters.filters)
51
+ ? { op: 'AND' as const, children: parameters.filters }
52
+ : parameters.filters,
53
+ };
54
+
55
+ return (
56
+ <EuiFlexGroup gutterSize="l" alignItems="stretch">
57
+ <EuiFlexItem grow={2}>
58
+ <EuiText>
59
+ <h1>{t('title')}</h1>
60
+ </EuiText>
61
+
62
+ <EuiSpacer size="m" />
63
+ <EuiText size="s">
64
+ <h2>{tPage('filledParameters')}</h2>
65
+ </EuiText>
66
+ <EuiSpacer size="s" />
67
+ {displayParameters && (
68
+ <FilterDisplay parameters={displayParameters} />
69
+ )}
70
+
71
+ <EuiSpacer size="m" />
72
+ <EuiText size="s">
73
+ <h2>
74
+ {tPage('results')}{' '}
75
+ {results ? `(${results.length})` : ''}
76
+ </h2>
77
+ </EuiText>
78
+ <EuiSpacer size="s" />
79
+
80
+ <WfoSearchResults
81
+ results={results ?? []}
82
+ loading={isLoadingResults}
83
+ selectedRecordIndex={-1}
84
+ onRecordSelect={() => {}}
85
+ />
86
+ </EuiFlexItem>
87
+
88
+ <EuiFlexItem grow={1}>
89
+ <CopilotSidebar
90
+ defaultOpen
91
+ clickOutsideToClose={false}
92
+ labels={{
93
+ title: tPage('copilot.title'),
94
+ initial: tPage('copilot.initial'),
95
+ }}
96
+ />
97
+ </EuiFlexItem>
98
+ </EuiFlexGroup>
99
+ );
100
+ }
@@ -0,0 +1 @@
1
+ export * from './WfoAgent';
@@ -0,0 +1,2 @@
1
+ export * from './WfoAgent';
2
+ export * from './FilterDisplay';