Skip to content

Commit d70c279

Browse files
refactor: split EventLog into separate components and hook up new Event search (#7777)
Hooks up the new Event search and filtering capabilities to the new Event Log component. In doing so, it also splits the existing EventLog component into two: `LegacyEventLog` and `NewEventLog`. The naming is probably temporary, as the old EventLog isn't really legacy yet. But we can rename them later. The other half of #7768 .
1 parent d4069f2 commit d70c279

File tree

2 files changed

+135
-53
lines changed

2 files changed

+135
-53
lines changed

frontend/src/component/events/EventLog/EventLog.tsx

Lines changed: 118 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
1515
import { useUiFlag } from 'hooks/useUiFlag';
1616
import { EventLogFilters } from './EventLogFilters';
1717
import type { EventSchema } from 'openapi';
18+
import { useEventLogSearch } from './useEventLogSearch';
1819

1920
interface IEventLogProps {
2021
title: string;
@@ -41,7 +42,98 @@ const EventResultWrapper = styled('div')(({ theme }) => ({
4142
gap: theme.spacing(1),
4243
}));
4344

44-
export const EventLog = ({ title, project, feature }: IEventLogProps) => {
45+
const NewEventLog = ({ title, project, feature }: IEventLogProps) => {
46+
const { events, total, loading, tableState, setTableState, filterState } =
47+
useEventLogSearch(
48+
project
49+
? { type: 'project', projectId: project }
50+
: feature
51+
? { type: 'flag', flagName: feature }
52+
: { type: 'global' },
53+
);
54+
55+
const setSearchValue = (query = '') => {
56+
setTableState({ query });
57+
};
58+
const { eventSettings, setEventSettings } = useEventSettings();
59+
const isSmallScreen = useMediaQuery(theme.breakpoints.down('md'));
60+
61+
const onShowData = () => {
62+
setEventSettings((prev) => ({ showData: !prev.showData }));
63+
};
64+
65+
const searchInputField = (
66+
<Search
67+
onChange={setSearchValue}
68+
initialValue={tableState.query || ''}
69+
debounceTime={500}
70+
/>
71+
);
72+
73+
const showDataSwitch = (
74+
<FormControlLabel
75+
label='Full events'
76+
control={
77+
<Switch
78+
checked={eventSettings.showData}
79+
onChange={onShowData}
80+
color='primary'
81+
/>
82+
}
83+
/>
84+
);
85+
86+
const resultComponent = () => {
87+
if (loading) {
88+
return <p>Loading...</p>;
89+
} else if (events.length === 0) {
90+
return <p>No events found.</p>;
91+
} else {
92+
return (
93+
<StyledEventsList>
94+
{events.map((entry) => (
95+
<ConditionallyRender
96+
key={entry.id}
97+
condition={eventSettings.showData}
98+
show={() => <EventJson entry={entry} />}
99+
elseShow={() => <EventCard entry={entry} />}
100+
/>
101+
))}
102+
</StyledEventsList>
103+
);
104+
}
105+
};
106+
107+
return (
108+
<PageContent
109+
bodyClass={'no-padding'}
110+
header={
111+
<PageHeader
112+
title={`${title} (${total})`}
113+
actions={
114+
<>
115+
{showDataSwitch}
116+
{!isSmallScreen && searchInputField}
117+
</>
118+
}
119+
>
120+
{isSmallScreen && searchInputField}
121+
</PageHeader>
122+
}
123+
>
124+
<EventResultWrapper>
125+
<StyledFilters
126+
logType={project ? 'project' : feature ? 'flag' : 'global'}
127+
state={filterState}
128+
onChange={setTableState}
129+
/>
130+
{resultComponent()}
131+
</EventResultWrapper>
132+
</PageContent>
133+
);
134+
};
135+
136+
export const LegacyEventLog = ({ title, project, feature }: IEventLogProps) => {
45137
const [query, setQuery] = useState('');
46138
const { events, totalEvents, fetchNextPage } = useLegacyEventSearch(
47139
project,
@@ -51,8 +143,6 @@ export const EventLog = ({ title, project, feature }: IEventLogProps) => {
51143
const fetchNextPageRef = useOnVisible<HTMLDivElement>(fetchNextPage);
52144
const { eventSettings, setEventSettings } = useEventSettings();
53145
const isSmallScreen = useMediaQuery(theme.breakpoints.down('md'));
54-
const { isEnterprise } = useUiConfig();
55-
const showFilters = useUiFlag('newEventSearch') && isEnterprise();
56146

57147
// Cache the previous search results so that we can show those while
58148
// fetching new results for a new search query in the background.
@@ -82,33 +172,8 @@ export const EventLog = ({ title, project, feature }: IEventLogProps) => {
82172
const totalCount = totalEvents || 0;
83173
const countText = `${count} of ${totalCount}`;
84174

85-
const EventResults = (
86-
<>
87-
<ConditionallyRender
88-
condition={Boolean(cache && cache.length === 0)}
89-
show={<p>No events found.</p>}
90-
/>
91-
<ConditionallyRender
92-
condition={Boolean(cache && cache.length > 0)}
93-
show={
94-
<StyledEventsList>
95-
{cache?.map((entry) => (
96-
<ConditionallyRender
97-
key={entry.id}
98-
condition={eventSettings.showData}
99-
show={() => <EventJson entry={entry} />}
100-
elseShow={() => <EventCard entry={entry} />}
101-
/>
102-
))}
103-
</StyledEventsList>
104-
}
105-
/>
106-
</>
107-
);
108-
109175
return (
110176
<PageContent
111-
bodyClass={showFilters ? 'no-padding' : ''}
112177
header={
113178
<PageHeader
114179
title={`${title} (${countText})`}
@@ -124,25 +189,35 @@ export const EventLog = ({ title, project, feature }: IEventLogProps) => {
124189
}
125190
>
126191
<ConditionallyRender
127-
condition={showFilters}
192+
condition={Boolean(cache && cache.length === 0)}
193+
show={<p>No events found.</p>}
194+
/>
195+
<ConditionallyRender
196+
condition={Boolean(cache && cache.length > 0)}
128197
show={
129-
<EventResultWrapper>
130-
<StyledFilters
131-
logType={
132-
project
133-
? 'project'
134-
: feature
135-
? 'flag'
136-
: 'global'
137-
}
138-
/>
139-
{EventResults}
140-
</EventResultWrapper>
198+
<StyledEventsList>
199+
{cache?.map((entry) => (
200+
<ConditionallyRender
201+
key={entry.id}
202+
condition={eventSettings.showData}
203+
show={() => <EventJson entry={entry} />}
204+
elseShow={() => <EventCard entry={entry} />}
205+
/>
206+
))}
207+
</StyledEventsList>
141208
}
142-
elseShow={EventResults}
143209
/>
144-
145210
<div ref={fetchNextPageRef} />
146211
</PageContent>
147212
);
148213
};
214+
215+
export const EventLog = (props: IEventLogProps) => {
216+
const { isEnterprise } = useUiConfig();
217+
const showFilters = useUiFlag('newEventSearch') && isEnterprise();
218+
if (showFilters) {
219+
return <NewEventLog {...props} />;
220+
} else {
221+
return <LegacyEventLog {...props} />;
222+
}
223+
};

frontend/src/component/events/EventLog/EventLogFilters.tsx

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
import { useState, useEffect, type FC } from 'react';
2-
import { Filters, type IFilterItem } from 'component/filter/Filters/Filters';
2+
import {
3+
type FilterItemParamHolder,
4+
Filters,
5+
type IFilterItem,
6+
} from 'component/filter/Filters/Filters';
37
import useProjects from 'hooks/api/getters/useProjects/useProjects';
48
import { useFeatureSearch } from 'hooks/api/getters/useFeatureSearch/useFeatureSearch';
59
import { EventSchemaType } from 'openapi';
@@ -30,14 +34,13 @@ const sharedFilters: IFilterItem[] = [
3034
pluralOperators: ['IS_ANY_OF'],
3135
},
3236
{
33-
// todo fill this in with actual values
3437
label: 'Event type',
3538
icon: 'announcement',
3639
options: Object.entries(EventSchemaType).map(([key, value]) => ({
3740
label: key,
3841
value: value,
3942
})),
40-
filterKey: 'eventType',
43+
filterKey: 'type',
4144
singularOperators: ['IS'],
4245
pluralOperators: ['IS_ANY_OF'],
4346
},
@@ -46,11 +49,15 @@ const sharedFilters: IFilterItem[] = [
4649
type EventLogFiltersProps = {
4750
logType: 'flag' | 'project' | 'global';
4851
className?: string;
52+
state: FilterItemParamHolder;
53+
onChange: (value: FilterItemParamHolder) => void;
4954
};
50-
export const EventLogFilters: FC<EventLogFiltersProps> = (
51-
{ logType, className },
52-
// {state, onChange,} // these are to fill in later to make the filters work
53-
) => {
55+
export const EventLogFilters: FC<EventLogFiltersProps> = ({
56+
logType,
57+
className,
58+
state,
59+
onChange,
60+
}) => {
5461
const { projects } = useProjects();
5562
const { features } = useFeatureSearch({});
5663

@@ -90,7 +97,7 @@ export const EventLogFilters: FC<EventLogFiltersProps> = (
9097
label: 'Feature Flag',
9198
icon: 'flag',
9299
options: flagOptions,
93-
filterKey: 'flag',
100+
filterKey: 'feature',
94101
singularOperators: ['IS'],
95102
pluralOperators: ['IS_ANY_OF'],
96103
},
@@ -105,8 +112,8 @@ export const EventLogFilters: FC<EventLogFiltersProps> = (
105112
<Filters
106113
className={className}
107114
availableFilters={availableFilters}
108-
state={{}}
109-
onChange={(v) => console.log(v)}
115+
state={state}
116+
onChange={onChange}
110117
/>
111118
);
112119
};

0 commit comments

Comments
 (0)