From 13eccbbb84b3f3a9d621d827d649b87bd6fef209 Mon Sep 17 00:00:00 2001 From: Eric Wei Date: Wed, 15 Mar 2023 16:39:19 -0700 Subject: [PATCH] [Refactoring] Explorer sidebar refactoring (#326) * move fields toggle from explorer to under sidebar Signed-off-by: Eric Wei * fix the bug when switching index seeing fields from old index Signed-off-by: Eric Wei * update tests/snapshots Signed-off-by: Eric Wei --------- Signed-off-by: Eric Wei --- .../event_analytics/explorer/explorer.tsx | 50 +- .../__snapshots__/sidebar.test.tsx.snap | 14502 ++++++++-------- .../sidebar/__tests__/sidebar.test.tsx | 84 +- .../explorer/sidebar/sidebar.tsx | 77 +- .../explorer/visualizations/index.tsx | 6 - .../event_analytics/hooks/use_fetch_events.ts | 1 + 6 files changed, 7384 insertions(+), 7336 deletions(-) diff --git a/public/components/event_analytics/explorer/explorer.tsx b/public/components/event_analytics/explorer/explorer.tsx index 8c6ec2ed3..9bd371ecd 100644 --- a/public/components/event_analytics/explorer/explorer.tsx +++ b/public/components/event_analytics/explorer/explorer.tsx @@ -20,11 +20,10 @@ import { } from '@elastic/eui'; import { FormattedMessage } from '@osd/i18n/react'; import classNames from 'classnames'; -import { cloneDeep, has, isEmpty, isEqual, reduce } from 'lodash'; +import { has, isEmpty, isEqual, reduce } from 'lodash'; import React, { ReactElement, useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { batch, useDispatch, useSelector } from 'react-redux'; import { - AVAILABLE_FIELDS, DATE_PICKER_FORMAT, DEFAULT_AVAILABILITY_QUERY, EVENT_ANALYTICS_DOCUMENTATION_URL, @@ -33,7 +32,6 @@ import { PATTERNS_EXTRACTOR_REGEX, PATTERNS_REGEX, PATTERN_REGEX, - PPL_DEFAULT_PATTERN_REGEX_FILETER, RAW_QUERY, SAVED_OBJECT_ID, SAVED_OBJECT_TYPE, @@ -74,8 +72,7 @@ import { Search } from '../../common/search/search'; import { getVizContainerProps } from '../../visualizations/charts/helpers'; import { TabContext, useFetchEvents, useFetchPatterns, useFetchVisualizations } from '../hooks'; import { selectCountDistribution } from '../redux/slices/count_distribution_slice'; -import { selectFields, sortFields, updateFields } from '../redux/slices/field_slice'; -import { selectPatterns } from '../redux/slices/patterns_slice'; +import { selectFields, updateFields } from '../redux/slices/field_slice'; import { selectQueryResult } from '../redux/slices/query_result_slice'; import { changeDateRange, changeQuery, selectQueries } from '../redux/slices/query_slice'; import { updateTabName } from '../redux/slices/query_tab_slice'; @@ -129,11 +126,11 @@ export const Explorer = ({ }: IExplorerProps) => { const dispatch = useDispatch(); const requestParams = { tabId }; - const { getLiveTail, getEvents, getAvailableFields, isEventsLoading } = useFetchEvents({ + const { getLiveTail, getEvents } = useFetchEvents({ pplService, requestParams, }); - const { getVisualizations, getCountVisualizations, isVisLoading } = useFetchVisualizations({ + const { getCountVisualizations } = useFetchVisualizations({ pplService, requestParams, }); @@ -506,11 +503,6 @@ export const Explorer = ({ } }, [savedObjectId]); - const handleAddField = (field: IField) => toggleFields(field, AVAILABLE_FIELDS, SELECTED_FIELDS); - - const handleRemoveField = (field: IField) => - toggleFields(field, SELECTED_FIELDS, AVAILABLE_FIELDS); - const handleTimePickerChange = async (timeRange: string[]) => { if (appLogEvents) { setStartTime(timeRange[0]); @@ -558,36 +550,6 @@ export const Explorer = ({ } }; - /** - * Toggle fields between selected and unselected sets - * @param field field to be toggled - * @param FieldSetToRemove set where this field to be removed from - * @param FieldSetToAdd set where this field to be added - */ - const toggleFields = (field: IField, FieldSetToRemove: string, FieldSetToAdd: string) => { - const nextFields = cloneDeep(explorerFields); - const thisFieldSet = nextFields[FieldSetToRemove]; - const nextFieldSet = thisFieldSet.filter((fd: IField) => fd.name !== field.name); - nextFields[FieldSetToRemove] = nextFieldSet; - nextFields[FieldSetToAdd].push(field); - batch(() => { - dispatch( - updateFields({ - tabId, - data: { - ...nextFields, - }, - }) - ); - dispatch( - sortFields({ - tabId, - data: [FieldSetToAdd], - }) - ); - }); - }; - const sidebarClassName = classNames({ closed: isSidebarClosed, }); @@ -686,8 +648,6 @@ export const Explorer = ({ selectedPattern={query[SELECTED_PATTERN_FIELD]} handleOverrideTimestamp={handleOverrideTimestamp} handleOverridePattern={handleOverridePattern} - handleAddField={(field: IField) => handleAddField(field)} - handleRemoveField={(field: IField) => handleRemoveField(field)} isOverridingTimestamp={isOverridingTimestamp} isOverridingPattern={isOverridingPattern} isFieldToggleButtonDisabled={ @@ -891,8 +851,6 @@ export const Explorer = ({ explorerFields={explorerFields} explorerVis={explorerVisualizations} explorerData={explorerData} - handleAddField={handleAddField} - handleRemoveField={handleRemoveField} visualizations={visualizations} handleOverrideTimestamp={handleOverrideTimestamp} callback={callbackForConfig} diff --git a/public/components/event_analytics/explorer/sidebar/__tests__/__snapshots__/sidebar.test.tsx.snap b/public/components/event_analytics/explorer/sidebar/__tests__/__snapshots__/sidebar.test.tsx.snap index 556467262..1d5a67a00 100644 --- a/public/components/event_analytics/explorer/sidebar/__tests__/__snapshots__/sidebar.test.tsx.snap +++ b/public/components/event_analytics/explorer/sidebar/__tests__/__snapshots__/sidebar.test.tsx.snap @@ -1,857 +1,803 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Siderbar component Renders empty sidebar component 1`] = ` - - - + + - -
-
+ +
- - -
- - - - -
- + + + +
- - - - -
-
+ > + + + + +
+
+
+
-
- - - - + + + + +
+
- -
-
-
-
-
-
+ + + + + + `; exports[`Siderbar component Renders sidebar component 1`] = ` - - - + + - -
-
+ +
- - -
- - - - -
- + + + +
- - - - -
-
+ + + + + + +
+
+
+
-
- - - - -
- -
- - - Query fields - - - } - id="fieldSelector__queriedFields" - initialIsOpen={true} - isLoading={false} - isLoadingMessage={false} - paddingSize="xs" + + +
+
+ +
+ + + Query fields + + + } + id="fieldSelector__queriedFields" + initialIsOpen={true} + isLoading={false} + isLoadingMessage={false} + paddingSize="xs" >
- -
-
- + Query fields + + + + +
+
-
-
-
    +
    +
    -
  • - - - - - - - - - - - - - - - } - fieldIcon={ - - } - fieldName={ - - double_per_ip_bytes - - } - isActive={false} - onClick={[Function]} - size="m" - /> + -
    -
    + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="dscSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
    +
    -
    + + + + + + + + + + + + + } + fieldIcon={ + + } + fieldName={ + + double_per_ip_bytes + + } + isActive={false} + onClick={[Function]} + size="m" > - -
    - - - - - - - - +
    + - + + + + + + - - - - + > + + + + + + + +
    -
    - + +
    -
    - - -
  • -
  • - + +
  • +
  • - - - - - - - - - - - - - - } - fieldIcon={ - - } - fieldName={ - - host - - } - isActive={false} - onClick={[Function]} - size="m" - /> + -
    -
    + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="dscSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
    +
    -
    + + + + + + + + + + + + + } + fieldIcon={ + + } + fieldName={ + + host + + } + isActive={false} + onClick={[Function]} + size="m" > - -
    - - - - - - - - +
    + - + + + + + + - - - - + > + + + + + + + +
    -
    - + +
    -
    - - -
  • -
  • - + +
  • +
  • - - - - - - - - - - - - - - } - fieldIcon={ - - } - fieldName={ - - ip_count - - } - isActive={false} - onClick={[Function]} - size="m" - /> + -
    -
    + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="dscSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
    +
    -
    + + + + + + + + + + + + + } + fieldIcon={ + + } + fieldName={ + + ip_count + + } + isActive={false} + onClick={[Function]} + size="m" > - -
    - - - - - - - - +
    + - + + + + + + - - - - + > + + + + + + + +
    -
    - + +
    -
    - - -
  • -
  • - + +
  • +
  • - - - - - - - - - - - - - - } - fieldIcon={ - - } - fieldName={ - - per_ip_bytes - - } - isActive={false} - onClick={[Function]} - size="m" - /> + -
    -
    + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="dscSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
    +
    -
    + + + + + + + + + + + + + } + fieldIcon={ + + } + fieldName={ + + per_ip_bytes + + } + isActive={false} + onClick={[Function]} + size="m" > - -
    - - - - - - - - +
    + - + + + + + + - - - - + > + + + + + + + +
    -
    - + +
    -
    - - -
  • -
  • - + +
  • +
  • - - - - - - - - - - - - - - } - fieldIcon={ - - } - fieldName={ - - resp_code - - } - isActive={false} - onClick={[Function]} - size="m" - /> + -
    -
    + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="dscSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
    +
    -
    + + + + + + + + + + + + + } + fieldIcon={ + + } + fieldName={ + + resp_code + + } + isActive={false} + onClick={[Function]} + size="m" > - -
    + +
    + + + + + + + + + + + + + +
    +
    + +
    +
    + + +
  • +
  • + + - + - + - + - - - - -
  • -
    - -
-
- - - -
  • - - - - - - - - - - - - - - - } - fieldIcon={ - - } - fieldName={ - - sum_bytes - - } - isActive={false} - onClick={[Function]} - size="m" - /> - } - closePopover={[Function]} - display="block" - hasArrow={true} - isOpen={false} - ownFocus={true} - panelClassName="dscSidebarItem__fieldPopoverPanel" - panelPaddingSize="m" - > -
    -
    - - - - - - - - - - + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="dscSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
    +
    -
    + + + + + + + + + + + + + } + fieldIcon={ + + } + fieldName={ + + sum_bytes + + } + isActive={false} + onClick={[Function]} + size="m" > - -
    - - - - - - - - +
    + - + + + + + + - - - - + > + + + + + + + +
    -
    - + +
    -
    - - -
  • - + + + + +
    -
    - + +
    - - - -
    - - - - Selected Fields - - - } - id="fieldSelector__selectedFields" - initialIsOpen={true} - isLoading={false} - isLoadingMessage={false} - paddingSize="xs" - > -
    +
    + + + + Selected Fields + + + } + id="fieldSelector__selectedFields" + initialIsOpen={true} + isLoading={false} + isLoadingMessage={false} + paddingSize="xs" + > +
    - -
    -
    - + Selected Fields + + + + +
    +
    -
    -
    -
      + +
      +
      +
        +
      -
    - + +
    -
    - - -
    - - - - Available Fields - - - } - id="fieldSelector__availableFields" - initialIsOpen={true} - isLoading={false} - isLoadingMessage={false} - paddingSize="xs" - > -
    +
    + + + + Available Fields + + + } + id="fieldSelector__availableFields" + initialIsOpen={true} + isLoading={false} + isLoadingMessage={false} + paddingSize="xs" + > +
    - -
    -
    - + Available Fields + + + + +
    +
    -
    -
    -
      +
      +
      -
    • - - - - - - Override - - - - - - - - - - - - - } - fieldIcon={ - - } - fieldName={ - - agent - - } - isActive={false} - onClick={[Function]} - size="m" - /> + -
      -
      + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="dscSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
      +
      -
      + + + + Override + + + + + + + + + + + + + } + fieldIcon={ + + } + fieldName={ + + agent + + } + isActive={false} + onClick={[Function]} + size="m" > - -
      - - +
      + - - - - - - - - - - + + + + + + + + - + + + - - - - + > + + + + + + + +
      -
      - + +
      -
      - - -
    • -
    • - + +
    • +
    • - - - - - - - - - - - - - - } - fieldIcon={ - - } - fieldName={ - - bytes - - } - isActive={false} - onClick={[Function]} - size="m" - /> + -
      -
      + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="dscSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
      +
      -
      - + } + isActive={false} + onClick={[Function]} + size="m" + >
      - - - - - - + className="osdFieldButton__fieldIcon" + > + + + + + + + + + + + + - + bytes + + + +
      + + + + + + + + - - - - + > + + + + + + + +
      -
      - + +
      -
      - - -
    • -
    • - + +
    • +
    • - - - - - - - - - - - - - - } - fieldIcon={ - - } - fieldName={ - - clientip - - } - isActive={false} - onClick={[Function]} - size="m" - /> + -
      -
      + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="dscSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
      +
      -
      + + + + + + + + + + + + + } + fieldIcon={ + + } + fieldName={ + + clientip + + } + isActive={false} + onClick={[Function]} + size="m" > - -
      - - - - - - - - +
      + - + + + + + + - - - - + > + + + + + + + +
      -
      - + +
      -
      - - -
    • -
    • - + +
    • +
    • - - - - - - - - - - - - - - } - fieldIcon={ - - } - fieldName={ - - event - - } - isActive={false} - onClick={[Function]} - size="m" - /> + -
      -
      + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="dscSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
      +
      -
      + + + + + + + + + + + + + } + fieldIcon={ + + } + fieldName={ + + event + + } + isActive={false} + onClick={[Function]} + size="m" > - -
      - - - - - - - - +
      + - + + + + + + - - - - + > + + + + + + + +
      -
      - + +
      -
      - - -
    • -
    • - + +
    • +
    • - - - - - Override - - - - - - - - - - - - - } - fieldIcon={ - - } - fieldName={ - - extension - - } - isActive={false} - onClick={[Function]} - size="m" - /> + -
      -
      + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="dscSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
      +
      -
      + + + + Override + + + + + + + + + + + + + } + fieldIcon={ + + } + fieldName={ + + extension + + } + isActive={false} + onClick={[Function]} + size="m" > - -
      - - +
      + - - - - - - - - - - + + + + + + + + - + + + - - - - + > + + + + + + + +
      -
      - + +
      -
      - - -
    • -
    • - + +
    • +
    • - - - - - - - - - - - - - - } - fieldIcon={ - - } - fieldName={ - - geo - - } - isActive={false} - onClick={[Function]} - size="m" - /> + -
      -
      + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="dscSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
      +
      -
      + + + + + + + + + + + + + } + fieldIcon={ + + } + fieldName={ + + geo + + } + isActive={false} + onClick={[Function]} + size="m" > - -
      - - - - - - - - +
      + - + + + + + + - - - - + > + + + + + + + +
      -
      - + +
      -
      - - -
    • -
    • - + +
    • +
    • - - - - - Override - - - - - - - - - - - - - } - fieldIcon={ - - } - fieldName={ - - host - - } - isActive={false} - onClick={[Function]} - size="m" - /> + -
      -
      + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="dscSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
      +
      -
      + + + + Override + + + + + + + + + + + + + } + fieldIcon={ + + } + fieldName={ + + host + + } + isActive={false} + onClick={[Function]} + size="m" > - -
      - - +
      + - - - - - - - - - - + + + + + + + + - + + + - - - - + > + + + + + + + +
      -
      - + +
      -
      - - -
    • -
    • - + +
    • +
    • - - - - - Override - - - - - - - - - - - - - } - fieldIcon={ - - } - fieldName={ - - index - - } - isActive={false} - onClick={[Function]} - size="m" - /> + -
      -
      + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="dscSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
      +
      -
      + + + + Override + + + + + + + + + + + + + } + fieldIcon={ + + } + fieldName={ + + index + + } + isActive={false} + onClick={[Function]} + size="m" > - -
      - - +
      + - - - - - - - - - - + + - + + + - - - - + > + + + + + + + +
      -
      - + +
      -
      - - -
    • -
    • - + +
    • +
    • - - - - - - - - - - - - - - } - fieldIcon={ - - } - fieldName={ - - ip - - } - isActive={false} - onClick={[Function]} - size="m" - /> + -
      -
      + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="dscSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
      +
      -
      + + + + + + + + + + + + + } + fieldIcon={ + + } + fieldName={ + + ip + + } + isActive={false} + onClick={[Function]} + size="m" > - -
      - - - - - - - - +
      + - + + + + + + - - - - + > + + + + + + + +
      -
      - + +
      -
      - - -
    • -
    • - + +
    • +
    • - - - - - - - - - - - - - - } - fieldIcon={ - - } - fieldName={ - - machine - - } - isActive={false} - onClick={[Function]} - size="m" - /> + -
      -
      + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="dscSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
      +
      -
      + + + + + + + + + + + + + } + fieldIcon={ + + } + fieldName={ + + machine + + } + isActive={false} + onClick={[Function]} + size="m" > - -
      - - - - - - - - +
      + - + + + + + + - - - - + > + + + + + + + +
      -
      - + +
      -
      - - -
    • -
    • - + +
    • +
    • - - - - - - - - - - - - - - } - fieldIcon={ - - } - fieldName={ - - memory - - } - isActive={false} - onClick={[Function]} - size="m" - /> + -
      -
      + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="dscSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
      +
      -
      + + + + + + + + + + + + + } + fieldIcon={ + + } + fieldName={ + + memory + + } + isActive={false} + onClick={[Function]} + size="m" > - -
      - - - - - - - - +
      + - + + + + + + - - - - + > + + + + + + + +
      -
      - + +
      -
      - - -
    • -
    • - + +
    • +
    • - - - - - Override - - - - - - - - - - - - - } - fieldIcon={ - - } - fieldName={ - - message - - } - isActive={false} - onClick={[Function]} - size="m" - /> + -
      -
      + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="dscSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
      +
      -
      + + + + Override + + + + + + + + + + + + + } + fieldIcon={ + + } + fieldName={ + + message + + } + isActive={false} + onClick={[Function]} + size="m" > - -
      - - +
      + - - - - - - - - - - + + + + + + + + - + + + - - - - + > + + + + + + + +
      -
      - + +
      -
      - - -
    • -
    • - + +
    • +
    • - - - - - - - - - - - - - - } - fieldIcon={ - - } - fieldName={ - - phpmemory - - } - isActive={false} - onClick={[Function]} - size="m" - /> + -
      -
      + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="dscSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
      +
      -
      + + + + + + + + + + + + + } + fieldIcon={ + + } + fieldName={ + + phpmemory + + } + isActive={false} + onClick={[Function]} + size="m" > - -
      - - - - - - - - +
      + - + + + + + + - - - - + > + + + + + + + +
      -
      - + +
      -
      - - -
    • -
    • - + +
    • +
    • - - - - - Override - - - - - - - - - - - - - } - fieldIcon={ - - } - fieldName={ - - referer - - } - isActive={false} - onClick={[Function]} - size="m" - /> + -
      -
      + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="dscSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
      +
      -
      + + + + Override + + + + + + + + + + + + + } + fieldIcon={ + + } + fieldName={ + + referer + + } + isActive={false} + onClick={[Function]} + size="m" > - -
      - - +
      + - - - - - - - - - - + + + + + + + + - + + + - - - - + > + + + + + + + +
      -
      - + +
      -
      - - -
    • -
    • - + +
    • +
    • - - - - - Override - - - - - - - - - - - - - } - fieldIcon={ - - } - fieldName={ - - request - - } - isActive={false} - onClick={[Function]} - size="m" - /> + -
      -
      + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="dscSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
      +
      -
      + + + + Override + + + + + + + + + + + + + } + fieldIcon={ + + } + fieldName={ + + request + + } + isActive={false} + onClick={[Function]} + size="m" > - -
      - - +
      + - - - - - - - - - - + + + + + + + + - + + + - - - - + > + + + + + + + +
      -
      - + +
      -
      - - -
    • -
    • - + +
    • +
    • - - - - - Override - - - - - - - - - - - - - } - fieldIcon={ - - } - fieldName={ - - response - - } - isActive={false} - onClick={[Function]} - size="m" - /> + -
      -
      + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="dscSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
      +
      -
      + + + + Override + + + + + + + + + + + + + } + fieldIcon={ + + } + fieldName={ + + response + + } + isActive={false} + onClick={[Function]} + size="m" > - -
      - - +
      + - - - - - - - - - - + + + + + + + + - + + + - - - - + > + + + + + + + +
      -
      - + +
      -
      - - -
    • -
    • - + +
    • +
    • - - - - - Override - - - - - - - - - - - - - } - fieldIcon={ - - } - fieldName={ - - tags - - } - isActive={false} - onClick={[Function]} - size="m" - /> + -
      -
      + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="dscSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
      +
      -
      + + + + Override + + + + + + + + + + + + + } + fieldIcon={ + + } + fieldName={ + + tags + + } + isActive={false} + onClick={[Function]} + size="m" > - -
      - - +
      + - - - - - - - - - - + + + + + + + + - + + + - - - - -
      -
      - -
      -
      - - -
    • -
    • - - - - - - - - - Default Timestamp - - - - - - - - - - } - fieldIcon={ - - } - fieldName={ - - timestamp - - } - isActive={false} - onClick={[Function]} - size="m" - /> + + + + + +
    • +
      + +
    +
    + + + +
  • + -
    -
    + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="dscSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
    +
    -
    + + + + + + + Default Timestamp + + + + + + + + + + } + fieldIcon={ + + } + fieldName={ + + timestamp + + } + isActive={false} + onClick={[Function]} + size="m" > - -
    - - - - - +
    + - + + + - - Default Timestamp - - - - - - + Default Timestamp + + + + + - - - - - + > + + + + + + + +
    -
    - + +
    -
    - - -
  • -
  • - + +
  • +
  • - - - - - Override - - - - - - - - - - - - - } - fieldIcon={ - - } - fieldName={ - - url - - } - isActive={false} - onClick={[Function]} - size="m" - /> + -
    -
    + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="dscSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
    +
    -
    + + + + Override + + + + + + + + + + + + + } + fieldIcon={ + + } + fieldName={ + + url + + } + isActive={false} + onClick={[Function]} + size="m" > - -
    - - +
    + - - - - - - - - - - + + + + + + + + - + + + - - - - + > + + + + + + + +
    -
    - + +
    -
    - - -
  • -
  • - + +
  • +
  • - - - - - - - - Override - - - - - - - - - - } - fieldIcon={ - - } - fieldName={ - - utc_time - - } - isActive={false} - onClick={[Function]} - size="m" - /> + -
    -
    + + } + closePopover={[Function]} + display="block" + hasArrow={true} + isOpen={false} + ownFocus={true} + panelClassName="dscSidebarItem__fieldPopoverPanel" + panelPaddingSize="m" + > +
    +
    -
    + + + + + + + Override + + + + + + + + + + } + fieldIcon={ + + } + fieldName={ + + utc_time + + } + isActive={false} + onClick={[Function]} + size="m" > - -
    - - - - - +
    + - + + + - - - - - - + + + + + + + + - - - - - + > + + + + + + + +
    -
    - + +
    -
    - - -
  • - + + + + +
    -
    - + +
    -
    - - -
    -
    -
    -
    -
    + + + + + + + + `; diff --git a/public/components/event_analytics/explorer/sidebar/__tests__/sidebar.test.tsx b/public/components/event_analytics/explorer/sidebar/__tests__/sidebar.test.tsx index 6e1b9c5c7..ae18768c1 100644 --- a/public/components/event_analytics/explorer/sidebar/__tests__/sidebar.test.tsx +++ b/public/components/event_analytics/explorer/sidebar/__tests__/sidebar.test.tsx @@ -4,52 +4,64 @@ */ import { configure, mount } from 'enzyme'; +import { useDispatch, Provider } from 'react-redux'; +import { configureStore } from '@reduxjs/toolkit'; import Adapter from 'enzyme-adapter-react-16'; import React from 'react'; import { waitFor } from '@testing-library/react'; import { Sidebar } from '../sidebar'; -import { - SELECTED_FIELDS, +import { + SELECTED_FIELDS, AVAILABLE_FIELDS, UNSELECTED_FIELDS, - QUERIED_FIELDS + QUERIED_FIELDS, } from '../../../../../../common/constants/explorer'; -import { +import { AVAILABLE_FIELDS as SIDEBAR_AVAILABLE_FIELDS, QUERY_FIELDS, JSON_DATA, - JSON_DATA_ALL + JSON_DATA_ALL, } from '../../../../../../test/event_analytics_constants'; +jest.mock('react-redux', () => ({ + ...jest.requireActual('react-redux'), + useDispatch: jest.fn(), +})); + describe('Siderbar component', () => { configure({ adapter: new Adapter() }); + const store = configureStore({ + reducer: jest.fn(), + }); + beforeEach(() => { + useDispatch.mockClear(); + useDispatch.mockReturnValue(jest.fn()); + }); it('Renders empty sidebar component', async () => { const explorerFields = { [SELECTED_FIELDS]: [], [AVAILABLE_FIELDS]: [], [UNSELECTED_FIELDS]: [], - [QUERIED_FIELDS]: [] + [QUERIED_FIELDS]: [], }; - const handleAddField = jest.fn(); const handleOverrideTimestamp = jest.fn(); const selectedTimestamp = 'timestamp'; const explorerData = {}; - const handleRemoveField = jest.fn(); - + const wrapper = mount( - + + + ); - + wrapper.update(); await waitFor(() => { @@ -62,32 +74,30 @@ describe('Siderbar component', () => { [SELECTED_FIELDS]: [], [UNSELECTED_FIELDS]: [], [AVAILABLE_FIELDS]: SIDEBAR_AVAILABLE_FIELDS, - [QUERIED_FIELDS]: QUERY_FIELDS + [QUERIED_FIELDS]: QUERY_FIELDS, }; - const handleAddField = jest.fn(); const handleOverrideTimestamp = jest.fn(); const selectedTimestamp = 'timestamp'; const explorerData = { - 'jsonData': JSON_DATA, - 'jsonDataAll': JSON_DATA_ALL + jsonData: JSON_DATA, + jsonDataAll: JSON_DATA_ALL, }; - const handleRemoveField = jest.fn(); - + const wrapper = mount( - + + + ); await waitFor(() => { expect(wrapper).toMatchSnapshot(); }); }); -}); \ No newline at end of file +}); diff --git a/public/components/event_analytics/explorer/sidebar/sidebar.tsx b/public/components/event_analytics/explorer/sidebar/sidebar.tsx index 9b57aae09..f949047f5 100644 --- a/public/components/event_analytics/explorer/sidebar/sidebar.tsx +++ b/public/components/event_analytics/explorer/sidebar/sidebar.tsx @@ -3,12 +3,16 @@ * SPDX-License-Identifier: Apache-2.0 */ -import React, { useState } from 'react'; +import React, { useState, useCallback, useContext } from 'react'; +import { batch, useDispatch } from 'react-redux'; import { isEmpty } from 'lodash'; import { EuiTitle, EuiSpacer, EuiFieldSearch, EuiAccordion } from '@elastic/eui'; import { I18nProvider } from '@osd/i18n/react'; import { Field } from './field'; -import { IExplorerFields, IField } from '../../../../../common/types/explorer'; +import { ExplorerFields, IExplorerFields, IField } from '../../../../../common/types/explorer'; +import { AVAILABLE_FIELDS, SELECTED_FIELDS } from '../../../../../common/constants/explorer'; +import { sortFields, updateFields } from '../../redux/slices/field_slice'; +import { TabContext } from '../../hooks/use_tab_context'; interface ISidebarProps { query: string; @@ -21,8 +25,6 @@ interface ISidebarProps { isFieldToggleButtonDisabled: boolean; handleOverridePattern: (pattern: IField) => void; handleOverrideTimestamp: (timestamp: IField) => void; - handleAddField: (field: IField) => void; - handleRemoveField: (field: IField) => void; } export const Sidebar = (props: ISidebarProps) => { @@ -37,13 +39,76 @@ export const Sidebar = (props: ISidebarProps) => { isFieldToggleButtonDisabled, handleOverridePattern, handleOverrideTimestamp, - handleAddField, - handleRemoveField, } = props; + const dispatch = useDispatch(); + const { tabId } = useContext(TabContext); const [showFields, setShowFields] = useState(false); const [searchTerm, setSearchTerm] = useState(''); + /** + * Toggle fields between selected and unselected sets + * @param fieldState all fields in store + * @param field field to be toggled + * @param FieldSetToRemove the set where this field to be removed from + * @param FieldSetToAdd the set where this field to be added to + * returns new fields state + */ + const toggleFields = ( + fieldState: ExplorerFields, + field: IField, + fieldSetToRemove: string, + fieldSetToAdd: string + ): ExplorerFields => { + const nextFields = { ...fieldState }; + nextFields[fieldSetToRemove] = nextFields[fieldSetToRemove].filter( + (fd: IField) => fd.name !== field.name + ); + nextFields[fieldSetToAdd] = [...nextFields[fieldSetToAdd], field]; + return nextFields; + }; + + const updateStoreFields = (fieldsData: ExplorerFields, tabID: string, modifiedField: string) => { + batch(() => { + dispatch( + updateFields({ + tabId: tabID, + data: { + ...fieldsData, + }, + }) + ); + dispatch( + sortFields({ + tabId: tabID, + data: [modifiedField], + }) + ); + }); + }; + + const handleAddField = useCallback( + (field: IField) => { + updateStoreFields( + toggleFields(explorerFields, field, AVAILABLE_FIELDS, SELECTED_FIELDS), + tabId, + SELECTED_FIELDS + ); + }, + [explorerFields, tabId] + ); + + const handleRemoveField = useCallback( + (field: IField) => { + updateStoreFields( + toggleFields(explorerFields, field, SELECTED_FIELDS, AVAILABLE_FIELDS), + tabId, + AVAILABLE_FIELDS + ); + }, + [explorerFields, tabId] + ); + return (
    diff --git a/public/components/event_analytics/explorer/visualizations/index.tsx b/public/components/event_analytics/explorer/visualizations/index.tsx index 11efb16f2..41b6eab6a 100644 --- a/public/components/event_analytics/explorer/visualizations/index.tsx +++ b/public/components/event_analytics/explorer/visualizations/index.tsx @@ -29,8 +29,6 @@ interface IExplorerVisualizationsProps { explorerVis: any; explorerFields: ExplorerFields; explorerData: any; - handleAddField: (field: IField) => void; - handleRemoveField: (field: IField) => void; visualizations: IVisualizationContainerProps; handleOverrideTimestamp: (field: IField) => void; callback?: any; @@ -44,8 +42,6 @@ export const ExplorerVisualizations = ({ explorerVis, explorerFields, explorerData, - handleAddField, - handleRemoveField, visualizations, handleOverrideTimestamp, callback, @@ -111,8 +107,6 @@ export const ExplorerVisualizations = ({ explorerData={explorerData} selectedTimestamp={visualizations?.data?.query[SELECTED_TIMESTAMP] || ''} handleOverrideTimestamp={handleOverrideTimestamp} - handleAddField={(field: IField) => handleAddField(field)} - handleRemoveField={(field: IField) => handleRemoveField(field)} isFieldToggleButtonDisabled={ vis.name === VIS_CHART_TYPES.LogsView ? isEmpty(explorerData.jsonData) || diff --git a/public/components/event_analytics/hooks/use_fetch_events.ts b/public/components/event_analytics/hooks/use_fetch_events.ts index 4bab88084..bbcbb4b78 100644 --- a/public/components/event_analytics/hooks/use_fetch_events.ts +++ b/public/components/event_analytics/hooks/use_fetch_events.ts @@ -83,6 +83,7 @@ export const useFetchEvents = ({ pplService, requestParams }: IFetchEventsParams [UNSELECTED_FIELDS]: res?.schema ? [...res.schema] : [], [QUERIED_FIELDS]: [], [AVAILABLE_FIELDS]: res?.schema || [], + [SELECTED_FIELDS]: [], }, }) );