@orchestrator-ui/orchestrator-ui-components 5.9.0 → 6.1.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 (61) hide show
  1. package/.turbo/turbo-build.log +8 -8
  2. package/.turbo/turbo-lint.log +10 -1
  3. package/.turbo/turbo-test.log +10 -10
  4. package/CHANGELOG.md +12 -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 +1432 -2
  8. package/dist/index.js +3006 -28
  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/icons/WfoPencil.tsx +23 -4
  54. package/src/messages/en-GB.json +79 -1
  55. package/src/messages/nl-NL.json +2 -1
  56. package/src/rtk/endpoints/index.ts +1 -0
  57. package/src/rtk/endpoints/search.ts +90 -0
  58. package/src/types/index.ts +1 -0
  59. package/src/types/search.ts +215 -0
  60. package/src/utils/optionalArray.spec.ts +27 -0
  61. package/src/utils/optionalArray.ts +5 -0
@@ -0,0 +1,133 @@
1
+ import { useEffect, useState } from 'react';
2
+
3
+ import {
4
+ useSearchDefinitionsQuery,
5
+ useSearchPathsQuery,
6
+ } from '@/rtk/endpoints';
7
+ import { EntityKind, PathInfo, value_schema } from '@/types';
8
+
9
+ import { useDebounce } from './useDebounce';
10
+
11
+ const FALLBACK_DEFINITIONS: Record<
12
+ string,
13
+ {
14
+ operators: string[];
15
+ value_schema: Record<string, value_schema>;
16
+ }
17
+ > = {
18
+ string: {
19
+ operators: ['eq', 'neq'],
20
+ value_schema: {
21
+ eq: { kind: 'string' },
22
+ neq: { kind: 'string' },
23
+ },
24
+ },
25
+ number: {
26
+ operators: ['eq', 'neq', 'lt', 'lte', 'gt', 'gte'],
27
+ value_schema: {
28
+ eq: { kind: 'number' },
29
+ neq: { kind: 'number' },
30
+ lt: { kind: 'number' },
31
+ lte: { kind: 'number' },
32
+ gt: { kind: 'number' },
33
+ gte: { kind: 'number' },
34
+ },
35
+ },
36
+ boolean: {
37
+ operators: ['eq', 'neq'],
38
+ value_schema: {
39
+ eq: { kind: 'boolean' },
40
+ neq: { kind: 'boolean' },
41
+ },
42
+ },
43
+ datetime: {
44
+ operators: ['eq', 'neq', 'lt', 'lte', 'gt', 'gte'],
45
+ value_schema: {
46
+ eq: { kind: 'datetime' },
47
+ neq: { kind: 'datetime' },
48
+ lt: { kind: 'datetime' },
49
+ lte: { kind: 'datetime' },
50
+ gt: { kind: 'datetime' },
51
+ gte: { kind: 'datetime' },
52
+ },
53
+ },
54
+ };
55
+
56
+ export const usePathAutocomplete = (prefix: string, entityType: EntityKind) => {
57
+ const [paths, setPaths] = useState<PathInfo[]>([]);
58
+ const debouncedPrefix = useDebounce(prefix, 300);
59
+
60
+ const { data: definitions = FALLBACK_DEFINITIONS, isError: defError } =
61
+ useSearchDefinitionsQuery();
62
+
63
+ const {
64
+ data: pathData,
65
+ isLoading,
66
+ isError,
67
+ } = useSearchPathsQuery(
68
+ { q: debouncedPrefix, entity_type: entityType },
69
+ { skip: debouncedPrefix.length < 1 },
70
+ );
71
+
72
+ useEffect(() => {
73
+ if (debouncedPrefix.length < 1) {
74
+ setPaths([]);
75
+ return;
76
+ }
77
+
78
+ if (!pathData) {
79
+ return;
80
+ }
81
+
82
+ const enrichedPaths: PathInfo[] = [];
83
+
84
+ // Process leaves first
85
+ (pathData.leaves || []).forEach((leaf) => {
86
+ const primaryType = leaf.ui_types[0] || 'string';
87
+ const typeDefinition = definitions[primaryType];
88
+
89
+ enrichedPaths.push({
90
+ path: leaf.name,
91
+ type: primaryType as
92
+ | 'string'
93
+ | 'number'
94
+ | 'datetime'
95
+ | 'boolean',
96
+ operators: typeDefinition?.operators || [],
97
+ value_schema: typeDefinition?.value_schema || {},
98
+ group: 'leaf',
99
+ displayLabel: leaf.name,
100
+ ui_types: leaf.ui_types,
101
+ availablePaths: leaf.paths || [],
102
+ pathCount: leaf.paths ? leaf.paths.length : 0,
103
+ });
104
+ });
105
+
106
+ (pathData.components || []).forEach((component) => {
107
+ const primaryType = component.ui_types[0] || 'string';
108
+ const typeDefinition = definitions[primaryType];
109
+
110
+ enrichedPaths.push({
111
+ path: component.name,
112
+ type: 'component',
113
+ operators: typeDefinition?.operators || [],
114
+ value_schema: typeDefinition?.value_schema || {},
115
+ group: 'component',
116
+ displayLabel: component.name,
117
+ ui_types: component.ui_types,
118
+ availablePaths: component.paths || [],
119
+ pathCount: component.paths ? component.paths.length : 0,
120
+ });
121
+ });
122
+
123
+ setPaths(enrichedPaths);
124
+ }, [pathData, definitions]);
125
+
126
+ const errorMessage = isError
127
+ ? 'Failed to load paths'
128
+ : defError
129
+ ? 'Failed to load definitions'
130
+ : null;
131
+
132
+ return { paths, loading: isLoading, error: errorMessage };
133
+ };
@@ -0,0 +1,83 @@
1
+ import { useEffect, useState } from 'react';
2
+
3
+ import { Query } from '@elastic/eui';
4
+
5
+ import { useSearchMutation } from '@/rtk/endpoints';
6
+ import { EntityKind, Group, PaginatedSearchResults } from '@/types';
7
+
8
+ export const useSearch = (
9
+ query: Query | string,
10
+ entityType: EntityKind,
11
+ filterGroup?: Group,
12
+ limit?: number,
13
+ ) => {
14
+ const [results, setResults] = useState<PaginatedSearchResults>({
15
+ data: [],
16
+ page_info: { has_next_page: false, next_page_cursor: null },
17
+ search_metadata: { search_type: null, description: null },
18
+ });
19
+
20
+ const [triggerSearch, { isLoading, isError }] = useSearchMutation();
21
+
22
+ useEffect(() => {
23
+ const queryText =
24
+ typeof query === 'string' ? query : query.text?.trim() || '';
25
+
26
+ const hasFilters = filterGroup && filterGroup.children.length > 0;
27
+
28
+ if (queryText.length < 2 && !hasFilters) {
29
+ setResults({
30
+ data: [],
31
+ page_info: { has_next_page: false, next_page_cursor: null },
32
+ search_metadata: { search_type: null, description: null },
33
+ });
34
+ return;
35
+ }
36
+
37
+ const performSearch = async () => {
38
+ try {
39
+ const result = await triggerSearch({
40
+ action: 'select',
41
+ entity_type: entityType,
42
+ query: queryText,
43
+ filters:
44
+ filterGroup && filterGroup.children.length > 0
45
+ ? filterGroup
46
+ : undefined,
47
+ limit: limit,
48
+ }).unwrap();
49
+
50
+ setResults({
51
+ data: result.data || [],
52
+ page_info: {
53
+ has_next_page: result.page_info?.has_next_page || false,
54
+ next_page_cursor:
55
+ result.page_info?.next_page_cursor || null,
56
+ },
57
+ search_metadata: {
58
+ search_type:
59
+ result.search_metadata?.search_type || null,
60
+ description:
61
+ result.search_metadata?.description || null,
62
+ },
63
+ });
64
+ } catch (error) {
65
+ console.error('Search error:', error);
66
+ setResults({
67
+ data: [],
68
+ page_info: { has_next_page: false, next_page_cursor: null },
69
+ search_metadata: { search_type: null, description: null },
70
+ });
71
+ }
72
+ };
73
+
74
+ performSearch();
75
+ }, [query, entityType, filterGroup, limit, triggerSearch]);
76
+
77
+ return {
78
+ results,
79
+ loading: isLoading,
80
+ error: isError ? 'Search failed' : null,
81
+ setResults,
82
+ };
83
+ };
@@ -0,0 +1,148 @@
1
+ import { useCallback, useState } from 'react';
2
+
3
+ import { Query } from '@elastic/eui';
4
+
5
+ import { buildSearchParams } from '@/components/WfoSearchPage/utils';
6
+ import { useSearchWithPaginationMutation } from '@/rtk/endpoints';
7
+ import {
8
+ AnySearchResult,
9
+ EntityKind,
10
+ Group,
11
+ PaginatedSearchResults,
12
+ } from '@/types';
13
+
14
+ interface PageHistoryItem {
15
+ page: number;
16
+ results: AnySearchResult[];
17
+ cursor: number | null;
18
+ }
19
+
20
+ interface UseSearchPaginationReturn {
21
+ currentPage: number;
22
+ pageHistory: PageHistoryItem[];
23
+ error: string | null;
24
+ isLoadingMore: boolean;
25
+ handleNextPage: (nextPageCursor: number) => Promise<void>;
26
+ handlePrevPage: () => void;
27
+ resetPagination: () => void;
28
+ setError: (error: string | null) => void;
29
+ }
30
+
31
+ export const useSearchPagination = (
32
+ debouncedQuery: Query | string,
33
+ selectedEntityTab: EntityKind,
34
+ filterGroup: Group,
35
+ pageSize: number,
36
+ results: PaginatedSearchResults,
37
+ setResults: (results: PaginatedSearchResults) => void,
38
+ ): UseSearchPaginationReturn => {
39
+ const [currentPage, setCurrentPage] = useState<number>(1);
40
+ const [pageHistory, setPageHistory] = useState<PageHistoryItem[]>([]);
41
+ const [error, setError] = useState<string | null>(null);
42
+ const [isLoadingMore, setIsLoadingMore] = useState<boolean>(false);
43
+
44
+ const [triggerSearchPagination] = useSearchWithPaginationMutation();
45
+
46
+ const handleNextPage = useCallback(
47
+ async (nextPageCursor: number) => {
48
+ if (!nextPageCursor || isLoadingMore) return;
49
+
50
+ setIsLoadingMore(true);
51
+
52
+ setPageHistory((prev) => [
53
+ ...prev.filter((p) => p.page !== currentPage),
54
+ {
55
+ page: currentPage,
56
+ results: results.data,
57
+ cursor: results.page_info.next_page_cursor,
58
+ },
59
+ ]);
60
+
61
+ try {
62
+ setError(null);
63
+ const searchParams = buildSearchParams(
64
+ debouncedQuery,
65
+ selectedEntityTab,
66
+ filterGroup,
67
+ pageSize,
68
+ );
69
+
70
+ const res = await triggerSearchPagination({
71
+ ...searchParams,
72
+ cursor: nextPageCursor,
73
+ }).unwrap();
74
+
75
+ setResults({
76
+ data: res.data || [],
77
+ page_info: {
78
+ has_next_page: res.page_info.has_next_page,
79
+ next_page_cursor: res.page_info.next_page_cursor,
80
+ },
81
+ search_metadata: {
82
+ search_type: res.search_metadata.search_type,
83
+ description: res.search_metadata.description,
84
+ },
85
+ });
86
+
87
+ setCurrentPage((prev) => prev + 1);
88
+ } catch (error) {
89
+ const errorMessage =
90
+ error instanceof Error
91
+ ? error.message
92
+ : 'An unexpected error occurred while loading the next page';
93
+ setError(errorMessage);
94
+ console.error('Load next page error:', error);
95
+ } finally {
96
+ setIsLoadingMore(false);
97
+ }
98
+ },
99
+ [
100
+ currentPage,
101
+ results.data,
102
+ results.page_info.next_page_cursor,
103
+ isLoadingMore,
104
+ debouncedQuery,
105
+ selectedEntityTab,
106
+ filterGroup,
107
+ pageSize,
108
+ setResults,
109
+ triggerSearchPagination,
110
+ ],
111
+ );
112
+
113
+ const handlePrevPage = useCallback(() => {
114
+ const previousPage = pageHistory.find(
115
+ (p) => p.page === currentPage - 1,
116
+ );
117
+ if (previousPage) {
118
+ setResults({
119
+ data: previousPage.results,
120
+ page_info: {
121
+ has_next_page: true,
122
+ next_page_cursor: previousPage.cursor,
123
+ },
124
+ search_metadata: results.search_metadata,
125
+ });
126
+
127
+ setCurrentPage((prev) => prev - 1);
128
+
129
+ setPageHistory((prev) => prev.filter((p) => p.page < currentPage));
130
+ }
131
+ }, [currentPage, pageHistory, results.search_metadata, setResults]);
132
+
133
+ const resetPagination = useCallback(() => {
134
+ setCurrentPage(1);
135
+ setPageHistory([]);
136
+ }, []);
137
+
138
+ return {
139
+ currentPage,
140
+ pageHistory,
141
+ error,
142
+ isLoadingMore,
143
+ handleNextPage,
144
+ handlePrevPage,
145
+ resetPagination,
146
+ setError,
147
+ };
148
+ };
@@ -0,0 +1,120 @@
1
+ import { useCallback, useEffect, useState } from 'react';
2
+
3
+ import { Query } from '@elastic/eui';
4
+
5
+ import { EntityKind } from '@/types';
6
+
7
+ import {
8
+ DEFAULT_ENTITY_TAB,
9
+ VALID_ENTITY_TYPES,
10
+ } from '../components/WfoSearchPage/constants';
11
+
12
+ interface UseUrlParamsReturn {
13
+ urlParams: URLSearchParams;
14
+ query: Query | string;
15
+ selectedEntityTab: EntityKind;
16
+ showFilters: boolean;
17
+ selectedRecordIndex: number;
18
+ selectedRecordId: string | null;
19
+ setQuery: (query: Query | string) => void;
20
+ setSelectedEntityTab: (tab: EntityKind) => void;
21
+ setShowFilters: (show: boolean) => void;
22
+ setSelectedRecordIndex: (index: number) => void;
23
+ setSelectedRecordId: (id: string | null) => void;
24
+ }
25
+
26
+ export const useUrlParams = (): UseUrlParamsReturn => {
27
+ const [urlParams, setUrlParams] = useState(() => {
28
+ if (typeof window !== 'undefined') {
29
+ return new URLSearchParams(window.location.search);
30
+ }
31
+ return new URLSearchParams();
32
+ });
33
+
34
+ const [query, setQuery] = useState<Query | string>(() => {
35
+ const queryParam = urlParams.get('q');
36
+ return queryParam || '';
37
+ });
38
+
39
+ const [selectedEntityTab, setSelectedEntityTab] = useState<EntityKind>(
40
+ () => {
41
+ const tabParam = urlParams.get('tab') as EntityKind;
42
+ return tabParam && VALID_ENTITY_TYPES.includes(tabParam)
43
+ ? tabParam
44
+ : DEFAULT_ENTITY_TAB;
45
+ },
46
+ );
47
+
48
+ const [showFilters, setShowFilters] = useState<boolean>(() => {
49
+ return urlParams.get('filters') === 'true';
50
+ });
51
+
52
+ const [selectedRecordIndex, setSelectedRecordIndex] = useState<number>(
53
+ () => {
54
+ const indexParam = urlParams.get('selected');
55
+ return indexParam ? parseInt(indexParam, 10) || 0 : 0;
56
+ },
57
+ );
58
+
59
+ const [selectedRecordId, setSelectedRecordId] = useState<string | null>(
60
+ () => {
61
+ return urlParams.get('id') || null;
62
+ },
63
+ );
64
+
65
+ const updateUrl = useCallback(() => {
66
+ const newParams = new URLSearchParams();
67
+
68
+ const queryText = typeof query === 'string' ? query : query.text || '';
69
+ if (queryText && queryText !== '*') {
70
+ newParams.set('q', queryText);
71
+ }
72
+
73
+ if (selectedEntityTab !== DEFAULT_ENTITY_TAB) {
74
+ newParams.set('tab', selectedEntityTab);
75
+ }
76
+
77
+ if (showFilters) {
78
+ newParams.set('filters', 'true');
79
+ }
80
+
81
+ if (selectedRecordIndex > 0) {
82
+ newParams.set('selected', selectedRecordIndex.toString());
83
+ }
84
+
85
+ if (selectedRecordId) {
86
+ newParams.set('id', selectedRecordId);
87
+ }
88
+
89
+ const newUrl = newParams.toString()
90
+ ? `${window.location.pathname}?${newParams.toString()}`
91
+ : window.location.pathname;
92
+
93
+ window.history.replaceState({}, '', newUrl);
94
+ setUrlParams(newParams);
95
+ }, [
96
+ query,
97
+ selectedEntityTab,
98
+ showFilters,
99
+ selectedRecordIndex,
100
+ selectedRecordId,
101
+ ]);
102
+
103
+ useEffect(() => {
104
+ updateUrl();
105
+ }, [updateUrl]);
106
+
107
+ return {
108
+ urlParams,
109
+ query,
110
+ selectedEntityTab,
111
+ showFilters,
112
+ selectedRecordIndex,
113
+ selectedRecordId,
114
+ setQuery,
115
+ setSelectedEntityTab,
116
+ setShowFilters,
117
+ setSelectedRecordIndex,
118
+ setSelectedRecordId,
119
+ };
120
+ };
@@ -2,6 +2,13 @@ import React, { FC } from 'react';
2
2
 
3
3
  import { WfoIconProps } from './WfoIconProps';
4
4
 
5
+ const Path = ({ color }: { color: string }) => (
6
+ <path
7
+ fill={color}
8
+ d="M13.3787,7.7928875 L16.2071,10.6213175 L7.82842,18.9999975 L5,18.9999975 L5,16.1715975 L13.3787,7.7928875 Z M18.4142,5.5857875 C19.1953,6.3668275 19.1953,7.6331575 18.4142,8.4142075 L17.6213,9.2071075 L14.7929,6.3786775 L15.5858,5.5857875 C16.3668,4.8047375 17.6332,4.8047375 18.4142,5.5857875 Z"
9
+ />
10
+ );
11
+
5
12
  export const WfoPencil: FC<WfoIconProps> = ({
6
13
  width = 24,
7
14
  height = 24,
@@ -13,9 +20,21 @@ export const WfoPencil: FC<WfoIconProps> = ({
13
20
  height={height}
14
21
  viewBox="0 0 24 24"
15
22
  >
16
- <path
17
- fill={color}
18
- d="M13.3787,7.7928875 L16.2071,10.6213175 L7.82842,18.9999975 L5,18.9999975 L5,16.1715975 L13.3787,7.7928875 Z M18.4142,5.5857875 C19.1953,6.3668275 19.1953,7.6331575 18.4142,8.4142075 L17.6213,9.2071075 L14.7929,6.3786775 L15.5858,5.5857875 C16.3668,4.8047375 17.6332,4.8047375 18.4142,5.5857875 Z"
19
- />
23
+ <Path color={color} />
24
+ </svg>
25
+ );
26
+
27
+ export const WfoPencilCompact: FC<WfoIconProps> = ({
28
+ width = 24,
29
+ height = 24,
30
+ color = '#000000',
31
+ }) => (
32
+ <svg
33
+ xmlns="http://www.w3.org/2000/svg"
34
+ width={width}
35
+ height={height}
36
+ viewBox="5 5 14 14"
37
+ >
38
+ <Path color={color} />
20
39
  </svg>
21
40
  );
@@ -291,7 +291,8 @@
291
291
  "metadata": "Metadata",
292
292
  "note": "Note",
293
293
  "customerFullname": "Customer",
294
- "customerShortcode": "Customer abbr"
294
+ "customerShortcode": "Customer abbr",
295
+ "actions": "Actions"
295
296
  },
296
297
  "detail": {
297
298
  "title": "Subscriptions",
@@ -465,5 +466,82 @@
465
466
  "softwareVersions": "Software Versions",
466
467
  "logout": "Logout",
467
468
  "aoStatusPage": "A&O application status page"
469
+ },
470
+ "agent": {
471
+ "title": "Search results",
472
+ "page": {
473
+ "filledParameters": "Filled parameters",
474
+ "results": "Results",
475
+ "emptyGroup": "Empty group",
476
+ "searchQuery": "Search query",
477
+ "activeFilters": "Active filters",
478
+ "noFiltersApplied": "No filters applied",
479
+ "entityType": "Entity type",
480
+ "action": "Action",
481
+ "copilot": {
482
+ "title": "Database assistant",
483
+ "initial": "Ask me things such as:\n• *Find active subscriptions for Surf*\n• *Show terminated workflows”*\n\nThe filled template and results will appear on the left."
484
+ }
485
+ }
486
+ },
487
+ "search": {
488
+ "page": {
489
+ "selectFieldFirst": "Select a field first",
490
+ "maxNestingDepth": "Maximum nesting depth reached",
491
+ "addNestedGroup": "Add nested group",
492
+ "addCondition": "Add condition",
493
+ "addGroup": "Add group",
494
+ "removeGroup": "Remove group",
495
+ "emptyGroupDescription": "Add conditions or nested groups to build your filter.",
496
+ "emptyGroupTitle": "Empty group",
497
+ "fieldSearchPlaceholder": "Type to search fields...",
498
+ "removeConditionAriaLabel": "Remove condition",
499
+ "groupLabel": "Group",
500
+ "hideFilters": "Hide filters",
501
+ "showFilters": "Show filters",
502
+ "structuredFilters": "Structured filters",
503
+ "searchError": "Error",
504
+ "selectResultInstruction": "Detail content will be implemented here...",
505
+ "showingDetailsForResult": "Showing details for result #{resultNumber}",
506
+ "details": "Details",
507
+ "dismiss": "Dismiss",
508
+ "searchPlaceholder": "Search for {entityType}…",
509
+ "noResults": "No Results",
510
+ "noResultsMessage": "No {entityType} found matching your search criteria.",
511
+ "noResultsSuggestions": "Try adjusting your search terms, removing filters, or searching for different keywords.",
512
+ "noResultsFound": "No results found for your search.",
513
+ "loadingSearchResults": "Loading search results...",
514
+ "previousPage": "Previous page",
515
+ "page": "Page",
516
+ "nextPage": "Next page",
517
+ "resultsOnPage": "{resultCount} result(s) on this page",
518
+ "searchResultsPagination": "Search results pagination",
519
+ "viewDetails": "View details",
520
+ "closeButton": "Close",
521
+ "selectOrEnterValue": "Select or type value",
522
+ "enterValue": "Enter value",
523
+ "fromNumber": "From",
524
+ "toNumber": "To",
525
+ "fromDate": "From date",
526
+ "toDate": "To date",
527
+ "enterNumber": "Enter number",
528
+ "selectDateAndTime": "Select date",
529
+ "valueControlTo": "to",
530
+ "searchFieldsPlaceholder": "Search fields...",
531
+ "selectSpecificPathPlaceholder": "Select a specific path...",
532
+ "anyPathOption": "Any path",
533
+ "operatorLabel": "Operator",
534
+ "fieldLabel": "Field",
535
+ "valueLabel": "Value",
536
+ "fieldsGroupLabel": "Fields",
537
+ "componentsGroupLabel": "Components",
538
+ "pathsCount": "{count} paths"
539
+ },
540
+ "tabs": {
541
+ "subscriptions": "Subscriptions",
542
+ "products": "Products",
543
+ "workflows": "Workflows",
544
+ "processes": "Processes"
545
+ }
468
546
  }
469
547
  }
@@ -288,7 +288,8 @@
288
288
  "note": "Notitie",
289
289
  "metadata": "Metadata",
290
290
  "customerFullname": "Klant",
291
- "customerShortcode": "Klantafkorting"
291
+ "customerShortcode": "Klantafkorting",
292
+ "actions": "Acties"
292
293
  },
293
294
  "detail": {
294
295
  "title": "Subscriptions",
@@ -20,3 +20,4 @@ export * from './forms';
20
20
  export * from './deprecated';
21
21
  export * from './formFields';
22
22
  export * from './fileUpload';
23
+ export * from './search';