@finos/legend-application 7.2.0 → 8.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/lib/components/ActionAlert.js +2 -1
  2. package/lib/components/ActionAlert.js.map +1 -1
  3. package/lib/components/ApplicationStoreProvider.d.ts +3 -3
  4. package/lib/components/ApplicationStoreProvider.d.ts.map +1 -1
  5. package/lib/components/ApplicationStoreProviderTestUtils.d.ts +1 -1
  6. package/lib/components/ApplicationStoreProviderTestUtils.js.map +1 -1
  7. package/lib/components/VirtualAssistant.d.ts.map +1 -1
  8. package/lib/components/VirtualAssistant.js +21 -12
  9. package/lib/components/VirtualAssistant.js.map +1 -1
  10. package/lib/components/shared/CustomDatePicker.d.ts.map +1 -1
  11. package/lib/components/shared/CustomDatePicker.js +31 -9
  12. package/lib/components/shared/CustomDatePicker.js.map +1 -1
  13. package/lib/components/shared/TextSearchAdvancedConfigMenu.d.ts +22 -0
  14. package/lib/components/shared/TextSearchAdvancedConfigMenu.d.ts.map +1 -0
  15. package/lib/components/shared/TextSearchAdvancedConfigMenu.js +37 -0
  16. package/lib/components/shared/TextSearchAdvancedConfigMenu.js.map +1 -0
  17. package/lib/index.css +2 -2
  18. package/lib/index.css.map +1 -1
  19. package/lib/index.d.ts +2 -0
  20. package/lib/index.d.ts.map +1 -1
  21. package/lib/index.js +2 -0
  22. package/lib/index.js.map +1 -1
  23. package/lib/stores/ApplicationStore.d.ts +4 -4
  24. package/lib/stores/ApplicationStore.d.ts.map +1 -1
  25. package/lib/stores/ApplicationStore.js +7 -4
  26. package/lib/stores/ApplicationStore.js.map +1 -1
  27. package/lib/stores/ApplicationStoreTestUtils.d.ts +1 -1
  28. package/lib/stores/ApplicationStoreTestUtils.js.map +1 -1
  29. package/lib/stores/ApplicationTelemetry.d.ts +5 -0
  30. package/lib/stores/ApplicationTelemetry.d.ts.map +1 -1
  31. package/lib/stores/ApplicationTelemetry.js.map +1 -1
  32. package/lib/stores/AssistantService.d.ts +10 -2
  33. package/lib/stores/AssistantService.d.ts.map +1 -1
  34. package/lib/stores/AssistantService.js +55 -4
  35. package/lib/stores/AssistantService.js.map +1 -1
  36. package/lib/stores/LegendApplicationDocumentation.d.ts +19 -0
  37. package/lib/stores/LegendApplicationDocumentation.d.ts.map +1 -0
  38. package/lib/stores/LegendApplicationDocumentation.js +20 -0
  39. package/lib/stores/LegendApplicationDocumentation.js.map +1 -0
  40. package/lib/stores/PureLanguageSupport.js +3 -3
  41. package/lib/stores/PureLanguageSupport.js.map +1 -1
  42. package/lib/stores/shared/LambdaParameterState.d.ts +6 -2
  43. package/lib/stores/shared/LambdaParameterState.d.ts.map +1 -1
  44. package/lib/stores/shared/LambdaParameterState.js +26 -2
  45. package/lib/stores/shared/LambdaParameterState.js.map +1 -1
  46. package/lib/stores/shared/TextSearchAdvancedConfigState.d.ts +30 -0
  47. package/lib/stores/shared/TextSearchAdvancedConfigState.d.ts.map +1 -0
  48. package/lib/stores/shared/TextSearchAdvancedConfigState.js +59 -0
  49. package/lib/stores/shared/TextSearchAdvancedConfigState.js.map +1 -0
  50. package/package.json +9 -9
  51. package/src/components/ActionAlert.tsx +1 -1
  52. package/src/components/ApplicationStoreProvider.tsx +3 -3
  53. package/src/components/ApplicationStoreProviderTestUtils.tsx +2 -2
  54. package/src/components/VirtualAssistant.tsx +127 -76
  55. package/src/components/shared/CustomDatePicker.tsx +40 -2
  56. package/src/components/shared/TextSearchAdvancedConfigMenu.tsx +73 -0
  57. package/src/index.ts +3 -0
  58. package/src/stores/ApplicationStore.ts +10 -11
  59. package/src/stores/ApplicationStoreTestUtils.ts +2 -2
  60. package/src/stores/ApplicationTelemetry.ts +5 -0
  61. package/src/stores/AssistantService.ts +69 -4
  62. package/src/stores/LegendApplicationDocumentation.ts +19 -0
  63. package/src/stores/PureLanguageSupport.ts +3 -3
  64. package/src/stores/shared/LambdaParameterState.ts +33 -3
  65. package/src/stores/shared/TextSearchAdvancedConfigState.ts +65 -0
  66. package/tsconfig.json +3 -0
@@ -36,6 +36,7 @@ import {
36
36
  PanelLoadingIndicator,
37
37
  BasePopover,
38
38
  FaceSadTearIcon,
39
+ CogIcon,
39
40
  } from '@finos/legend-art';
40
41
  import {
41
42
  ContentType,
@@ -56,6 +57,7 @@ import { useApplicationStore } from './ApplicationStoreProvider.js';
56
57
  import Draggable from 'react-draggable';
57
58
  import { DATE_TIME_FORMAT } from '@finos/legend-graph';
58
59
  import { ApplicationTelemetry } from '../stores/ApplicationTelemetry.js';
60
+ import { TextSearchAdvancedConfigMenu } from './shared/TextSearchAdvancedConfigMenu.js';
59
61
 
60
62
  const WIZARD_GREETING = `Bonjour, It's Pierre!`;
61
63
 
@@ -222,6 +224,7 @@ const VirtualAssistantContextualSupportPanel = observer(() => {
222
224
  )}
223
225
  </>
224
226
  )}
227
+
225
228
  {contextualEntry.related.length && (
226
229
  <div className="virtual-assistant__contextual-support__relevant-entries">
227
230
  <div className="virtual-assistant__contextual-support__relevant-entries__title">
@@ -245,8 +248,8 @@ const VirtualAssistantContextualSupportPanel = observer(() => {
245
248
  No contextual documentation found!
246
249
  </div>
247
250
  <div className="virtual-assistant__panel__placeholder__instruction">
248
- Keep using the app, when contextual doc available, we will let you
249
- know!
251
+ Keep using the app. When contextual help is available, we will let
252
+ you know!
250
253
  </div>
251
254
  </div>
252
255
  </BlankPanelContent>
@@ -258,7 +261,10 @@ const VirtualAssistantContextualSupportPanel = observer(() => {
258
261
  const VirtualAssistantSearchPanel = observer(() => {
259
262
  const applicationStore = useApplicationStore();
260
263
  const searchInputRef = useRef<HTMLInputElement>(null);
264
+ const searchConfigButtonRef = useRef<HTMLButtonElement>(null);
261
265
  const assistantService = applicationStore.assistantService;
266
+
267
+ // search text
262
268
  const searchText = assistantService.searchText;
263
269
  const debouncedSearch = useMemo(
264
270
  () => debounce(() => assistantService.search(), 100),
@@ -272,13 +278,10 @@ const VirtualAssistantSearchPanel = observer(() => {
272
278
  };
273
279
  const clearSearchText = (): void => {
274
280
  assistantService.resetSearch();
281
+ assistantService.currentDocumentationEntry = undefined;
275
282
  searchInputRef.current?.focus();
276
283
  };
277
- const results = assistantService.searchResults;
278
- const resultCount =
279
- assistantService.searchResults.length > 99
280
- ? '99+'
281
- : assistantService.searchResults.length;
284
+
282
285
  const downloadDocRegistry = (): void => {
283
286
  downloadFileUsingDataURI(
284
287
  `documentation-registry_${format(
@@ -307,6 +310,10 @@ const VirtualAssistantSearchPanel = observer(() => {
307
310
  ContentType.APPLICATION_JSON,
308
311
  );
309
312
  };
313
+ const toggleSearchConfigMenu = (): void =>
314
+ assistantService.setShowSearchConfigurationMenu(
315
+ !assistantService.showSearchConfigurationMenu,
316
+ );
310
317
 
311
318
  useEffect(() => {
312
319
  searchInputRef.current?.focus();
@@ -351,94 +358,138 @@ const VirtualAssistantSearchPanel = observer(() => {
351
358
  className={clsx('virtual-assistant__search__input input--dark', {
352
359
  'virtual-assistant__search__input--searching': searchText,
353
360
  })}
361
+ spellCheck={false}
354
362
  onChange={onSearchTextChange}
355
363
  value={searchText}
356
364
  placeholder="Ask me a question"
357
365
  />
366
+ {searchText && (
367
+ <div className="virtual-assistant__search__input__search__count">
368
+ {assistantService.searchResults.length +
369
+ (assistantService.isOverSearchLimit ? '+' : '')}
370
+ </div>
371
+ )}
372
+ <button
373
+ ref={searchConfigButtonRef}
374
+ className={clsx('virtual-assistant__search__input__config__trigger', {
375
+ 'virtual-assistant__search__input__config__trigger--toggled':
376
+ assistantService.showSearchConfigurationMenu,
377
+ 'virtual-assistant__search__input__config__trigger--active':
378
+ assistantService.searchConfigurationState.isAdvancedSearchActive,
379
+ })}
380
+ tabIndex={-1}
381
+ onClick={toggleSearchConfigMenu}
382
+ title={`${
383
+ assistantService.searchConfigurationState.isAdvancedSearchActive
384
+ ? 'Advanced search is currently active\n'
385
+ : ''
386
+ }Click to toggle search config menu`}
387
+ >
388
+ <CogIcon />
389
+ </button>
358
390
  {!searchText ? (
359
391
  <div className="virtual-assistant__search__input__search__icon">
360
392
  <SearchIcon />
361
393
  </div>
362
394
  ) : (
363
- <>
364
- <div className="virtual-assistant__search__input__search__count">
365
- {resultCount}
366
- </div>
367
- <button
368
- className="virtual-assistant__search__input__clear-btn"
369
- tabIndex={-1}
370
- onClick={clearSearchText}
371
- title="Clear"
372
- >
373
- <TimesIcon />
374
- </button>
375
- </>
395
+ <button
396
+ className="virtual-assistant__search__input__clear-btn"
397
+ tabIndex={-1}
398
+ onClick={clearSearchText}
399
+ title="Clear"
400
+ >
401
+ <TimesIcon />
402
+ </button>
376
403
  )}
377
404
  </div>
378
405
  <div className="virtual-assistant__search__content">
379
406
  <PanelLoadingIndicator
380
407
  isLoading={assistantService.searchState.isInProgress}
381
408
  />
382
- {Boolean(results.length) && (
409
+ {/* {assistantService.showSearchConfigurationMenu && ( */}
410
+ <div
411
+ className={clsx('virtual-assistant__search__input__config__panel', {
412
+ 'virtual-assistant__search__input__config__panel--toggled':
413
+ assistantService.showSearchConfigurationMenu,
414
+ })}
415
+ >
416
+ <TextSearchAdvancedConfigMenu
417
+ configState={assistantService.searchConfigurationState}
418
+ />
419
+ </div>
420
+ {/* )} */}
421
+ {assistantService.currentDocumentationEntry && (
383
422
  <div className="virtual-assistant__search__results">
384
- {results.map((result) => (
385
- <VirtualAssistantDocumentationEntryViewer
386
- key={result.uuid}
387
- entry={result}
388
- />
389
- ))}
423
+ <VirtualAssistantDocumentationEntryViewer
424
+ key={assistantService.currentDocumentationEntry.uuid}
425
+ entry={assistantService.currentDocumentationEntry}
426
+ />
390
427
  </div>
391
428
  )}
392
- {searchText && !results.length && (
393
- <BlankPanelContent>
394
- <div className="virtual-assistant__panel__placeholder">
395
- <FaceSadTearIcon className="virtual-assistant__panel__placeholder__icon" />
396
- <div className="virtual-assistant__panel__placeholder__message">
397
- No result...
398
- </div>
399
- </div>
400
- </BlankPanelContent>
401
- )}
402
- {/*
403
- NOTE: technically, we don't need to check for the result size here.
404
- However, since the search results update is slightly delayed compared to
405
- the search text update, we do this to avoid showing the placeholder too
406
- early, i.e. when the search results are not yet cleaned
407
- */}
408
- {!searchText && !results.length && (
409
- <ContextMenu
410
- className="virtual-assistant__character__container"
411
- menuProps={{
412
- elevation: 7,
413
- classes: {
414
- root: 'virtual-assistant__context-menu',
415
- },
416
- }}
417
- content={
418
- <MenuContent>
419
- <MenuContentItem onClick={downloadDocRegistry}>
420
- Download documentation registry
421
- </MenuContentItem>
422
- <MenuContentItem onClick={downloadContextualDocIndex}>
423
- Download contextual documentation mapping
424
- </MenuContentItem>
425
- </MenuContent>
426
- }
427
- >
428
- <div className="virtual-assistant__character">
429
- <div className="virtual-assistant__character__figure">
430
- <WizardHatIcon className="virtual-assistant__character__hat" />
431
- <SunglassesIcon className="virtual-assistant__character__glasses" />
432
- <BeardIcon className="virtual-assistant__character__beard" />
433
- </div>
434
- <div className="virtual-assistant__character__greeting">
435
- {WIZARD_GREETING}
436
- </div>
437
- <div className="virtual-assistant__character__question">
438
- How can I help today?
429
+ {!assistantService.currentDocumentationEntry && (
430
+ <>
431
+ {Boolean(assistantService.searchResults.length) && (
432
+ <div className="virtual-assistant__search__results">
433
+ {assistantService.searchResults.map((result) => (
434
+ <VirtualAssistantDocumentationEntryViewer
435
+ key={result.uuid}
436
+ entry={result}
437
+ />
438
+ ))}
439
439
  </div>
440
- </div>
441
- </ContextMenu>
440
+ )}
441
+ {searchText && !assistantService.searchResults.length && (
442
+ <BlankPanelContent>
443
+ <div className="virtual-assistant__panel__placeholder">
444
+ <FaceSadTearIcon className="virtual-assistant__panel__placeholder__icon" />
445
+ <div className="virtual-assistant__panel__placeholder__message">
446
+ No result...
447
+ </div>
448
+ </div>
449
+ </BlankPanelContent>
450
+ )}
451
+ {/*
452
+ NOTE: technically, we don't need to check for the result size here.
453
+ However, since the search results update is slightly delayed compared to
454
+ the search text update, we do this to avoid showing the placeholder too
455
+ early, i.e. when the search results are not yet cleaned
456
+ */}
457
+ {!searchText && !assistantService.searchResults.length && (
458
+ <ContextMenu
459
+ className="virtual-assistant__character__container"
460
+ menuProps={{
461
+ elevation: 7,
462
+ classes: {
463
+ root: 'virtual-assistant__context-menu',
464
+ },
465
+ }}
466
+ content={
467
+ <MenuContent>
468
+ <MenuContentItem onClick={downloadDocRegistry}>
469
+ Download documentation registry
470
+ </MenuContentItem>
471
+ <MenuContentItem onClick={downloadContextualDocIndex}>
472
+ Download contextual documentation mapping
473
+ </MenuContentItem>
474
+ </MenuContent>
475
+ }
476
+ >
477
+ <div className="virtual-assistant__character">
478
+ <div className="virtual-assistant__character__figure">
479
+ <WizardHatIcon className="virtual-assistant__character__hat" />
480
+ <SunglassesIcon className="virtual-assistant__character__glasses" />
481
+ <BeardIcon className="virtual-assistant__character__beard" />
482
+ </div>
483
+ <div className="virtual-assistant__character__greeting">
484
+ {WIZARD_GREETING}
485
+ </div>
486
+ <div className="virtual-assistant__character__question">
487
+ How can I help today?
488
+ </div>
489
+ </div>
490
+ </ContextMenu>
491
+ )}
492
+ </>
442
493
  )}
443
494
  </div>
444
495
  </div>
@@ -15,6 +15,7 @@
15
15
  */
16
16
 
17
17
  import {
18
+ type SelectComponent,
18
19
  BasePopover,
19
20
  BaseRadioGroup,
20
21
  CustomSelectorInput,
@@ -41,9 +42,11 @@ import {
41
42
  } from '@finos/legend-graph';
42
43
  import {
43
44
  guaranteeNonNullable,
45
+ parseNumber,
46
+ returnUndefOnError,
44
47
  UnsupportedOperationError,
45
48
  } from '@finos/legend-shared';
46
- import { useEffect, useState } from 'react';
49
+ import { useEffect, useRef, useState } from 'react';
47
50
  import {
48
51
  genericType_setRawType,
49
52
  instanceValue_changeValue,
@@ -682,6 +685,7 @@ const AbsoluteDateValueSpecificationEditor: React.FC<{
682
685
  setValueSpecification,
683
686
  setDatePickerOption,
684
687
  } = props;
688
+ const inputRef = useRef<HTMLInputElement>(null);
685
689
  const absoluteDateValue =
686
690
  valueSpecification instanceof SimpleFunctionExpression
687
691
  ? ''
@@ -717,9 +721,15 @@ const AbsoluteDateValueSpecificationEditor: React.FC<{
717
721
  ),
718
722
  );
719
723
  };
724
+
725
+ useEffect(() => {
726
+ inputRef.current?.focus();
727
+ }, []);
728
+
720
729
  return (
721
730
  <div className="value-spec-editor__date-picker__absolute-date">
722
731
  <input
732
+ ref={inputRef}
723
733
  className="panel__content__form__section__input value-spec-editor__date-picker__absolute-date__input input--dark"
724
734
  type="date"
725
735
  spellCheck={false}
@@ -742,6 +752,7 @@ const AbsoluteTimeValueSpecificationEditor: React.FC<{
742
752
  setValueSpecification,
743
753
  setDatePickerOption,
744
754
  } = props;
755
+ const inputRef = useRef<HTMLInputElement>(null);
745
756
  const absoluteTimeValue =
746
757
  valueSpecification instanceof SimpleFunctionExpression
747
758
  ? ''
@@ -777,9 +788,15 @@ const AbsoluteTimeValueSpecificationEditor: React.FC<{
777
788
  ),
778
789
  );
779
790
  };
791
+
792
+ useEffect(() => {
793
+ inputRef.current?.focus();
794
+ }, []);
795
+
780
796
  return (
781
797
  <div className="value-spec-editor__date-picker__absolute-date">
782
798
  <input
799
+ ref={inputRef}
783
800
  className="panel__content__form__section__input value-spec-editor__date-picker__absolute-date__input input--dark"
784
801
  // Despite its name this would actually allow us to register time in UTC
785
802
  // See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/datetime-local#setting_timezones
@@ -804,6 +821,7 @@ const CustomDateInstanceValueEditor: React.FC<{
804
821
  setValueSpecification,
805
822
  setDatePickerOption,
806
823
  } = props;
824
+ const inputRef = useRef<HTMLInputElement>(null);
807
825
  const [durationValue, setDurationValue] = useState(
808
826
  customDateOptionValue.duration,
809
827
  );
@@ -859,15 +877,22 @@ const CustomDateInstanceValueEditor: React.FC<{
859
877
  event,
860
878
  ) => {
861
879
  const duration =
862
- event.target.value !== '' ? parseInt(event.target.value) : 0;
880
+ event.target.value !== ''
881
+ ? returnUndefOnError(() => parseNumber(event.target.value)) ?? 0
882
+ : 0;
863
883
  setDurationValue(duration);
864
884
  changeValue(duration, unitValue, directionValue, referenceMomentValue);
865
885
  };
866
886
 
887
+ useEffect(() => {
888
+ inputRef.current?.focus();
889
+ }, []);
890
+
867
891
  return (
868
892
  <div className="value-spec-editor__date-picker__custom-date">
869
893
  <div className="value-spec-editor__date-picker__custom-date__input">
870
894
  <input
895
+ ref={inputRef}
871
896
  className="value-spec-editor__date-picker__custom-date__input-text-editor input--dark"
872
897
  spellCheck={false}
873
898
  value={durationValue}
@@ -958,6 +983,7 @@ const CustomFirstDayOfValueSpecificationEditor: React.FC<{
958
983
  setValueSpecification,
959
984
  setDatePickerOption,
960
985
  } = props;
986
+ const selectorRef = useRef<SelectComponent>(null);
961
987
  const [unitValue, setUnitValue] = useState(
962
988
  customDateAdjustOptionValue instanceof CustomFirstDayOfOption
963
989
  ? (customDateAdjustOptionValue.unit as string)
@@ -982,10 +1008,15 @@ const CustomFirstDayOfValueSpecificationEditor: React.FC<{
982
1008
  }
983
1009
  };
984
1010
 
1011
+ useEffect(() => {
1012
+ selectorRef.current?.focus();
1013
+ }, []);
1014
+
985
1015
  return (
986
1016
  <div className="value-spec-editor__date-picker__custom-date">
987
1017
  <div className="value-spec-editor__date-picker__custom-date__input">
988
1018
  <CustomSelectorInput
1019
+ ref={selectorRef}
989
1020
  placeholder="Choose a unit..."
990
1021
  className="value-spec-editor__date-picker__custom-date__input-dropdown value-spec-editor__date-picker__custom-date__input-dropdown--full"
991
1022
  options={Object.values(CUSTOM_DATE_FIRST_DAY_OF_UNIT).map((t) => ({
@@ -1018,6 +1049,7 @@ const CustomPreviousDayOfWeekValueSpecificationEditor: React.FC<{
1018
1049
  setValueSpecification,
1019
1050
  setDatePickerOption,
1020
1051
  } = props;
1052
+ const selectorRef = useRef<SelectComponent>(null);
1021
1053
  const [dayOfWeekValue, setDayOfWeekValue] = useState(
1022
1054
  customDateAdjustOptionValue instanceof CustomPreviousDayOfWeekOption
1023
1055
  ? (customDateAdjustOptionValue.day as string)
@@ -1036,10 +1068,15 @@ const CustomPreviousDayOfWeekValueSpecificationEditor: React.FC<{
1036
1068
  }
1037
1069
  };
1038
1070
 
1071
+ useEffect(() => {
1072
+ selectorRef.current?.focus();
1073
+ }, []);
1074
+
1039
1075
  return (
1040
1076
  <div className="value-spec-editor__date-picker__custom-date">
1041
1077
  <div className="value-spec-editor__date-picker__custom-date__input">
1042
1078
  <CustomSelectorInput
1079
+ ref={selectorRef}
1043
1080
  placeholder="Choose a day..."
1044
1081
  className="value-spec-editor__date-picker__custom-date__input-dropdown value-spec-editor__date-picker__custom-date__input-dropdown--full"
1045
1082
  options={Object.values(CUSTOM_DATE_DAY_OF_WEEK).map((t) => ({
@@ -1241,6 +1278,7 @@ export const CustomDatePicker: React.FC<{
1241
1278
  }}
1242
1279
  >
1243
1280
  <BaseRadioGroup
1281
+ className="value-spec-editor__date-picker__options"
1244
1282
  value={datePickerOption.value}
1245
1283
  onChange={handleDatePickerOptionChange}
1246
1284
  row={true}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Copyright (c) 2020-present, Goldman Sachs
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import { BaseRadioGroup, InfoCircleIcon } from '@finos/legend-art';
18
+ import { observer } from 'mobx-react-lite';
19
+ import { LEGEND_APPLICATION_DOCUMENTATION_KEY } from '../../stores/LegendApplicationDocumentation.js';
20
+ import {
21
+ ADVANCED_TEXT_SEARCH_MODE,
22
+ type TextSearchAdvancedConfigState,
23
+ } from '../../stores/shared/TextSearchAdvancedConfigState.js';
24
+ import { useApplicationStore } from '../ApplicationStoreProvider.js';
25
+
26
+ export const TextSearchAdvancedConfigMenu = observer(
27
+ (props: { configState: TextSearchAdvancedConfigState }) => {
28
+ const { configState } = props;
29
+ const applicationStore = useApplicationStore();
30
+
31
+ const handleSearchMode: React.ChangeEventHandler<HTMLInputElement> = (
32
+ event,
33
+ ): void => {
34
+ const searchMode = event.target.value as ADVANCED_TEXT_SEARCH_MODE;
35
+ configState.setCurrentMode(searchMode);
36
+ };
37
+ const seeDocumentation = (): void =>
38
+ applicationStore.assistantService.openDocumentationEntry(
39
+ LEGEND_APPLICATION_DOCUMENTATION_KEY.QUESTION_HOW_TO_USE_ADVANCED_SEARCH_SYNTAX,
40
+ );
41
+
42
+ return (
43
+ <div className="text-search-advanced-config__panel">
44
+ <div className="text-search-advanced-config__panel__header__label">
45
+ search config
46
+ <button
47
+ className="text-search-advanced-config__panel__header__hint"
48
+ tabIndex={-1}
49
+ onClick={seeDocumentation}
50
+ title="Click to see more details on advanced search"
51
+ >
52
+ <InfoCircleIcon />
53
+ </button>
54
+ </div>
55
+ <div>
56
+ <BaseRadioGroup
57
+ className="text-search-advanced-config__options"
58
+ value={configState.currentMode}
59
+ onChange={handleSearchMode}
60
+ row={false}
61
+ options={[
62
+ ADVANCED_TEXT_SEARCH_MODE.STANDARD,
63
+ ADVANCED_TEXT_SEARCH_MODE.INCLUDE,
64
+ ADVANCED_TEXT_SEARCH_MODE.EXACT,
65
+ ADVANCED_TEXT_SEARCH_MODE.INVERSE,
66
+ ]}
67
+ size={1}
68
+ />
69
+ </div>
70
+ </div>
71
+ );
72
+ },
73
+ );
package/src/index.ts CHANGED
@@ -39,6 +39,9 @@ export * from './stores/AssistantService.js';
39
39
  export * from './stores/ApplicationNavigationContextService.js';
40
40
  export * from './stores/LegendApplicationPlugin.js';
41
41
 
42
+ export * from './components/shared/TextSearchAdvancedConfigMenu.js';
43
+ export * from './stores/shared/TextSearchAdvancedConfigState.js';
44
+
42
45
  export * from './stores/ApplicationStoreTestUtils.js';
43
46
 
44
47
  // ------------------------------------------- Shared components -------------------------------------------
@@ -25,7 +25,7 @@ import {
25
25
  isString,
26
26
  ApplicationError,
27
27
  } from '@finos/legend-shared';
28
- import { makeAutoObservable, action } from 'mobx';
28
+ import { action, makeObservable, observable } from 'mobx';
29
29
  import { APPLICATION_EVENT } from './ApplicationEvent.js';
30
30
  import type { LegendApplicationConfig } from '../application/LegendApplicationConfig.js';
31
31
  import type { WebApplicationNavigator } from './WebApplicationNavigator.js';
@@ -105,15 +105,15 @@ export class Notification {
105
105
 
106
106
  export type GenericLegendApplicationStore = ApplicationStore<
107
107
  LegendApplicationConfig,
108
- LegendApplicationPlugin
108
+ LegendApplicationPluginManager<LegendApplicationPlugin>
109
109
  >;
110
110
 
111
111
  export class ApplicationStore<
112
112
  T extends LegendApplicationConfig,
113
- V extends LegendApplicationPlugin,
113
+ V extends LegendApplicationPluginManager<LegendApplicationPlugin>,
114
114
  > {
115
- pluginManager: LegendApplicationPluginManager<V>;
116
115
  config: T;
116
+ pluginManager: V;
117
117
 
118
118
  // navigation
119
119
  navigator: WebApplicationNavigator;
@@ -144,13 +144,12 @@ export class ApplicationStore<
144
144
  */
145
145
  TEMPORARY__isLightThemeEnabled = false;
146
146
 
147
- constructor(
148
- config: T,
149
- navigator: WebApplicationNavigator,
150
- pluginManager: LegendApplicationPluginManager<V>,
151
- ) {
152
- makeAutoObservable(this, {
153
- navigator: false,
147
+ constructor(config: T, navigator: WebApplicationNavigator, pluginManager: V) {
148
+ makeObservable(this, {
149
+ notification: observable,
150
+ blockingAlertInfo: observable,
151
+ actionAlertInfo: observable,
152
+ TEMPORARY__isLightThemeEnabled: observable,
154
153
  setBlockingAlert: action,
155
154
  setActionAlertInfo: action,
156
155
  setNotification: action,
@@ -52,10 +52,10 @@ export const TEST__getGenericApplicationConfig = (
52
52
 
53
53
  export const TEST__getTestApplicationStore = <
54
54
  T extends LegendApplicationConfig,
55
- V extends LegendApplicationPlugin,
55
+ V extends LegendApplicationPluginManager<LegendApplicationPlugin>,
56
56
  >(
57
57
  config: T,
58
- pluginManager: LegendApplicationPluginManager<V>,
58
+ pluginManager: V,
59
59
  ): ApplicationStore<T, V> =>
60
60
  new ApplicationStore(
61
61
  config,
@@ -18,6 +18,11 @@ import type { TelemetryService } from '@finos/legend-shared';
18
18
  import { APPLICATION_EVENT } from './ApplicationEvent.js';
19
19
 
20
20
  type ApplicationLoaded_TelemetryData = {
21
+ application: {
22
+ name: string;
23
+ version: string;
24
+ env: string;
25
+ };
21
26
  browser: {
22
27
  userAgent: string;
23
28
  };