Kaynağa Gözat

Allow to edit active smart filter

michalcesek 2 yıl önce
ebeveyn
işleme
6d380bf8a8

+ 1 - 1
kafka-ui-react-app/src/components/Topics/Topic/Messages/Filters/EditFilter.tsx

@@ -22,7 +22,7 @@ const EditFilter: React.FC<EditFilterProps> = ({
   };
   return (
     <>
-      <S.FilterTitle>Edit saved filter</S.FilterTitle>
+      <S.FilterTitle>Edit filter</S.FilterTitle>
       <AddEditFilterContainer
         cancelBtnHandler={() => toggleEditModal()}
         submitBtnText="Save"

+ 28 - 24
kafka-ui-react-app/src/components/Topics/Topic/Messages/Filters/FilterModal.tsx

@@ -1,17 +1,18 @@
 import React from 'react';
 import * as S from 'components/Topics/Topic/Messages/Filters/Filters.styled';
-import { MessageFilters } from 'components/Topics/Topic/Messages/Filters/Filters';
+import { ActiveMessageFilter, MessageFilters } from 'components/Topics/Topic/Messages/Filters/Filters';
 import AddFilter from 'components/Topics/Topic/Messages/Filters/AddFilter';
 import EditFilter from 'components/Topics/Topic/Messages/Filters/EditFilter';
 
 export interface FilterModalProps {
   toggleIsOpen(): void;
-  filters: MessageFilters[];
-  addFilter(values: MessageFilters): void;
-  deleteFilter(index: number): void;
-  activeFilterHandler(activeFilter: MessageFilters, index: number): void;
+  filters?: MessageFilters[];
+  addFilter?(values: MessageFilters): void;
+  deleteFilter?(index: number): void;
+  activeFilterHandler?(activeFilter: MessageFilters, index: number): void;
   editSavedFilter(filter: FilterEdit): void;
-  activeFilter?: MessageFilters;
+  activeFilter?: ActiveMessageFilter;
+  quickEditMode?: boolean
 }
 
 export interface FilterEdit {
@@ -27,45 +28,48 @@ const FilterModal: React.FC<FilterModalProps> = ({
   activeFilterHandler,
   editSavedFilter,
   activeFilter,
-}) => {
-  const [addFilterModal, setAddFilterModal] = React.useState<boolean>(true);
+  quickEditMode = false,
+  }) => {
+  const [isInEditMode, setIsInEditMode] = React.useState<boolean>(quickEditMode);
   const [isSavedFiltersOpen, setIsSavedFiltersOpen] =
     React.useState<boolean>(false);
 
   const toggleEditModal = () => {
-    setAddFilterModal(!addFilterModal);
+    setIsInEditMode(!isInEditMode);
   };
 
-  const [editFilter, setEditFilter] = React.useState<FilterEdit>({
-    index: -1,
-    filter: { name: '', code: '' },
+  const [editFilter, setEditFilter] = React.useState<FilterEdit>( () => {
+    const {index, name, code} = activeFilter!;
+    return quickEditMode ? { index, filter: { name, code } } : { index: -1, filter: { name: "", code: "" } };
   });
   const editFilterHandler = (value: FilterEdit) => {
     setEditFilter(value);
-    setAddFilterModal(!addFilterModal);
+    setIsInEditMode(!isInEditMode);
   };
 
+  const toggleEditModalHandler = quickEditMode ? toggleIsOpen : toggleEditModal;
+
   return (
     <S.MessageFilterModal data-testid="messageFilterModal">
-      {addFilterModal ? (
+      {isInEditMode ? (
+          <EditFilter
+            editFilter={editFilter}
+            toggleEditModal={toggleEditModalHandler}
+            editSavedFilter={editSavedFilter}
+          />
+      ) : (
         <AddFilter
           toggleIsOpen={toggleIsOpen}
-          filters={filters}
-          addFilter={addFilter}
-          deleteFilter={deleteFilter}
-          activeFilterHandler={activeFilterHandler}
+          filters={filters!}
+          addFilter={addFilter!}
+          deleteFilter={deleteFilter!}
+          activeFilterHandler={activeFilterHandler!}
           toggleEditModal={toggleEditModal}
           editFilter={editFilterHandler}
           isSavedFiltersOpen={isSavedFiltersOpen}
           onClickSavedFilters={() => setIsSavedFiltersOpen(!isSavedFiltersOpen)}
           activeFilter={activeFilter}
         />
-      ) : (
-        <EditFilter
-          editFilter={editFilter}
-          toggleEditModal={toggleEditModal}
-          editSavedFilter={editSavedFilter}
-        />
       )}
     </S.MessageFilterModal>
   );

+ 61 - 14
kafka-ui-react-app/src/components/Topics/Topic/Messages/Filters/Filters.styled.ts

@@ -2,6 +2,8 @@ import Input from 'components/common/Input/Input';
 import Select from 'components/common/Select/Select';
 import styled, { css } from 'styled-components';
 import DatePicker from 'react-datepicker';
+import EditIcon from 'components/common/Icons/EditIcon';
+import closeIcon from 'components/common/Icons/CloseIcon';
 
 interface SavedFilterProps {
   selected: boolean;
@@ -280,28 +282,73 @@ export const SavedFilter = styled.div.attrs({
 `;
 
 export const ActiveSmartFilter = styled.div`
-  border-radius: 4px;
-  min-width: 115px;
-  height: 24px;
-  background: ${({ theme }) => theme.savedFilter.backgroundColor};
-  font-size: 14px;
-  line-height: 20px;
   display: flex;
   align-items: center;
   justify-content: space-between;
-  color: ${({ theme }) => theme.savedFilter.color};
-  padding: 16px 8px;
+  height: 32px;
+  color: ${({ theme }) => theme.activeFilter.color};
+  background: ${({ theme }) => theme.activeFilter.backgroundColor};
+  border-radius: 4px;
+  font-size: 14px;
+  line-height: 20px;
+
 `;
 
-export const DeleteSavedFilterIcon = styled.div`
-  color: ${({ theme }) => theme.icons.closeIcon};
+
+export const EditSmartFilterIcon = styled.div(
+  ({ theme: { icons } }) => css`
+    color: ${({ theme }) => theme.icons.editIcon.normal};
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    height: 32px;
+    width: 32px;
+    cursor: pointer;
+    border-left: 1px solid ${icons.editIcon.border};
+
+    &:hover {
+      ${EditIcon} {
+        fill: ${icons.editIcon.hover};
+      }
+    }
+
+    &:active {
+      ${EditIcon} {
+        fill: ${icons.editIcon.active};
+      }
+    }
+  `
+);
+
+export const SmartFilterName = styled.div(
+  ({ theme: { icons } }) => css`
+    padding: 0 8px;
+    min-width: 32px;
+  `);
+
+export const DeleteSmartFilterIcon = styled.div(
+  ({ theme: { icons } }) => css`
+  color: ${({ theme }) => theme.icons.closeIcon.normal};
   display: flex;
   align-items: center;
-  padding-left: 6px;
-  height: 24px;
+  justify-content: center;
+  height: 32px;
+  width: 32px;
   cursor: pointer;
-  margin-left: 4px;
-`;
+  border-left: 1px solid ${icons.closeIcon.border};
+
+  &:hover {
+    ${closeIcon} {
+      fill: ${icons.closeIcon.hover};
+    }
+  }
+
+  &:active {
+    ${closeIcon} {
+      fill: ${icons.closeIcon.active};
+    }
+  }
+`);
 
 export const MessageLoading = styled.div.attrs({
   role: 'contentLoader',

+ 44 - 17
kafka-ui-react-app/src/components/Topics/Topic/Messages/Filters/Filters.tsx

@@ -30,6 +30,7 @@ import useBoolean from 'lib/hooks/useBoolean';
 import { RouteParamsClusterTopic } from 'lib/paths';
 import useAppParams from 'lib/hooks/useAppParams';
 import PlusIcon from 'components/common/Icons/PlusIcon';
+import EditIcon from 'components/common/Icons/EditIcon';
 import CloseIcon from 'components/common/Icons/CloseIcon';
 import ClockIcon from 'components/common/Icons/ClockIcon';
 import ArrowDownIcon from 'components/common/Icons/ArrowDownIcon';
@@ -67,7 +68,7 @@ export interface MessageFilters {
   code: string;
 }
 
-interface ActiveMessageFilter {
+export interface ActiveMessageFilter {
   index: number;
   name: string;
   code: string;
@@ -108,6 +109,8 @@ const Filters: React.FC<FiltersProps> = ({
 
   const { value: isOpen, toggle } = useBoolean();
 
+  const { value: isQuickEditOpen, toggle: toggleQuickEdit } = useBoolean();
+
   const source = React.useRef<EventSource | null>(null);
 
   const [selectedPartitions, setSelectedPartitions] = React.useState<Option[]>(
@@ -307,27 +310,37 @@ const Filters: React.FC<FiltersProps> = ({
     setActiveFilter({ index, ...newActiveFilter });
     setQueryType(MessageFilterType.GROOVY_SCRIPT);
   };
+
+  const composeMessageFilter = (filter: FilterEdit) : ActiveMessageFilter => ({
+    index: filter.index,
+    name: filter.filter.name,
+    code: filter.filter.code,
+  });
+
+  const storeAsActiveFilter = (filter: FilterEdit) => {
+    const messageFilter = JSON.stringify(composeMessageFilter(filter));
+    localStorage.setItem('activeFilter', messageFilter);
+  }
+
   const editSavedFilter = (filter: FilterEdit) => {
     const filters = [...savedFilters];
     filters[filter.index] = filter.filter;
     if (activeFilter.name && activeFilter.index === filter.index) {
-      setActiveFilter({
-        index: filter.index,
-        name: filter.filter.name,
-        code: filter.filter.code,
-      });
-      localStorage.setItem(
-        'activeFilter',
-        JSON.stringify({
-          index: filter.index,
-          name: filter.filter.name,
-          code: filter.filter.code,
-        })
-      );
+      setActiveFilter(composeMessageFilter(filter));
+      storeAsActiveFilter(filter);
     }
     localStorage.setItem('savedFilters', JSON.stringify(filters));
     setSavedFilters(filters);
   };
+
+  const editCurrentFilter = (filter: FilterEdit) => {
+    if (filter.index < 0) {
+      setActiveFilter(composeMessageFilter(filter));
+      storeAsActiveFilter(filter);
+    } else {
+      editSavedFilter(filter);
+    }
+  };
   // eslint-disable-next-line consistent-return
   React.useEffect(() => {
     if (location.search?.length !== 0) {
@@ -542,13 +555,27 @@ const Filters: React.FC<FiltersProps> = ({
         </Button>
         {activeFilter.name && (
           <S.ActiveSmartFilter data-testid="activeSmartFilter">
-            {activeFilter.name}
-            <S.DeleteSavedFilterIcon onClick={deleteActiveFilter}>
+            <S.SmartFilterName>
+              {activeFilter.name}
+            </S.SmartFilterName>
+            <S.EditSmartFilterIcon onClick={toggleQuickEdit}>
+              <EditIcon />
+            </S.EditSmartFilterIcon>
+            <S.DeleteSmartFilterIcon onClick={deleteActiveFilter}>
               <CloseIcon />
-            </S.DeleteSavedFilterIcon>
+            </S.DeleteSmartFilterIcon>
           </S.ActiveSmartFilter>
         )}
       </S.ActiveSmartFilterWrapper>
+      {isQuickEditOpen &&
+        <FilterModal
+          quickEditMode
+          activeFilter={activeFilter}
+          toggleIsOpen={toggleQuickEdit}
+          editSavedFilter={editCurrentFilter}
+        />
+      }
+
       {isOpen && (
         <FilterModal
           toggleIsOpen={toggle}

+ 33 - 5
kafka-ui-react-app/src/theme/theme.ts

@@ -161,7 +161,18 @@ const baseTheme = {
   },
   icons: {
     chevronDownIcon: Colors.neutral[0],
-    editIcon: Colors.neutral[30],
+    editIcon: {
+      normal: Colors.neutral[30],
+      hover: Colors.neutral[90],
+      active: Colors.neutral[100],
+      border: Colors.neutral[10]
+    },
+    closeIcon: {
+      normal: Colors.neutral[30],
+      hover: Colors.neutral[90],
+      active: Colors.neutral[100],
+      border: Colors.neutral[10]
+    },
     cancelIcon: Colors.neutral[30],
     autoIcon: Colors.neutral[95],
     fileIcon: Colors.neutral[90],
@@ -170,7 +181,7 @@ const baseTheme = {
     moonIcon: Colors.neutral[95],
     sunIcon: Colors.neutral[95],
     infoIcon: Colors.neutral[30],
-    closeIcon: Colors.neutral[30],
+    closeCircleIcon: Colors.neutral[30],
     deleteIcon: Colors.red[20],
     warningIcon: Colors.yellow[20],
     warningRedIcon: {
@@ -678,10 +689,13 @@ export const theme = {
       color: Colors.neutral[80],
     },
   },
+  activeFilter: {
+    color: Colors.neutral[70],
+    backgroundColor: Colors.neutral[5],
+  },
   savedFilter: {
     filterName: Colors.neutral[90],
     color: Colors.neutral[30],
-    backgroundColor: Colors.neutral[5],
   },
   editFilter: {
     textColor: Colors.brand[50],
@@ -1073,10 +1087,13 @@ export const darkTheme: ThemeType = {
       color: Colors.neutral[0],
     },
   },
+  activeFilter: {
+    color: Colors.neutral[0],
+    backgroundColor: Colors.neutral[80],
+  },
   savedFilter: {
     filterName: Colors.neutral[0],
     color: Colors.neutral[70],
-    backgroundColor: Colors.neutral[80],
   },
   editFilter: {
     textColor: Colors.brand[30],
@@ -1102,7 +1119,18 @@ export const darkTheme: ThemeType = {
   },
   icons: {
     ...baseTheme.icons,
-    editIcon: Colors.neutral[0],
+    editIcon: {
+      normal: Colors.neutral[50],
+      hover: Colors.neutral[30],
+      active: Colors.neutral[40],
+      border: Colors.neutral[70]
+    },
+    closeIcon: {
+      normal: Colors.neutral[50],
+      hover: Colors.neutral[30],
+      active: Colors.neutral[40],
+      border: Colors.neutral[70]
+    },
     cancelIcon: Colors.neutral[0],
     autoIcon: Colors.neutral[0],
     fileIcon: Colors.neutral[0],