Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
X
xiaomai-cloud-class-web
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
xiaomai-cloud-class
xiaomai-cloud-class-web
Commits
bd6794c0
Commit
bd6794c0
authored
Aug 02, 2021
by
yuananting
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat:添加培训内容部分
parent
52a7b420
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
476 additions
and
52 deletions
+476
-52
src/common/less/icon-font.less
+3
-3
src/index.html
+32
-32
src/modules/task-center/train-task/AddTrainTask.jsx
+14
-2
src/modules/task-center/train-task/components/RelatedCourseDrawer.jsx
+0
-0
src/modules/task-center/train-task/components/RelatedCourseDrawer.less
+141
-0
src/modules/task-center/train-task/components/TrainContent.jsx
+227
-15
src/modules/task-center/train-task/components/TrainContent.less
+59
-0
No files found.
src/common/less/icon-font.less
View file @
bd6794c0
@font-face {
font-family: 'iconfont'; /* Project id 2223403 */
src: url('//at.alicdn.com/t/font_2223403_
oe5p510553.woff2?t=1624259078391
') format('woff2'),
url('//at.alicdn.com/t/font_2223403_
oe5p510553.woff?t=1624259078391
') format('woff'),
url('//at.alicdn.com/t/font_2223403_
oe5p510553.ttf?t=1624259078391
') format('truetype');
src: url('//at.alicdn.com/t/font_2223403_
e1xgcyaur7.woff2?t=1627810786858
') format('woff2'),
url('//at.alicdn.com/t/font_2223403_
e1xgcyaur7.woff?t=1627810786858
') format('woff'),
url('//at.alicdn.com/t/font_2223403_
e1xgcyaur7.ttf?t=1627810786858
') format('truetype');
}
.iconfont {
font-family: 'iconfont' !important;
...
...
src/index.html
View file @
bd6794c0
...
...
@@ -8,30 +8,30 @@
-->
<!DOCTYPE html>
<html>
<head>
<meta
charset=
"utf-8"
/>
<link
rel=
"icon"
href=
""
/>
<meta
name=
"viewport"
content=
"width=device-width, initial-scale=1"
/>
<meta
name=
"theme-color"
content=
"#000000"
/>
<meta
name=
"description"
content=
"小麦企学院,一站式企业培训数字化服务商,通过“工具+内容”,帮助企业快速从0到1搭建数字化培训体系,并让整个培训过程可视化,降低培训成本,提升培训效率。"
/>
<meta
name=
"keywords"
content=
"小麦企学院,企业培训,员工培训,企业大学,企业内训,企业外训,培训计划,培训素材,企培,企训,素材库,培训课程,培训任务,直播课,线上课,图文课,线下活动,知识库,作业,考试,排行榜,培训类别管理,定制培训计划,管理数据,学习数据,企学院,资料共享,培训数字化,数字化培训,培训工具,在线培训,线上培训,培训saas,培训管理,企业微信培训,对客培训,客户培训,直播培训,互联网培训,新员工培训,管理培训,管理者培训,工人培训,制造业培训,餐饮培训,服务业培训,零售培训,门店培训,工厂培训,车间培训,培训补贴,人事培训,财务培训,职场培训,企业学院平台,教育企业学院,教育企业平台,教育平台学院,企业学习,酷学院,小鹅通,企业学院,云学堂,时代光华,云课堂,魔学院,云大学,米知云,授课学堂"
/>
<!-- <link rel="apple-touch-icon" href="../src/common/images/logo.png" /> -->
<link
rel=
"shortcut icon"
href=
"https://image.xiaomaiketang.com/xm/c4KiP2epBP.png"
/>
<head>
<meta
charset=
"utf-8"
/>
<link
rel=
"icon"
href=
""
/>
<meta
name=
"viewport"
content=
"width=device-width, initial-scale=1"
/>
<meta
name=
"theme-color"
content=
"#000000"
/>
<meta
name=
"description"
content=
"小麦企学院,一站式企业培训数字化服务商,通过“工具+内容”,帮助企业快速从0到1搭建数字化培训体系,并让整个培训过程可视化,降低培训成本,提升培训效率。"
/>
<meta
name=
"keywords"
content=
"小麦企学院,企业培训,员工培训,企业大学,企业内训,企业外训,培训计划,培训素材,企培,企训,素材库,培训课程,培训任务,直播课,线上课,图文课,线下活动,知识库,作业,考试,排行榜,培训类别管理,定制培训计划,管理数据,学习数据,企学院,资料共享,培训数字化,数字化培训,培训工具,在线培训,线上培训,培训saas,培训管理,企业微信培训,对客培训,客户培训,直播培训,互联网培训,新员工培训,管理培训,管理者培训,工人培训,制造业培训,餐饮培训,服务业培训,零售培训,门店培训,工厂培训,车间培训,培训补贴,人事培训,财务培训,职场培训,企业学院平台,教育企业学院,教育企业平台,教育平台学院,企业学习,酷学院,小鹅通,企业学院,云学堂,时代光华,云课堂,魔学院,云大学,米知云,授课学堂"
/>
<!-- <link rel="apple-touch-icon" href="../src/common/images/logo.png" /> -->
<link
rel=
"shortcut icon"
href=
"https://image.xiaomaiketang.com/xm/c4KiP2epBP.png"
/>
<!--
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link
rel=
"manifest"
href=
"%PUBLIC_URL%/manifest.json"
/>
<link
rel=
"stylesheet"
href=
"//at.alicdn.com/t/font_2223403_oe5p510553
.css"
/>
<link
rel=
"manifest"
href=
"%PUBLIC_URL%/manifest.json"
/>
<link
rel=
"stylesheet"
href=
"//at.alicdn.com/t/font_2223403_e1xgcyaur7
.css"
/>
<!--
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
...
...
@@ -40,19 +40,19 @@
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>
小麦企学院
</title>
<script
type=
"text/javascript"
src=
"https://image.xiaomaiketang.com/xm/iscroll-zoom-min.js"
></script>
<script
type=
"text/javascript"
src=
"https://image.xiaomaiketang.com/xm/hammer.min.js"
></script>
<script
type=
"text/javascript"
src=
"https://image.xiaomaiketang.com/xm/lrz.all.bundle.js"
></script>
<script
type=
"text/javascript"
src=
"https://image.xiaomaiketang.com/xm/PhotoClip.js"
></script>
<script
type=
"text/javascript"
charset=
"utf-8"
src=
"//g.alicdn.com/sd/ncpc/nc.js?t=2015052012"
></script>
<script
type=
"text/javascript"
src=
"https://xiaomai-js.oss-cn-hangzhou.aliyuncs.com/loghub-xm-0.0.1-beta.js"
></script>
</head>
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div
id=
"root"
></div>
<title>
小麦企学院
</title>
<script
type=
"text/javascript"
src=
"https://image.xiaomaiketang.com/xm/iscroll-zoom-min.js"
></script>
<script
type=
"text/javascript"
src=
"https://image.xiaomaiketang.com/xm/hammer.min.js"
></script>
<script
type=
"text/javascript"
src=
"https://image.xiaomaiketang.com/xm/lrz.all.bundle.js"
></script>
<script
type=
"text/javascript"
src=
"https://image.xiaomaiketang.com/xm/PhotoClip.js"
></script>
<script
type=
"text/javascript"
charset=
"utf-8"
src=
"//g.alicdn.com/sd/ncpc/nc.js?t=2015052012"
></script>
<script
type=
"text/javascript"
src=
"https://xiaomai-js.oss-cn-hangzhou.aliyuncs.com/loghub-xm-0.0.1-beta.js"
></script>
</head>
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div
id=
"root"
></div>
<!--
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
...
...
@@ -62,5 +62,5 @@
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</body>
</html>
src/modules/task-center/train-task/AddTrainTask.jsx
View file @
bd6794c0
...
...
@@ -2,7 +2,7 @@
* @Author: yuananting
* @Date: 2021-07-29 13:57:03
* @LastEditors: yuananting
* @LastEditTime: 2021-0
7-30 16:35:59
* @LastEditTime: 2021-0
8-02 10:42:28
* @Description: 任务中心-培训任务-新建页面
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
...
...
@@ -38,10 +38,18 @@ const DEFAULT_BASIC_INFO = {
percentCompletePicture
:
100
,
};
const
DEFAULT_TASK_LIST
=
[
{
taskName
:
'阶段一'
,
courseList
:
[],
},
];
function
AddTrainTask
()
{
const
type
=
getParameterByName
(
'type'
);
const
[
activeStep
,
setActiveStep
]
=
useState
(
'BASIC_INFO'
);
const
[
basicInfo
,
setBasicInfo
]
=
useState
(
DEFAULT_BASIC_INFO
);
const
[
taskList
,
setTaskList
]
=
useState
(
DEFAULT_TASK_LIST
);
function
renderFooter
()
{
return
(
...
...
@@ -81,6 +89,10 @@ function AddTrainTask() {
});
}
function
handleChangeTaskInfo
(
value
)
{
setTaskList
(
value
);
}
return
(
<
div
className=
'page add-train-task'
>
<
Breadcrumbs
navList=
{
type
==
'add'
?
'新建培训任务'
:
'编辑培训任务'
}
goBack=
{
handleGoBack
}
/>
...
...
@@ -93,7 +105,7 @@ function AddTrainTask() {
<
BasicInfo
data=
{
basicInfo
}
onChange=
{
handleChangeBasicInfo
}
/>
</
TabPane
>
<
TabPane
tab=
'2 培训内容'
key=
'TRAIN_CONTENT'
>
<
TrainContent
/>
<
TrainContent
data=
{
taskList
}
onChange=
{
handleChangeTaskInfo
}
/>
</
TabPane
>
</
Tabs
>
</
div
>
...
...
src/modules/task-center/train-task/components/RelatedCourseDrawer.jsx
0 → 100644
View file @
bd6794c0
This diff is collapsed.
Click to expand it.
src/modules/task-center/train-task/components/RelatedCourseDrawer.less
0 → 100644
View file @
bd6794c0
.related-course-drawer {
.link-create-course {
color: #666666;
font-size: 14px;
width: 638px;
text-align: left;
display: inline-block;
span {
color: #2966ff;
}
}
.search-container {
margin-bottom: 16px;
}
.select-area {
margin-bottom: 12px;
display: flex;
justify-content: space-between;
.select-box {
display: inline-box;
width: 186px;
background: #e9efff;
border-radius: 4px;
padding: 6px 16px;
margin-right: 8px;
display: flex;
justify-content: space-between;
.tip-icon {
color: #2966ff;
font-size: 14px;
margin-right: 4px;
}
.select-num {
color: #666666;
font-size: 14px;
}
.clear-btn {
text-align: right;
color: #2966ff;
font-size: 14px;
}
}
.related-box {
padding: 6px 16px;
background: #e9efff;
border-radius: 4px;
flex: 1;
color: #666666;
font-size: 14px;
}
}
.search-container {
margin-bottom: 16px;
}
.select-area {
margin-bottom: 12px;
display: flex;
justify-content: space-between;
.select-box {
display: inline-box;
width: 186px;
background: #e9efff;
border-radius: 4px;
padding: 6px 16px;
margin-right: 8px;
display: flex;
justify-content: space-between;
.tip-icon {
color: #2966ff;
font-size: 14px;
margin-right: 4px;
}
.select-num {
color: #666666;
font-size: 14px;
}
.clear-btn {
text-align: right;
color: #5289fa;
font-size: 14px;
}
}
.related-box {
padding: 6px 16px;
background: #e9efff;
border-radius: 4px;
flex: 1;
color: #666666;
font-size: 14px;
}
}
.course-info {
display: flex;
align-items: center;
.course-cover {
width: 97px;
height: 55px;
display: inline-block;
border-radius: 4px;
margin-right: 8px;
}
.course-name {
font-size: 14px;
color: #666;
text-overflow: -o-ellipsis-lastline;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
line-clamp: 2;
-webkit-box-orient: vertical;
width: 180px;
}
.course-status {
font-size: 12px;
line-height: 18px;
display: inline-block;
border-radius: 2px;
padding: 0 8px;
margin-top: 8px;
}
}
.footer {
position: fixed;
right: 0;
bottom: 0;
height: 50px;
width: 720px;
display: flex;
align-items: center;
justify-content: flex-end;
padding-right: 24px;
background: #fff;
border-top: 1px solid #e8e8e8;
z-index: 9999;
.ant-btn {
margin-left: 8px;
}
}
}
src/modules/task-center/train-task/components/TrainContent.jsx
View file @
bd6794c0
...
...
@@ -2,27 +2,239 @@
* @Author: yuananting
* @Date: 2021-07-30 16:33:58
* @LastEditors: yuananting
* @LastEditTime: 2021-0
7-30 16:58:03
* @LastEditTime: 2021-0
8-02 10:58:34
* @Description: 任务中心-培训任务-新建-培训内容
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
import
React
from
'react'
;
import
{
Form
,
Button
,
Input
,
Space
,
DatePicker
,
Radio
,
Tag
,
Col
,
message
,
Tooltip
}
from
'antd'
;
import
React
,
{
Component
}
from
'react'
;
import
{
Form
,
Button
,
Input
,
Space
,
DatePicker
,
Radio
,
Tag
,
Col
,
message
,
Tooltip
,
Collapse
,
Dropdown
,
Menu
,
Drawer
}
from
'antd'
;
import
{
sortableContainer
,
sortableElement
,
sortableHandle
}
from
'react-sortable-hoc'
;
import
arrayMove
from
'array-move'
;
import
'./TrainContent.less'
;
import
RelatedCourseDrawer
from
'./RelatedCourseDrawer'
;
const
{
Panel
}
=
Collapse
;
const
SortableTaskContainer
=
sortableContainer
((
props
)
=>
<
div
{
...
props
}
></
div
>);
const
SortableTaskItem
=
sortableElement
((
props
)
=>
<
div
{
...
props
}
>
{
props
.
taskitem
}
</
div
>);
const
DragHandle
=
sortableHandle
(()
=>
<
span
className=
'drag-btn'
>
::
</
span
>);
class
TrainContent
extends
Component
{
constructor
(
props
)
{
super
(
props
);
this
.
state
=
{
dataSource
:
props
.
data
,
showCourseDrawer
:
false
,
};
}
setTrianTypeOption
=
()
=>
{
return
(
<
Menu
>
<
Menu
.
Item
key=
'course'
onClick=
{
()
=>
this
.
setState
({
showCourseDrawer
:
true
})
}
>
<
img
className=
'type-option-icon'
src=
'https://image.xiaomaiketang.com/xm/6C2GjSpnDp.png'
/>
<
span
>
课程
</
span
>
</
Menu
.
Item
>
<
Menu
.
Item
key=
'exam'
>
<
img
className=
'type-option-icon'
src=
'https://image.xiaomaiketang.com/xm/M4BEXnRWbb.png'
/>
<
span
>
考试
</
span
>
</
Menu
.
Item
>
<
Menu
.
Item
key=
'homework'
>
<
img
className=
'type-option-icon'
src=
'https://image.xiaomaiketang.com/xm/ypWQcFWnxB.png'
/>
<
span
>
实操作业
</
span
>
</
Menu
.
Item
>
</
Menu
>
);
};
onTaskSortEnd
=
({
oldIndex
,
newIndex
})
=>
{
const
{
dataSource
}
=
this
.
state
;
if
(
oldIndex
!==
newIndex
)
{
const
newData
=
arrayMove
([].
concat
(
dataSource
),
oldIndex
,
newIndex
).
filter
((
el
)
=>
!!
el
);
this
.
setState
(
{
dataSource
:
newData
,
},
()
=>
{
this
.
props
.
onChange
(
newData
);
}
);
}
};
handleRenameTaskName
=
(
e
,
item
)
=>
{
const
{
value
}
=
e
.
target
;
const
{
dataSource
}
=
this
.
state
;
item
.
taskName
=
value
;
this
.
setState
(
{
dataSource
,
},
()
=>
{
this
.
props
.
onChange
(
dataSource
);
}
);
};
handleTaskNameBlur
=
(
e
,
item
)
=>
{
const
{
value
}
=
e
.
target
;
const
{
dataSource
}
=
this
.
state
;
let
input
=
/^
[\s]
*$/
;
if
(
value
&&
!
input
.
test
(
value
))
{
item
.
type
=
'text'
;
this
.
setState
(
{
dataSource
,
},
()
=>
{
this
.
props
.
onChange
(
dataSource
);
}
);
}
};
handleValidatorTaskName
=
(
rule
,
value
)
=>
{
let
input
=
/^
[\s]
*$/
;
if
(
input
.
test
(
value
)
||
!
value
)
{
return
Promise
.
reject
(
new
Error
(
'请输入任务名称'
));
}
return
Promise
.
resolve
();
};
renderTaskInfo
=
(
item
,
index
)
=>
{
return
(
<
div
className=
'sort-task-item'
>
<
Choose
>
<
When
condition=
{
item
.
type
===
'input'
}
>
<
div
className=
'task-name-con'
>
{
/* <span className='number'>{index + 1}.</span> */
}
<
Form
>
<
Form
.
Item
initialValue=
{
item
.
taskName
}
validateTrigger=
{
[
'onChange'
,
'onBlur'
]
}
name=
{
[
'taskName'
]
}
rules=
{
[
{
validator
:
(
rule
,
value
)
=>
this
.
handleValidatorTaskName
(
rule
,
value
),
},
]
}
>
<
Input
className=
'task-name-input'
style=
{
{
width
:
300
}
}
placeholder=
'请输入阶段名称'
maxLength=
{
20
}
onChange=
{
(
e
)
=>
{
this
.
handleRenameTaskName
(
e
,
item
);
e
.
stopPropagation
();
}
}
onBlur=
{
(
e
)
=>
{
this
.
handleTaskNameBlur
(
e
,
item
);
e
.
stopPropagation
();
}
}
/>
</
Form
.
Item
>
</
Form
>
</
div
>
</
When
>
<
Otherwise
>
<
div
className=
'task-name-con'
>
{
/* <span className='number'>{index + 1}.</span> */
}
<
span
className=
'task-name'
>
{
item
.
taskName
}
</
span
>
</
div
>
</
Otherwise
>
</
Choose
>
<
span
className=
'item-operate'
>
<
span
className=
'operate__item'
onClick=
{
(
e
)
=>
{
const
{
dataSource
}
=
this
.
state
;
item
.
type
=
'input'
;
this
.
setState
({
dataSource
});
e
.
stopPropagation
();
}
}
>
<
span
className=
'icon iconfont'
>

</
span
>
<
span
className=
'text'
>
重命名
</
span
>
</
span
>
<
span
className=
'operate__item'
style=
{
{
marginLeft
:
16
}
}
onClick=
{
(
e
)
=>
{
this
.
handleDeleteTask
(
index
);
e
.
stopPropagation
();
}
}
>
<
span
className=
'icon iconfont'
>

</
span
>
<
span
className=
'text'
>
删除
</
span
>
</
span
>
</
span
>
<
DragHandle
/>
</
div
>
);
};
renderTaskItem
=
(
item
,
index
)
=>
{
return
(
<
Collapse
ghost
>
<
Panel
header=
{
this
.
renderTaskInfo
(
item
,
index
)
}
key=
{
index
}
>
{
/* {renderTaskItem(props.iteminfo, props.index)} */
}
<
Dropdown
overlay=
{
this
.
setTrianTypeOption
()
}
className=
'add-course-btn'
onClick=
{
()
=>
{
// this.showRelatedCourseModal(index);
}
}
>
<
span
>
+ 关联课程
</
span
>
</
Dropdown
>
</
Panel
>
</
Collapse
>
);
};
// 添加阶段
addStage
=
()
=>
{
const
{
dataSource
}
=
this
.
state
;
const
taskObj
=
{
taskName
:
''
,
index
:
dataSource
.
length
,
type
:
'input'
,
open
:
true
,
courseList
:
[],
};
const
newData
=
[...
dataSource
,
taskObj
];
this
.
setState
(
{
dataSource
:
newData
,
},
()
=>
{
this
.
props
.
onChange
(
newData
);
}
);
};
onCloseCourseDrawer
=
()
=>
{
this
.
setState
({
showCourseDrawer
:
false
,
});
};
function
TrainContent
(
props
)
{
const
SortableTaskContainer
=
sortableContainer
((
props
)
=>
<
div
{
...
props
}
></
div
>);
return
(
<
div
className=
'train-content__warp'
>
<
SortableTaskContainer
useDragHandle
disableAutoscroll
helperClass=
'row-dragging'
onSortEnd=
{
this
.
onTaskSortEnd
}
className=
'plan-task-sort-container'
>
{
dataSource
.
map
((
item
,
index
)
=>
(
<
SortableTaskItem
taskitem=
{
this
.
renderTaskItem
(
item
,
index
)
}
index=
{
index
}
key=
{
index
}
></
SortableTaskItem
>
))
}
</
SortableTaskContainer
>
</
div
>
);
render
()
{
const
{
dataSource
,
showCourseDrawer
}
=
this
.
state
;
return
(
<
div
className=
'train-content__warp'
>
<
SortableTaskContainer
useDragHandle
disableAutoscroll
helperClass=
'row-dragging'
onSortEnd=
{
this
.
onTaskSortEnd
}
>
{
dataSource
.
map
((
item
,
index
)
=>
(
<
SortableTaskItem
taskitem=
{
this
.
renderTaskItem
(
item
,
index
)
}
index=
{
index
}
key=
{
index
}
></
SortableTaskItem
>
))
}
</
SortableTaskContainer
>
<
div
className=
'add-task-btn'
onClick=
{
()
=>
this
.
addStage
()
}
>
+ 添加阶段
</
div
>
<
RelatedCourseDrawer
data=
{
dataSource
}
onClose=
{
this
.
onCloseCourseDrawer
}
visible=
{
showCourseDrawer
}
/>
</
div
>
);
}
}
export
default
TrainContent
;
src/modules/task-center/train-task/components/TrainContent.less
0 → 100644
View file @
bd6794c0
.train-content__warp {
.ant-collapse-content {
padding-left: 24px !important;
}
}
.sort-task-item {
width: calc(100% - 24px);
display: inline-flex;
align-items: center;
.ant-form-item {
margin-bottom: 0 !important;
}
.item-name {
color: #333333;
}
.item-operate {
display: none;
margin-left: 30px;
.operate__item {
cursor: pointer;
.icon {
color: #bfbfbf;
font-size: 14px;
}
.text {
color: #666666;
margin-left: 8px;
}
}
}
&:hover {
.item-operate {
display: block;
}
}
.drag-btn {
margin-left: auto;
}
}
.add-course-btn {
color: #2966ff;
}
.add-task-btn {
color: #2966ff;
height: 52px;
background: #f7f8f9;
border-radius: 2px;
padding: 16px;
margin-top: 16px;
cursor: pointer;
}
.type-option-icon {
width: 20px;
height: 20px;
margin-right: 12px;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment