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
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);
|