Skip to content

Commit

Permalink
[GEN-1760]: preserve filters-state for destinations modal (#1862)
Browse files Browse the repository at this point in the history
  • Loading branch information
BenElferink authored Nov 26, 2024
1 parent 9707d28 commit 47fa3b3
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 86 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,58 +2,82 @@ import React, { useMemo, useState } from 'react';
import styled from 'styled-components';
import { SignalUppercase } from '@/utils';
import { useDestinationTypes } from '@/hooks';
import type { DestinationTypeItem } from '@/types';
import { DestinationsList } from './destinations-list';
import { Divider, SectionTitle } from '@/reuseable-components';
import type { DropdownOption, DestinationTypeItem } from '@/types';
import { ChooseDestinationFilters } from './choose-destination-filters';
import { Divider, Dropdown, Input, MonitoringCheckboxes, SectionTitle } from '@/reuseable-components';

interface Props {
onSelect: (item: DestinationTypeItem) => void;
hidden?: boolean;
}

const DEFAULT_MONITORS: SignalUppercase[] = ['LOGS', 'METRICS', 'TRACES'];
const DEFAULT_DROPDOWN_VALUE = { id: 'all', value: 'All types' };

const Container = styled.div`
display: flex;
flex-direction: column;
gap: 24px;
`;

export const ChooseDestinationBody: React.FC<Props> = ({ onSelect }) => {
const [searchValue, setSearchValue] = useState('');
const Filters = styled.div`
display: flex;
align-items: center;
gap: 12px;
`;

const WidthConstraint = styled.div`
width: 160px;
margin-right: 8px;
`;

const DROPDOWN_OPTIONS = [
{ value: 'All types', id: 'all' },
{ value: 'Managed', id: 'managed' },
{ value: 'Self-hosted', id: 'self hosted' },
];

const DEFAULT_CATEGORY = DROPDOWN_OPTIONS[0];
const DEFAULT_MONITORS: SignalUppercase[] = ['LOGS', 'METRICS', 'TRACES'];

export const ChooseDestinationBody: React.FC<Props> = ({ onSelect, hidden }) => {
const [search, setSearch] = useState('');
const [selectedCategory, setSelectedCategory] = useState(DEFAULT_CATEGORY);
const [selectedMonitors, setSelectedMonitors] = useState<SignalUppercase[]>(DEFAULT_MONITORS);
const [dropdownValue, setDropdownValue] = useState<DropdownOption>(DEFAULT_DROPDOWN_VALUE);

const { destinations } = useDestinationTypes();
const { destinations: destinationTypes } = useDestinationTypes();

const filteredDestinations = useMemo(() => {
return destinations
return destinationTypes
.map((category) => {
const filteredItems = category.items.filter((item) => {
const matchesSearch = searchValue ? item.displayName.toLowerCase().includes(searchValue.toLowerCase()) : true;
const matchesDropdown = dropdownValue.id !== 'all' ? category.name === dropdownValue.id : true;
const matchesMonitor = selectedMonitors.length ? selectedMonitors.some((monitor) => item.supportedSignals[monitor.toLowerCase()]?.supported) : true;
const matchesSearch = !search || item.displayName.toLowerCase().includes(search.toLowerCase());
const matchesCategory = selectedCategory.id === 'all' || selectedCategory.id === category.name;
const matchesMonitor = selectedMonitors.some((monitor) => item.supportedSignals[monitor.toLowerCase()]?.supported);

return matchesSearch && matchesDropdown && matchesMonitor;
return matchesSearch && matchesCategory && matchesMonitor;
});

return { ...category, items: filteredItems };
})
.filter((category) => category.items.length > 0); // Filter out empty categories
}, [destinations, searchValue, dropdownValue, selectedMonitors]);
.filter(({ items }) => !!items.length); // Filter out empty categories
}, [destinationTypes, search, selectedCategory, selectedMonitors]);

if (hidden) return null;

return (
<Container>
<SectionTitle title='Choose destination' description='Add backend destination you want to connect with Odigos.' />
<ChooseDestinationFilters
selectedTag={dropdownValue}
onTagSelect={(opt) => setDropdownValue(opt)}
onSearch={setSearchValue}
selectedMonitors={selectedMonitors}
setSelectedMonitors={setSelectedMonitors}
/>

<Filters>
<WidthConstraint>
<Input placeholder='Search...' icon='/icons/common/search.svg' value={search} onChange={({ target: { value } }) => setSearch(value)} />
</WidthConstraint>
<WidthConstraint>
<Dropdown options={DROPDOWN_OPTIONS} value={selectedCategory} onSelect={(opt) => setSelectedCategory(opt)} onDeselect={() => {}} />
</WidthConstraint>
<MonitoringCheckboxes title='' selectedSignals={selectedMonitors} setSelectedSignals={setSelectedMonitors} />
</Filters>

<Divider />

<DestinationsList items={filteredDestinations} setSelectedItems={onSelect} />
</Container>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,13 @@ export const DestinationModal: React.FC<AddDestinationModalProps> = ({ isOnboard
</SideMenuWrapper>

<ModalBody style={{ margin: '32px 24px 0 24px' }}>
{!!selectedItem ? (
{/*
in other modals we would render this out, but for this case we will use "hidden" instead,
this is to preserve the filters-state when going back-and-forth between selections
*/}
<ChooseDestinationBody onSelect={handleSelect} hidden={!!selectedItem} />

{!!selectedItem && (
<DestinationFormBody
destination={selectedItem}
isFormOk={isFormOk}
Expand All @@ -132,8 +138,6 @@ export const DestinationModal: React.FC<AddDestinationModalProps> = ({ isOnboard
dynamicFields={dynamicFields}
setDynamicFields={setDynamicFields}
/>
) : (
<ChooseDestinationBody onSelect={handleSelect} />
)}
</ModalBody>
</Container>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,15 @@ const MonitoringCheckboxes: React.FC<Props> = ({ isVertical, title = 'Monitoring
const recordedRows = useRef(JSON.stringify(selectedSignals));

useEffect(() => {
const payload: SignalUppercase[] = [];

monitors.forEach(({ type }) => {
if (isAllowed(type, allowedSignals)) {
payload.push(type.toUpperCase() as SignalUppercase);
}
});
const payload: SignalUppercase[] = selectedSignals;

if (!payload.length) {
monitors.forEach(({ type }) => {
if (isAllowed(type, allowedSignals)) {
payload.push(type.toUpperCase() as SignalUppercase);
}
});
}

const stringified = JSON.stringify(payload);

Expand Down

0 comments on commit 47fa3b3

Please sign in to comment.