Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
疯人忠
Cvat
提交
56893f84
C
Cvat
项目概览
疯人忠
/
Cvat
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
C
Cvat
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
56893f84
编写于
4月 19, 2023
作者:
K
klakhov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
added analytics page, empty quality page
上级
c1614ceb
变更
11
隐藏空白更改
内联
并排
Showing
11 changed file
with
259 addition
and
31 deletion
+259
-31
cvat-core/src/session.ts
cvat-core/src/session.ts
+22
-23
cvat-ui/src/components/actions-menu/actions-menu.tsx
cvat-ui/src/components/actions-menu/actions-menu.tsx
+11
-2
cvat-ui/src/components/cvat-app.tsx
cvat-ui/src/components/cvat-app.tsx
+2
-0
cvat-ui/src/components/task-analytics-page/quality/empty-quality.tsx
.../components/task-analytics-page/quality/empty-quality.tsx
+46
-0
cvat-ui/src/components/task-analytics-page/quality/task-quality-component.tsx
...ts/task-analytics-page/quality/task-quality-component.tsx
+28
-0
cvat-ui/src/components/task-analytics-page/styles.scss
cvat-ui/src/components/task-analytics-page/styles.scss
+22
-0
cvat-ui/src/components/task-analytics-page/task-analytics-page.tsx
...rc/components/task-analytics-page/task-analytics-page.tsx
+97
-0
cvat-ui/src/components/task-page/job-list.tsx
cvat-ui/src/components/task-page/job-list.tsx
+4
-2
cvat-ui/src/components/task-page/top-bar.tsx
cvat-ui/src/components/task-page/top-bar.tsx
+12
-2
cvat-ui/src/components/tasks-page/task-item.tsx
cvat-ui/src/components/tasks-page/task-item.tsx
+11
-1
cvat-ui/src/containers/actions-menu/actions-menu.tsx
cvat-ui/src/containers/actions-menu/actions-menu.tsx
+4
-1
未找到文件。
cvat-core/src/session.ts
浏览文件 @
56893f84
...
...
@@ -723,29 +723,28 @@ export class Task extends Session {
if
(
Array
.
isArray
(
initialData
.
jobs
))
{
for
(
const
job
of
initialData
.
jobs
)
{
if
(
job
.
type
===
JobType
.
NORMAL
)
{
const
jobInstance
=
new
Job
({
url
:
job
.
url
,
id
:
job
.
id
,
assignee
:
job
.
assignee
,
state
:
job
.
state
,
stage
:
job
.
stage
,
start_frame
:
job
.
start_frame
,
stop_frame
:
job
.
stop_frame
,
// following fields also returned when doing API request /jobs/<id>
// here we know them from task and append to constructor
task_id
:
data
.
id
,
project_id
:
data
.
project_id
,
labels
:
data
.
labels
,
bug_tracker
:
data
.
bug_tracker
,
mode
:
data
.
mode
,
dimension
:
data
.
dimension
,
data_compressed_chunk_type
:
data
.
data_compressed_chunk_type
,
data_chunk_size
:
data
.
data_chunk_size
,
});
data
.
jobs
.
push
(
jobInstance
);
}
const
jobInstance
=
new
Job
({
url
:
job
.
url
,
id
:
job
.
id
,
assignee
:
job
.
assignee
,
state
:
job
.
state
,
stage
:
job
.
stage
,
type
:
job
.
type
,
start_frame
:
job
.
start_frame
,
stop_frame
:
job
.
stop_frame
,
// following fields also returned when doing API request /jobs/<id>
// here we know them from task and append to constructor
task_id
:
data
.
id
,
project_id
:
data
.
project_id
,
labels
:
data
.
labels
,
bug_tracker
:
data
.
bug_tracker
,
mode
:
data
.
mode
,
dimension
:
data
.
dimension
,
data_compressed_chunk_type
:
data
.
data_compressed_chunk_type
,
data_chunk_size
:
data
.
data_chunk_size
,
});
data
.
jobs
.
push
(
jobInstance
);
}
}
...
...
cvat-ui/src/components/actions-menu/actions-menu.tsx
浏览文件 @
56893f84
...
...
@@ -35,6 +35,7 @@ export enum Actions {
MOVE_TASK_TO_PROJECT
=
'
move_task_to_project
'
,
OPEN_BUG_TRACKER
=
'
open_bug_tracker
'
,
BACKUP_TASK
=
'
backup_task
'
,
VIEW_ANALYTICS
=
'
view_analytics
'
,
}
function
ActionsMenuComponent
(
props
:
Props
):
JSX
.
Element
{
...
...
@@ -107,10 +108,18 @@ function ActionsMenuComponent(props: Props): JSX.Element {
</
Menu
.
Item
>
),
40
]);
menuItems
.
push
([(
<
Menu
.
Item
key
=
{
Actions
.
VIEW_ANALYTICS
}
>
View analytics
</
Menu
.
Item
>
),
50
]);
if
(
projectID
===
null
)
{
menuItems
.
push
([(
<
Menu
.
Item
key
=
{
Actions
.
MOVE_TASK_TO_PROJECT
}
>
Move to project
</
Menu
.
Item
>
),
5
0
]);
),
6
0
]);
}
menuItems
.
push
([(
...
...
@@ -118,7 +127,7 @@ function ActionsMenuComponent(props: Props): JSX.Element {
<
Menu
.
Divider
/>
<
Menu
.
Item
key
=
{
Actions
.
DELETE_TASK
}
>
Delete
</
Menu
.
Item
>
</
React
.
Fragment
>
),
6
0
]);
),
7
0
]);
menuItems
.
push
(
...
plugins
.
map
(({
component
:
Component
,
weight
},
index
)
=>
{
...
...
cvat-ui/src/components/cvat-app.tsx
浏览文件 @
56893f84
...
...
@@ -74,6 +74,7 @@ import EmailVerificationSentPage from './email-confirmation-pages/email-verifica
import
IncorrectEmailConfirmationPage
from
'
./email-confirmation-pages/incorrect-email-confirmation
'
;
import
CreateModelPage
from
'
./create-model-page/create-model-page
'
;
import
CreateJobPage
from
'
./create-job-page/create-job-page
'
;
import
TaskAnalyticsPage
from
'
./task-analytics-page/task-analytics-page
'
;
interface
CVATAppProps
{
loadFormats
:
()
=>
void
;
...
...
@@ -461,6 +462,7 @@ class CVATApplication extends React.PureComponent<CVATAppProps & RouteComponentP
<
Route
exact
path
=
'/tasks'
component
=
{
TasksPageContainer
}
/>
<
Route
exact
path
=
'/tasks/create'
component
=
{
CreateTaskPageContainer
}
/>
<
Route
exact
path
=
'/tasks/:id'
component
=
{
TaskPageComponent
}
/>
<
Route
exact
path
=
'/tasks/:id/analytics'
component
=
{
TaskAnalyticsPage
}
/>
<
Route
exact
path
=
'/tasks/:id/jobs/create'
component
=
{
CreateJobPage
}
/>
<
Route
exact
path
=
'/tasks/:tid/jobs/:jid'
component
=
{
AnnotationPageContainer
}
/>
<
Route
exact
path
=
'/jobs'
component
=
{
JobsPageComponent
}
/>
...
...
cvat-ui/src/components/task-analytics-page/quality/empty-quality.tsx
0 → 100644
浏览文件 @
56893f84
// Copyright (C) 2023 CVAT.ai Corporation
//
// SPDX-License-Identifier: MIT
import
'
./styles.scss
'
;
import
React
from
'
react
'
;
import
{
Link
}
from
'
react-router-dom
'
;
import
Text
from
'
antd/lib/typography/Text
'
;
import
Empty
from
'
antd/lib/empty
'
;
import
{
Col
,
Row
}
from
'
antd/lib/grid
'
;
interface
Props
{
taskId
:
number
,
}
function
EmptyQualityComponent
(
props
:
Props
):
JSX
.
Element
{
const
{
taskId
}
=
props
;
return
(
<
div
className
=
'cvat-task-quality-page cvat-task-quality-page-empty'
>
<
Empty
description
=
{
(
<>
<
Row
justify
=
'center'
align
=
'middle'
>
<
Col
>
<
Text
strong
>
No Ground truth job created yet ...
</
Text
>
</
Col
>
</
Row
>
<
Row
justify
=
'center'
align
=
'middle'
>
<
Col
>
<
Text
type
=
'secondary'
>
To start viewing quality data
</
Text
>
</
Col
>
</
Row
>
<
Row
justify
=
'center'
align
=
'middle'
>
<
Col
>
<
Link
to
=
{
`/tasks/
${
taskId
}
/jobs/create`
}
>
create a new one
</
Link
>
</
Col
>
</
Row
>
</>
)
}
/>
</
div
>
);
}
export
default
React
.
memo
(
EmptyQualityComponent
);
cvat-ui/src/components/task-analytics-page/quality/task-quality-component.tsx
0 → 100644
浏览文件 @
56893f84
// Copyright (C) 2023 CVAT.ai Corporation
//
// SPDX-License-Identifier: MIT
import
'
./styles.scss
'
;
import
React
from
'
react
'
;
import
{
Job
,
JobType
,
Task
}
from
'
cvat-core-wrapper
'
;
import
EmptyQuality
from
'
./empty-quality
'
;
interface
Props
{
task
:
Task
,
}
function
TaskQualityComponent
(
props
:
Props
):
JSX
.
Element
{
const
{
task
}
=
props
;
const
hasGTJob
=
task
.
jobs
.
some
((
job
:
Job
)
=>
job
.
type
===
JobType
.
GROUND_TRUTH
);
if
(
!
hasGTJob
)
{
return
(<
EmptyQuality
taskId
=
{
task
.
id
}
/>);
}
return
(
<
div
className
=
'cvat-task-quality-page'
>
hello
</
div
>
);
}
export
default
React
.
memo
(
TaskQualityComponent
);
cvat-ui/src/components/task-analytics-page/styles.scss
0 → 100644
浏览文件 @
56893f84
// Copyright (C) 2023 CVAT.ai Corporation
//
// SPDX-License-Identifier: MIT
@import
'../../base.scss'
;
.cvat-analytics-inner
{
background
:
$background-color-1
;
min-height
:
$grid-unit-size
*
95
;
padding
:
$grid-unit-size
*
2
;
.ant-tabs
{
height
:
100%
;
}
}
.cvat-task-quality-page-empty
{
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
height
:
$grid-unit-size
*
68
;
}
cvat-ui/src/components/task-analytics-page/task-analytics-page.tsx
0 → 100644
浏览文件 @
56893f84
// Copyright (C) 2023 CVAT.ai Corporation
//
// SPDX-License-Identifier: MIT
import
'
./styles.scss
'
;
import
React
,
{
useEffect
,
useState
}
from
'
react
'
;
import
{
Row
,
Col
}
from
'
antd/lib/grid
'
;
import
Tabs
from
'
antd/lib/tabs
'
;
import
{
useHistory
,
useParams
}
from
'
react-router
'
;
import
Text
from
'
antd/lib/typography/Text
'
;
import
Spin
from
'
antd/lib/spin
'
;
import
Button
from
'
antd/lib/button
'
;
import
{
Task
}
from
'
reducers
'
;
import
{
notification
}
from
'
antd
'
;
import
{
getCore
}
from
'
cvat-core-wrapper
'
;
import
{
LeftOutlined
}
from
'
@ant-design/icons/lib/icons
'
;
import
TaskQualityComponent
from
'
./quality/task-quality-component
'
;
const
core
=
getCore
();
function
TaskAnalyticsPage
():
JSX
.
Element
{
const
[
fetchingTask
,
setFetchingTask
]
=
useState
(
true
);
const
[
taskInstance
,
setTaskInstance
]
=
useState
<
Task
|
null
>
(
null
);
const
history
=
useHistory
();
const
id
=
+
useParams
<
{
id
:
string
}
>
().
id
;
useEffect
(():
void
=>
{
if
(
Number
.
isInteger
(
id
))
{
core
.
tasks
.
get
({
id
})
.
then
(([
task
]:
Task
[])
=>
{
if
(
task
)
{
setTaskInstance
(
task
);
}
}).
catch
((
error
:
Error
)
=>
{
notification
.
error
({
message
:
'
Could not fetch requested task from the server
'
,
description
:
error
.
toString
(),
});
}).
finally
(()
=>
{
setFetchingTask
(
false
);
});
}
else
{
notification
.
error
({
message
:
'
Could not receive the requested task from the server
'
,
description
:
`Requested task id "
${
id
}
" is not valid`
,
});
setFetchingTask
(
false
);
}
},
[]);
return
(
<
div
className
=
'cvat-task-analytics-page'
>
{
fetchingTask
?
(
<
div
className
=
'cvat-create-job-loding'
>
<
Spin
size
=
'large'
className
=
'cvat-spinner'
/>
</
div
>
)
:
(
<
Row
justify
=
'center'
align
=
'top'
className
=
'cvat-analytics-wrapper'
>
<
Col
md
=
{
22
}
lg
=
{
18
}
xl
=
{
16
}
xxl
=
{
14
}
className
=
'cvat-task-top-bar'
>
<
Button
className
=
'cvat-back-to-task-button'
onClick
=
{
()
=>
history
.
push
(
`/tasks/
${
taskInstance
.
id
}
`
)
}
type
=
'link'
size
=
'large'
>
<
LeftOutlined
/>
Back to task
</
Button
>
</
Col
>
<
Col
md
=
{
22
}
lg
=
{
18
}
xl
=
{
16
}
xxl
=
{
14
}
className
=
'cvat-analytics-inner'
>
<
Tabs
type
=
'card'
>
<
Tabs
.
TabPane
tab
=
{
(
<
span
>
<
Text
>
Quality
</
Text
>
</
span
>
)
}
key
=
'quality'
>
<
TaskQualityComponent
task
=
{
taskInstance
}
/>
</
Tabs
.
TabPane
>
</
Tabs
>
</
Col
>
</
Row
>
)
}
</
div
>
);
}
export
default
React
.
memo
(
TaskAnalyticsPage
);
cvat-ui/src/components/task-page/job-list.tsx
浏览文件 @
56893f84
...
...
@@ -15,7 +15,7 @@ import Text from 'antd/lib/typography/Text';
import
moment
from
'
moment
'
;
import
copy
from
'
copy-to-clipboard
'
;
import
{
Task
,
Job
}
from
'
cvat-core-wrapper
'
;
import
{
Task
,
Job
,
JobType
}
from
'
cvat-core-wrapper
'
;
import
{
JobStage
}
from
'
reducers
'
;
import
CVATTooltip
from
'
components/common/cvat-tooltip
'
;
import
UserSelector
,
{
User
}
from
'
./user-selector
'
;
...
...
@@ -89,7 +89,9 @@ function JobListComponent(props: Props): JSX.Element {
}
=
props
;
const
history
=
useHistory
();
const
{
jobs
,
id
:
taskId
}
=
taskInstance
;
const
{
id
:
taskId
}
=
taskInstance
;
let
{
jobs
}
=
taskInstance
;
jobs
=
jobs
.
filter
((
job
:
Job
)
=>
job
.
type
===
JobType
.
NORMAL
);
function
sorter
(
path
:
string
)
{
return
(
obj1
:
any
,
obj2
:
any
):
number
=>
{
...
...
cvat-ui/src/components/task-page/top-bar.tsx
浏览文件 @
56893f84
...
...
@@ -2,7 +2,7 @@
//
// SPDX-License-Identifier: MIT
import
React
from
'
react
'
;
import
React
,
{
useCallback
}
from
'
react
'
;
import
{
useHistory
}
from
'
react-router
'
;
import
{
Row
,
Col
}
from
'
antd/lib/grid
'
;
import
{
LeftOutlined
,
MoreOutlined
}
from
'
@ant-design/icons
'
;
...
...
@@ -21,6 +21,10 @@ export default function DetailsComponent(props: DetailsComponentProps): JSX.Elem
const
history
=
useHistory
();
const
onViewAnalytics
=
useCallback
(()
=>
{
history
.
push
(
`/tasks/
${
taskInstance
.
id
}
/analytics`
);
},
[
history
]);
return
(
<
Row
className
=
'cvat-task-top-bar'
justify
=
'space-between'
align
=
'middle'
>
<
Col
>
...
...
@@ -47,7 +51,13 @@ export default function DetailsComponent(props: DetailsComponentProps): JSX.Elem
)
}
</
Col
>
<
Col
>
<
Dropdown
overlay
=
{
<
ActionsMenuContainer
taskInstance
=
{
taskInstance
}
/>
}
>
<
Dropdown
overlay
=
{
(
<
ActionsMenuContainer
taskInstance
=
{
taskInstance
}
onViewAnalytics
=
{
onViewAnalytics
}
/>
)
}
>
<
Button
size
=
'middle'
className
=
'cvat-task-page-actions-button'
>
<
Text
className
=
'cvat-text-color'
>
Actions
</
Text
>
<
MoreOutlined
className
=
'cvat-menu-icon'
/>
...
...
cvat-ui/src/components/tasks-page/task-item.tsx
浏览文件 @
56893f84
...
...
@@ -144,6 +144,10 @@ class TaskItemComponent extends React.PureComponent<TaskItemProps & RouteCompone
const
{
taskInstance
,
history
}
=
this
.
props
;
const
{
id
}
=
taskInstance
;
const
onViewAnalytics
=
():
void
=>
{
history
.
push
(
`/tasks/
${
taskInstance
.
id
}
/analytics`
);
};
return
(
<
Col
span
=
{
4
}
>
<
Row
justify
=
'end'
>
...
...
@@ -164,7 +168,13 @@ class TaskItemComponent extends React.PureComponent<TaskItemProps & RouteCompone
</
Col
>
</
Row
>
<
Row
justify
=
'end'
>
<
Dropdown
overlay
=
{
<
ActionsMenuContainer
taskInstance
=
{
taskInstance
}
/>
}
>
<
Dropdown
overlay
=
{
(
<
ActionsMenuContainer
taskInstance
=
{
taskInstance
}
onViewAnalytics
=
{
onViewAnalytics
}
/>
)
}
>
<
Col
className
=
'cvat-item-open-task-actions'
>
<
Text
className
=
'cvat-text-color'
>
Actions
</
Text
>
<
MoreOutlined
className
=
'cvat-menu-icon'
/>
...
...
cvat-ui/src/containers/actions-menu/actions-menu.tsx
浏览文件 @
56893f84
...
...
@@ -20,6 +20,7 @@ import { importActions } from 'actions/import-actions';
interface
OwnProps
{
taskInstance
:
any
;
onViewAnalytics
:
()
=>
void
;
}
interface
StateToProps
{
...
...
@@ -87,8 +88,8 @@ function ActionsMenuContainer(props: OwnProps & StateToProps & DispatchToProps):
deleteTask
,
openRunModelWindow
,
openMoveTaskToProjectWindow
,
onViewAnalytics
,
}
=
props
;
const
onClickMenu
=
(
params
:
MenuInfo
):
void
|
JSX
.
Element
=>
{
const
[
action
]
=
params
.
keyPath
;
if
(
action
===
Actions
.
EXPORT_TASK_DATASET
)
{
...
...
@@ -105,6 +106,8 @@ function ActionsMenuContainer(props: OwnProps & StateToProps & DispatchToProps):
openMoveTaskToProjectWindow
(
taskInstance
.
id
);
}
else
if
(
action
===
Actions
.
LOAD_TASK_ANNO
)
{
showImportModal
(
taskInstance
);
}
else
if
(
action
===
Actions
.
VIEW_ANALYTICS
)
{
onViewAnalytics
();
}
};
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录