Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Q
quasar-web-base
Project
Project
Details
Activity
Releases
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
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Nguyễn Hải Sơn
quasar-web-base
Commits
33b9a73e
Commit
33b9a73e
authored
May 08, 2021
by
Tình Trương
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update
parent
db2b67de
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
220 additions
and
91 deletions
+220
-91
configurations.example.ts
src/assets/configurations.example.ts
+2
-0
enums.ts
src/assets/enums.ts
+5
-0
type.ts
src/assets/type.ts
+15
-0
index.vue
...components/units-manager/add-update-unit-dialog/index.vue
+77
-14
index.vue
...components/units-manager/unit-add-update-artist/index.vue
+45
-53
index.ts
src/i18n/vi/index.ts
+7
-4
index.vue
src/pages/don-vi-chu-quan/index.vue
+69
-20
No files found.
src/assets/configurations.example.ts
View file @
33b9a73e
...
...
@@ -48,4 +48,6 @@ export enum API_PATHS {
bankOptions
=
'bank'
,
cardTypeOptions
=
'cardType'
,
uploadImage
=
'file/upload'
,
getDetailUnit
=
'artistOwner/detail'
,
updateUnit
=
'artistOwner/update'
,
}
src/assets/enums.ts
View file @
33b9a73e
...
...
@@ -3,3 +3,8 @@ export enum EditMode {
add
=
1
,
edit
=
2
,
}
export
enum
UnitStatus
{
active
=
1
,
inactive
=
2
,
}
src/assets/type.ts
View file @
33b9a73e
import
{
type
}
from
'os'
;
export
type
PaginationResponse
<
DataType
>
=
{
pageIndex
:
null
|
number
;
pageSize
:
null
|
number
;
...
...
@@ -203,3 +205,16 @@ export type ArtistOwnerAdd = {
fields
:
Array
<
FieldType
>
;
contracts
:
Array
<
Contract
>
;
};
export
type
DetailUnit
=
{
id
:
number
;
name
:
string
;
code
:
string
;
representative
:
string
;
address
:
string
;
email
:
string
;
phoneNumber
:
string
;
status
:
number
;
fields
:
Array
<
FieldType
>
;
contracts
:
Array
<
Contract
>
;
};
src/components/units-manager/add-update-unit-dialog/index.vue
View file @
33b9a73e
...
...
@@ -5,12 +5,20 @@
@
update:model-value=
"$emit('update:isOpened', $event)"
>
<q-card
class=
"full-width"
style=
"max-width: 85.71rem"
bordered
>
<q-form
greedy
@
submit
.
prevent=
"$emit('addNewUnit')"
>
<q-form
greedy
@
submit
.
prevent=
"
$emit('addNewUnit',
{});
$emit('update:isOpened', false);
"
>
<q-card-section
class=
"q-pa-none"
>
<q-item>
<q-item-section>
<q-item-label
class=
"text-h6 text-weight-regular"
>
{{
$t
(
'managingUnit.dialogLabel.title.add'
)
isUpdate
?
$t
(
'managingUnit.dialogLabel.title.add'
)
:
$t
(
'managingUnit.dialogLabel.title.update'
)
}}
</q-item-label>
</q-item-section>
</q-item>
...
...
@@ -90,6 +98,7 @@
option-label=
"name"
class=
"q-my-sm"
outlined
use-chips
clearable
></q-select>
<q-input
...
...
@@ -108,6 +117,8 @@
}}
</span
><q-toggle
:model-value=
"status"
:true-value=
"UnitStatus.active"
:false-value=
"UnitStatus.inactive"
@
update:model-value=
"$emit('update:status', $event)"
/>
</div>
...
...
@@ -142,7 +153,13 @@
>
<template
v-slot:body-cell-action=
"item"
>
<q-td
style=
"padding: 0"
class=
"flex flex-center"
>
<q-btn
flat
round
color=
"primary"
icon=
"mdi-delete-outline"
>
<q-btn
flat
round
color=
"primary"
icon=
"mdi-delete-outline"
@
click=
"deleteContract(item.rowIndex)"
>
<q-tooltip
:offset=
"[20, 10]"
>
{{
$t
(
'managingUnitAdd.toolTipMessage.delete'
)
}}
</q-tooltip>
...
...
@@ -164,12 +181,16 @@
<q-td>
<div
align=
"center"
>
<q-chip
:color=
"rowData.value ? 'positive' : 'orange'"
:color=
"
rowData.value === UnitStatus.active
? 'positive'
: 'orange'
"
text-color=
"white"
size=
"sm"
>
{{
rowData
.
value
rowData
.
value
===
UnitStatus
.
active
?
$t
(
'managingUnitAdd.statusLabel.active'
)
:
$t
(
'managingUnitAdd.statusLabel.inactive'
)
}}
...
...
@@ -177,6 +198,12 @@
</div>
</q-td>
</
template
>
<
template
v-slot:body-cell-timeAdd=
"rowData"
>
<q-td>
{{
rowData
.
row
.
contractFrom
.
split
(
' '
)[
0
]
}}
-
{{
rowData
.
row
.
contractTo
.
split
(
' '
)[
0
]
}}
</q-td>
</
template
>
</q-table>
</div>
</q-card-section>
...
...
@@ -213,6 +240,7 @@
v-model:contractTimeTo=
"contractTimeTo"
:artistOptions=
"artistOptions"
:fieldOptions=
"fieldsOptions"
isUpdate
@
saveArtistInfo=
"addNewArtist"
/>
...
...
@@ -225,7 +253,6 @@
v-model:contractTimeTo=
"contractTimeTo"
:artistOptions=
"artistOptions"
:fieldOptions=
"fieldsOptions"
isUpdate
@
saveArtistInfo=
"updateArtistContract"
/>
</template>
...
...
@@ -235,19 +262,20 @@ import { defineComponent, Ref, ref, onMounted, watch, PropType } from 'vue';
import
{
i18n
}
from
'src/boot/i18n'
;
import
{
isEmail
}
from
'../../../boot/functions'
;
import
{
isMobilePhone
}
from
'../../../boot/functions'
;
import
{
API_PATHS
}
from
'src/assets/configurations
.example
'
;
import
{
API_PATHS
}
from
'src/assets/configurations'
;
import
{
AxiosResponse
}
from
'axios'
;
import
{
api
,
BaseResponseBody
}
from
'src/boot/axios'
;
import
{
FieldType
,
ArtistInfoType
,
Contract
}
from
'src/assets/type'
;
import
{
config
}
from
'src/assets/configurations'
;
import
UnitAddUpdateArtistDialog
from
'../unit-add-update-artist/index.vue'
;
import
moment
from
'moment'
;
import
{
Notify
}
from
'quasar'
;
import
{
Dialog
,
Notify
}
from
'quasar'
;
import
{
UnitStatus
}
from
'src/assets/enums'
;
const
artistTableColumns
=
[
{
name
:
'nameAdd'
,
field
:
'
f
ullName'
,
field
:
'
artistF
ullName'
,
required
:
true
,
label
:
i18n
.
global
.
t
(
'managingUnitAdd.tableColumns.nameAdd'
),
headerStyle
:
'text-align: center !important;'
,
...
...
@@ -308,6 +336,7 @@ export default defineComponent({
type
:
Boolean
,
required
:
true
,
},
isUpdate
:
{
type
:
Boolean
,
default
:
false
},
fieldsOptions
:
{
type
:
Array
,
required
:
true
},
fields
:
{
type
:
Number
,
required
:
true
},
code
:
{
type
:
String
,
required
:
true
},
...
...
@@ -316,7 +345,7 @@ export default defineComponent({
email
:
{
type
:
String
,
required
:
true
},
address
:
{
type
:
String
,
required
:
true
},
phoneNumber
:
{
type
:
String
,
required
:
true
},
status
:
{
type
:
Boolean
,
required
:
true
},
status
:
{
type
:
Number
,
required
:
true
},
artistList
:
{
type
:
Array
as
PropType
<
unknown
[]
>
,
required
:
true
},
},
setup
(
props
,
context
)
{
...
...
@@ -475,8 +504,14 @@ export default defineComponent({
updateArtistDialogIsOpened
.
value
=
true
;
artistField
.
value
=
{
id
:
artist
.
fieldId
,
name
:
artist
.
field
};
artistStatus
.
value
=
artist
.
status
;
contractTimeFrom
.
value
=
artist
.
contractFrom
;
contractTimeTo
.
value
=
artist
.
contractTo
;
contractTimeFrom
.
value
=
moment
(
artist
.
contractFrom
,
'DD/MM/YYYY HH:mm:ss'
).
format
(
'DD/MM/YYYY'
);
contractTimeTo
.
value
=
moment
(
artist
.
contractTo
,
'DD/MM/YYYY HH:mm:ss'
).
format
(
'DD/MM/YYYY'
);
};
const
updateArtistContract
=
()
=>
{
...
...
@@ -489,7 +524,7 @@ export default defineComponent({
status
:
artistStatus
.
value
,
artistId
:
artistName
.
value
?.
id
,
artistName
:
artistName
.
value
?.
artistName
,
f
ullName
:
artistName
.
value
?.
fullName
,
artistF
ullName
:
artistName
.
value
?.
fullName
,
field
:
artistField
.
value
?.
name
,
};
context
.
emit
(
'update:artistList'
,
[...
newArtistList
]);
...
...
@@ -512,7 +547,7 @@ export default defineComponent({
status
:
artistStatus
.
value
,
artistId
:
artistName
.
value
?.
id
,
artistName
:
artistName
.
value
?.
artistName
,
f
ullName
:
artistName
.
value
?.
fullName
,
artistF
ullName
:
artistName
.
value
?.
fullName
,
field
:
artistField
.
value
?.
name
,
});
context
.
emit
(
'update:artistList'
,
[...
newArtistList
]);
...
...
@@ -525,6 +560,32 @@ export default defineComponent({
});
};
const
deleteContract
=
(
index
:
number
)
=>
{
Dialog
.
create
({
title
:
i18n
.
global
.
t
(
'managingUnit.confirmActionsTitle.confirmDeleteManagingUnitsTitle'
),
message
:
i18n
.
global
.
t
(
'managingUnitAdd.confirmActionsTitle.confirmDelete'
),
cancel
:
i18n
.
global
.
t
(
'managingUnit.confirmActionsTitle.confirmDeleteManagingUnitsCancelBtnLabel'
),
color
:
'negative'
,
}).
onOk
(()
=>
{
const
newArtistList
=
[...
props
.
artistList
];
newArtistList
.
splice
(
index
,
1
);
context
.
emit
(
'update:artistList'
,
[...
newArtistList
]);
Notify
.
create
({
type
:
'positive'
,
message
:
i18n
.
global
.
t
(
'managingUnitAdd.actionMessages.unitDeleteArtistSuccess'
),
actions
:
[{
icon
:
'close'
,
color
:
'white'
}],
});
});
};
onMounted
(()
=>
{
void
getFieldOptions
();
});
...
...
@@ -552,6 +613,8 @@ export default defineComponent({
updateArtistContract
,
updateArtistDialogIsOpened
,
openUpdateArtistDialog
,
UnitStatus
,
deleteContract
,
};
},
emits
:
[
...
...
src/components/units-manager/unit-add-update-artist/index.vue
View file @
33b9a73e
...
...
@@ -4,7 +4,7 @@
:model-value=
"isOpened"
@
update:model-value=
"$emit('update:isOpened', $event)"
>
<q-card
style=
"min-width: 700px
"
bordered
>
<q-card
class=
"full-width"
style=
"max-width: 50rem
"
bordered
>
<q-form
greedy
@
submit
.
prevent=
"
...
...
@@ -54,32 +54,30 @@
outlined
:rules=
"contractTimeFromRules"
readonly
><template
v-slot:append
>
<q-icon
name=
"event"
class=
"cursor-pointer"
>
<q-popup-proxy
ref=
"qDateProxy"
transition-show=
"scale"
transition-hide=
"scale"
>
<q-date
:model-value=
"contractTimeFrom"
@
update:model-value=
"
$emit('update:contractTimeFrom', $event)
"
mask=
"DD/MM/YYYY"
>
<div
class=
"row items-center justify-end"
>
<q-btn
v-close-popup
label=
"Close"
color=
"primary"
flat
/>
</div>
</q-date>
</q-popup-proxy>
</q-icon>
</
template
></q-input>
>
<template
v-slot:append
>
<q-icon
name=
"event"
class=
"cursor-pointer"
>
</q-icon>
</
template
>
<q-popup-proxy
ref=
"qDateProxy"
transition-show=
"scale"
transition-hide=
"scale"
:breakpoint=
"100000"
>
<q-date
:model-value=
"contractTimeFrom"
@
update:model-value=
"
$emit('update:contractTimeFrom', $event)
"
mask=
"DD/MM/YYYY"
>
<div
class=
"row items-center justify-end"
>
<q-btn
v-close-popup
label=
"Ok"
color=
"primary"
flat
/>
</div>
</q-date>
</q-popup-proxy>
</q-input>
<div>
<span
class=
"text-body1"
>
{{
$t('managingUnitAdd.dialogLabel.fieldLabels.status')
...
...
@@ -126,31 +124,24 @@
:rules=
"contractTimeToRules"
readonly
><
template
v-slot:append
>
<q-icon
name=
"event"
class=
"cursor-pointer"
>
<q-popup-proxy
ref=
"qDateProxy"
transition-show=
"scale"
transition-hide=
"scale"
>
<q-date
:model-value=
"contractTimeTo"
mask=
"DD/MM/YYYY"
@
update:model-value=
"
$emit('update:contractTimeTo', $event)
"
>
<div
class=
"row items-center justify-end"
>
<q-btn
v-close-popup
label=
"Close"
color=
"primary"
flat
/>
</div>
</q-date>
</q-popup-proxy>
</q-icon>
<q-icon
name=
"event"
class=
"cursor-pointer"
>
</q-icon>
</
template
>
<q-popup-proxy
ref=
"qDateProxy"
transition-show=
"scale"
transition-hide=
"scale"
:breakpoint=
"100000"
>
<q-date
:model-value=
"contractTimeTo"
mask=
"DD/MM/YYYY"
@
update:model-value=
"$emit('update:contractTimeTo', $event)"
>
<div
class=
"row items-center justify-end"
>
<q-btn
v-close-popup
label=
"Ok"
color=
"primary"
flat
/>
</div>
</q-date>
</q-popup-proxy>
</q-input>
</div>
</div>
...
...
@@ -180,8 +171,9 @@
</template>
<
script
lang=
"ts"
>
import
{
defineComponent
}
from
'vue'
;
import
{
defineComponent
,
PropType
}
from
'vue'
;
import
{
i18n
}
from
'src/boot/i18n'
;
import
{
ArtistInfoType
}
from
'src/assets/type'
;
export
default
defineComponent
({
props
:
{
...
...
@@ -193,7 +185,7 @@ export default defineComponent({
artistOptions
:
{
type
:
Array
,
required
:
true
},
fieldOptions
:
{
type
:
Array
,
required
:
true
},
artistField
:
{
type
:
Number
,
required
:
true
},
artistName
:
{
type
:
Number
,
required
:
true
},
artistName
:
{
type
:
Object
as
PropType
<
ArtistInfoType
>
,
required
:
true
},
artistStatus
:
{
type
:
Number
,
required
:
true
},
contractTimeFrom
:
{
type
:
String
,
required
:
true
},
contractTimeTo
:
{
type
:
String
,
required
:
true
},
...
...
src/i18n/vi/index.ts
View file @
33b9a73e
...
...
@@ -21,6 +21,7 @@ export default {
responseErrorMsg
:
{
'msg-1'
:
'Lỗi không xác định'
,
msg999
:
'Lỗi hệ thống'
,
msg99
:
'Lỗi hệ thống'
,
},
emptyData
:
'Không có dữ liệu'
,
crudActions
:
{
...
...
@@ -252,11 +253,13 @@ export default {
requireArtistField
:
'Vui lòng chọn Lĩnh vực'
,
requireContractTimeFromRules
:
'Vui lòng chọn Thời gian bắt đầu hợp đồng'
,
},
// confirmActionsTitle: {
// },
confirmActionsTitle
:
{
confirmDelete
:
'Bạn có chắc chắn muốn xóa hợp đồng với nghệ sỹ?'
,
},
actionMessages
:
{
unitAddArtistSuccess
:
'Thêm nghệ sỹ thành công'
,
unitUpdateArtistSuccess
:
'Cập nhật nghệ sỹ thành công'
,
unitAddArtistSuccess
:
'Thêm hợp đồng nghệ sỹ thành công'
,
unitUpdateArtistSuccess
:
'Cập nhật hợp đồng nghệ sỹ thành công'
,
unitDeleteArtistSuccess
:
'Xóa hợp đồng nghệ sỹ thành công'
,
},
},
...
...
src/pages/don-vi-chu-quan/index.vue
View file @
33b9a73e
...
...
@@ -62,7 +62,7 @@
round
color=
"primary"
icon=
"mdi-account-edit-outline"
@
click=
"openUpdateUnitDialog()"
@
click=
"openUpdateUnitDialog(
item.row.id
)"
>
<q-tooltip
:offset=
"[20, 10]"
>
{{
$t
(
'managingUnit.toolTipMessage.updateInfo'
)
...
...
@@ -90,7 +90,7 @@
size=
"sm"
>
{{
rowData
.
value
rowData
.
value
===
UnitStatus
.
active
?
$t
(
'managingUnit.statusLabel.active'
)
:
$t
(
'managingUnit.statusLabel.inactive'
)
}}
...
...
@@ -122,6 +122,7 @@
v-model:representative=
"unitRepresentative"
v-model:status=
"unitStatus"
v-model:artistList=
"unitArtistList"
isUpdate
@
addNewUnit=
"addNewUnit"
/>
...
...
@@ -137,7 +138,7 @@
v-model:representative=
"unitRepresentative"
v-model:status=
"unitStatus"
v-model:artistList=
"unitArtistList"
@
update
NewUnit=
"updateNewUnit"
@
add
NewUnit=
"updateNewUnit"
/>
</div>
</template>
...
...
@@ -147,7 +148,7 @@ import { i18n } from 'src/boot/i18n';
import
{
defineComponent
,
onMounted
,
ref
,
Ref
}
from
'vue'
;
import
Pagination
from
'components/pagination/index.vue'
;
import
{
Dialog
,
Notify
}
from
'quasar'
;
import
{
API_PATHS
}
from
'src/assets/configurations
.example
'
;
import
{
API_PATHS
}
from
'src/assets/configurations'
;
import
{
AxiosResponse
}
from
'axios'
;
import
{
api
,
BaseResponseBody
}
from
'src/boot/axios'
;
import
{
...
...
@@ -155,9 +156,11 @@ import {
ArtistOwner
,
FieldType
,
ArtistOwnerAdd
,
DetailUnit
,
}
from
'src/assets/type'
;
import
{
config
}
from
'src/assets/configurations'
;
import
AddUpdateUnitDialog
from
'components/units-manager/add-update-unit-dialog/index.vue'
;
import
{
UnitStatus
}
from
'src/assets/enums'
;
export
default
defineComponent
({
components
:
{
...
...
@@ -259,15 +262,16 @@ export default defineComponent({
const
fieldSelected
:
Ref
<
number
|
undefined
>
=
ref
();
const
addUnitDialogIsOpened
=
ref
(
false
);
const
updateUnitDialogIsOpened
=
ref
(
false
);
const
unitField
=
ref
(
undefined
);
const
unitField
:
Ref
<
FieldType
[]
|
undefined
>
=
ref
(
undefined
);
const
unitCode
=
ref
(
''
);
const
unitName
=
ref
(
''
);
const
unitRepresentative
=
ref
(
''
);
const
unitEmail
=
ref
(
''
);
const
unitAddress
=
ref
(
''
);
const
unitPhoneNumber
=
ref
(
''
);
const
unitStatus
:
Ref
<
boolean
|
number
>
=
ref
(
tru
e
);
const
unitStatus
:
Ref
<
number
>
=
ref
(
UnitStatus
.
activ
e
);
const
unitArtistList
:
Ref
<
unknown
[]
>
=
ref
([]);
const
unitId
:
Ref
<
number
|
undefined
>
=
ref
(
undefined
);
const
getListUnits
=
async
()
=>
{
try
{
...
...
@@ -294,20 +298,38 @@ export default defineComponent({
unitEmail
.
value
=
''
;
unitAddress
.
value
=
''
;
unitPhoneNumber
.
value
=
''
;
unitStatus
.
value
=
true
;
unitArtistList
.
value
=
[];
unitStatus
.
value
=
UnitStatus
.
active
;
addUnitDialogIsOpened
.
value
=
true
;
};
const
openUpdateUnitDialog
=
()
=>
{
// unitField.value = undefined;
// unitCode.value = '';
// unitName.value = '';
// unitRepresentative.value = '';
// unitEmail.value = '';
// unitAddress.value = '';
// unitPhoneNumber.value = '';
// unitStatus.value = true;
const
openUpdateUnitDialog
=
(
id
:
number
)
=>
{
updateUnitDialogIsOpened
.
value
=
true
;
void
getDetailUnit
(
id
);
};
const
getDetailUnit
=
async
(
id
:
number
)
=>
{
try
{
const
response
=
(
await
api
({
url
:
API_PATHS
.
getDetailUnit
,
method
:
'GET'
,
params
:
{
id
:
id
,
},
}))
as
AxiosResponse
<
BaseResponseBody
<
DetailUnit
>>
;
if
(
response
.
data
.
error
.
code
===
config
.
API_RES_CODE
.
OK
.
code
)
{
unitId
.
value
=
response
.
data
.
data
.
id
;
unitName
.
value
=
response
.
data
.
data
.
name
;
unitCode
.
value
=
response
.
data
.
data
.
code
;
unitEmail
.
value
=
response
.
data
.
data
.
email
;
unitPhoneNumber
.
value
=
response
.
data
.
data
.
phoneNumber
;
unitRepresentative
.
value
=
response
.
data
.
data
.
representative
;
unitAddress
.
value
=
response
.
data
.
data
.
address
;
unitStatus
.
value
=
response
.
data
.
data
.
status
;
unitArtistList
.
value
=
response
.
data
.
data
.
contracts
;
unitField
.
value
=
response
.
data
.
data
.
fields
;
}
}
catch
(
error
)
{}
};
const
changePageSize
=
()
=>
{
...
...
@@ -367,10 +389,35 @@ export default defineComponent({
}
};
const
updateNewUnit
=
()
=>
{
//gọi api update
try
{
}
catch
(
error
)
{}
const
updateNewUnit
=
async
()
=>
{
const
data
=
{
id
:
unitId
.
value
,
name
:
unitName
.
value
,
code
:
unitCode
.
value
,
representative
:
unitRepresentative
.
value
,
address
:
unitAddress
.
value
,
email
:
unitEmail
.
value
,
phoneNumber
:
unitPhoneNumber
.
value
,
status
:
unitStatus
.
value
?
1
:
2
,
fields
:
unitField
.
value
,
contracts
:
unitArtistList
.
value
,
};
const
response
=
(
await
api
({
url
:
API_PATHS
.
updateUnit
,
method
:
'POST'
,
data
,
}))
as
AxiosResponse
<
BaseResponseBody
<
ArtistOwnerAdd
[]
>>
;
if
(
response
.
data
.
error
.
code
===
config
.
API_RES_CODE
.
OK
.
code
)
{
updateUnitDialogIsOpened
.
value
=
false
;
Notify
.
create
({
type
:
'positive'
,
message
:
i18n
.
global
.
t
(
'managingUnit.actionMessages.updateManagingUnitsAccess'
),
actions
:
[{
icon
:
'close'
,
color
:
'white'
}],
});
void
getListUnits
();
}
};
//add
...
...
@@ -409,6 +456,7 @@ export default defineComponent({
void
getFieldOptions
();
});
return
{
getDetailUnit
,
addUnitDialogIsOpened
,
updateUnitDialogIsOpened
,
getFieldOptions
,
...
...
@@ -438,6 +486,7 @@ export default defineComponent({
unitArtistList
,
addNewUnit
,
openUpdateUnitDialog
,
UnitStatus
,
};
},
});
...
...
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