@orchestrator-ui/orchestrator-ui-components 7.5.1 → 7.6.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 (45) hide show
  1. package/.turbo/turbo-build.log +7 -7
  2. package/.turbo/turbo-lint.log +1 -1
  3. package/.turbo/turbo-test.log +9 -9
  4. package/CHANGELOG.md +14 -0
  5. package/dist/index.d.ts +481 -10
  6. package/dist/index.js +550 -481
  7. package/dist/index.js.map +1 -1
  8. package/jest.config.cjs +4 -1
  9. package/package.json +6 -6
  10. package/src/components/WfoAgent/ExportButton/ExportButton.tsx +5 -11
  11. package/src/components/WfoAgent/WfoAgent/WfoAgent.tsx +79 -31
  12. package/src/components/WfoAgent/WfoAgentChart/WfoAgentLineChart.tsx +2 -2
  13. package/src/components/WfoAgent/WfoAgentChart/WfoAgentPieChart.tsx +2 -2
  14. package/src/components/WfoAgent/WfoAgentTable/WfoAgentTable.tsx +9 -9
  15. package/src/components/WfoAgent/WfoAgentVisualization/WfoAgentVisualization.tsx +2 -2
  16. package/src/components/WfoAgent/WfoPlanProgress/WfoPlanProgress.tsx +107 -0
  17. package/src/components/WfoAgent/WfoPlanProgress/index.ts +1 -0
  18. package/src/components/WfoAgent/WfoPlanProgress/styles.ts +62 -0
  19. package/src/components/WfoAgent/WfoQueryArtifact/WfoQueryArtifact.tsx +40 -0
  20. package/src/components/WfoAgent/WfoQueryArtifact/index.ts +1 -0
  21. package/src/components/WfoAgent/index.ts +2 -0
  22. package/src/components/WfoBadges/WfoVersionIncompatibleBadge/WfoVersionIncompatibleBadge.tsx +7 -6
  23. package/src/components/WfoKeyValueTable/WfoValueCell.tsx +1 -1
  24. package/src/components/WfoPydanticForm/fields/WfoInteger.tsx +22 -3
  25. package/src/components/WfoSubscription/WfoSubscriptionActions/WfoSubscriptionActions.tsx +3 -2
  26. package/src/components/WfoSubscriptionsList/WfoSubscriptionsList.tsx +9 -9
  27. package/src/components/WfoTable/WfoAdvancedTable/WfoAdvancedTable.tsx +1 -1
  28. package/src/components/WfoTable/WfoFirstPartUUID/WfoFirstPartUUID.tsx +1 -1
  29. package/src/configuration/constants.ts +3 -0
  30. package/src/configuration/version.ts +1 -1
  31. package/src/hooks/useAgentPlanEvents.ts +188 -0
  32. package/src/messages/en-GB.json +5 -0
  33. package/src/rtk/endpoints/agentQueryResults.ts +19 -0
  34. package/src/rtk/endpoints/index.ts +1 -0
  35. package/src/types/search.ts +19 -4
  36. package/src/utils/compareVersions.spec.ts +5 -0
  37. package/src/utils/compareVersions.ts +55 -23
  38. package/src/components/WfoAgent/ToolProgress/DiscoverFilterPathsDisplay.tsx +0 -99
  39. package/src/components/WfoAgent/ToolProgress/RunSearchDisplay.tsx +0 -34
  40. package/src/components/WfoAgent/ToolProgress/SetFilterTreeDisplay.styles.ts +0 -62
  41. package/src/components/WfoAgent/ToolProgress/SetFilterTreeDisplay.tsx +0 -107
  42. package/src/components/WfoAgent/ToolProgress/StartNewSearchDisplay.tsx +0 -60
  43. package/src/components/WfoAgent/ToolProgress/ToolProgress.tsx +0 -98
  44. package/src/components/WfoAgent/ToolProgress/index.ts +0 -1
  45. package/src/components/WfoAgent/ToolProgress/styles.ts +0 -52
@@ -80,6 +80,11 @@ export const WfoSubscriptionsList: FC<WfoSubscriptionsListProps> = ({
80
80
  const subscriptionList = mapGraphQlSubscriptionsResultToSubscriptionListItems(data);
81
81
 
82
82
  const tableColumnConfig: WfoAdvancedTableColumnConfig<SubscriptionListItem> = {
83
+ actions: {
84
+ columnType: ColumnType.CONTROL,
85
+ width: '50px',
86
+ renderControl: (row) => <WfoSubscriptionActions compactMode={true} subscriptionId={row.subscriptionId} />,
87
+ },
83
88
  subscriptionId: {
84
89
  columnType: ColumnType.DATA,
85
90
  label: t('id'),
@@ -104,11 +109,12 @@ export const WfoSubscriptionsList: FC<WfoSubscriptionsListProps> = ({
104
109
  insync: {
105
110
  columnType: ColumnType.DATA,
106
111
  label: t('insync'),
107
- width: '80px',
112
+ width: '75px',
108
113
  renderData: (value) => <WfoInsyncIcon inSync={value} />,
109
114
  },
110
115
  productName: {
111
116
  columnType: ColumnType.DATA,
117
+ width: '260px',
112
118
  label: t('product'),
113
119
  },
114
120
  tag: {
@@ -128,7 +134,7 @@ export const WfoSubscriptionsList: FC<WfoSubscriptionsListProps> = ({
128
134
  startDate: {
129
135
  columnType: ColumnType.DATA,
130
136
  label: t('startDate'),
131
- width: '120px',
137
+ width: '100px',
132
138
  renderData: (value) => <WfoDateTime dateOrIsoString={value} />,
133
139
  renderDetails: parseDateToLocaleDateTimeString,
134
140
  clipboardText: parseDateToLocaleDateTimeString,
@@ -137,7 +143,7 @@ export const WfoSubscriptionsList: FC<WfoSubscriptionsListProps> = ({
137
143
  endDate: {
138
144
  columnType: ColumnType.DATA,
139
145
  label: t('endDate'),
140
- width: '120px',
146
+ width: '100px',
141
147
  renderData: (value) => <WfoDateTime dateOrIsoString={value} />,
142
148
  renderDetails: parseDateToLocaleDateTimeString,
143
149
  clipboardText: parseDateToLocaleDateTimeString,
@@ -159,12 +165,6 @@ export const WfoSubscriptionsList: FC<WfoSubscriptionsListProps> = ({
159
165
  );
160
166
  },
161
167
  },
162
- actions: {
163
- columnType: ColumnType.CONTROL,
164
- label: t('actions'),
165
- width: '80px',
166
- renderControl: (row) => <WfoSubscriptionActions compactMode={true} subscriptionId={row.subscriptionId} />,
167
- },
168
168
  metadata: {
169
169
  columnType: ColumnType.DATA,
170
170
  label: t('metadata'),
@@ -81,7 +81,7 @@ export const WfoAdvancedTable = <T extends object>({
81
81
  width: '36px',
82
82
  renderControl: (row) => (
83
83
  <EuiFlexItem css={{ cursor: 'pointer' }} onClick={() => setSelectedDataForDetailModal(row)}>
84
- <WfoArrowsExpand color={theme.colors.borderBasePlain} />
84
+ <WfoArrowsExpand color={theme.colors.textDisabled} />
85
85
  </EuiFlexItem>
86
86
  ),
87
87
  },
@@ -24,7 +24,7 @@ export const WfoFirstPartUUID: FC<WfoFirstUUIDPartProps> = ({ UUID, showCopyIcon
24
24
  <EuiCopy textToCopy={UUID}>
25
25
  {(copy) => (
26
26
  <div className={COPY_ICON_CLASS} onClick={copy} css={clickable}>
27
- <WfoClipboardCopy width={16} height={16} color={theme.colors.backgroundBaseDisabled} />
27
+ <WfoClipboardCopy width={16} height={16} color={theme.colors.backgroundBaseAccent} />
28
28
  </div>
29
29
  )}
30
30
  </EuiCopy>
@@ -35,3 +35,6 @@ export const METADATA_PRODUCT_BLOCK_ENDPOINT = 'product_blocks';
35
35
  export const METADATA_RESOURCE_TYPE_ENDPOINT = 'resource_types';
36
36
  export const METADATA_WORKFLOWS_ENDPOINT = 'workflows';
37
37
  export const METADATA_SCHEDULES_ENDPOINT = 'schedules';
38
+
39
+ //search
40
+ export const SEARCH_QUERY_RESULTS_ENDPOINT = 'search/queries';
@@ -1 +1 @@
1
- export const ORCHESTRATOR_UI_LIBRARY_VERSION = '7.5.1';
1
+ export const ORCHESTRATOR_UI_LIBRARY_VERSION = '7.6.0';
@@ -0,0 +1,188 @@
1
+ import { useEffect, useState } from 'react';
2
+
3
+ import type { AgentSubscriber } from '@ag-ui/client';
4
+ // @ts-expect-error - v2 subpath exists but TypeScript moduleResolution doesn't recognize it
5
+ import { useAgent } from '@copilotkit/react-core/v2';
6
+
7
+ /** AG-UI custom event names emitted by the backend agent. */
8
+ enum AgentEvent {
9
+ PLAN_CREATED = 'PLAN_CREATED',
10
+ STEP_ACTIVE = 'AGENT_STEP_ACTIVE',
11
+ }
12
+
13
+ /** The backend step name used for the planning phase (not a real task). */
14
+ const PLANNER_STEP_NAME = 'Planner';
15
+
16
+ export type ToolCallState = {
17
+ id: string;
18
+ name: string;
19
+ status: 'executing' | 'complete';
20
+ };
21
+
22
+ export type PlanStep = {
23
+ step_name: string;
24
+ reasoning: string | null;
25
+ status: 'pending' | 'active' | 'completed';
26
+ tool_calls: ToolCallState[];
27
+ };
28
+
29
+ export type PlanExecutionState = {
30
+ planning: boolean;
31
+ steps: PlanStep[];
32
+ };
33
+
34
+ const initialState: PlanExecutionState = {
35
+ planning: false,
36
+ steps: [],
37
+ };
38
+
39
+ const updateSteps = (
40
+ steps: PlanStep[],
41
+ predicate: (step: PlanStep) => boolean,
42
+ updater: (step: PlanStep) => PlanStep,
43
+ ): PlanStep[] => steps.map((step) => (predicate(step) ? updater(step) : step));
44
+
45
+ export function useAgentPlanEvents(agentId: string = 'query_agent'): PlanExecutionState {
46
+ const { agent } = useAgent({ agentId });
47
+ const [executionState, setExecutionState] = useState<PlanExecutionState>(initialState);
48
+
49
+ useEffect(() => {
50
+ if (!agent) {
51
+ return;
52
+ }
53
+
54
+ const subscriber: AgentSubscriber = {
55
+ onCustomEvent: (params) => {
56
+ const event = params?.event;
57
+ if (!event) return;
58
+
59
+ if (event.name === AgentEvent.PLAN_CREATED) {
60
+ const tasks = event.value as Array<{
61
+ skillName: string;
62
+ reasoning: string;
63
+ }>;
64
+ if (!Array.isArray(tasks)) return;
65
+
66
+ setExecutionState({
67
+ planning: false,
68
+ steps: tasks.map((task) => ({
69
+ step_name: task.skillName,
70
+ reasoning: task.reasoning,
71
+ status: 'pending' as const,
72
+ tool_calls: [],
73
+ })),
74
+ });
75
+ return;
76
+ }
77
+
78
+ if (event.name === AgentEvent.STEP_ACTIVE) {
79
+ const stepName = event.value?.step;
80
+ if (!stepName) return;
81
+
82
+ if (stepName === PLANNER_STEP_NAME) {
83
+ setExecutionState((prev) => ({
84
+ ...prev,
85
+ planning: true,
86
+ }));
87
+ return;
88
+ }
89
+
90
+ const reasoning = event.value?.reasoning ?? null;
91
+
92
+ setExecutionState((prev) => {
93
+ // Mark previous active step as completed
94
+ const steps = updateSteps(
95
+ prev.steps,
96
+ (step) => step.status === 'active',
97
+ (step) => ({ ...step, status: 'completed' as const }),
98
+ );
99
+
100
+ // If step already exists (from PLAN_CREATED), activate it
101
+ const existingIndex = steps.findIndex((step) => step.step_name === stepName);
102
+ if (existingIndex >= 0) {
103
+ steps[existingIndex] = {
104
+ ...steps[existingIndex],
105
+ status: 'active',
106
+ reasoning: reasoning ?? steps[existingIndex].reasoning,
107
+ };
108
+ } else {
109
+ steps.push({
110
+ step_name: stepName,
111
+ reasoning,
112
+ status: 'active',
113
+ tool_calls: [],
114
+ });
115
+ }
116
+
117
+ return { planning: false, steps };
118
+ });
119
+ }
120
+ },
121
+
122
+ onToolCallStartEvent: ({ event }) => {
123
+ setExecutionState((prev) => {
124
+ const currentStep = prev.steps.find((step) => step.status === 'active');
125
+ if (!currentStep) return prev;
126
+
127
+ return {
128
+ ...prev,
129
+ steps: updateSteps(
130
+ prev.steps,
131
+ (step) => step.step_name === currentStep.step_name,
132
+ (step) => ({
133
+ ...step,
134
+ tool_calls: [
135
+ ...step.tool_calls,
136
+ {
137
+ id: event.toolCallId,
138
+ name: event.toolCallName,
139
+ status: 'executing' as const,
140
+ },
141
+ ],
142
+ }),
143
+ ),
144
+ };
145
+ });
146
+ },
147
+
148
+ onToolCallEndEvent: ({ event }) => {
149
+ setExecutionState((prev) => ({
150
+ ...prev,
151
+ steps: updateSteps(
152
+ prev.steps,
153
+ (step) => step.tool_calls.some((toolCall) => toolCall.id === event.toolCallId),
154
+ (step) => ({
155
+ ...step,
156
+ tool_calls: step.tool_calls.map((toolCall) =>
157
+ toolCall.id === event.toolCallId ? { ...toolCall, status: 'complete' as const } : toolCall,
158
+ ),
159
+ }),
160
+ ),
161
+ }));
162
+ },
163
+
164
+ onRunStartedEvent: () => {
165
+ setExecutionState(initialState);
166
+ },
167
+
168
+ onRunFinishedEvent: () => {
169
+ setExecutionState((prev) => ({
170
+ planning: false,
171
+ steps: updateSteps(
172
+ prev.steps,
173
+ (step) => step.status === 'active',
174
+ (step) => ({ ...step, status: 'completed' as const }),
175
+ ),
176
+ }));
177
+ },
178
+ };
179
+
180
+ const subscription = agent.subscribe(subscriber);
181
+
182
+ return () => {
183
+ subscription.unsubscribe();
184
+ };
185
+ }, [agent]);
186
+
187
+ return executionState;
188
+ }
@@ -558,6 +558,11 @@
558
558
  "get_valid_operators": "I'm getting valid operators",
559
559
  "set_temporal_grouping": "I'm setting temporal grouping"
560
560
  },
561
+ "planProgress": {
562
+ "planning": "Planning...",
563
+ "completed": "Plan completed",
564
+ "executing": "Executing plan ({completed}/{total})"
565
+ },
561
566
  "visualization": {
562
567
  "noDataAvailable": "No data available for visualization.",
563
568
  "invalidDataStructure": "Invalid data structure."
@@ -0,0 +1,19 @@
1
+ import { SEARCH_QUERY_RESULTS_ENDPOINT } from '@/configuration';
2
+ import { BaseQueryTypes, orchestratorApi } from '@/rtk';
3
+ import { QueryResultsData } from '@/types';
4
+
5
+ const agentQueryResultsApi = orchestratorApi.injectEndpoints({
6
+ endpoints: (builder) => ({
7
+ getAgentQueryResults: builder.query<QueryResultsData, string>({
8
+ query: (queryId) => ({
9
+ url: `${SEARCH_QUERY_RESULTS_ENDPOINT}/${queryId}/results`,
10
+ method: 'GET',
11
+ }),
12
+ extraOptions: {
13
+ baseQueryType: BaseQueryTypes.fetch,
14
+ },
15
+ }),
16
+ }),
17
+ });
18
+
19
+ export const { useGetAgentQueryResultsQuery } = agentQueryResultsApi;
@@ -20,3 +20,4 @@ export * from './forms';
20
20
  export * from './fileUpload';
21
21
  export * from './search';
22
22
  export * from './availability';
23
+ export * from './agentQueryResults';
@@ -156,7 +156,7 @@ export type PathInfo = {
156
156
 
157
157
  /** ---------- Agent visualization types ---------- */
158
158
 
159
- export type AggregationResult = {
159
+ export type ResultRow = {
160
160
  group_values: Record<string, string>;
161
161
  aggregations: Record<string, number>;
162
162
  };
@@ -172,11 +172,26 @@ export enum VisualizationType {
172
172
  TABLE = 'table',
173
173
  }
174
174
 
175
- export type AggregationResultsData = {
176
- results: AggregationResult[];
177
- total_groups: number;
175
+ export type QueryResultsData = {
176
+ results: ResultRow[];
177
+ total_results: number;
178
178
  metadata: SearchMetadata;
179
179
  visualization_type: {
180
180
  type: VisualizationType;
181
181
  };
182
182
  };
183
+
184
+ export type QueryArtifact = {
185
+ query_id: string;
186
+ total_results: number;
187
+ visualization_type: {
188
+ type: VisualizationType;
189
+ };
190
+ description: string;
191
+ };
192
+
193
+ export type ExportArtifact = {
194
+ query_id: string;
195
+ download_url: string;
196
+ description: string;
197
+ };
@@ -48,4 +48,9 @@ describe('isOrchestratorUiVersionCompatible', () => {
48
48
  expect(getOrchestratorCoreVersionIfNotCompatible('1.0.0', '2.10.0', TEST_VERSIONS)).toBe(null); // falls back to first MAPPED_VERSION
49
49
  expect(getOrchestratorCoreVersionIfNotCompatible('1.0.0', '2.9.9', TEST_VERSIONS)).toBe('2.10.0');
50
50
  });
51
+
52
+ test('handles prerelease orchestratorCoreVersion (e.g. 5.0.0a7)', () => {
53
+ expect(getOrchestratorCoreVersionIfNotCompatible('3.10.0', '5.0.0a7', TEST_VERSIONS)).toBe(null);
54
+ expect(getOrchestratorCoreVersionIfNotCompatible('3.10.0', '3.1.1a1', TEST_VERSIONS)).toBe('3.1.1');
55
+ });
51
56
  });
@@ -1,33 +1,62 @@
1
1
  import { MappedVersion } from '@/types';
2
2
 
3
- const compareVersions = (versionString1: string, versionString2: string): number => {
4
- const splittedVersion1 = versionString1.split('.');
5
- const splittedVersion2 = versionString2.split('.');
6
-
7
- for (let i = 0; i < splittedVersion1.length; i++) {
8
- if (parseInt(splittedVersion1[i]) > parseInt(splittedVersion2[i])) {
9
- return 1;
10
- } else if (parseInt(splittedVersion1[i]) < parseInt(splittedVersion2[i])) {
11
- return -1;
3
+ const compareVersions = (v1: string, v2: string): number => {
4
+ const parse = (v: string) => {
5
+ const parts = v.split('.');
6
+
7
+ const major = parseInt(parts[0]);
8
+ const minor = parseInt(parts[1]);
9
+
10
+ const patchPart = parts[2] ?? '';
11
+
12
+ let patch = 0;
13
+ let suffix = '';
14
+
15
+ // extract numeric patch and suffix manually
16
+ for (let i = 0; i < patchPart.length; i++) {
17
+ const char = patchPart[i];
18
+
19
+ if (char >= '0' && char <= '9') {
20
+ patch = patch * 10 + Number(char);
21
+ } else {
22
+ suffix = patchPart.slice(i);
23
+ break;
24
+ }
12
25
  }
13
- }
14
- return 0;
26
+
27
+ return { major, minor, patch, suffix };
28
+ };
29
+
30
+ const a = parse(v1);
31
+ const b = parse(v2);
32
+
33
+ // compare numeric parts
34
+ if (a.major !== b.major) return a.major > b.major ? 1 : -1;
35
+ if (a.minor !== b.minor) return a.minor > b.minor ? 1 : -1;
36
+ if (a.patch !== b.patch) return a.patch > b.patch ? 1 : -1;
37
+
38
+ // compare suffix
39
+ if (a.suffix === b.suffix) return 0;
40
+ if (!a.suffix) return 1; // stable > pre-release
41
+ if (!b.suffix) return -1;
42
+
43
+ return a.suffix > b.suffix ? 1 : -1;
15
44
  };
16
45
 
17
46
  const findMinimumOrchestratorCoreVersion = (
18
47
  orchestratorUiVersion: string,
19
48
  versionMappings: MappedVersion[],
20
- ): string => {
21
- const orchestratorUiVersions = versionMappings.map((version) => version.orchestratorUiVersion);
22
- let mappedVersion = versionMappings[0];
49
+ ): string | null => {
50
+ // sort mappings descending by UI version. This is done just in case the input versionMappings are not sorted
51
+ const sorted = [...versionMappings].sort((a, b) => compareVersions(b.orchestratorUiVersion, a.orchestratorUiVersion));
23
52
 
24
- for (let i = 0; i < orchestratorUiVersions.length; i++) {
25
- if ([0, 1].includes(compareVersions(orchestratorUiVersion, orchestratorUiVersions[i]))) {
26
- mappedVersion = versionMappings[i];
53
+ for (const mapping of sorted) {
54
+ if (compareVersions(orchestratorUiVersion, mapping.orchestratorUiVersion) >= 0) {
55
+ return mapping.minimumOrchestratorCoreVersion;
27
56
  }
28
57
  }
29
58
 
30
- return mappedVersion.minimumOrchestratorCoreVersion;
59
+ return sorted[sorted.length - 1]?.minimumOrchestratorCoreVersion ?? null;
31
60
  };
32
61
 
33
62
  export const getOrchestratorCoreVersionIfNotCompatible = (
@@ -35,10 +64,13 @@ export const getOrchestratorCoreVersionIfNotCompatible = (
35
64
  orchestratorCoreVersion: string,
36
65
  versionMappings: MappedVersion[],
37
66
  ): string | null => {
38
- const minimumOrchestratorCoreVersion = findMinimumOrchestratorCoreVersion(orchestratorUiVersion, versionMappings);
39
- const comparison = compareVersions(orchestratorCoreVersion, minimumOrchestratorCoreVersion);
40
- if (comparison === -1) {
41
- return minimumOrchestratorCoreVersion;
67
+ const minimumVersion = findMinimumOrchestratorCoreVersion(orchestratorUiVersion, versionMappings);
68
+
69
+ if (!minimumVersion) {
70
+ return null;
42
71
  }
43
- return null;
72
+
73
+ const isCompatible = compareVersions(orchestratorCoreVersion, minimumVersion) !== -1;
74
+
75
+ return isCompatible ? null : minimumVersion;
44
76
  };
@@ -1,99 +0,0 @@
1
- import React from 'react';
2
-
3
- import { EuiSpacer, EuiText } from '@elastic/eui';
4
-
5
- import { WfoBadge } from '@/components/WfoBadges';
6
- import { WfoPathBreadcrumb } from '@/components/WfoSearchPage/WfoSearchResults/WfoPathBreadcrumb';
7
-
8
- interface DiscoverFilterPathsResult {
9
- status?: string;
10
- leaves?: Array<{
11
- paths?: string[];
12
- name?: string;
13
- }>;
14
- }
15
-
16
- type DiscoverFilterPathsDisplayProps = {
17
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
18
- result?: any;
19
- parameters: {
20
- field_names?: string[];
21
- entity_type?: string;
22
- };
23
- };
24
-
25
- export const DiscoverFilterPathsDisplay = ({ parameters, result }: DiscoverFilterPathsDisplayProps) => {
26
- const { field_names = [] } = parameters;
27
-
28
- const foundFields: [string, DiscoverFilterPathsResult][] =
29
- result ?
30
- Object.entries(result as Record<string, DiscoverFilterPathsResult>).filter(
31
- ([, fieldResult]) => fieldResult.status !== 'NOT_FOUND',
32
- )
33
- : [];
34
-
35
- // Count total paths across all found fields
36
- const totalPaths = foundFields.reduce((count, [, fieldResult]) => {
37
- const pathCount =
38
- fieldResult.leaves?.reduce((leafCount: number, leaf) => {
39
- return leafCount + (leaf.paths?.length || 1);
40
- }, 0) || 0;
41
- return count + pathCount;
42
- }, 0);
43
-
44
- return (
45
- <div>
46
- {field_names.length > 0 && (
47
- <>
48
- <EuiText size="xs" color="subdued">
49
- Looking for{' '}
50
- {field_names.map((name, idx) => (
51
- <React.Fragment key={name}>
52
- {idx > 0 && ', '}
53
- <WfoBadge color="hollow" textColor="default">
54
- {name}
55
- </WfoBadge>
56
- </React.Fragment>
57
- ))}
58
- </EuiText>
59
- <EuiSpacer size="s" />
60
- </>
61
- )}
62
-
63
- {result && totalPaths > 0 && (
64
- <div>
65
- <EuiText size="xs" color="subdued">
66
- <strong>
67
- Found {totalPaths} path
68
- {totalPaths > 1 ? 's' : ''}:
69
- </strong>
70
- </EuiText>
71
- <EuiSpacer size="xs" />
72
- {foundFields.map(([fieldName, fieldResult]) => (
73
- <div key={fieldName} style={{ marginBottom: '8px' }}>
74
- {fieldResult.leaves
75
- && fieldResult.leaves.length > 0
76
- && fieldResult.leaves.map((leaf, leafIdx: number) => {
77
- const paths = leaf.paths || (leaf.name ? [leaf.name] : []);
78
- return (
79
- <React.Fragment key={leafIdx}>
80
- {paths.map((path: string, pathIdx: number) => (
81
- <div
82
- key={pathIdx}
83
- style={{
84
- marginBottom: '4px',
85
- }}
86
- >
87
- <WfoPathBreadcrumb path={path} size="s" />
88
- </div>
89
- ))}
90
- </React.Fragment>
91
- );
92
- })}
93
- </div>
94
- ))}
95
- </div>
96
- )}
97
- </div>
98
- );
99
- };
@@ -1,34 +0,0 @@
1
- import React from 'react';
2
-
3
- import { EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui';
4
-
5
- import { WfoBadge } from '@/components/WfoBadges';
6
-
7
- type RunSearchDisplayProps = {
8
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
9
- result?: any;
10
- parameters: {
11
- limit?: number;
12
- };
13
- };
14
-
15
- export const RunSearchDisplay = ({ parameters }: RunSearchDisplayProps) => {
16
- const { limit = 10 } = parameters;
17
-
18
- return (
19
- <div>
20
- <EuiFlexGroup gutterSize="s" alignItems="center">
21
- <EuiFlexItem grow={false}>
22
- <EuiText size="xs" color="subdued">
23
- <strong>Results Limit</strong>
24
- </EuiText>
25
- </EuiFlexItem>
26
- <EuiFlexItem grow={false}>
27
- <WfoBadge textColor="default" color="hollow">
28
- {limit}
29
- </WfoBadge>
30
- </EuiFlexItem>
31
- </EuiFlexGroup>
32
- </div>
33
- );
34
- };
@@ -1,62 +0,0 @@
1
- import { css } from '@emotion/react';
2
-
3
- import { WfoThemeHelpers } from '@/hooks';
4
-
5
- export const getFilterDisplayStyles = ({ theme }: WfoThemeHelpers) => {
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.backgroundBasePlain,
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.borderBaseSubdued}`,
32
- borderRadius: theme.border.radius.medium,
33
- padding: theme.size.s,
34
- margin: theme.size.xs,
35
- backgroundColor: theme.colors.backgroundBasePlain,
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.textGhost,
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
- };