From 764d03767bce3868cfd57bc9e00c806dac4d4e0e Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Wed, 14 Aug 2024 10:03:28 +0200 Subject: [PATCH] chore: begin front end cleanup (#7865) Begins cleaning up the front end. Removes the "legacy" event log component in favor of only using the new one. What we do is simply not to show the filters if you're not on enterprise. This means that we'll get pagination (and maybe exports?) for everyone. It also means that you can reverse-engineer the filters and use them even on non-enterprise, as long as you're happy editing URLs manually. However, putting it behind a flag on the front end always exposed that kind of risk, so I don't think this is a bad move. --- .../component/events/EventLog/EventLog.tsx | 126 ++++-------------- .../useEventSearch/useLegacyEventSearch.ts | 92 ------------- 2 files changed, 24 insertions(+), 194 deletions(-) delete mode 100644 frontend/src/hooks/api/getters/useEventSearch/useLegacyEventSearch.ts diff --git a/frontend/src/component/events/EventLog/EventLog.tsx b/frontend/src/component/events/EventLog/EventLog.tsx index d56b8a20cc..e61ca8915c 100644 --- a/frontend/src/component/events/EventLog/EventLog.tsx +++ b/frontend/src/component/events/EventLog/EventLog.tsx @@ -4,17 +4,13 @@ import { PageContent } from 'component/common/PageContent/PageContent'; import { PageHeader } from 'component/common/PageHeader/PageHeader'; import EventCard from 'component/events/EventCard/EventCard'; import { useEventSettings } from 'hooks/useEventSettings'; -import { useState, useEffect } from 'react'; import { Search } from 'component/common/Search/Search'; import theme from 'themes/theme'; -import { useLegacyEventSearch } from 'hooks/api/getters/useEventSearch/useLegacyEventSearch'; import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; -import { useOnVisible } from 'hooks/useOnVisible'; import { styled } from '@mui/system'; import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; import { useUiFlag } from 'hooks/useUiFlag'; import { EventLogFilters } from './EventLogFilters'; -import type { EventSchema } from 'openapi'; import { useEventLogSearch } from './useEventLogSearch'; import { StickyPaginationBar } from 'component/common/Table/StickyPaginationBar/StickyPaginationBar'; import { EventActions } from './EventActions'; @@ -38,11 +34,13 @@ const StyledFilters = styled(EventLogFilters)({ padding: 0, }); -const EventResultWrapper = styled('div')(({ theme }) => ({ - padding: theme.spacing(2, 4, 4, 4), +const EventResultWrapper = styled('div', { + shouldForwardProp: (prop) => prop !== 'withFilters', +})<{ withFilters: boolean }>(({ theme, withFilters }) => ({ + padding: theme.spacing(withFilters ? 2 : 4, 4, 4, 4), display: 'flex', flexFlow: 'column', - gap: theme.spacing(1), + gap: theme.spacing(2), })); const Placeholder = styled('li')({ @@ -51,7 +49,9 @@ const Placeholder = styled('li')({ '&[data-loading-events=true]': { zIndex: '1' }, // .skeleton has z-index: 9990 }); -const NewEventLog = ({ title, project, feature }: IEventLogProps) => { +export const EventLog = ({ title, project, feature }: IEventLogProps) => { + const { isEnterprise } = useUiConfig(); + const showFilters = useUiFlag('newEventSearch') && isEnterprise(); const { events, total, @@ -148,11 +148,22 @@ const NewEventLog = ({ title, project, feature }: IEventLogProps) => { } > - - + + } /> {resultComponent()} @@ -172,92 +183,3 @@ const NewEventLog = ({ title, project, feature }: IEventLogProps) => { ); }; - -export const LegacyEventLog = ({ title, project, feature }: IEventLogProps) => { - const [query, setQuery] = useState(''); - const { events, totalEvents, fetchNextPage } = useLegacyEventSearch( - project, - feature, - query, - ); - const fetchNextPageRef = useOnVisible(fetchNextPage); - const { eventSettings, setEventSettings } = useEventSettings(); - const isSmallScreen = useMediaQuery(theme.breakpoints.down('md')); - - // Cache the previous search results so that we can show those while - // fetching new results for a new search query in the background. - const [cache, setCache] = useState(); - useEffect(() => events && setCache(events), [events]); - - const onShowData = () => { - setEventSettings((prev) => ({ showData: !prev.showData })); - }; - - const searchInputField = ; - - const showDataSwitch = ( - - } - /> - ); - - const count = events?.length || 0; - const totalCount = totalEvents || 0; - const countText = `${count} of ${totalCount}`; - - return ( - - {showDataSwitch} - {!isSmallScreen && searchInputField} - - } - > - {isSmallScreen && searchInputField} - - } - > - No events found.

} - /> - 0)} - show={ - - {cache?.map((entry) => ( - } - elseShow={() => } - /> - ))} - - } - /> -
- - ); -}; - -export const EventLog = (props: IEventLogProps) => { - const { isEnterprise } = useUiConfig(); - const showFilters = useUiFlag('newEventSearch') && isEnterprise(); - if (showFilters) { - return ; - } else { - return ; - } -}; diff --git a/frontend/src/hooks/api/getters/useEventSearch/useLegacyEventSearch.ts b/frontend/src/hooks/api/getters/useEventSearch/useLegacyEventSearch.ts deleted file mode 100644 index d9f61c1735..0000000000 --- a/frontend/src/hooks/api/getters/useEventSearch/useLegacyEventSearch.ts +++ /dev/null @@ -1,92 +0,0 @@ -import useSWR from 'swr'; -import { useCallback, useState, useEffect, useMemo } from 'react'; -import { formatApiPath } from 'utils/formatPath'; -import handleErrorResponses from '../httpErrorResponseHandler'; -import type { EventSchema } from 'openapi'; - -const PATH = formatApiPath('api/admin/events/search'); - -export interface IUseEventSearchOutput { - events?: EventSchema[]; - fetchNextPage: () => void; - loading: boolean; - totalEvents?: number; - error?: Error; -} - -interface IEventSearch { - type?: string; - project?: string; - feature?: string; - query?: string; - limit?: number; - offset?: number; -} - -/** - * @deprecated Use useEventSearch instead. Remove with flag: newEventSearch - */ -export const useLegacyEventSearch = ( - project?: string, - feature?: string, - query?: string, -): IUseEventSearchOutput => { - const [events, setEvents] = useState(); - const [totalEvents, setTotalEvents] = useState(0); - const [offset, setOffset] = useState(0); - - const search: IEventSearch = useMemo( - () => ({ project, feature, query, limit: 50 }), - [project, feature, query], - ); - - const { data, error, isValidating } = useSWR<{ - events: EventSchema[]; - totalEvents?: number; - }>([PATH, search, offset], () => searchEvents(PATH, { ...search, offset })); - - // Reset the page when there are new search conditions. - useEffect(() => { - setOffset(0); - setTotalEvents(0); - setEvents(undefined); - }, [search]); - - // Append results to the page when more data has been fetched. - useEffect(() => { - if (data) { - setEvents((prev) => [ - ...(prev?.slice(0, offset) || []), - ...data.events, - ]); - if (data.totalEvents) { - setTotalEvents(data.totalEvents); - } - } - }, [data]); - - // Update the offset to fetch more results at the end of the page. - const fetchNextPage = useCallback(() => { - if (events && !isValidating) { - setOffset(events.length); - } - }, [events, isValidating]); - - return { - events, - loading: !error && !data, - fetchNextPage, - totalEvents, - error, - }; -}; - -const searchEvents = (path: string, search: IEventSearch) => { - return fetch(path, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(search), - }) - .then(handleErrorResponses('Event history')) - .then((res) => res.json()); -};