Allow to edit active smart filter

This commit is contained in:
michalcesek 2023-04-27 17:23:48 +07:00
parent a391eb2f92
commit 6d380bf8a8
5 changed files with 167 additions and 61 deletions

View file

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

View file

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

View file

@ -2,6 +2,8 @@ import Input from 'components/common/Input/Input';
import Select from 'components/common/Select/Select'; import Select from 'components/common/Select/Select';
import styled, { css } from 'styled-components'; import styled, { css } from 'styled-components';
import DatePicker from 'react-datepicker'; import DatePicker from 'react-datepicker';
import EditIcon from 'components/common/Icons/EditIcon';
import closeIcon from 'components/common/Icons/CloseIcon';
interface SavedFilterProps { interface SavedFilterProps {
selected: boolean; selected: boolean;
@ -280,28 +282,73 @@ export const SavedFilter = styled.div.attrs({
`; `;
export const ActiveSmartFilter = styled.div` 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; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
color: ${({ theme }) => theme.savedFilter.color}; height: 32px;
padding: 16px 8px; 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; display: flex;
align-items: center; align-items: center;
padding-left: 6px; justify-content: center;
height: 24px; height: 32px;
width: 32px;
cursor: pointer; cursor: pointer;
margin-left: 4px; 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;
justify-content: center;
height: 32px;
width: 32px;
cursor: pointer;
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({ export const MessageLoading = styled.div.attrs({
role: 'contentLoader', role: 'contentLoader',

View file

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

View file

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