@finos/legend-query-builder 4.14.69 → 4.14.71

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 (100) hide show
  1. package/lib/__lib__/QueryBuilderTesting.d.ts +1 -0
  2. package/lib/__lib__/QueryBuilderTesting.d.ts.map +1 -1
  3. package/lib/__lib__/QueryBuilderTesting.js +1 -0
  4. package/lib/__lib__/QueryBuilderTesting.js.map +1 -1
  5. package/lib/components/QueryBuilderConstantExpressionPanel.d.ts.map +1 -1
  6. package/lib/components/QueryBuilderConstantExpressionPanel.js +2 -1
  7. package/lib/components/QueryBuilderConstantExpressionPanel.js.map +1 -1
  8. package/lib/components/explorer/QueryBuilderExplorerPanel.d.ts +1 -0
  9. package/lib/components/explorer/QueryBuilderExplorerPanel.d.ts.map +1 -1
  10. package/lib/components/explorer/QueryBuilderExplorerPanel.js +87 -52
  11. package/lib/components/explorer/QueryBuilderExplorerPanel.js.map +1 -1
  12. package/lib/components/explorer/QueryBuilderPropertySearchPanel.d.ts +4 -0
  13. package/lib/components/explorer/QueryBuilderPropertySearchPanel.d.ts.map +1 -1
  14. package/lib/components/explorer/QueryBuilderPropertySearchPanel.js +172 -108
  15. package/lib/components/explorer/QueryBuilderPropertySearchPanel.js.map +1 -1
  16. package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.d.ts.map +1 -1
  17. package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.js +2 -1
  18. package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.js.map +1 -1
  19. package/lib/components/fetch-structure/QueryBuilderTDSPanel.d.ts.map +1 -1
  20. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js +29 -18
  21. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js.map +1 -1
  22. package/lib/components/fetch-structure/QueryBuilderTDSWindowPanel.d.ts.map +1 -1
  23. package/lib/components/fetch-structure/QueryBuilderTDSWindowPanel.js +13 -4
  24. package/lib/components/fetch-structure/QueryBuilderTDSWindowPanel.js.map +1 -1
  25. package/lib/components/filter/QueryBuilderFilterPanel.d.ts.map +1 -1
  26. package/lib/components/filter/QueryBuilderFilterPanel.js +4 -3
  27. package/lib/components/filter/QueryBuilderFilterPanel.js.map +1 -1
  28. package/lib/components/result/QueryBuilderResultPanel.d.ts +12 -0
  29. package/lib/components/result/QueryBuilderResultPanel.d.ts.map +1 -1
  30. package/lib/components/result/QueryBuilderResultPanel.js +60 -8
  31. package/lib/components/result/QueryBuilderResultPanel.js.map +1 -1
  32. package/lib/components/shared/QueryBuilderFilterHelper.d.ts.map +1 -1
  33. package/lib/components/shared/QueryBuilderFilterHelper.js +3 -0
  34. package/lib/components/shared/QueryBuilderFilterHelper.js.map +1 -1
  35. package/lib/components/shared/QueryBuilderPropertyInfoTooltip.d.ts +11 -0
  36. package/lib/components/shared/QueryBuilderPropertyInfoTooltip.d.ts.map +1 -1
  37. package/lib/components/shared/QueryBuilderPropertyInfoTooltip.js +6 -3
  38. package/lib/components/shared/QueryBuilderPropertyInfoTooltip.js.map +1 -1
  39. package/lib/graph-manager/QueryBuilderConfig.d.ts +4 -0
  40. package/lib/graph-manager/QueryBuilderConfig.d.ts.map +1 -1
  41. package/lib/graph-manager/QueryBuilderConfig.js +5 -0
  42. package/lib/graph-manager/QueryBuilderConfig.js.map +1 -1
  43. package/lib/index.css +2 -2
  44. package/lib/index.css.map +1 -1
  45. package/lib/package.json +1 -1
  46. package/lib/stores/QueryBuilderConstantsState.d.ts +1 -0
  47. package/lib/stores/QueryBuilderConstantsState.d.ts.map +1 -1
  48. package/lib/stores/QueryBuilderConstantsState.js +6 -1
  49. package/lib/stores/QueryBuilderConstantsState.js.map +1 -1
  50. package/lib/stores/QueryBuilderResultState.d.ts +11 -3
  51. package/lib/stores/QueryBuilderResultState.d.ts.map +1 -1
  52. package/lib/stores/QueryBuilderResultState.js +47 -4
  53. package/lib/stores/QueryBuilderResultState.js.map +1 -1
  54. package/lib/stores/QueryBuilderValueSpecificationBuilderHelper.d.ts +4 -0
  55. package/lib/stores/QueryBuilderValueSpecificationBuilderHelper.d.ts.map +1 -1
  56. package/lib/stores/explorer/QueryBuilderExplorerState.d.ts +3 -1
  57. package/lib/stores/explorer/QueryBuilderExplorerState.d.ts.map +1 -1
  58. package/lib/stores/explorer/QueryBuilderExplorerState.js +63 -8
  59. package/lib/stores/explorer/QueryBuilderExplorerState.js.map +1 -1
  60. package/lib/stores/explorer/QueryBuilderFuzzySearchAdvancedConfigState.d.ts +24 -0
  61. package/lib/stores/explorer/QueryBuilderFuzzySearchAdvancedConfigState.d.ts.map +1 -0
  62. package/lib/stores/explorer/QueryBuilderFuzzySearchAdvancedConfigState.js +39 -0
  63. package/lib/stores/explorer/QueryBuilderFuzzySearchAdvancedConfigState.js.map +1 -0
  64. package/lib/stores/explorer/QueryBuilderPropertySearchState.d.ts +8 -4
  65. package/lib/stores/explorer/QueryBuilderPropertySearchState.d.ts.map +1 -1
  66. package/lib/stores/explorer/QueryBuilderPropertySearchState.js +204 -114
  67. package/lib/stores/explorer/QueryBuilderPropertySearchState.js.map +1 -1
  68. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.d.ts.map +1 -1
  69. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.js +8 -1
  70. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.js.map +1 -1
  71. package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionValueSpecificationBuilder.d.ts.map +1 -1
  72. package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionValueSpecificationBuilder.js +12 -1
  73. package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionValueSpecificationBuilder.js.map +1 -1
  74. package/lib/stores/filter/QueryBuilderFilterState.d.ts +8 -1
  75. package/lib/stores/filter/QueryBuilderFilterState.d.ts.map +1 -1
  76. package/lib/stores/filter/QueryBuilderFilterState.js +27 -10
  77. package/lib/stores/filter/QueryBuilderFilterState.js.map +1 -1
  78. package/package.json +8 -8
  79. package/src/__lib__/QueryBuilderTesting.ts +1 -0
  80. package/src/components/QueryBuilderConstantExpressionPanel.tsx +2 -1
  81. package/src/components/explorer/QueryBuilderExplorerPanel.tsx +220 -114
  82. package/src/components/explorer/QueryBuilderPropertySearchPanel.tsx +618 -388
  83. package/src/components/fetch-structure/QueryBuilderPostFilterPanel.tsx +5 -2
  84. package/src/components/fetch-structure/QueryBuilderTDSPanel.tsx +78 -44
  85. package/src/components/fetch-structure/QueryBuilderTDSWindowPanel.tsx +63 -10
  86. package/src/components/filter/QueryBuilderFilterPanel.tsx +4 -2
  87. package/src/components/result/QueryBuilderResultPanel.tsx +207 -20
  88. package/src/components/shared/QueryBuilderFilterHelper.ts +8 -0
  89. package/src/components/shared/QueryBuilderPropertyInfoTooltip.tsx +13 -3
  90. package/src/graph-manager/QueryBuilderConfig.ts +6 -0
  91. package/src/stores/QueryBuilderConstantsState.ts +16 -1
  92. package/src/stores/QueryBuilderResultState.ts +64 -10
  93. package/src/stores/QueryBuilderValueSpecificationBuilderHelper.ts +5 -0
  94. package/src/stores/explorer/QueryBuilderExplorerState.ts +92 -8
  95. package/src/stores/explorer/QueryBuilderFuzzySearchAdvancedConfigState.ts +46 -0
  96. package/src/stores/explorer/QueryBuilderPropertySearchState.ts +280 -142
  97. package/src/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.ts +8 -1
  98. package/src/stores/fetch-structure/tds/projection/QueryBuilderProjectionValueSpecificationBuilder.ts +15 -2
  99. package/src/stores/filter/QueryBuilderFilterState.ts +34 -11
  100. package/tsconfig.json +1 -0
@@ -14,7 +14,6 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import { useMemo, useRef, useState } from 'react';
18
17
  import {
19
18
  clsx,
20
19
  CheckSquareIcon,
@@ -25,21 +24,29 @@ import {
25
24
  ResizablePanel,
26
25
  ResizablePanelSplitterLine,
27
26
  InfoCircleIcon,
28
- TimesIcon,
29
- SearchIcon,
30
27
  useDragPreviewLayer,
31
28
  PanelLoadingIndicator,
32
29
  BlankPanelContent,
33
- CogIcon,
30
+ ChevronDownIcon,
31
+ ChevronRightIcon,
32
+ ShareBoxIcon,
33
+ Tooltip,
34
+ BaseRadioGroup,
35
+ ClickAwayListener,
34
36
  } from '@finos/legend-art';
35
37
  import {
38
+ CORE_PURE_PATH,
36
39
  Class,
40
+ ELEMENT_PATH_DELIMITER,
37
41
  Enumeration,
42
+ PROPERTY_ACCESSOR,
43
+ PURE_DOC_TAG,
44
+ TYPE_CAST_TOKEN,
38
45
  getAllClassProperties,
39
46
  getAllOwnClassProperties,
40
47
  } from '@finos/legend-graph';
41
48
  import {
42
- debounce,
49
+ ADVANCED_FUZZY_SEARCH_MODE,
43
50
  guaranteeNonNullable,
44
51
  prettyCONSTName,
45
52
  } from '@finos/legend-shared';
@@ -56,59 +63,171 @@ import {
56
63
  } from '../../stores/explorer/QueryBuilderExplorerState.js';
57
64
  import type { QueryBuilderState } from '../../stores/QueryBuilderState.js';
58
65
  import {
66
+ QUERY_BUILDER_EXPLORER_SEARCH_INPUT_NAME,
59
67
  QueryBuilderSubclassInfoTooltip,
60
68
  renderPropertyTypeIcon,
61
69
  } from './QueryBuilderExplorerPanel.js';
62
70
  import { QueryBuilderPropertyInfoTooltip } from '../shared/QueryBuilderPropertyInfoTooltip.js';
63
71
  import { QUERY_BUILDER_TEST_ID } from '../../__lib__/QueryBuilderTesting.js';
64
- import { FuzzySearchAdvancedConfigMenu } from '@finos/legend-lego/application';
72
+ import { DocumentationLink } from '@finos/legend-lego/application';
73
+ import { LEGEND_APPLICATION_DOCUMENTATION_KEY } from '@finos/legend-application';
65
74
 
66
- const prettyPropertyNameFromNodeId = (name: string): string => {
67
- let propNameArray = name.split('.');
68
- propNameArray = propNameArray.map(prettyCONSTName);
69
- let propName = '';
70
- propNameArray.forEach((p) => {
71
- propName = `${propName + p}/`;
72
- });
73
- propName = propName.slice(0, -1);
74
- return propName;
75
- };
75
+ export const prettyPropertyNameFromNodeId = (
76
+ name: string,
77
+ spaceBetweenSlash?: boolean,
78
+ ): string =>
79
+ name
80
+ .split(TYPE_CAST_TOKEN)
81
+ .map((p) =>
82
+ p.replace(new RegExp(String.raw`.*${ELEMENT_PATH_DELIMITER}`), ''),
83
+ )
84
+ .filter((p) => p !== '')
85
+ .map((p) =>
86
+ p
87
+ .split(PROPERTY_ACCESSOR)
88
+ .map(prettyCONSTName)
89
+ .join(spaceBetweenSlash ? ' / ' : '/'),
90
+ )
91
+ .join(TYPE_CAST_TOKEN);
76
92
 
77
- const prettyPropertyNameForSubType = (name: string): string => {
78
- let propNameArray = name.split('@');
93
+ export const prettyPropertyNameForSubType = (
94
+ name: string,
95
+ spaceBetweenSlash?: boolean,
96
+ ): string => {
97
+ let propNameArray = name.split(TYPE_CAST_TOKEN);
79
98
  propNameArray = propNameArray
80
- .map((p) => p.replace(/.*::/, ''))
81
- .filter((p) => p !== '')
82
- .map((p) => prettyCONSTName(p));
83
- let propName = '';
84
- propNameArray.slice(0, -1).forEach((p) => {
85
- propName = `${propName}(@${p})/`;
86
- });
99
+ .map((p) =>
100
+ p.replace(new RegExp(String.raw`.*${ELEMENT_PATH_DELIMITER}`), ''),
101
+ )
102
+ .filter((p) => p !== '');
103
+ let propName = propNameArray
104
+ .slice(0, -1)
105
+ .map(
106
+ (p) =>
107
+ `(${TYPE_CAST_TOKEN}${p
108
+ .split(PROPERTY_ACCESSOR)
109
+ .map((sp) => prettyCONSTName(sp))
110
+ .join(spaceBetweenSlash ? ' / ' : '/')})`,
111
+ )
112
+ .join(spaceBetweenSlash ? ' / ' : '/');
113
+ propName += spaceBetweenSlash ? ' / ' : '/';
87
114
  propNameArray = guaranteeNonNullable(
88
115
  propNameArray[propNameArray.length - 1],
89
- ).split('.');
116
+ ).split(PROPERTY_ACCESSOR);
90
117
  propNameArray = propNameArray.map((p) => prettyCONSTName(p));
91
- propName = `${propName}(@${propNameArray[0]})/`;
118
+ propName = `${propName}(${TYPE_CAST_TOKEN}${propNameArray[0]})${spaceBetweenSlash ? ' / ' : '/'}`;
92
119
  propNameArray.slice(1).forEach((p) => {
93
- propName = `${propName + p}/`;
120
+ propName = `${propName + p}${spaceBetweenSlash ? ' / ' : '/'}`;
94
121
  });
95
- propName = propName.slice(0, -1);
122
+ propName = propName.slice(0, spaceBetweenSlash ? -3 : -1);
96
123
  return propName;
97
124
  };
98
125
 
99
- const prettyPropertyNameForSubTypeClass = (name: string): string => {
100
- let propNameArray = name.split('@');
101
- propNameArray = propNameArray
102
- .map((p) => p.replace(/.*::/, ''))
103
- .filter((p) => p !== '')
104
- .map((p) => prettyCONSTName(p));
105
- let propName = '';
106
- propNameArray.forEach((p) => {
107
- propName = `${propName}@${p}`;
126
+ export const formatTextWithHighlightedMatches = (
127
+ displayText: string,
128
+ searchText: string,
129
+ className: string,
130
+ id: string,
131
+ ): React.ReactNode => {
132
+ // Get ranges to highlight
133
+ const highlightRanges: [number, number][] = [];
134
+ searchText
135
+ .split(/\/| /)
136
+ .filter((word) => word.trim().length > 0)
137
+ .forEach((word) => {
138
+ const regex = new RegExp(word, 'gi');
139
+ let match;
140
+ while ((match = regex.exec(displayText))) {
141
+ highlightRanges.push([match.index, match.index + word.length]);
142
+ }
143
+ });
144
+
145
+ // Combine any overlapping highlight ranges
146
+ const combinedHighlightRanges: [number, number][] = [];
147
+ highlightRanges.sort((a, b) => a[0] - b[0]);
148
+ highlightRanges.forEach((range) => {
149
+ if (!combinedHighlightRanges.length) {
150
+ combinedHighlightRanges.push(range);
151
+ } else {
152
+ const lastRange =
153
+ combinedHighlightRanges[combinedHighlightRanges.length - 1];
154
+ if (lastRange !== undefined && range[0] <= lastRange[1]) {
155
+ lastRange[1] = Math.max(lastRange[1], range[1]);
156
+ } else {
157
+ combinedHighlightRanges.push(range);
158
+ }
159
+ }
108
160
  });
109
- return propName;
161
+
162
+ // Return the property name if there are no highlight ranges
163
+ if (!combinedHighlightRanges.length) {
164
+ return <span>{displayText}</span>;
165
+ }
166
+
167
+ // Create formatted node
168
+ const formattedNode: React.ReactNode[] = [];
169
+ if (combinedHighlightRanges[0]![0] > 0) {
170
+ formattedNode.push(
171
+ <span
172
+ key={`${id}-0-${displayText.substring(0, combinedHighlightRanges[0]![0])}`}
173
+ >
174
+ {displayText.substring(0, combinedHighlightRanges[0]![0])}
175
+ </span>,
176
+ );
177
+ }
178
+
179
+ combinedHighlightRanges.forEach((range, index) => {
180
+ formattedNode.push(
181
+ <span
182
+ key={`${id}-${index * 2}-${displayText.substring(range[0], range[1])}`}
183
+ className={`${className}--highlight`}
184
+ >
185
+ {displayText.substring(range[0], range[1])}
186
+ </span>,
187
+ );
188
+ if (
189
+ index < combinedHighlightRanges.length - 1 &&
190
+ range[1] < displayText.length
191
+ ) {
192
+ formattedNode.push(
193
+ <span
194
+ key={`${id}-${index * 2 + 1}--${displayText.substring(
195
+ range[1],
196
+ combinedHighlightRanges[index + 1]![0],
197
+ )}`}
198
+ >
199
+ {displayText.substring(
200
+ range[1],
201
+ combinedHighlightRanges[index + 1]![0],
202
+ )}
203
+ </span>,
204
+ );
205
+ }
206
+ });
207
+ if (
208
+ combinedHighlightRanges[combinedHighlightRanges.length - 1]![1] <
209
+ displayText.length
210
+ ) {
211
+ formattedNode.push(
212
+ <span
213
+ key={`${id}-${combinedHighlightRanges.length * 2 + 2}-${displayText.substring(
214
+ combinedHighlightRanges[combinedHighlightRanges.length - 1]![1],
215
+ )}`}
216
+ >
217
+ {displayText.substring(
218
+ combinedHighlightRanges[combinedHighlightRanges.length - 1]![1],
219
+ )}
220
+ </span>,
221
+ );
222
+ }
223
+ return formattedNode;
110
224
  };
111
225
 
226
+ const QUERY_BUILDER_PROPERTY_SEARCH_LABEL_TEXT_CLASS =
227
+ 'query-builder-property-search-panel__node__label';
228
+ const QUERY_BUILDER_PROPERTY_SEARCH_DOC_TEXT_CLASS =
229
+ 'query-builder-property-search-panel__node__doc';
230
+
112
231
  const QueryBuilderTreeNodeViewer = observer(
113
232
  (props: {
114
233
  node: QueryBuilderExplorerTreeNodeData;
@@ -119,8 +238,9 @@ const QueryBuilderTreeNodeViewer = observer(
119
238
  }) => {
120
239
  const { node, queryBuilderState, explorerState, level, stepPaddingInRem } =
121
240
  props;
122
- const [isExpandable, setIsExpandable] = useState(false);
241
+ const isExpandable = Boolean(node.childrenIds.length);
123
242
  const propertySearchState = explorerState.propertySearchState;
243
+
124
244
  const [, dragConnector, dragPreviewConnector] = useDrag<{
125
245
  node?: QueryBuilderExplorerTreePropertyNodeData;
126
246
  }>(
@@ -143,6 +263,7 @@ const QueryBuilderTreeNodeViewer = observer(
143
263
  }),
144
264
  [node],
145
265
  );
266
+
146
267
  useDragPreviewLayer(dragPreviewConnector);
147
268
 
148
269
  const getChildrenNodes = (): QueryBuilderExplorerTreeNodeData[] => {
@@ -177,20 +298,55 @@ const QueryBuilderTreeNodeViewer = observer(
177
298
  }
178
299
  return childNodes;
179
300
  };
301
+
302
+ const handleHighlightNode = (): void => {
303
+ explorerState.propertySearchState.setIsSearchPanelOpen(false);
304
+ explorerState.propertySearchState.resetSearch();
305
+ explorerState.highlightTreeNode(node.id);
306
+ };
307
+
180
308
  const parentNode = propertySearchState.indexedExplorerTreeNodes.find(
181
309
  (pn) =>
182
310
  node instanceof QueryBuilderExplorerTreePropertyNodeData &&
183
311
  node.parentId === pn.id,
184
312
  );
313
+
185
314
  const propertyName =
186
315
  parentNode instanceof QueryBuilderExplorerTreeSubTypeNodeData
187
- ? prettyPropertyNameForSubType(node.id)
188
- : node instanceof QueryBuilderExplorerTreeSubTypeNodeData
189
- ? prettyPropertyNameForSubTypeClass(node.id)
190
- : prettyPropertyNameFromNodeId(node.id);
316
+ ? prettyPropertyNameForSubType(node.id, true)
317
+ : prettyPropertyNameFromNodeId(node.id, true);
318
+
319
+ const nodeExpandIcon = isExpandable ? (
320
+ node.isOpen ? (
321
+ <ChevronDownIcon />
322
+ ) : (
323
+ <ChevronRightIcon />
324
+ )
325
+ ) : (
326
+ <div />
327
+ );
328
+
329
+ const docText: string | null =
330
+ node instanceof QueryBuilderExplorerTreePropertyNodeData
331
+ ? (node.property.taggedValues.find(
332
+ (taggedValue) =>
333
+ taggedValue.tag.ownerReference.value.path ===
334
+ CORE_PURE_PATH.PROFILE_DOC &&
335
+ taggedValue.tag.value.value === PURE_DOC_TAG,
336
+ )?.value ?? null)
337
+ : null;
338
+ const formattedDocText =
339
+ docText !== null
340
+ ? formatTextWithHighlightedMatches(
341
+ docText,
342
+ propertySearchState.searchText,
343
+ QUERY_BUILDER_PROPERTY_SEARCH_DOC_TEXT_CLASS,
344
+ `${node.id}_doc`,
345
+ )
346
+ : null;
191
347
 
192
348
  return (
193
- <div>
349
+ <>
194
350
  <div
195
351
  className="tree-view__node__container query-builder-property-search-panel__node__container"
196
352
  ref={dragConnector}
@@ -198,7 +354,7 @@ const QueryBuilderTreeNodeViewer = observer(
198
354
  paddingLeft: `${(level - 1) * stepPaddingInRem + 0.5}rem`,
199
355
  display: 'flex',
200
356
  }}
201
- onClick={(): void => setIsExpandable(!isExpandable)}
357
+ onClick={(): void => node.setIsOpen(!node.isOpen)}
202
358
  // Temporarily hide away the panel when we drag-and-drop the properties
203
359
  onDrag={(): void => propertySearchState.setIsSearchPanelHidden(true)}
204
360
  onDragEnd={(): void =>
@@ -206,52 +362,89 @@ const QueryBuilderTreeNodeViewer = observer(
206
362
  }
207
363
  >
208
364
  <div className="tree-view__node__icon query-builder-property-search-panel__node__icon">
365
+ <div className="query-builder-property-search-panel__expand-icon">
366
+ {nodeExpandIcon}
367
+ </div>
209
368
  <div className="query-builder-property-search-panel__type-icon">
210
369
  {renderPropertyTypeIcon(node.type)}
211
370
  </div>
212
371
  </div>
213
- <div className="tree-view__node__label query-builder-property-search-panel__node__label query-builder-property-search-panel__node__label--with-action">
214
- {propertyName}
372
+ <div className="query-builder-property-search-panel__node__content">
373
+ <div className="tree-view__node__label query-builder-property-search-panel__node__label">
374
+ {formatTextWithHighlightedMatches(
375
+ propertyName,
376
+ propertySearchState.searchText,
377
+ QUERY_BUILDER_PROPERTY_SEARCH_LABEL_TEXT_CLASS,
378
+ node.id,
379
+ )}
380
+ </div>
381
+ <div className="tree-view__node__label query-builder-property-search-panel__node__doc">
382
+ {formattedDocText}
383
+ </div>
215
384
  </div>
216
385
  <div className="query-builder-property-search-panel__node__actions">
217
386
  {node instanceof QueryBuilderExplorerTreePropertyNodeData && (
218
- <QueryBuilderPropertyInfoTooltip
219
- title={propertyName}
220
- property={node.property}
221
- path={node.id}
222
- isMapped={node.mappingData.mapped}
223
- >
224
- <div className="query-builder-property-search-panel__node__action query-builder-property-search-panel__node__info">
225
- <InfoCircleIcon />
226
- </div>
227
- </QueryBuilderPropertyInfoTooltip>
387
+ <>
388
+ <QueryBuilderPropertyInfoTooltip
389
+ title={propertyName}
390
+ property={node.property}
391
+ path={node.id}
392
+ isMapped={node.mappingData.mapped}
393
+ >
394
+ <div
395
+ title="Property info"
396
+ className="query-builder-property-search-panel__node__action query-builder-property-search-panel__node__info"
397
+ >
398
+ <InfoCircleIcon />
399
+ </div>
400
+ </QueryBuilderPropertyInfoTooltip>
401
+ <button
402
+ onClick={handleHighlightNode}
403
+ title="Show in tree"
404
+ className="query-builder-property-search-panel__node__action query-builder-property-search-panel__node__highlight"
405
+ >
406
+ <ShareBoxIcon />
407
+ </button>
408
+ </>
228
409
  )}
229
410
  {node instanceof QueryBuilderExplorerTreeSubTypeNodeData && (
230
- <QueryBuilderSubclassInfoTooltip
231
- subclass={node.subclass}
232
- path={node.id}
233
- isMapped={node.mappingData.mapped}
234
- multiplicity={node.multiplicity}
235
- >
236
- <div className="query-builder-property-search-panel__node__action query-builder-property-search-panel__node__info">
237
- <InfoCircleIcon />
238
- </div>
239
- </QueryBuilderSubclassInfoTooltip>
411
+ <>
412
+ <QueryBuilderSubclassInfoTooltip
413
+ subclass={node.subclass}
414
+ path={node.id}
415
+ isMapped={node.mappingData.mapped}
416
+ multiplicity={node.multiplicity}
417
+ >
418
+ <div
419
+ title="Property info"
420
+ className="query-builder-property-search-panel__node__action query-builder-property-search-panel__node__info"
421
+ >
422
+ <InfoCircleIcon />
423
+ </div>
424
+ </QueryBuilderSubclassInfoTooltip>
425
+ <button
426
+ onClick={handleHighlightNode}
427
+ title="Show in tree"
428
+ className="query-builder-property-search-panel__node__action query-builder-property-search-panel__node__highlight"
429
+ >
430
+ <ShareBoxIcon />
431
+ </button>
432
+ </>
240
433
  )}
241
434
  </div>
242
435
  </div>
243
- {isExpandable &&
436
+ {node.isOpen &&
244
437
  getChildrenNodes().map((childNode) => (
245
438
  <QueryBuilderTreeNodeViewer
246
- key={childNode.id}
439
+ key={`${node.id}>${childNode.id}`}
247
440
  node={childNode}
248
441
  queryBuilderState={queryBuilderState}
249
- level={1}
442
+ level={level + 1}
250
443
  stepPaddingInRem={2}
251
444
  explorerState={queryBuilderState.explorerState}
252
445
  />
253
446
  ))}
254
- </div>
447
+ </>
255
448
  );
256
449
  },
257
450
  );
@@ -260,41 +453,54 @@ export const QueryBuilderPropertySearchPanel = observer(
260
453
  (props: {
261
454
  queryBuilderState: QueryBuilderState;
262
455
  triggerElement: HTMLElement | null;
456
+ clearSearch: () => void;
263
457
  }) => {
264
- const { queryBuilderState, triggerElement } = props;
458
+ const { queryBuilderState, triggerElement, clearSearch } = props;
265
459
  const explorerState = queryBuilderState.explorerState;
266
460
  const propertySearchState = explorerState.propertySearchState;
267
- const searchInputRef = useRef<HTMLInputElement>(null);
268
- const searchConfigTriggerRef = useRef<HTMLButtonElement>(null);
269
461
 
270
- // search text
271
- const debouncedSearchProperty = useMemo(
272
- () => debounce(() => propertySearchState.search(), 100),
273
- [propertySearchState],
274
- );
275
- const onSearchPropertyTextChange: React.ChangeEventHandler<
276
- HTMLInputElement
277
- > = (event) => {
278
- propertySearchState.setSearchText(event.target.value);
279
- debouncedSearchProperty();
462
+ const handleClose = (event: MouseEvent | TouchEvent): void => {
463
+ if (
464
+ event.target instanceof HTMLInputElement &&
465
+ event.target.name === QUERY_BUILDER_EXPLORER_SEARCH_INPUT_NAME
466
+ ) {
467
+ return;
468
+ }
469
+ clearSearch();
470
+ propertySearchState.setIsSearchPanelOpen(false);
280
471
  };
281
472
 
282
- // search actions
283
- const clearSearch = (): void => {
284
- propertySearchState.resetSearch();
473
+ const handleSearchMode: React.ChangeEventHandler<HTMLInputElement> = (
474
+ event,
475
+ ): void => {
476
+ const searchMode = event.target.value as ADVANCED_FUZZY_SEARCH_MODE;
477
+ propertySearchState.searchConfigurationState.setCurrentMode(searchMode);
285
478
  };
286
- const toggleSearchConfigMenu = (): void =>
287
- propertySearchState.setShowSearchConfigurationMenu(
288
- !propertySearchState.showSearchConfigurationMenu,
479
+
480
+ const handleToggleIncludeSubTypes = () => {
481
+ (async () => {
482
+ propertySearchState.searchConfigurationState.setIncludeSubTypes(
483
+ !propertySearchState.searchConfigurationState.includeSubTypes,
484
+ );
485
+ await propertySearchState.initialize();
486
+ await propertySearchState.search();
487
+ })().catch(
488
+ propertySearchState.queryBuilderState.applicationStore
489
+ .alertUnhandledError,
289
490
  );
290
- const closeSearchConfigMenu = (): void =>
291
- propertySearchState.setShowSearchConfigurationMenu(false);
491
+ };
292
492
 
293
- // life-cycle
294
- const handleEnter = (): void => searchInputRef.current?.focus();
295
- const handleClose = (): void => {
296
- clearSearch();
297
- propertySearchState.setIsSearchPanelOpen(false);
493
+ const handleToggleIncludeDocumentation = () => {
494
+ (async () => {
495
+ propertySearchState.searchConfigurationState.setIncludeDocumentation(
496
+ !propertySearchState.searchConfigurationState.includeDocumentation,
497
+ );
498
+ await propertySearchState.initialize();
499
+ await propertySearchState.search();
500
+ })().catch(
501
+ propertySearchState.queryBuilderState.applicationStore
502
+ .alertUnhandledError,
503
+ );
298
504
  };
299
505
 
300
506
  return (
@@ -311,319 +517,343 @@ export const QueryBuilderPropertySearchPanel = observer(
311
517
  })}
312
518
  anchorEl={triggerElement}
313
519
  onClose={handleClose}
520
+ hideBackdrop={true}
521
+ disableAutoFocus={true}
522
+ disableEnforceFocus={true}
314
523
  anchorOrigin={{
315
- vertical: 'bottom',
524
+ vertical: 40,
316
525
  horizontal: 'left',
317
526
  }}
318
527
  transformOrigin={{
319
528
  vertical: 'top',
320
529
  horizontal: 'center',
321
530
  }}
322
- TransitionProps={{ onEnter: handleEnter }}
323
531
  >
324
- <div
325
- data-testid={
326
- QUERY_BUILDER_TEST_ID.QUERY_BUILDER_PROPERTY_SEARCH_PANEL
327
- }
328
- className="query-builder-property-search-panel"
329
- >
330
- <div className="query-builder-property-search-panel__header">
331
- <div className="query-builder-property-search-panel__input__container">
332
- <input
333
- ref={searchInputRef}
334
- className={clsx(
335
- 'query-builder-property-search-panel__input input--dark',
336
- {
337
- 'query-builder-property-search-panel__input--searching':
338
- propertySearchState.searchText,
339
- },
340
- )}
341
- spellCheck={false}
342
- onChange={onSearchPropertyTextChange}
343
- value={propertySearchState.searchText}
344
- placeholder="Search for a property by name or documentation"
345
- />
346
- {propertySearchState.searchText && (
347
- <div className="query-builder-property-search-panel__input__search__count">
348
- {propertySearchState.filteredSearchResults.length +
349
- (propertySearchState.isOverSearchLimit &&
350
- propertySearchState.filteredSearchResults.length !== 0
351
- ? '+'
352
- : '')}
353
- </div>
354
- )}
355
- <button
356
- ref={searchConfigTriggerRef}
357
- className={clsx(
358
- 'query-builder-property-search-panel__input__search__config__trigger',
359
- {
360
- 'query-builder-property-search-panel__input__search__config__trigger--toggled':
361
- propertySearchState.showSearchConfigurationMenu,
362
- 'query-builder-property-search-panel__input__search__config__trigger--active':
363
- propertySearchState.searchConfigurationState
364
- .isAdvancedSearchActive,
365
- },
366
- )}
367
- tabIndex={-1}
368
- onClick={toggleSearchConfigMenu}
369
- title="Click to toggle search config menu"
370
- >
371
- <CogIcon />
372
- </button>
373
- <BasePopover
374
- open={Boolean(propertySearchState.showSearchConfigurationMenu)}
375
- TransitionProps={{
376
- onEnter: handleEnter,
377
- }}
378
- anchorEl={searchConfigTriggerRef.current}
379
- onClose={closeSearchConfigMenu}
380
- anchorOrigin={{
381
- vertical: 'bottom',
382
- horizontal: 'center',
383
- }}
384
- transformOrigin={{
385
- vertical: 'top',
386
- horizontal: 'center',
387
- }}
388
- >
389
- <FuzzySearchAdvancedConfigMenu
390
- configState={propertySearchState.searchConfigurationState}
391
- />
392
- </BasePopover>
393
- {!propertySearchState.searchText ? (
394
- <>
395
- <div className="query-builder-property-search-panel__input__search__icon">
396
- <SearchIcon />
397
- </div>
398
- </>
399
- ) : (
400
- <button
401
- className="query-builder-property-search-panel__input__clear-btn"
402
- tabIndex={-1}
403
- onClick={clearSearch}
404
- title="Clear"
405
- >
406
- <TimesIcon />
407
- </button>
408
- )}
409
- </div>
410
- <button
411
- className="btn btn--dark query-builder-property-search-panel__close-btn"
412
- tabIndex={-1}
413
- title="Close"
414
- onClick={handleClose}
415
- >
416
- <TimesIcon />
417
- </button>
418
- </div>
419
- <div className="query-builder-property-search-panel__content">
420
- <ResizablePanelGroup orientation="vertical">
421
- <ResizablePanel size={150}>
422
- <div className="query-builder-property-search-panel__config">
423
- <div className="query-builder-property-search-panel__form__section">
424
- <div className="query-builder-property-search-panel__form__section__header__label">
425
- By type
532
+ <ClickAwayListener onClickAway={handleClose}>
533
+ <div
534
+ data-testid={
535
+ QUERY_BUILDER_TEST_ID.QUERY_BUILDER_PROPERTY_SEARCH_PANEL
536
+ }
537
+ className="query-builder-property-search-panel"
538
+ >
539
+ <div className="query-builder-property-search-panel__content">
540
+ <ResizablePanelGroup orientation="vertical">
541
+ <ResizablePanel size={175}>
542
+ <div className="query-builder-property-search-panel__config">
543
+ <div className="query-builder-property-search-panel__form__section">
544
+ <div className="query-builder-property-search-panel__form__section__header__label">
545
+ Search Mode
546
+ <DocumentationLink
547
+ documentationKey={
548
+ LEGEND_APPLICATION_DOCUMENTATION_KEY.QUESTION_HOW_TO_USE_ADVANCED_SEARCH_SYNTAX
549
+ }
550
+ />
551
+ </div>
552
+ <div className="query-builder-property-search-panel__filter__element">
553
+ <BaseRadioGroup
554
+ className="query-builder-property-search-panel__search-mode__options"
555
+ value={
556
+ propertySearchState.searchConfigurationState
557
+ .currentMode
558
+ }
559
+ onChange={handleSearchMode}
560
+ row={false}
561
+ options={[
562
+ ADVANCED_FUZZY_SEARCH_MODE.STANDARD,
563
+ ADVANCED_FUZZY_SEARCH_MODE.INCLUDE,
564
+ ADVANCED_FUZZY_SEARCH_MODE.EXACT,
565
+ ADVANCED_FUZZY_SEARCH_MODE.INVERSE,
566
+ ]}
567
+ size={1}
568
+ />
569
+ </div>
426
570
  </div>
427
- <div className="query-builder-property-search-panel__filter__element">
428
- <button
429
- className={clsx(
430
- 'query-builder-property-search-panel__form__section__toggler__btn',
431
- {
432
- 'query-builder-property-search-panel__form__section__toggler__btn--toggled':
433
- propertySearchState.typeFilters.includes(
434
- QUERY_BUILDER_PROPERTY_SEARCH_TYPE.CLASS,
435
- ),
436
- },
437
- )}
438
- onClick={(): void => {
439
- propertySearchState.toggleFilterForType(
440
- QUERY_BUILDER_PROPERTY_SEARCH_TYPE.CLASS,
441
- );
442
- }}
443
- tabIndex={-1}
444
- >
445
- {propertySearchState.typeFilters.includes(
446
- QUERY_BUILDER_PROPERTY_SEARCH_TYPE.CLASS,
447
- ) ? (
448
- <CheckSquareIcon />
449
- ) : (
450
- <SquareIcon />
451
- )}
452
- </button>
453
- <div className="query-builder-property-search-panel__form__section__toggler__prompt">
454
- Class
571
+ <div className="query-builder-property-search-panel__form__section">
572
+ <div className="query-builder-property-search-panel__form__section__header__label">
573
+ Documentation
574
+ <Tooltip
575
+ TransitionProps={{
576
+ timeout: 0,
577
+ }}
578
+ title={
579
+ <div>
580
+ Include &quot;doc&quot; type tagged values in
581
+ search results
582
+ </div>
583
+ }
584
+ >
585
+ <div className="query-builder-property-search-panel__tagged-values__tooltip">
586
+ <InfoCircleIcon />
587
+ </div>
588
+ </Tooltip>
589
+ </div>
590
+ <div className="query-builder-property-search-panel__filter__element">
591
+ <button
592
+ className={clsx(
593
+ 'query-builder-property-search-panel__form__section__toggler__btn',
594
+ {
595
+ 'query-builder-property-search-panel__form__section__toggler__btn--toggled':
596
+ propertySearchState.searchConfigurationState
597
+ .includeDocumentation,
598
+ },
599
+ )}
600
+ onClick={handleToggleIncludeDocumentation}
601
+ tabIndex={-1}
602
+ >
603
+ {propertySearchState.searchConfigurationState
604
+ .includeDocumentation ? (
605
+ <CheckSquareIcon />
606
+ ) : (
607
+ <SquareIcon />
608
+ )}
609
+ </button>
610
+ <div className="query-builder-property-search-panel__form__section__toggler__prompt">
611
+ Include
612
+ </div>
455
613
  </div>
456
614
  </div>
457
- <div className="query-builder-property-search-panel__filter__element">
458
- <button
459
- className={clsx(
460
- 'query-builder-property-search-panel__form__section__toggler__btn',
461
- {
462
- 'query-builder-property-search-panel__form__section__toggler__btn--toggled':
463
- propertySearchState.typeFilters.includes(
464
- QUERY_BUILDER_PROPERTY_SEARCH_TYPE.STRING,
465
- ),
466
- },
467
- )}
468
- onClick={(): void => {
469
- propertySearchState.toggleFilterForType(
470
- QUERY_BUILDER_PROPERTY_SEARCH_TYPE.STRING,
471
- );
472
- }}
473
- tabIndex={-1}
474
- >
475
- {propertySearchState.typeFilters.includes(
476
- QUERY_BUILDER_PROPERTY_SEARCH_TYPE.STRING,
477
- ) ? (
478
- <CheckSquareIcon />
479
- ) : (
480
- <SquareIcon />
481
- )}
482
- </button>
483
- <div className="query-builder-property-search-panel__form__section__toggler__prompt">
484
- String
615
+ <div className="query-builder-property-search-panel__form__section">
616
+ <div className="query-builder-property-search-panel__form__section__header__label">
617
+ Sub-types
618
+ </div>
619
+ <div className="query-builder-property-search-panel__filter__element">
620
+ <button
621
+ className={clsx(
622
+ 'query-builder-property-search-panel__form__section__toggler__btn',
623
+ {
624
+ 'query-builder-property-search-panel__form__section__toggler__btn--toggled':
625
+ propertySearchState.searchConfigurationState
626
+ .includeSubTypes,
627
+ },
628
+ )}
629
+ onClick={handleToggleIncludeSubTypes}
630
+ tabIndex={-1}
631
+ >
632
+ {propertySearchState.searchConfigurationState
633
+ .includeSubTypes ? (
634
+ <CheckSquareIcon />
635
+ ) : (
636
+ <SquareIcon />
637
+ )}
638
+ </button>
639
+ <div className="query-builder-property-search-panel__form__section__toggler__prompt">
640
+ Include
641
+ </div>
485
642
  </div>
486
643
  </div>
487
- <div className="query-builder-property-search-panel__filter__element">
488
- <button
489
- className={clsx(
490
- 'query-builder-property-search-panel__form__section__toggler__btn',
491
- {
492
- 'query-builder-property-search-panel__form__section__toggler__btn--toggled':
493
- propertySearchState.typeFilters.includes(
494
- QUERY_BUILDER_PROPERTY_SEARCH_TYPE.BOOLEAN,
495
- ),
496
- },
497
- )}
498
- onClick={(): void => {
499
- propertySearchState.toggleFilterForType(
644
+ <div className="query-builder-property-search-panel__form__section">
645
+ <div className="query-builder-property-search-panel__form__section__header__label">
646
+ By type
647
+ </div>
648
+ <div className="query-builder-property-search-panel__filter__element">
649
+ <button
650
+ className={clsx(
651
+ 'query-builder-property-search-panel__form__section__toggler__btn',
652
+ {
653
+ 'query-builder-property-search-panel__form__section__toggler__btn--toggled':
654
+ propertySearchState.typeFilters.includes(
655
+ QUERY_BUILDER_PROPERTY_SEARCH_TYPE.CLASS,
656
+ ),
657
+ },
658
+ )}
659
+ onClick={(): void => {
660
+ propertySearchState.toggleFilterForType(
661
+ QUERY_BUILDER_PROPERTY_SEARCH_TYPE.CLASS,
662
+ );
663
+ }}
664
+ tabIndex={-1}
665
+ >
666
+ {propertySearchState.typeFilters.includes(
667
+ QUERY_BUILDER_PROPERTY_SEARCH_TYPE.CLASS,
668
+ ) ? (
669
+ <CheckSquareIcon />
670
+ ) : (
671
+ <SquareIcon />
672
+ )}
673
+ </button>
674
+ <div className="query-builder-property-search-panel__form__section__toggler__prompt">
675
+ Class
676
+ </div>
677
+ </div>
678
+ <div className="query-builder-property-search-panel__filter__element">
679
+ <button
680
+ className={clsx(
681
+ 'query-builder-property-search-panel__form__section__toggler__btn',
682
+ {
683
+ 'query-builder-property-search-panel__form__section__toggler__btn--toggled':
684
+ propertySearchState.typeFilters.includes(
685
+ QUERY_BUILDER_PROPERTY_SEARCH_TYPE.STRING,
686
+ ),
687
+ },
688
+ )}
689
+ onClick={(): void => {
690
+ propertySearchState.toggleFilterForType(
691
+ QUERY_BUILDER_PROPERTY_SEARCH_TYPE.STRING,
692
+ );
693
+ }}
694
+ tabIndex={-1}
695
+ >
696
+ {propertySearchState.typeFilters.includes(
697
+ QUERY_BUILDER_PROPERTY_SEARCH_TYPE.STRING,
698
+ ) ? (
699
+ <CheckSquareIcon />
700
+ ) : (
701
+ <SquareIcon />
702
+ )}
703
+ </button>
704
+ <div className="query-builder-property-search-panel__form__section__toggler__prompt">
705
+ String
706
+ </div>
707
+ </div>
708
+ <div className="query-builder-property-search-panel__filter__element">
709
+ <button
710
+ className={clsx(
711
+ 'query-builder-property-search-panel__form__section__toggler__btn',
712
+ {
713
+ 'query-builder-property-search-panel__form__section__toggler__btn--toggled':
714
+ propertySearchState.typeFilters.includes(
715
+ QUERY_BUILDER_PROPERTY_SEARCH_TYPE.BOOLEAN,
716
+ ),
717
+ },
718
+ )}
719
+ onClick={(): void => {
720
+ propertySearchState.toggleFilterForType(
721
+ QUERY_BUILDER_PROPERTY_SEARCH_TYPE.BOOLEAN,
722
+ );
723
+ }}
724
+ tabIndex={-1}
725
+ >
726
+ {propertySearchState.typeFilters.includes(
500
727
  QUERY_BUILDER_PROPERTY_SEARCH_TYPE.BOOLEAN,
501
- );
502
- }}
503
- tabIndex={-1}
504
- >
505
- {propertySearchState.typeFilters.includes(
506
- QUERY_BUILDER_PROPERTY_SEARCH_TYPE.BOOLEAN,
507
- ) ? (
508
- <CheckSquareIcon />
509
- ) : (
510
- <SquareIcon />
511
- )}
512
- </button>
513
- <div className="query-builder-property-search-panel__form__section__toggler__prompt">
514
- Boolean
728
+ ) ? (
729
+ <CheckSquareIcon />
730
+ ) : (
731
+ <SquareIcon />
732
+ )}
733
+ </button>
734
+ <div className="query-builder-property-search-panel__form__section__toggler__prompt">
735
+ Boolean
736
+ </div>
515
737
  </div>
516
- </div>
517
- <div className="query-builder-property-search-panel__filter__element">
518
- <button
519
- className={clsx(
520
- 'query-builder-property-search-panel__form__section__toggler__btn',
521
- {
522
- 'query-builder-property-search-panel__form__section__toggler__btn--toggled':
523
- propertySearchState.typeFilters.includes(
524
- QUERY_BUILDER_PROPERTY_SEARCH_TYPE.NUMBER,
525
- ),
526
- },
527
- )}
528
- onClick={(): void => {
529
- propertySearchState.toggleFilterForType(
738
+ <div className="query-builder-property-search-panel__filter__element">
739
+ <button
740
+ className={clsx(
741
+ 'query-builder-property-search-panel__form__section__toggler__btn',
742
+ {
743
+ 'query-builder-property-search-panel__form__section__toggler__btn--toggled':
744
+ propertySearchState.typeFilters.includes(
745
+ QUERY_BUILDER_PROPERTY_SEARCH_TYPE.NUMBER,
746
+ ),
747
+ },
748
+ )}
749
+ onClick={(): void => {
750
+ propertySearchState.toggleFilterForType(
751
+ QUERY_BUILDER_PROPERTY_SEARCH_TYPE.NUMBER,
752
+ );
753
+ }}
754
+ tabIndex={-1}
755
+ >
756
+ {propertySearchState.typeFilters.includes(
530
757
  QUERY_BUILDER_PROPERTY_SEARCH_TYPE.NUMBER,
531
- );
532
- }}
533
- tabIndex={-1}
534
- >
535
- {propertySearchState.typeFilters.includes(
536
- QUERY_BUILDER_PROPERTY_SEARCH_TYPE.NUMBER,
537
- ) ? (
538
- <CheckSquareIcon />
539
- ) : (
540
- <SquareIcon />
541
- )}
542
- </button>
543
- <div className="query-builder-property-search-panel__form__section__toggler__prompt">
544
- Number
758
+ ) ? (
759
+ <CheckSquareIcon />
760
+ ) : (
761
+ <SquareIcon />
762
+ )}
763
+ </button>
764
+ <div className="query-builder-property-search-panel__form__section__toggler__prompt">
765
+ Number
766
+ </div>
545
767
  </div>
546
- </div>
547
- <div className="query-builder-property-search-panel__filter__element">
548
- <button
549
- className={clsx(
550
- 'query-builder-property-search-panel__form__section__toggler__btn',
551
- {
552
- 'query-builder-property-search-panel__form__section__toggler__btn--toggled':
553
- propertySearchState.typeFilters.includes(
554
- QUERY_BUILDER_PROPERTY_SEARCH_TYPE.DATE,
555
- ),
556
- },
557
- )}
558
- onClick={(): void => {
559
- propertySearchState.toggleFilterForType(
768
+ <div className="query-builder-property-search-panel__filter__element">
769
+ <button
770
+ className={clsx(
771
+ 'query-builder-property-search-panel__form__section__toggler__btn',
772
+ {
773
+ 'query-builder-property-search-panel__form__section__toggler__btn--toggled':
774
+ propertySearchState.typeFilters.includes(
775
+ QUERY_BUILDER_PROPERTY_SEARCH_TYPE.DATE,
776
+ ),
777
+ },
778
+ )}
779
+ onClick={(): void => {
780
+ propertySearchState.toggleFilterForType(
781
+ QUERY_BUILDER_PROPERTY_SEARCH_TYPE.DATE,
782
+ );
783
+ }}
784
+ tabIndex={-1}
785
+ >
786
+ {propertySearchState.typeFilters.includes(
560
787
  QUERY_BUILDER_PROPERTY_SEARCH_TYPE.DATE,
561
- );
562
- }}
563
- tabIndex={-1}
564
- >
565
- {propertySearchState.typeFilters.includes(
566
- QUERY_BUILDER_PROPERTY_SEARCH_TYPE.DATE,
567
- ) ? (
568
- <CheckSquareIcon />
569
- ) : (
570
- <SquareIcon />
571
- )}
572
- </button>
573
- <div className="query-builder-property-search-panel__form__section__toggler__prompt">
574
- Date
788
+ ) ? (
789
+ <CheckSquareIcon />
790
+ ) : (
791
+ <SquareIcon />
792
+ )}
793
+ </button>
794
+ <div className="query-builder-property-search-panel__form__section__toggler__prompt">
795
+ Date
796
+ </div>
575
797
  </div>
576
798
  </div>
577
799
  </div>
578
- </div>
579
- </ResizablePanel>
580
- <ResizablePanelSplitter>
581
- <ResizablePanelSplitterLine color="var(--color-dark-grey-200)" />
582
- </ResizablePanelSplitter>
583
- <ResizablePanel>
584
- {propertySearchState.searchState.isInProgress && (
585
- <PanelLoadingIndicator isLoading={true} />
586
- )}
587
- <div className="query-builder-property-search-panel__results">
588
- {!propertySearchState.searchState.isInProgress && (
589
- <>
590
- {Boolean(
591
- propertySearchState.filteredSearchResults.length,
592
- ) &&
593
- propertySearchState.filteredSearchResults.map(
594
- (node) => (
595
- <QueryBuilderTreeNodeViewer
596
- key={node.id}
597
- node={node}
598
- queryBuilderState={queryBuilderState}
599
- level={1}
600
- stepPaddingInRem={0}
601
- explorerState={queryBuilderState.explorerState}
602
- />
603
- ),
604
- )}
605
- {!propertySearchState.filteredSearchResults.length &&
606
- propertySearchState.searchText && (
607
- <BlankPanelContent>
608
- <div className="query-builder-property-search-panel__result-placeholder__text">
609
- No result
610
- </div>
611
- <div className="query-builder-property-search-panel__result-placeholder__tips">
612
- Tips: Navigate deeper into the explorer tree to
613
- improve the scope and accuracy of the search
614
- </div>
615
- </BlankPanelContent>
616
- )}
617
- </>
800
+ </ResizablePanel>
801
+ <ResizablePanelSplitter>
802
+ <ResizablePanelSplitterLine color="var(--color-dark-grey-200)" />
803
+ </ResizablePanelSplitter>
804
+ <ResizablePanel>
805
+ {(propertySearchState.initializationState.isInProgress ||
806
+ propertySearchState.searchState.isInProgress) && (
807
+ <PanelLoadingIndicator isLoading={true} />
618
808
  )}
619
- {propertySearchState.searchState.isInProgress && (
620
- <BlankPanelContent>Searching...</BlankPanelContent>
621
- )}
622
- </div>
623
- </ResizablePanel>
624
- </ResizablePanelGroup>
809
+ <div className="query-builder-property-search-panel__results">
810
+ {!propertySearchState.initializationState.isInProgress &&
811
+ !propertySearchState.searchState.isInProgress && (
812
+ <>
813
+ {Boolean(
814
+ propertySearchState.filteredSearchResults.length,
815
+ ) &&
816
+ propertySearchState.filteredSearchResults.map(
817
+ (node) => (
818
+ <QueryBuilderTreeNodeViewer
819
+ key={node.id}
820
+ node={node}
821
+ queryBuilderState={queryBuilderState}
822
+ level={1}
823
+ stepPaddingInRem={0}
824
+ explorerState={
825
+ queryBuilderState.explorerState
826
+ }
827
+ />
828
+ ),
829
+ )}
830
+ {!propertySearchState.filteredSearchResults.length &&
831
+ propertySearchState.searchText && (
832
+ <BlankPanelContent>
833
+ <div className="query-builder-property-search-panel__result-placeholder__text">
834
+ No result
835
+ </div>
836
+ <div className="query-builder-property-search-panel__result-placeholder__tips">
837
+ Tips: Navigate deeper into the explorer tree
838
+ to improve the scope and accuracy of the
839
+ search
840
+ </div>
841
+ </BlankPanelContent>
842
+ )}
843
+ </>
844
+ )}
845
+ {propertySearchState.initializationState.isInProgress && (
846
+ <BlankPanelContent>Initializing...</BlankPanelContent>
847
+ )}
848
+ {propertySearchState.searchState.isInProgress && (
849
+ <BlankPanelContent>Searching...</BlankPanelContent>
850
+ )}
851
+ </div>
852
+ </ResizablePanel>
853
+ </ResizablePanelGroup>
854
+ </div>
625
855
  </div>
626
- </div>
856
+ </ClickAwayListener>
627
857
  </BasePopover>
628
858
  );
629
859
  },