Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
疯人忠
Cvat
提交
582e23bf
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,发现更多精彩内容 >>
未验证
提交
582e23bf
编写于
8月 19, 2020
作者:
D
Dmitry Kalinin
提交者:
GitHub
8月 19, 2020
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Batch of fixes (#2031)
上级
9c4e717d
变更
16
隐藏空白更改
内联
并排
Showing
16 changed file
with
100 addition
and
19 deletion
+100
-19
CHANGELOG.md
CHANGELOG.md
+1
-0
cvat-ui/package-lock.json
cvat-ui/package-lock.json
+1
-1
cvat-ui/package.json
cvat-ui/package.json
+1
-1
cvat-ui/src/actions/tasks-actions.ts
cvat-ui/src/actions/tasks-actions.ts
+6
-4
cvat-ui/src/components/create-task-page/create-task-content.tsx
...i/src/components/create-task-page/create-task-content.tsx
+17
-3
cvat-ui/src/components/create-task-page/create-task-page.tsx
cvat-ui/src/components/create-task-page/create-task-page.tsx
+3
-0
cvat-ui/src/components/header/header.tsx
cvat-ui/src/components/header/header.tsx
+20
-6
cvat-ui/src/components/labels-editor/constructor-creator.tsx
cvat-ui/src/components/labels-editor/constructor-creator.tsx
+19
-3
cvat-ui/src/components/labels-editor/label-form.tsx
cvat-ui/src/components/labels-editor/label-form.tsx
+9
-0
cvat-ui/src/components/labels-editor/labels-editor.tsx
cvat-ui/src/components/labels-editor/labels-editor.tsx
+2
-0
cvat-ui/src/components/labels-editor/raw-viewer.tsx
cvat-ui/src/components/labels-editor/raw-viewer.tsx
+4
-0
cvat-ui/src/containers/create-task-page/create-task-page.tsx
cvat-ui/src/containers/create-task-page/create-task-page.tsx
+1
-0
cvat-ui/src/reducers/interfaces.ts
cvat-ui/src/reducers/interfaces.ts
+1
-0
cvat-ui/src/reducers/tasks-reducer.ts
cvat-ui/src/reducers/tasks-reducer.ts
+4
-0
cvat/apps/engine/serializers.py
cvat/apps/engine/serializers.py
+10
-0
tests/cypress/support/commands.js
tests/cypress/support/commands.js
+1
-1
未找到文件。
CHANGELOG.md
浏览文件 @
582e23bf
...
...
@@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed
-
Issue loading openvino models for semi-automatic and automatic annotation (
<https://github.com/opencv/cvat/pull/1996>
)
-
Basic functions of CVAT works without activated nuclio dashboard
-
Fixed error with creating task with labels with the same name (
<https://github.com/opencv/cvat/pull/2031>
)
### Security
-
...
...
cvat-ui/package-lock.json
浏览文件 @
582e23bf
{
"name": "cvat-ui",
"version": "1.7.
1
",
"version": "1.7.
2
",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
cvat-ui/package.json
浏览文件 @
582e23bf
{
"name"
:
"cvat-ui"
,
"version"
:
"1.7.
1
"
,
"version"
:
"1.7.
2
"
,
"description"
:
"CVAT single-page application"
,
"main"
:
"src/index.tsx"
,
"scripts"
:
{
...
...
cvat-ui/src/actions/tasks-actions.ts
浏览文件 @
582e23bf
...
...
@@ -344,10 +344,12 @@ function createTask(): AnyAction {
return
action
;
}
function
createTaskSuccess
():
AnyAction
{
function
createTaskSuccess
(
taskId
:
number
):
AnyAction
{
const
action
=
{
type
:
TasksActionTypes
.
CREATE_TASK_SUCCESS
,
payload
:
{},
payload
:
{
taskId
,
},
};
return
action
;
...
...
@@ -433,10 +435,10 @@ ThunkAction<Promise<void>, {}, {}, AnyAction> {
dispatch
(
createTask
());
try
{
await
taskInstance
.
save
((
status
:
string
):
void
=>
{
const
savedTask
=
await
taskInstance
.
save
((
status
:
string
):
void
=>
{
dispatch
(
createTaskUpdateStatus
(
status
));
});
dispatch
(
createTaskSuccess
());
dispatch
(
createTaskSuccess
(
savedTask
.
id
));
}
catch
(
error
)
{
dispatch
(
createTaskFailed
(
error
));
}
...
...
cvat-ui/src/components/create-task-page/create-task-content.tsx
浏览文件 @
582e23bf
...
...
@@ -3,6 +3,8 @@
// SPDX-License-Identifier: MIT
import
React
from
'
react
'
;
import
{
RouteComponentProps
}
from
'
react-router
'
;
import
{
withRouter
}
from
'
react-router-dom
'
;
import
{
Row
,
Col
}
from
'
antd/lib/grid
'
;
import
Alert
from
'
antd/lib/alert
'
;
import
Button
from
'
antd/lib/button
'
;
...
...
@@ -26,6 +28,7 @@ export interface CreateTaskData {
interface
Props
{
onCreate
:
(
data
:
CreateTaskData
)
=>
void
;
status
:
string
;
taskId
:
number
|
null
;
installedGit
:
boolean
;
}
...
...
@@ -48,22 +51,31 @@ const defaultState = {
},
};
export
default
class
CreateTaskContent
extends
React
.
PureComponent
<
Props
,
State
>
{
class
CreateTaskContent
extends
React
.
PureComponent
<
Props
&
RouteComponent
Props
,
State
>
{
private
basicConfigurationComponent
:
any
;
private
advancedConfigurationComponent
:
any
;
private
fileManagerContainer
:
any
;
public
constructor
(
props
:
Props
)
{
public
constructor
(
props
:
Props
&
RouteComponentProps
)
{
super
(
props
);
this
.
state
=
{
...
defaultState
};
}
public
componentDidUpdate
(
prevProps
:
Props
):
void
{
const
{
status
}
=
this
.
props
;
const
{
status
,
history
,
taskId
}
=
this
.
props
;
if
(
status
===
'
CREATED
'
&&
prevProps
.
status
!==
'
CREATED
'
)
{
const
btn
=
(
<
Button
onClick
=
{
()
=>
history
.
push
(
`/tasks/
${
taskId
}
`
)
}
>
Open task
</
Button
>
);
notification
.
info
({
message
:
'
The task has been created
'
,
btn
,
});
this
.
basicConfigurationComponent
.
resetFields
();
...
...
@@ -252,3 +264,5 @@ export default class CreateTaskContent extends React.PureComponent<Props, State>
);
}
}
export
default
withRouter
(
CreateTaskContent
);
cvat-ui/src/components/create-task-page/create-task-page.tsx
浏览文件 @
582e23bf
...
...
@@ -16,6 +16,7 @@ interface Props {
onCreate
:
(
data
:
CreateTaskData
)
=>
void
;
status
:
string
;
error
:
string
;
taskId
:
number
|
null
;
installedGit
:
boolean
;
}
...
...
@@ -23,6 +24,7 @@ export default function CreateTaskPage(props: Props): JSX.Element {
const
{
error
,
status
,
taskId
,
onCreate
,
installedGit
,
}
=
props
;
...
...
@@ -66,6 +68,7 @@ export default function CreateTaskPage(props: Props): JSX.Element {
<
Col
md
=
{
20
}
lg
=
{
16
}
xl
=
{
14
}
xxl
=
{
9
}
>
<
Text
className
=
'cvat-title'
>
Create a new task
</
Text
>
<
CreateTaskContent
taskId
=
{
taskId
}
status
=
{
status
}
onCreate
=
{
onCreate
}
installedGit
=
{
installedGit
}
...
...
cvat-ui/src/components/header/header.tsx
浏览文件 @
582e23bf
...
...
@@ -3,7 +3,7 @@
// SPDX-License-Identifier: MIT
import
'
./styles.scss
'
;
import
React
from
'
react
'
;
import
React
,
{
MouseEvent
}
from
'
react
'
;
import
{
RouteComponentProps
}
from
'
react-router
'
;
import
{
withRouter
}
from
'
react-router-dom
'
;
import
{
Row
,
Col
}
from
'
antd/lib/grid
'
;
...
...
@@ -174,8 +174,12 @@ function HeaderContainer(props: Props): JSX.Element {
className
=
'cvat-header-button'
type
=
'link'
value
=
'tasks'
href
=
'/tasks?page=1'
onClick
=
{
():
void
=>
props
.
history
.
push
(
'
/tasks?page=1
'
)
(
event
:
React
.
MouseEvent
):
void
=>
{
event
.
preventDefault
();
props
.
history
.
push
(
'
/tasks?page=1
'
);
}
}
>
Tasks
...
...
@@ -184,8 +188,12 @@ function HeaderContainer(props: Props): JSX.Element {
className
=
'cvat-header-button'
type
=
'link'
value
=
'models'
href
=
'/models'
onClick
=
{
():
void
=>
props
.
history
.
push
(
'
/models
'
)
(
event
:
React
.
MouseEvent
):
void
=>
{
event
.
preventDefault
();
props
.
history
.
push
(
'
/models
'
);
}
}
>
Models
...
...
@@ -195,8 +203,10 @@ function HeaderContainer(props: Props): JSX.Element {
<
Button
className
=
'cvat-header-button'
type
=
'link'
href
=
{
`
${
serverHost
}
/analytics/app/kibana`
}
onClick
=
{
():
void
=>
{
(
event
:
React
.
MouseEvent
):
void
=>
{
event
.
preventDefault
();
// false positive
// eslint-disable-next-line
window
.
open
(
`
${
serverHost
}
/analytics/app/kibana`
,
'
_blank
'
);
...
...
@@ -211,8 +221,10 @@ function HeaderContainer(props: Props): JSX.Element {
<
Button
className
=
'cvat-header-button'
type
=
'link'
href
=
{
GITHUB_URL
}
onClick
=
{
():
void
=>
{
(
event
:
React
.
MouseEvent
):
void
=>
{
event
.
preventDefault
();
// false positive
// eslint-disable-next-line security/detect-non-literal-fs-filename
window
.
open
(
GITHUB_URL
,
'
_blank
'
);
...
...
@@ -225,8 +237,10 @@ function HeaderContainer(props: Props): JSX.Element {
<
Button
className
=
'cvat-header-button'
type
=
'link'
href
=
{
`
${
serverHost
}
/documentation/user_guide.html`
}
onClick
=
{
():
void
=>
{
(
event
:
React
.
MouseEvent
):
void
=>
{
event
.
preventDefault
();
// false positive
// eslint-disable-next-line
window
.
open
(
`
${
serverHost
}
/documentation/user_guide.html`
,
'
_blank
'
)
...
...
cvat-ui/src/components/labels-editor/constructor-creator.tsx
浏览文件 @
582e23bf
...
...
@@ -8,14 +8,30 @@ import LabelForm from './label-form';
import
{
Label
}
from
'
./common
'
;
interface
Props
{
labelNames
:
string
[];
onCreate
:
(
label
:
Label
|
null
)
=>
void
;
}
export
default
function
ConstructorCreator
(
props
:
Props
):
JSX
.
Element
{
const
{
onCreate
}
=
props
;
function
compareProps
(
prevProps
:
Props
,
nextProps
:
Props
):
boolean
{
if
(
prevProps
.
onCreate
!==
nextProps
.
onCreate
)
{
return
false
;
}
if
(
!
(
prevProps
.
labelNames
.
length
===
nextProps
.
labelNames
.
length
&&
prevProps
.
labelNames
.
map
((
value
,
index
)
=>
value
===
nextProps
.
labelNames
[
index
])
.
reduce
((
prevValue
,
curValue
)
=>
prevValue
&&
curValue
,
true
)
))
{
return
false
;
}
return
true
;
}
function
ConstructorCreator
(
props
:
Props
):
JSX
.
Element
{
const
{
onCreate
,
labelNames
}
=
props
;
return
(
<
div
className
=
'cvat-label-constructor-creator'
>
<
LabelForm
label
=
{
null
}
onSubmit
=
{
onCreate
}
/>
<
LabelForm
label
=
{
null
}
onSubmit
=
{
onCreate
}
labelNames
=
{
labelNames
}
/>
</
div
>
);
}
export
default
React
.
memo
(
ConstructorCreator
,
compareProps
);
cvat-ui/src/components/labels-editor/label-form.tsx
浏览文件 @
582e23bf
...
...
@@ -32,6 +32,7 @@ export enum AttributeType {
type
Props
=
FormComponentProps
&
{
label
:
Label
|
null
;
labelNames
?:
string
[];
onSubmit
:
(
label
:
Label
|
null
)
=>
void
;
};
...
...
@@ -384,6 +385,7 @@ class LabelForm extends React.PureComponent<Props, {}> {
const
{
label
,
form
,
labelNames
,
}
=
this
.
props
;
const
value
=
label
?
label
.
name
:
''
;
const
locked
=
label
?
label
.
id
>=
0
:
false
;
...
...
@@ -399,6 +401,13 @@ class LabelForm extends React.PureComponent<Props, {}> {
},
{
pattern
:
patterns
.
validateAttributeName
.
pattern
,
message
:
patterns
.
validateAttributeName
.
message
,
},
{
validator
:
async
(
_rule
:
any
,
labelName
:
string
,
callback
:
Function
)
=>
{
if
(
labelNames
&&
labelNames
.
includes
(
labelName
))
{
callback
(
'
Label name must be unique for the task
'
);
}
},
}],
})(<
Input
disabled
=
{
locked
}
placeholder
=
'Label name'
/>)
}
</
Form
.
Item
>
...
...
cvat-ui/src/components/labels-editor/labels-editor.tsx
浏览文件 @
582e23bf
...
...
@@ -221,6 +221,7 @@ export default class LabelsEditor
}
public
render
():
JSX
.
Element
{
const
{
labels
}
=
this
.
props
;
const
{
savedLabels
,
unsavedLabels
,
...
...
@@ -319,6 +320,7 @@ export default class LabelsEditor
constructorMode
===
ConstructorMode
.
CREATE
&&
(
<
ConstructorCreator
labelNames
=
{
labels
.
map
((
l
)
=>
l
.
name
)
}
onCreate
=
{
this
.
handleCreate
}
/>
)
...
...
cvat-ui/src/components/labels-editor/raw-viewer.tsx
浏览文件 @
582e23bf
...
...
@@ -28,6 +28,10 @@ class RawViewer extends React.PureComponent<Props> {
if
(
!
Array
.
isArray
(
parsed
))
{
callback
(
'
Field is expected to be a JSON array
'
);
}
const
labelNames
=
parsed
.
map
((
label
:
Label
)
=>
label
.
name
);
if
(
new
Set
(
labelNames
).
size
!==
labelNames
.
length
)
{
callback
(
'
Label names must be unique for the task
'
);
}
for
(
const
label
of
parsed
)
{
try
{
...
...
cvat-ui/src/containers/create-task-page/create-task-page.tsx
浏览文件 @
582e23bf
...
...
@@ -10,6 +10,7 @@ import { CreateTaskData } from 'components/create-task-page/create-task-content'
import
{
createTaskAsync
}
from
'
actions/tasks-actions
'
;
interface
StateToProps
{
taskId
:
number
|
null
;
status
:
string
;
error
:
string
;
installedGit
:
boolean
;
...
...
cvat-ui/src/reducers/interfaces.ts
浏览文件 @
582e23bf
...
...
@@ -60,6 +60,7 @@ export interface TasksState {
[
tid
:
number
]:
boolean
;
// deleted (deleting if in dictionary)
};
creates
:
{
taskId
:
number
|
null
;
status
:
string
;
error
:
string
;
};
...
...
cvat-ui/src/reducers/tasks-reducer.ts
浏览文件 @
582e23bf
...
...
@@ -31,6 +31,7 @@ const defaultState: TasksState = {
loads
:
{},
deletes
:
{},
creates
:
{
taskId
:
null
,
status
:
''
,
error
:
''
,
},
...
...
@@ -238,6 +239,7 @@ export default (state: TasksState = defaultState, action: AnyAction): TasksState
activities
:
{
...
state
.
activities
,
creates
:
{
taskId
:
null
,
status
:
''
,
error
:
''
,
},
...
...
@@ -259,12 +261,14 @@ export default (state: TasksState = defaultState, action: AnyAction): TasksState
};
}
case
TasksActionTypes
.
CREATE_TASK_SUCCESS
:
{
const
{
taskId
}
=
action
.
payload
;
return
{
...
state
,
activities
:
{
...
state
.
activities
,
creates
:
{
...
state
.
activities
.
creates
,
taskId
,
status
:
'
CREATED
'
,
},
},
...
...
cvat/apps/engine/serializers.py
浏览文件 @
582e23bf
...
...
@@ -37,6 +37,7 @@ class AttributeSerializer(serializers.ModelSerializer):
class
LabelSerializer
(
serializers
.
ModelSerializer
):
attributes
=
AttributeSerializer
(
many
=
True
,
source
=
'attributespec_set'
,
default
=
[])
class
Meta
:
model
=
models
.
Label
fields
=
(
'id'
,
'name'
,
'attributes'
)
...
...
@@ -305,6 +306,15 @@ class TaskSerializer(WriteOnceMixin, serializers.ModelSerializer):
instance
.
save
()
return
instance
def
validate_labels
(
self
,
value
):
if
not
value
:
raise
serializers
.
ValidationError
(
'Label set must not be empty'
)
label_names
=
[
label
[
'name'
]
for
label
in
value
]
if
len
(
label_names
)
!=
len
(
set
(
label_names
)):
raise
serializers
.
ValidationError
(
'All label names must be unique for the task'
)
return
value
class
ProjectSerializer
(
serializers
.
ModelSerializer
):
class
Meta
:
model
=
models
.
Project
...
...
tests/cypress/support/commands.js
浏览文件 @
582e23bf
...
...
@@ -44,7 +44,7 @@ Cypress.Commands.add('createAnnotationTask', (taksName='New annotation task',
cy
.
get
(
'
input[type="file"]
'
).
attachFile
(
image
,
{
subjectType
:
'
drag-n-drop
'
});
cy
.
contains
(
'
button
'
,
'
Submit
'
).
click
()
cy
.
contains
(
'
The task has been created
'
,
{
timeout
:
'
8000
'
})
cy
.
get
(
'
button
[value="tasks"]
'
).
click
()
cy
.
get
(
'
[value="tasks"]
'
).
click
()
cy
.
url
().
should
(
'
include
'
,
'
/tasks?page=
'
)
})
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录