Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
atlas
Project
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
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
dataplatform
atlas
Commits
a8fab3e7
Commit
a8fab3e7
authored
6 years ago
by
kevalbhatt
Committed by
Madhan Neethiraj
6 years ago
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ATLAS-2663: Glossary UI updates for related term association
Signed-off-by:
Madhan Neethiraj
<
madhan@apache.org
>
parent
570f2423
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
118 additions
and
43 deletions
+118
-43
VSearchList.js
dashboardv2/public/js/collection/VSearchList.js
+1
-1
Helpers.js
dashboardv2/public/js/modules/Helpers.js
+11
-0
Router.js
dashboardv2/public/js/router/Router.js
+1
-1
Modal.html
dashboardv2/public/js/templates/common/Modal.html
+2
-1
GlossaryDetailLayoutView_tmpl.html
.../js/templates/glossary/GlossaryDetailLayoutView_tmpl.html
+3
-3
TermRelationAttributeLayoutView_tmpl.html
...plates/glossary/TermRelationAttributeLayoutView_tmpl.html
+5
-4
TermRelationAttributeTable_tmpl.html
...s/templates/glossary/TermRelationAttributeTable_tmpl.html
+20
-13
CommonViewFunction.js
dashboardv2/public/js/utils/CommonViewFunction.js
+2
-2
Overrides.js
dashboardv2/public/js/utils/Overrides.js
+24
-2
Utils.js
dashboardv2/public/js/utils/Utils.js
+23
-5
DetailPageLayoutView.js
...ardv2/public/js/views/detail_page/DetailPageLayoutView.js
+2
-1
GlossaryDetailLayoutView.js
...rdv2/public/js/views/glossary/GlossaryDetailLayoutView.js
+3
-0
GlossaryLayoutView.js
dashboardv2/public/js/views/glossary/GlossaryLayoutView.js
+15
-6
TermRelationAttributeLayoutView.js
...blic/js/views/glossary/TermRelationAttributeLayoutView.js
+0
-0
SearchLayoutView.js
dashboardv2/public/js/views/search/SearchLayoutView.js
+2
-1
SearchResultLayoutView.js
dashboardv2/public/js/views/search/SearchResultLayoutView.js
+4
-3
No files found.
dashboardv2/public/js/collection/VSearchList.js
View file @
a8fab3e7
...
...
@@ -57,7 +57,7 @@ define(['require',
this
.
dynamicTable
=
false
;
return
resp
.
entities
?
resp
.
entities
:
[];
}
else
{
return
resp
?
resp
:
[];
return
[];
}
},
getBasicRearchResult
:
function
(
options
)
{
...
...
This diff is collapsed.
Click to expand it.
dashboardv2/public/js/modules/Helpers.js
View file @
a8fab3e7
...
...
@@ -100,5 +100,15 @@ define(['require',
return
(
obj
[
field
]
?
obj
[
field
]
:
(
defaulValue
?
defaulValue
:
""
));
});
Handlebars
.
registerHelper
(
'eachlookup'
,
function
(
obj
,
field
,
options
)
{
return
Handlebars
.
helpers
.
each
((
obj
[
field
]
?
obj
[
field
]
:
null
),
options
);
});
Handlebars
.
registerHelper
(
'callmyfunction'
,
function
(
functionObj
,
param
,
options
)
{
var
argumentObj
=
_
.
extend
([],
arguments
);
argumentObj
.
shift
();
return
functionObj
.
apply
(
this
,
argumentObj
);
});
return
HHelpers
;
});
\ No newline at end of file
This diff is collapsed.
Click to expand it.
dashboardv2/public/js/router/Router.js
View file @
a8fab3e7
...
...
@@ -225,7 +225,7 @@ define([
if
(
Utils
.
getUrlState
.
isTagTab
())
{
App
.
rSideNav
.
currentView
.
RTagLayoutView
.
currentView
.
manualRender
();
}
else
if
(
Utils
.
getUrlState
.
isGlossaryTab
())
{
App
.
rSideNav
.
currentView
.
RGlossaryLayoutView
.
currentView
.
manualRender
(
_
.
extend
({
isTrigger
:
true
},
paramObj
));
App
.
rSideNav
.
currentView
.
RGlossaryLayoutView
.
currentView
.
manualRender
(
_
.
extend
({
"isTrigger"
:
true
},
{
"value"
:
paramObj
}
));
}
}
...
...
This diff is collapsed.
Click to expand it.
dashboardv2/public/js/templates/common/Modal.html
View file @
a8fab3e7
...
...
@@ -28,7 +28,8 @@
</h4>
</div>
{{/if}} {{#if contentWithFooter}} {{else}}
<div
class=
"modal-body"
>
{{content}}
</div>
<div
class=
"modal-body"
>
{{#if contentHtml}} {{{contentHtm}}} {{else}} {{content}} {{/if}}
</div>
{{#if showFooter}}
<div
class=
"modal-footer"
>
{{#if buttons}} {{#each buttons}}
...
...
This diff is collapsed.
Click to expand it.
dashboardv2/public/js/templates/glossary/GlossaryDetailLayoutView_tmpl.html
View file @
a8fab3e7
...
...
@@ -52,7 +52,7 @@
</div>
{{/if}} {{#if isCategoryView}}
<div
class=
"form-group clearfix"
>
<span
class=
"control-label-sm-pr pull-left"
>
Term:
</span>
<span
class=
"control-label-sm-pr pull-left"
>
Term
s
:
</span>
<div
class=
"pull-left"
data-id=
"termList"
>
<button
class=
"btn btn-action btn-sm"
title=
"Add Term"
data-id=
"addTerm"
>
<i
class=
"fa fa-plus"
>
</i>
...
...
@@ -65,7 +65,7 @@
<ul
class=
"nav nav-tabs"
data-id=
"tab-list"
>
<li
role=
"entities"
class=
"tab active"
><a
href=
"#tab-entities"
aria-controls=
"tab-entities"
role=
"tab"
data-toggle=
"tab"
>
Entities
</a></li>
<li
role=
"classification"
><a
href=
"#tab-tagTable"
aria-controls=
"tab-tagTable"
role=
"tab"
data-toggle=
"tab"
>
Classifications
</a></li>
<li
role=
"
properties"
><a
href=
"#tab-properties"
aria-controls=
"tab-properties"
role=
"tab"
data-toggle=
"tab"
>
Propertie
s
</a></li>
<li
role=
"
relatedTerm"
><a
href=
"#tab-relatedTerm"
aria-controls=
"tab-relatedTerm"
role=
"tab"
data-toggle=
"tab"
>
Related Term
s
</a></li>
</ul>
</div>
</div>
...
...
@@ -89,7 +89,7 @@
</div>
</div>
</div>
<div
id=
"tab-
properties"
role=
"properties
"
class=
"tab-pane animated fadeIn"
>
<div
id=
"tab-
relatedTerm"
role=
"relatedTerm
"
class=
"tab-pane animated fadeIn"
>
<div
id=
"r_relationLayoutView"
>
<div
class=
"fontLoader-relative"
>
<i
class=
"fa fa-refresh fa-spin-custom"
></i>
...
...
This diff is collapsed.
Click to expand it.
dashboardv2/public/js/templates/glossary/TermRelationAttributeLayoutView_tmpl.html
View file @
a8fab3e7
...
...
@@ -16,17 +16,17 @@
-->
<div>
<div
class=
"row form-group"
>
<div
class=
"col-md-6"
>
<
!-- <
div class="col-md-6">
<select data-id="termAttributeSelect">
{{#each attributeList}}
<option value="{{@key}}">{{@key}}</option>{{/each}}
</select>
</div>
<div
class=
"col-md-6"
>
</div>
-->
<
!-- <
div class="col-md-6">
<button type="button" class="btn btn-action btn-md" data-id="addTermRelation">
<i class="fa fa-plus"></i> <span>Assign Term</span>
</button>
</div>
</div>
-->
</div>
<div
data-id=
"termAttributeTable"
></div>
</div>
\ No newline at end of file
This diff is collapsed.
Click to expand it.
dashboardv2/public/js/templates/glossary/TermRelationAttributeTable_tmpl.html
View file @
a8fab3e7
...
...
@@ -17,13 +17,19 @@
<table
class=
"table table-hover table-quickMenu"
>
<thead>
<tr>
<th>
Term
</th>
<th>
Attribute
</th>
<th>
Action
</th>
<th>
{{#if relationTypeTable}}Relation Types{{else}}Term{{/if}}
</th>
<th>
{{#if relationTypeTable}}Related Terms{{else}}Attribute{{/if}}
</th>
{{#if relationTypeTable}}
<th>
Attributes
</th>
{{/if}}
</tr>
</thead>
<tbody>
{{#if attributeValue}} {{#each attributeValue}}
{{#if relationTypeTable}} {{#each attributes}}
<tr>
<td>
{{@key}}
</td>
{{{callmyfunction ../getTerms @key}}}
</tr>
{{/each}} {{else}} {{#if attributeValue}} {{#each attributeValue}}
<tr>
<td>
{{this.displayText}}
</td>
<td>
...
...
@@ -39,22 +45,22 @@
{{#each ../attributes}}
<tr>
<td>
{{@key}}
</td>
<td>
{{lookup ../this @key "-"}}
</td>
{{#if ../../editMode}}
<td>
<input
data-id=
"attributeUpdate"
class=
"form-control"
type=
"text"
data-name=
"{{@key}}"
data-termguid=
"{{../../this.termGuid}}"
"
value=
"{{lookup ../../this @key ''}} "
>
</td>
{{else}}
<td>
{{lookup ../../this @key "- "}}
</td>
{{/if}}
</tr>
{{/each}}
</tbody>
</table>
</div>
</td>
<td>
<div
class=
"btn-inline"
>
<button
title=
"Delete"
data-termguid=
"{{this.termGuid}}"
class=
"btn btn-action btn-sm"
data-id=
"deleteAttribute"
data-name=
"Dimension"
><i
class=
"fa fa-trash"
></i></button>
</div>
</td>
</tr>
{{/each}}{{else}}
<tr
class=
"empty text-center"
>
<td
colspan=
"3"
><span>
No records found!
</span></td>
</tr>
{{/if}}
<tr
class=
"empty text-center
"
>
<td
colspan=
"3
"
><span>
No records found!
</span></td>
</tr>
{{/if}}
{{/if}}
</tbody>
</table>
\ No newline at end of file
This diff is collapsed.
Click to expand it.
dashboardv2/public/js/utils/CommonViewFunction.js
View file @
a8fab3e7
...
...
@@ -280,8 +280,8 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum
if
(
terms
)
{
terms
.
map
(
function
(
term
)
{
var
className
=
"btn btn-action btn-sm btn-blue btn-icon"
,
deleteIcon
=
'<i class="fa fa-times" data-id="delete" data-assetname="'
+
entityName
+
'"data-name="'
+
term
.
typeName
+
'" data-type="tag
" data-guid="'
+
obj
.
guid
+
'" data-termGuid="'
+
term
.
termGuid
+
'" ></i>'
,
termString
=
'<a class="'
+
className
+
'" data-id="termClick"><span title="'
+
term
.
typeName
+
'">'
+
term
.
displayText
+
'</span>'
+
deleteIcon
+
'</a>'
;
deleteIcon
=
'<i class="fa fa-times" data-id="delete" data-assetname="'
+
entityName
+
'"data-name="'
+
term
.
displayText
+
'" data-type="term
" data-guid="'
+
obj
.
guid
+
'" data-termGuid="'
+
term
.
termGuid
+
'" ></i>'
,
termString
=
'<a class="'
+
className
+
'" data-id="termClick"><span title="'
+
term
.
displayText
+
'">'
+
term
.
displayText
+
'</span>'
+
deleteIcon
+
'</a>'
;
if
(
count
>=
1
)
{
popTerm
+=
termString
;
}
else
{
...
...
This diff is collapsed.
Click to expand it.
dashboardv2/public/js/utils/Overrides.js
View file @
a8fab3e7
...
...
@@ -105,6 +105,12 @@ define(['require', 'utils/Utils', 'marionette', 'backgrid', 'asBreadcrumbs', 'jq
return
false
;
}
});
$
(
"body"
).
on
(
'click'
,
'.dropdown-menu.dropdown-changetitle li a'
,
function
()
{
$
(
this
).
parents
(
'li'
).
find
(
".btn:first-child"
).
html
(
$
(
this
).
text
()
+
' <span class="caret"></span>'
);
});
$
(
"body"
).
on
(
'click'
,
'.btn'
,
function
()
{
$
(
this
).
blur
();
});
// For placeholder support
if
(
!
(
'placeholder'
in
HTMLInputElement
.
prototype
))
{
...
...
@@ -144,8 +150,24 @@ define(['require', 'utils/Utils', 'marionette', 'backgrid', 'asBreadcrumbs', 'jq
var
that
=
this
;
Backgrid
.
HeaderRow
.
__super__
.
render
.
apply
(
this
,
arguments
);
_
.
each
(
this
.
columns
.
models
,
function
(
modelValue
)
{
if
(
modelValue
.
get
(
'width'
))
that
.
$el
.
find
(
'.'
+
modelValue
.
get
(
'name'
)).
css
(
'min-width'
,
modelValue
.
get
(
'width'
)
+
'px'
)
if
(
modelValue
.
get
(
'toolTip'
))
that
.
$el
.
find
(
'.'
+
modelValue
.
get
(
'name'
)).
attr
(
'title'
,
modelValue
.
get
(
'toolTip'
))
var
elAttr
=
modelValue
.
get
(
'elAttr'
),
elAttrObj
=
null
;
if
(
elAttr
)
{
if
(
_
.
isFunction
(
elAttr
))
{
elAttrObj
=
elAttr
(
modelValue
);
}
else
if
(
_
.
isObject
(
elAttr
))
{
if
(
!
_
.
isArray
(
elAttr
))
{
elAttrObj
=
[
elAttr
];
}
else
{
elAttrObj
=
elAttr
;
}
}
_
.
each
(
elAttrObj
,
function
(
val
)
{
that
.
$el
.
find
(
'.'
+
modelValue
.
get
(
'name'
)).
data
(
val
);
});
}
if
(
modelValue
.
get
(
'width'
))
that
.
$el
.
find
(
'.'
+
modelValue
.
get
(
'name'
)).
css
(
'min-width'
,
modelValue
.
get
(
'width'
)
+
'px'
);
if
(
modelValue
.
get
(
'toolTip'
))
that
.
$el
.
find
(
'.'
+
modelValue
.
get
(
'name'
)).
attr
(
'title'
,
modelValue
.
get
(
'toolTip'
));
});
return
this
;
}
...
...
This diff is collapsed.
Click to expand it.
dashboardv2/public/js/utils/Utils.js
View file @
a8fab3e7
...
...
@@ -305,21 +305,38 @@ define(['require', 'utils/Globals', 'pnotify', 'utils/Messages', 'utils/Enums',
lastValue
:
hashValue
.
split
(
'/'
)[
hashValue
.
split
(
'/'
).
length
-
1
]
}
},
checkTabUrl
:
function
(
options
)
{
var
url
=
options
&&
options
.
url
,
matchString
=
options
&&
options
.
matchString
,
quey
=
this
.
getQueryUrl
(
url
);
return
quey
.
firstValue
==
matchString
||
quey
.
queyParams
[
0
]
==
"#!/"
+
matchString
;
},
isInitial
:
function
()
{
return
this
.
getQueryUrl
().
firstValue
==
undefined
;
},
isTagTab
:
function
(
url
)
{
var
quey
=
this
.
getQueryUrl
(
url
);
return
quey
.
firstValue
==
"tag"
||
quey
.
queyParams
[
0
]
==
"#!/tag"
;
return
this
.
checkTabUrl
({
url
:
url
,
matchString
:
"tag"
});
},
isSearchTab
:
function
(
url
)
{
return
this
.
getQueryUrl
(
url
).
firstValue
==
"search"
;
return
this
.
checkTabUrl
({
url
:
url
,
matchString
:
"search"
});
},
isGlossaryTab
:
function
(
url
)
{
return
this
.
getQueryUrl
(
url
).
firstValue
==
"glossary"
;
return
this
.
checkTabUrl
({
url
:
url
,
matchString
:
"glossary"
});
},
isDetailPage
:
function
(
url
)
{
return
this
.
getQueryUrl
(
url
).
firstValue
==
"detailPage"
;
return
this
.
checkTabUrl
({
url
:
url
,
matchString
:
"detailPage"
});
},
getLastValue
:
function
()
{
return
this
.
getQueryUrl
().
lastValue
;
...
...
@@ -640,6 +657,7 @@ define(['require', 'utils/Globals', 'pnotify', 'utils/Messages', 'utils/Enums',
}
}
}
Utils
.
isUrl
=
function
(
url
)
{
var
regexp
=
/
(
ftp|http|https
)
:
\/\/(\w
+:
{0,1}\w
*@
)?(\S
+
)(
:
[
0-9
]
+
)?(\/
|
\/([\w
#!:.?+=&%@!
\-\/]))?
/
return
regexp
.
test
(
url
);
...
...
This diff is collapsed.
Click to expand it.
dashboardv2/public/js/views/detail_page/DetailPageLayoutView.js
View file @
a8fab3e7
...
...
@@ -502,4 +502,4 @@ define(['require',
}
});
return
DetailPageLayoutView
;
});
});
\ No newline at end of file
This diff is collapsed.
Click to expand it.
dashboardv2/public/js/views/glossary/GlossaryDetailLayoutView.js
View file @
a8fab3e7
...
...
@@ -195,11 +195,13 @@ define(['require',
if
(
this
.
isGlossaryView
)
{
if
(
this
.
glossaryCollection
.
fullCollection
.
length
)
{
this
.
data
=
this
.
glossaryCollection
.
fullCollection
.
get
(
this
.
guid
).
toJSON
();
this
.
glossaryCollection
.
trigger
(
"data:updated"
,
$
.
extend
(
true
,
{},
this
.
data
));
this
.
renderDetails
(
this
.
data
);
}
else
{
this
.
listenTo
(
this
.
glossaryCollection
.
fullCollection
,
"reset "
,
function
(
skip
)
{
var
foundGlossary
=
this
.
glossaryCollection
.
fullCollection
.
get
(
this
.
guid
);
this
.
data
=
foundGlossary
?
foundGlossary
.
toJSON
()
:
null
;
this
.
glossaryCollection
.
trigger
(
"data:updated"
,
$
.
extend
(
true
,
{},
this
.
data
));
if
(
this
.
data
==
null
)
{
this
.
glossary
.
selectedItem
=
{};
Utils
.
setUrl
({
...
...
@@ -248,6 +250,7 @@ define(['require',
that
.
renderRelationLayoutView
(
obj
);
}
that
.
data
=
data
;
that
.
glossaryCollection
.
trigger
(
"data:updated"
,
$
.
extend
(
true
,
{},
data
));
that
.
glossary
.
selectedItem
.
model
=
data
;
that
.
glossary
.
selectedItem
.
guid
=
data
.
guid
;
that
.
renderDetails
(
data
)
...
...
This diff is collapsed.
Click to expand it.
dashboardv2/public/js/views/glossary/GlossaryLayoutView.js
View file @
a8fab3e7
...
...
@@ -98,8 +98,8 @@ define(['require',
};
if
(
Utils
.
getUrlState
.
isGlossaryTab
()
&&
this
.
value
&&
this
.
value
.
viewType
)
{
this
.
viewType
=
this
.
value
.
viewType
;
this
.
query
[
this
.
viewType
]
=
_
.
extend
({},
this
.
value
,
{
"guid"
:
this
.
guid
});
}
this
.
query
[
this
.
viewType
]
=
_
.
extend
({},
this
.
value
,
{
"guid"
:
this
.
guid
});
},
bindEvents
:
function
()
{
var
that
=
this
;
...
...
@@ -164,6 +164,9 @@ define(['require',
this
.
viewType
=
"term"
;
}
var
setDefaultSelector
=
function
()
{
if
(
!
that
.
value
)
{
return
;
}
var
model
=
null
;
if
(
that
.
value
.
gId
)
{
model
=
that
.
glossaryCollection
.
fullCollection
.
get
(
that
.
value
.
gId
);
...
...
@@ -195,12 +198,13 @@ define(['require',
$tree
.
jstree
(
'activate_node'
,
that
.
glossary
.
selectedItem
.
guid
);
}
this
.
query
[
this
.
viewType
]
=
_
.
extend
(
obj
,
_
.
pick
(
this
.
glossary
.
selectedItem
,
'model'
,
'guid'
,
'gType'
),
{
"viewType"
:
this
.
viewType
,
"isNodeNotFoundAtLoad"
:
this
.
query
[
this
.
viewType
].
isNodeNotFoundAtLoad
});
var
url
=
_
.
isEmpty
(
this
.
glossary
.
selectedItem
)
?
'#!/glossary'
:
'#!/glossary/'
+
this
.
glossary
.
selectedItem
.
guid
;
Utils
.
setUrl
({
url
:
'#!/glossary/'
+
this
.
glossary
.
selectedItem
.
guid
,
urlParams
:
_
.
extend
({},
_
.
omit
(
obj
,
'guid'
,
'model'
,
'type'
,
'isNodeNotFoundAtLoad'
)),
mergeBrowserUrl
:
false
,
trigger
:
false
,
updateTabState
:
true
"url"
:
url
,
"urlParams"
:
_
.
extend
({},
_
.
omit
(
obj
,
'guid'
,
'model'
,
'type'
,
'isNodeNotFoundAtLoad'
)),
"mergeBrowserUrl"
:
false
,
"trigger"
:
false
,
"updateTabState"
:
true
});
}
},
...
...
@@ -615,6 +619,11 @@ define(['require',
var
url
=
gId
?
'#!/glossary/'
+
gId
:
'#!/glossary'
;
if
(
gId
==
null
)
{
that
.
glossary
.
selectedItem
=
{};
that
.
value
=
null
;
that
.
query
=
{
term
:
{},
category
:
{}
};
that
.
ui
.
categoryTree
.
jstree
(
true
).
refresh
();
that
.
ui
.
termTree
.
jstree
(
true
).
refresh
();
}
...
...
This diff is collapsed.
Click to expand it.
dashboardv2/public/js/views/glossary/TermRelationAttributeLayoutView.js
View file @
a8fab3e7
This diff is collapsed.
Click to expand it.
dashboardv2/public/js/views/search/SearchLayoutView.js
View file @
a8fab3e7
...
...
@@ -680,4 +680,4 @@ define(['require',
}
});
return
SearchLayoutView
;
});
});
\ No newline at end of file
This diff is collapsed.
Click to expand it.
dashboardv2/public/js/views/search/SearchResultLayoutView.js
View file @
a8fab3e7
...
...
@@ -713,7 +713,7 @@ define(['require',
})
};
this
.
getTagCol
({
'col'
:
col
,
'columnToShow'
:
columnToShow
});
if
(
this
.
fromView
!=
"glossary"
)
{
if
(
(
!
_
.
contains
([
"classification"
,
"glossary"
],
this
.
fromView
))
)
{
this
.
getTermCol
({
'col'
:
col
,
'columnToShow'
:
columnToShow
});
}
...
...
@@ -851,7 +851,7 @@ define(['require',
formatter
:
_
.
extend
({},
Backgrid
.
CellFormatter
.
prototype
,
{
fromRaw
:
function
(
rawValue
,
model
)
{
var
obj
=
model
.
toJSON
();
if
(
!
(
obj
.
typeName
.
startsWith
(
"AtlasGlossary"
)))
{
if
(
obj
.
typeName
&&
!
(
obj
.
typeName
.
startsWith
(
"AtlasGlossary"
)))
{
if
(
obj
.
status
&&
Enums
.
entityStateReadOnly
[
obj
.
status
])
{
return
'<div class="readOnly">'
+
CommonViewFunction
.
termForTable
(
obj
);
+
'</div>'
;
}
else
{
...
...
@@ -1089,4 +1089,4 @@ define(['require',
}
});
return
SearchResultLayoutView
;
});
});
\ No newline at end of file
This diff is collapsed.
Click to expand it.
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