Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions frontend/src/hooks/useInfiniteScroll.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ type UseInfinityParams<DataItem, Args extends InfinityListArgs> = {
useLazyQuery: UseLazyQuery<QueryDefinition<Args, any, any, ListResponse<DataItem>, any>>;
args: { limit?: number } & Args;
getPaginationParams: (listItem: DataItem) => Partial<Args>;
skip?: boolean;
// options?: UseQueryStateOptions<QueryDefinition<Args, any, any, Data[], any>, Record<string, any>>;
};

Expand All @@ -22,6 +23,7 @@ export const useInfiniteScroll = <DataItem, Args extends InfinityListArgs>({
getPaginationParams,
// options,
args,
skip,
}: UseInfinityParams<DataItem, Args>) => {
const [data, setData] = useState<ListResponse<DataItem>>([]);
const scrollElement = useRef<HTMLElement>(document.documentElement);
Expand Down Expand Up @@ -55,14 +57,14 @@ export const useInfiniteScroll = <DataItem, Args extends InfinityListArgs>({
};

useEffect(() => {
if (!isEqual(argsProp, lastArgsProps.current)) {
if (!isEqual(argsProp, lastArgsProps.current) && !skip) {
getEmptyList();
lastArgsProps.current = argsProp as Args;
}
}, [argsProp, lastArgsProps]);
}, [argsProp, lastArgsProps, skip]);

const getMore = async () => {
if (isLoadingRef.current || disabledMore) {
if (isLoadingRef.current || disabledMore || skip) {
return;
}

Expand All @@ -83,7 +85,9 @@ export const useInfiniteScroll = <DataItem, Args extends InfinityListArgs>({
console.log(e);
}

isLoadingRef.current = false;
setTimeout(() => {
isLoadingRef.current = false;
}, 10);
};

useLayoutEffect(() => {
Expand All @@ -106,6 +110,7 @@ export const useInfiniteScroll = <DataItem, Args extends InfinityListArgs>({
const scrollPositionFromBottom = element.scrollHeight - (element.clientHeight + element.scrollTop);

if (scrollPositionFromBottom < SCROLL_POSITION_GAP) {
console.log('test', element.scrollHeight);
getMore().catch(console.log);
}
}, [disabledMore, getMore]);
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/locale/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@
"refresh": "Refresh",
"quickstart": "Quickstart",
"ask_ai": "Ask AI",
"new": "New"
"new": "New",
"full_view": "Full view"
},

"auth": {
Expand Down
37 changes: 26 additions & 11 deletions frontend/src/pages/Events/List/hooks/useFilters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,14 @@ const multipleChoiseKeys: RequestParamsKeys[] = [
'actors',
];

const targetTypes = ['project', 'user', 'fleet', 'instance', 'run', 'job'];
const targetTypes = [
{ label: 'Project', value: 'project' },
{ label: 'User', value: 'user' },
{ label: 'Fleet', value: 'fleet' },
{ label: 'Instance', value: 'instance' },
{ label: 'Run', value: 'run' },
{ label: 'Job', value: 'job' },
];

export const useFilters = () => {
const [searchParams, setSearchParams] = useSearchParams();
Expand Down Expand Up @@ -100,7 +107,7 @@ export const useFilters = () => {
targetTypes?.forEach((targetType) => {
options.push({
propertyKey: filterKeys.INCLUDE_TARGET_TYPES,
value: targetType,
value: targetType.label,
});
});

Expand All @@ -117,53 +124,53 @@ export const useFilters = () => {
{
key: filterKeys.TARGET_PROJECTS,
operators: ['='],
propertyLabel: 'Target Projects',
propertyLabel: 'Target projects',
groupValuesLabel: 'Project ids',
},
{
key: filterKeys.TARGET_USERS,
operators: ['='],
propertyLabel: 'Target Users',
propertyLabel: 'Target users',
groupValuesLabel: 'Project ids',
},
{
key: filterKeys.TARGET_FLEETS,
operators: ['='],
propertyLabel: 'Target Fleets',
propertyLabel: 'Target fleets',
},
{
key: filterKeys.TARGET_INSTANCES,
operators: ['='],
propertyLabel: 'Target Instances',
propertyLabel: 'Target instances',
},
{
key: filterKeys.TARGET_RUNS,
operators: ['='],
propertyLabel: 'Target Runs',
propertyLabel: 'Target runs',
},
{
key: filterKeys.TARGET_JOBS,
operators: ['='],
propertyLabel: 'Target Jobs',
propertyLabel: 'Target jobs',
},

{
key: filterKeys.WITHIN_PROJECTS,
operators: ['='],
propertyLabel: 'Within Projects',
propertyLabel: 'Within projects',
groupValuesLabel: 'Project ids',
},

{
key: filterKeys.WITHIN_FLEETS,
operators: ['='],
propertyLabel: 'Within Fleets',
propertyLabel: 'Within fleets',
},

{
key: filterKeys.WITHIN_RUNS,
operators: ['='],
propertyLabel: 'Within Runs',
propertyLabel: 'Within runs',
},

{
Expand Down Expand Up @@ -240,6 +247,14 @@ export const useFilters = () => {
),
}
: {}),

...(params[filterKeys.INCLUDE_TARGET_TYPES] && Array.isArray(params[filterKeys.INCLUDE_TARGET_TYPES])
? {
[filterKeys.INCLUDE_TARGET_TYPES]: params[filterKeys.INCLUDE_TARGET_TYPES]?.map(
(selectedLabel: string) => targetTypes?.find(({ label }) => label === selectedLabel)?.['value'],
),
}
: {}),
};

return {
Expand Down
56 changes: 56 additions & 0 deletions frontend/src/pages/Fleets/Details/Events/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import { useNavigate, useParams } from 'react-router-dom';
import Button from '@cloudscape-design/components/button';

import { Header, Loader, Table } from 'components';

import { DEFAULT_TABLE_PAGE_SIZE } from 'consts';
import { useCollection, useInfiniteScroll } from 'hooks';
import { ROUTES } from 'routes';
import { useLazyGetAllEventsQuery } from 'services/events';

import { useColumnsDefinitions } from 'pages/Events/List/hooks/useColumnDefinitions';

export const EventsList = () => {
const { t } = useTranslation();
const params = useParams();
const paramFleetId = params.fleetId ?? '';
const navigate = useNavigate();

const { data, isLoading, isLoadingMore } = useInfiniteScroll<IEvent, TEventListRequestParams>({
useLazyQuery: useLazyGetAllEventsQuery,
args: { limit: DEFAULT_TABLE_PAGE_SIZE, within_fleets: [paramFleetId] },

getPaginationParams: (lastEvent) => ({
prev_recorded_at: lastEvent.recorded_at,
prev_id: lastEvent.id,
}),
});

const { items, collectionProps } = useCollection<IEvent>(data, {
selection: {},
});

const goToFullView = () => {
navigate(ROUTES.EVENTS.LIST + `?within_fleets=${paramFleetId}`);
};

const { columns } = useColumnsDefinitions();

return (
<Table
{...collectionProps}
columnDefinitions={columns}
items={items}
loading={isLoading}
loadingText={t('common.loading')}
header={
<Header actions={<Button onClick={goToFullView}>{t('common.full_view')}</Button>}>
{t('navigation.events')}
</Header>
}
footer={<Loader show={isLoadingMore} padding={{ vertical: 'm' }} />}
/>
);
};
97 changes: 97 additions & 0 deletions frontend/src/pages/Fleets/Details/FleetDetails/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import { useParams } from 'react-router-dom';
import { format } from 'date-fns';

import { Box, ColumnLayout, Container, Header, Loader, NavigateLink, StatusIndicator } from 'components';

import { DATE_TIME_FORMAT } from 'consts';
import { getFleetInstancesLinkText, getFleetPrice, getFleetStatusIconType } from 'libs/fleet';
import { ROUTES } from 'routes';
import { useGetFleetDetailsQuery } from 'services/fleet';

export const FleetDetails = () => {
const { t } = useTranslation();
const params = useParams();
const paramFleetId = params.fleetId ?? '';
const paramProjectName = params.projectName ?? '';

const { data, isLoading } = useGetFleetDetailsQuery(
{
projectName: paramProjectName,
fleetId: paramFleetId,
},
{
refetchOnMountOrArgChange: true,
},
);

const renderPrice = (fleet: IFleet) => {
const price = getFleetPrice(fleet);

if (typeof price === 'number') return `$${price}`;

return '-';
};

return (
<>
{isLoading && (
<Container>
<Loader />
</Container>
)}

{data && (
<Container header={<Header variant="h2">{t('common.general')}</Header>}>
<ColumnLayout columns={4} variant="text-grid">
<div>
<Box variant="awsui-key-label">{t('fleets.fleet')}</Box>
<div>{data.name}</div>
</div>

<div>
<Box variant="awsui-key-label">{t('fleets.instances.status')}</Box>

<div>
<StatusIndicator type={getFleetStatusIconType(data.status)}>
{t(`fleets.statuses.${data.status}`)}
</StatusIndicator>
</div>
</div>

<div>
<Box variant="awsui-key-label">{t('fleets.instances.project')}</Box>

<div>
<NavigateLink href={ROUTES.PROJECT.DETAILS.FORMAT(data.project_name)}>
{data.project_name}
</NavigateLink>
</div>
</div>

<div>
<Box variant="awsui-key-label">{t('fleets.instances.title')}</Box>

<div>
<NavigateLink href={ROUTES.INSTANCES.LIST + `?fleet_ids=${data.id}`}>
{getFleetInstancesLinkText(data)}
</NavigateLink>
</div>
</div>

<div>
<Box variant="awsui-key-label">{t('fleets.instances.started')}</Box>
<div>{format(new Date(data.created_at), DATE_TIME_FORMAT)}</div>
</div>

<div>
<Box variant="awsui-key-label">{t('fleets.instances.price')}</Box>
<div>{renderPrice(data)}</div>
</div>
</ColumnLayout>
</Container>
)}
</>
);
};
Loading