You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

107 lines
3.7 KiB
TypeScript

// Copyright (C) 2020-2022 Intel Corporation
// Copyright (C) 2022-2023 CVAT.ai Corporation
//
// SPDX-License-Identifier: MIT
import './styles.scss';
import React, { useCallback, useEffect } from 'react';
import { useHistory } from 'react-router';
import { useDispatch, useSelector } from 'react-redux';
import { getModelProvidersAsync, getModelsAsync } from 'actions/models-actions';
import { updateHistoryFromQuery } from 'components/resource-sorting-filtering';
import Spin from 'antd/lib/spin';
import notification from 'antd/lib/notification';
import { CombinedState, Indexable } from 'reducers';
import DeployedModelsList, { PAGE_SIZE } from './deployed-models-list';
import EmptyListComponent from './empty-list';
import FeedbackComponent from '../feedback/feedback';
import TopBar from './top-bar';
function ModelsPageComponent(): JSX.Element {
const history = useHistory();
const dispatch = useDispatch();
const fetching = useSelector((state: CombinedState) => state.models.fetching);
const query = useSelector((state: CombinedState) => state.models.query);
const totalCount = useSelector((state: CombinedState) => state.models.totalCount);
const onCreateModel = useCallback(() => {
history.push('/models/create');
}, []);
const updatedQuery = { ...query };
const queryParams = new URLSearchParams(history.location.search);
for (const key of Object.keys(updatedQuery)) {
(updatedQuery as Indexable)[key] = queryParams.get(key) || null;
if (key === 'page') {
updatedQuery.page = updatedQuery.page ? +updatedQuery.page : 1;
}
}
useEffect(() => {
history.replace({
search: updateHistoryFromQuery(query),
});
}, [query]);
const pageOutOfBounds = updatedQuery.page > Math.ceil(totalCount / PAGE_SIZE);
useEffect(() => {
dispatch(getModelProvidersAsync());
dispatch(getModelsAsync(updatedQuery));
if (pageOutOfBounds) {
notification.error({
message: 'Could not fetch models',
description: 'Invalid page',
});
}
}, []);
const content = (totalCount && !pageOutOfBounds) ? (
<DeployedModelsList query={updatedQuery} />
) : <EmptyListComponent />;
return (
<div className='cvat-models-page'>
<TopBar
disabled
query={updatedQuery}
onCreateModel={onCreateModel}
onApplySearch={(search: string | null) => {
dispatch(
getModelsAsync({
...query,
search,
page: 1,
}),
);
}}
onApplyFilter={(filter: string | null) => {
dispatch(
getModelsAsync({
...query,
filter,
page: 1,
}),
);
}}
onApplySorting={(sorting: string | null) => {
dispatch(
getModelsAsync({
...query,
sort: sorting,
page: 1,
}),
);
}}
/>
{ fetching ? (
<div className='cvat-empty-models-list'>
<Spin size='large' className='cvat-spinner' />
</div>
) : content }
<FeedbackComponent />
</div>
);
}
export default React.memo(ModelsPageComponent);