diff --git a/apps/meteor/client/views/marketplace/AppDetailsPage/AppDetailsPage.tsx b/apps/meteor/client/views/marketplace/AppDetailsPage/AppDetailsPage.tsx index 1a313181ce13d..09612c9fa90d0 100644 --- a/apps/meteor/client/views/marketplace/AppDetailsPage/AppDetailsPage.tsx +++ b/apps/meteor/client/views/marketplace/AppDetailsPage/AppDetailsPage.tsx @@ -163,7 +163,7 @@ const AppDetailsPage = ({ id }: AppDetailsPageProps): ReactElement => { {compactMode && contextualBar === 'filter-logs' && ( - + )} diff --git a/apps/meteor/client/views/marketplace/AppDetailsPage/tabs/AppLogs/AppLogs.tsx b/apps/meteor/client/views/marketplace/AppDetailsPage/tabs/AppLogs/AppLogs.tsx index ddc18e540216f..81b620dc237b6 100644 --- a/apps/meteor/client/views/marketplace/AppDetailsPage/tabs/AppLogs/AppLogs.tsx +++ b/apps/meteor/client/views/marketplace/AppDetailsPage/tabs/AppLogs/AppLogs.tsx @@ -1,5 +1,4 @@ import { Box, Pagination } from '@rocket.chat/fuselage'; -import { useDebouncedValue } from '@rocket.chat/fuselage-hooks'; import { useMemo, type ReactElement } from 'react'; import { useTranslation } from 'react-i18next'; @@ -23,15 +22,13 @@ const AppLogs = ({ id }: { id: string }): ReactElement => { const { current, itemsPerPage, setItemsPerPage: onSetItemsPerPage, setCurrent: onSetCurrent, ...paginationProps } = usePagination(); - const debouncedEvent = useDebouncedValue(event, 500); - const { data, isSuccess, isError, error, isFetching } = useLogs({ appId: id, current, itemsPerPage, ...(instance !== 'all' && { instanceId: instance }), ...(severity !== 'all' && { logLevel: severity }), - method: debouncedEvent, + ...(event !== 'all' && { method: event }), ...(startTime && startDate && { startDate: new Date(`${startDate}T${startTime}`).toISOString() }), ...(endTime && endDate && { endDate: new Date(`${endDate}T${endTime}`).toISOString() }), }); @@ -50,14 +47,14 @@ const AppLogs = ({ id }: { id: string }): ReactElement => { return ( <> - + {isFetching && } {isError && } {!isFetching && isSuccess && data?.logs?.length === 0 && } {!isFetching && isSuccess && data?.logs?.length > 0 && ( - + {data?.logs?.map((log, index) => )} diff --git a/apps/meteor/client/views/marketplace/AppDetailsPage/tabs/AppLogs/Filters/AppLogsFilter.stories.tsx b/apps/meteor/client/views/marketplace/AppDetailsPage/tabs/AppLogs/Filters/AppLogsFilter.stories.tsx index 4bfe63bb6b34b..09ae4a97e3a42 100644 --- a/apps/meteor/client/views/marketplace/AppDetailsPage/tabs/AppLogs/Filters/AppLogsFilter.stories.tsx +++ b/apps/meteor/client/views/marketplace/AppDetailsPage/tabs/AppLogs/Filters/AppLogsFilter.stories.tsx @@ -12,10 +12,10 @@ export default { args: {}, decorators: [ mockAppRoot() - // @ts-expect-error The endpoint is to be merged in https://github.com/RocketChat/Rocket.Chat/pull/36245 - .withEndpoint('GET', '/apps/logs/instanceIds', () => ({ + .withEndpoint('GET', '/apps/:id/logs/distinctValues', () => ({ success: true, instanceIds: ['instance-1', 'instance-2', 'instance-3'], + methods: ['method-1', 'method-2', 'method-3'], })) .buildStoryDecorator(), (fn) => { @@ -33,4 +33,4 @@ export default { }, } satisfies Meta; -export const Default = () => ; +export const Default = () => ; diff --git a/apps/meteor/client/views/marketplace/AppDetailsPage/tabs/AppLogs/Filters/AppLogsFilter.tsx b/apps/meteor/client/views/marketplace/AppDetailsPage/tabs/AppLogs/Filters/AppLogsFilter.tsx index 6622ec0add02b..703e959c5e2d1 100644 --- a/apps/meteor/client/views/marketplace/AppDetailsPage/tabs/AppLogs/Filters/AppLogsFilter.tsx +++ b/apps/meteor/client/views/marketplace/AppDetailsPage/tabs/AppLogs/Filters/AppLogsFilter.tsx @@ -1,9 +1,10 @@ -import { Box, Button, Icon, IconButton, Label, Palette, TextInput } from '@rocket.chat/fuselage'; +import { Box, Button, IconButton, Label } from '@rocket.chat/fuselage'; import { useRouter, useSetModal } from '@rocket.chat/ui-contexts'; import { Controller } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; import CompactFilterOptions from './AppsLogsFilterOptionsCompact'; +import { EventFilterSelect } from './EventFilterSelect'; import { InstanceFilterSelect } from './InstanceFilterSelect'; import { SeverityFilterSelect } from './SeverityFilterSelect'; import { TimeFilterSelect } from './TimeFilterSelect'; @@ -12,11 +13,12 @@ import { useAppLogsFilterFormContext } from '../useAppLogsFilterForm'; import { ExportLogsModal } from './ExportLogsModal'; type AppsLogsFilterProps = { + appId: string; isLoading?: boolean; noResults?: boolean; }; -export const AppLogsFilter = ({ isLoading = false, noResults = false }: AppsLogsFilterProps) => { +export const AppLogsFilter = ({ appId, isLoading = false, noResults = false }: AppsLogsFilterProps) => { const { t } = useTranslation(); const { control, getValues } = useAppLogsFilterFormContext(); @@ -44,17 +46,13 @@ export const AppLogsFilter = ({ isLoading = false, noResults = false }: AppsLogs return ( - + ( - } - id='eventFilter' - {...field} - /> - )} + render={({ field }) => } /> {!compactMode && ( @@ -73,7 +71,9 @@ export const AppLogsFilter = ({ isLoading = false, noResults = false }: AppsLogs } + render={({ field }) => ( + + )} /> )} diff --git a/apps/meteor/client/views/marketplace/AppDetailsPage/tabs/AppLogs/Filters/AppLogsFilterCompact.spec.tsx b/apps/meteor/client/views/marketplace/AppDetailsPage/tabs/AppLogs/Filters/AppLogsFilterCompact.spec.tsx index 9ca525a51febd..0be8a13c9dcae 100644 --- a/apps/meteor/client/views/marketplace/AppDetailsPage/tabs/AppLogs/Filters/AppLogsFilterCompact.spec.tsx +++ b/apps/meteor/client/views/marketplace/AppDetailsPage/tabs/AppLogs/Filters/AppLogsFilterCompact.spec.tsx @@ -19,7 +19,10 @@ test.each(testCases)(`renders AppLogsItem without crashing`, async (_storyname, test.each(testCases)('AppLogsItem should have no a11y violations', async (_storyname, Story) => { const { container } = render(, { wrapper: mockAppRoot().build() }); - const results = await axe(container); + /** + ** Disable 'nested-interactive' rule because our `Select` component is still not a11y compliant + **/ + const results = await axe(container, { rules: { 'nested-interactive': { enabled: false } } }); expect(results).toHaveNoViolations(); }); diff --git a/apps/meteor/client/views/marketplace/AppDetailsPage/tabs/AppLogs/Filters/AppLogsFilterContextualBar.stories.tsx b/apps/meteor/client/views/marketplace/AppDetailsPage/tabs/AppLogs/Filters/AppLogsFilterContextualBar.stories.tsx index 23fa65fdbaff1..e6a9bd6e27645 100644 --- a/apps/meteor/client/views/marketplace/AppDetailsPage/tabs/AppLogs/Filters/AppLogsFilterContextualBar.stories.tsx +++ b/apps/meteor/client/views/marketplace/AppDetailsPage/tabs/AppLogs/Filters/AppLogsFilterContextualBar.stories.tsx @@ -12,10 +12,10 @@ export default { args: {}, decorators: [ mockAppRoot() - // @ts-expect-error The endpoint is to be merged in https://github.com/RocketChat/Rocket.Chat/pull/36245 - .withEndpoint('GET', '/apps/logs/instanceIds', () => ({ + .withEndpoint('GET', '/apps/:id/logs/distinctValues', () => ({ success: true, instanceIds: ['instance-1', 'instance-2', 'instance-3'], + methods: ['method-1', 'method-2', 'method-3'], })) .buildStoryDecorator(), (fn) => { @@ -33,4 +33,4 @@ export default { }, } satisfies Meta; -export const Default = () => ; +export const Default = () => ; diff --git a/apps/meteor/client/views/marketplace/AppDetailsPage/tabs/AppLogs/Filters/AppLogsFilterContextualBar.tsx b/apps/meteor/client/views/marketplace/AppDetailsPage/tabs/AppLogs/Filters/AppLogsFilterContextualBar.tsx index f9802e3545bce..8f4f6222ce3a2 100644 --- a/apps/meteor/client/views/marketplace/AppDetailsPage/tabs/AppLogs/Filters/AppLogsFilterContextualBar.tsx +++ b/apps/meteor/client/views/marketplace/AppDetailsPage/tabs/AppLogs/Filters/AppLogsFilterContextualBar.tsx @@ -17,10 +17,11 @@ import { import { useAppLogsFilterFormContext } from '../useAppLogsFilterForm'; type AppLogsFilterContextualBarProps = { + appId: string; onClose: () => void; }; -export const AppLogsFilterContextualBar = ({ onClose = () => undefined }: AppLogsFilterContextualBarProps) => { +export const AppLogsFilterContextualBar = ({ appId, onClose = () => undefined }: AppLogsFilterContextualBarProps) => { const { t } = useTranslation(); const { control } = useAppLogsFilterFormContext(); @@ -54,7 +55,9 @@ export const AppLogsFilterContextualBar = ({ onClose = () => undefined }: AppLog } + render={({ field }) => ( + + )} /> diff --git a/apps/meteor/client/views/marketplace/AppDetailsPage/tabs/AppLogs/Filters/EventFilterSelect.tsx b/apps/meteor/client/views/marketplace/AppDetailsPage/tabs/AppLogs/Filters/EventFilterSelect.tsx new file mode 100644 index 0000000000000..1c2f0f33a2b3b --- /dev/null +++ b/apps/meteor/client/views/marketplace/AppDetailsPage/tabs/AppLogs/Filters/EventFilterSelect.tsx @@ -0,0 +1,26 @@ +import type { SelectOption } from '@rocket.chat/fuselage'; +import { InputBoxSkeleton, Select } from '@rocket.chat/fuselage'; +import type { ComponentProps } from 'react'; +import { useMemo } from 'react'; +import { useTranslation } from 'react-i18next'; + +import { useLogsDistinctValues } from '../../../../hooks/useLogsDistinctValues'; + +type EventFilterSelectProps = Omit, 'options'> & { appId: string }; + +export const EventFilterSelect = ({ appId, ...props }: EventFilterSelectProps) => { + const { t } = useTranslation(); + + const { data, isPending } = useLogsDistinctValues(appId); + + const options: SelectOption[] = useMemo(() => { + const mappedData: [string, string][] = data?.methods?.map((id: string) => [id, id]) || []; + return [['all', t('All')], ...mappedData]; + }, [data, t]); + + if (isPending) { + return ; + } + + return - - - + class="rcx-skeleton rcx-skeleton--text rcx-css-1qcz93u" + /> +