Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
1782aa70
Commit
1782aa70
authored
Jul 31, 2017
by
Phil Hughes
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'inline-js-removal-projects-other' into 'master'
Inline js removal projects other See merge request !13075
parents
202806c0
08a241d6
Changes
13
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
140 additions
and
113 deletions
+140
-113
app/assets/javascripts/dispatcher.js
app/assets/javascripts/dispatcher.js
+9
-1
app/assets/javascripts/pipelines/pipelines_charts.js
app/assets/javascripts/pipelines/pipelines_charts.js
+38
-0
app/assets/javascripts/pipelines/pipelines_times.js
app/assets/javascripts/pipelines/pipelines_times.js
+27
-0
app/assets/javascripts/projects/project_new.js
app/assets/javascripts/projects/project_new.js
+43
-0
app/assets/javascripts/ref_select_dropdown.js
app/assets/javascripts/ref_select_dropdown.js
+2
-1
app/views/projects/new.html.haml
app/views/projects/new.html.haml
+2
-43
app/views/projects/pipelines/charts/_pipeline_times.haml
app/views/projects/pipelines/charts/_pipeline_times.haml
+4
-21
app/views/projects/pipelines/charts/_pipelines.haml
app/views/projects/pipelines/charts/_pipelines.haml
+8
-28
app/views/projects/pipelines/new.html.haml
app/views/projects/pipelines/new.html.haml
+1
-4
app/views/projects/tags/new.html.haml
app/views/projects/tags/new.html.haml
+1
-4
app/views/projects/tree/_tree_content.html.haml
app/views/projects/tree/_tree_content.html.haml
+1
-7
app/views/projects/wikis/_sidebar.html.haml
app/views/projects/wikis/_sidebar.html.haml
+0
-3
config/webpack.config.js
config/webpack.config.js
+4
-1
No files found.
app/assets/javascripts/dispatcher.js
View file @
1782aa70
...
@@ -8,6 +8,7 @@
...
@@ -8,6 +8,7 @@
/* global LabelsSelect */
/* global LabelsSelect */
/* global MilestoneSelect */
/* global MilestoneSelect */
/* global Commit */
/* global Commit */
/* global NewBranchForm */
/* global NotificationsForm */
/* global NotificationsForm */
/* global NotificationsDropdown */
/* global NotificationsDropdown */
/* global GroupAvatar */
/* global GroupAvatar */
...
@@ -258,7 +259,7 @@ import GpgBadges from './gpg_badges';
...
@@ -258,7 +259,7 @@ import GpgBadges from './gpg_badges';
case
'
projects:tags:new
'
:
case
'
projects:tags:new
'
:
new
ZenMode
();
new
ZenMode
();
new
gl
.
GLForm
(
$
(
'
.tag-form
'
),
true
);
new
gl
.
GLForm
(
$
(
'
.tag-form
'
),
true
);
new
RefSelectDropdown
(
$
(
'
.js-branch-select
'
)
,
window
.
gl
.
availableRefs
);
new
RefSelectDropdown
(
$
(
'
.js-branch-select
'
));
break
;
break
;
case
'
projects:snippets:show
'
:
case
'
projects:snippets:show
'
:
initNotes
();
initNotes
();
...
@@ -330,6 +331,9 @@ import GpgBadges from './gpg_badges';
...
@@ -330,6 +331,9 @@ import GpgBadges from './gpg_badges';
case
'
projects:edit
'
:
case
'
projects:edit
'
:
setupProjectEdit
();
setupProjectEdit
();
break
;
break
;
case
'
projects:pipelines:new
'
:
new
NewBranchForm
(
$
(
'
.js-new-pipeline-form
'
));
break
;
case
'
projects:pipelines:builds
'
:
case
'
projects:pipelines:builds
'
:
case
'
projects:pipelines:failures
'
:
case
'
projects:pipelines:failures
'
:
case
'
projects:pipelines:show
'
:
case
'
projects:pipelines:show
'
:
...
@@ -383,6 +387,9 @@ import GpgBadges from './gpg_badges';
...
@@ -383,6 +387,9 @@ import GpgBadges from './gpg_badges';
shortcut_handler
=
new
ShortcutsNavigation
();
shortcut_handler
=
new
ShortcutsNavigation
();
new
TreeView
();
new
TreeView
();
new
BlobViewer
();
new
BlobViewer
();
$
(
'
#tree-slider
'
).
waitForImages
(
function
()
{
gl
.
utils
.
ajaxGet
(
document
.
querySelector
(
'
.js-tree-content
'
).
dataset
.
logsPath
);
});
break
;
break
;
case
'
projects:find_file:show
'
:
case
'
projects:find_file:show
'
:
shortcut_handler
=
true
;
shortcut_handler
=
true
;
...
@@ -540,6 +547,7 @@ import GpgBadges from './gpg_badges';
...
@@ -540,6 +547,7 @@ import GpgBadges from './gpg_badges';
shortcut_handler
=
new
ShortcutsWiki
();
shortcut_handler
=
new
ShortcutsWiki
();
new
ZenMode
();
new
ZenMode
();
new
gl
.
GLForm
(
$
(
'
.wiki-form
'
),
true
);
new
gl
.
GLForm
(
$
(
'
.wiki-form
'
),
true
);
new
Sidebar
();
break
;
break
;
case
'
snippets
'
:
case
'
snippets
'
:
shortcut_handler
=
new
ShortcutsNavigation
();
shortcut_handler
=
new
ShortcutsNavigation
();
...
...
app/assets/javascripts/pipelines/pipelines_charts.js
0 → 100644
View file @
1782aa70
import
Chart
from
'
vendor/Chart
'
;
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
{
const
chartData
=
JSON
.
parse
(
document
.
getElementById
(
'
pipelinesChartsData
'
).
innerHTML
);
const
buildChart
=
(
chartScope
)
=>
{
const
data
=
{
labels
:
chartScope
.
labels
,
datasets
:
[{
fillColor
:
'
#7f8fa4
'
,
strokeColor
:
'
#7f8fa4
'
,
pointColor
:
'
#7f8fa4
'
,
pointStrokeColor
:
'
#EEE
'
,
data
:
chartScope
.
totalValues
,
},
{
fillColor
:
'
#44aa22
'
,
strokeColor
:
'
#44aa22
'
,
pointColor
:
'
#44aa22
'
,
pointStrokeColor
:
'
#fff
'
,
data
:
chartScope
.
successValues
,
},
],
};
const
ctx
=
$
(
`#
${
chartScope
.
scope
}
Chart`
).
get
(
0
).
getContext
(
'
2d
'
);
const
options
=
{
scaleOverlay
:
true
,
responsive
:
true
,
maintainAspectRatio
:
false
,
};
if
(
window
.
innerWidth
<
768
)
{
// Scale fonts if window width lower than 768px (iPad portrait)
options
.
scaleFontSize
=
8
;
}
new
Chart
(
ctx
).
Line
(
data
,
options
);
};
chartData
.
forEach
(
scope
=>
buildChart
(
scope
));
});
app/assets/javascripts/pipelines/pipelines_times.js
0 → 100644
View file @
1782aa70
import
Chart
from
'
vendor/Chart
'
;
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
{
const
chartData
=
JSON
.
parse
(
document
.
getElementById
(
'
pipelinesTimesChartsData
'
).
innerHTML
);
const
data
=
{
labels
:
chartData
.
labels
,
datasets
:
[{
fillColor
:
'
rgba(220,220,220,0.5)
'
,
strokeColor
:
'
rgba(220,220,220,1)
'
,
barStrokeWidth
:
1
,
barValueSpacing
:
1
,
barDatasetSpacing
:
1
,
data
:
chartData
.
values
,
}],
};
const
ctx
=
$
(
'
#build_timesChart
'
).
get
(
0
).
getContext
(
'
2d
'
);
const
options
=
{
scaleOverlay
:
true
,
responsive
:
true
,
maintainAspectRatio
:
false
,
};
if
(
window
.
innerWidth
<
768
)
{
// Scale fonts if window width lower than 768px (iPad portrait)
options
.
scaleFontSize
=
8
;
}
new
Chart
(
ctx
).
Bar
(
data
,
options
);
});
app/assets/javascripts/projects/project_new.js
0 → 100644
View file @
1782aa70
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
{
const
importBtnTooltip
=
'
Please enter a valid project name.
'
;
const
$importBtnWrapper
=
$
(
'
.import_gitlab_project
'
);
$
(
'
.how_to_import_link
'
).
on
(
'
click
'
,
(
e
)
=>
{
e
.
preventDefault
();
$
(
'
.how_to_import_link
'
).
next
(
'
.modal
'
).
show
();
});
$
(
'
.modal-header .close
'
).
on
(
'
click
'
,
()
=>
{
$
(
'
.modal
'
).
hide
();
});
$
(
'
.btn_import_gitlab_project
'
).
on
(
'
click
'
,
()
=>
{
const
importHref
=
$
(
'
a.btn_import_gitlab_project
'
).
attr
(
'
href
'
);
$
(
'
.btn_import_gitlab_project
'
).
attr
(
'
href
'
,
`
${
importHref
}
?namespace_id=
${
$
(
'
#project_namespace_id
'
).
val
()}
&path=
${
$
(
'
#project_path
'
).
val
()}
`
);
});
$
(
'
.btn_import_gitlab_project
'
).
attr
(
'
disabled
'
,
!
$
(
'
#project_path
'
).
val
().
trim
().
length
);
$importBtnWrapper
.
attr
(
'
title
'
,
importBtnTooltip
);
$
(
'
#new_project
'
).
on
(
'
submit
'
,
()
=>
{
const
$path
=
$
(
'
#project_path
'
);
$path
.
val
(
$path
.
val
().
trim
());
});
$
(
'
#project_path
'
).
on
(
'
keyup
'
,
()
=>
{
if
(
$
(
'
#project_path
'
).
val
().
trim
().
length
)
{
$
(
'
.btn_import_gitlab_project
'
).
attr
(
'
disabled
'
,
false
);
$importBtnWrapper
.
attr
(
'
title
'
,
''
);
$importBtnWrapper
.
removeClass
(
'
has-tooltip
'
);
}
else
{
$
(
'
.btn_import_gitlab_project
'
).
attr
(
'
disabled
'
,
true
);
$importBtnWrapper
.
addClass
(
'
has-tooltip
'
);
}
});
$
(
'
#project_import_url
'
).
disable
();
$
(
'
.import_git
'
).
on
(
'
click
'
,
()
=>
{
const
$projectImportUrl
=
$
(
'
#project_import_url
'
);
$projectImportUrl
.
attr
(
'
disabled
'
,
!
$projectImportUrl
.
attr
(
'
disabled
'
));
});
});
app/assets/javascripts/ref_select_dropdown.js
View file @
1782aa70
class
RefSelectDropdown
{
class
RefSelectDropdown
{
constructor
(
$dropdownButton
,
availableRefs
)
{
constructor
(
$dropdownButton
,
availableRefs
)
{
const
availableRefsValue
=
availableRefs
||
JSON
.
parse
(
document
.
getElementById
(
'
availableRefs
'
).
innerHTML
);
$dropdownButton
.
glDropdown
({
$dropdownButton
.
glDropdown
({
data
:
availableRefs
,
data
:
availableRefs
Value
,
filterable
:
true
,
filterable
:
true
,
filterByText
:
true
,
filterByText
:
true
,
remote
:
false
,
remote
:
false
,
...
...
app/views/projects/new.html.haml
View file @
1782aa70
...
@@ -4,6 +4,8 @@
...
@@ -4,6 +4,8 @@
-
page_title
'New Project'
-
page_title
'New Project'
-
header_title
"Projects"
,
dashboard_projects_path
-
header_title
"Projects"
,
dashboard_projects_path
-
visibility_level
=
params
.
dig
(
:project
,
:visibility_level
)
||
default_project_visibility
-
visibility_level
=
params
.
dig
(
:project
,
:visibility_level
)
||
default_project_visibility
-
content_for
:page_specific_javascripts
do
=
webpack_bundle_tag
'project_new'
.project-edit-container
.project-edit-container
.project-edit-errors
.project-edit-errors
...
@@ -111,46 +113,3 @@
...
@@ -111,46 +113,3 @@
%i
.fa.fa-spinner.fa-spin
%i
.fa.fa-spinner.fa-spin
Creating project
&
repository.
Creating project
&
repository.
%p
Please wait a moment, this page will automatically refresh when ready.
%p
Please wait a moment, this page will automatically refresh when ready.
:javascript
var
importBtnTooltip
=
"
Please enter a valid project name.
"
;
var
$importBtnWrapper
=
$
(
'
.import_gitlab_project
'
);
$
(
'
.how_to_import_link
'
).
bind
(
'
click
'
,
function
(
e
)
{
e
.
preventDefault
();
var
import_modal
=
$
(
this
).
next
(
"
.modal
"
).
show
();
});
$
(
'
.modal-header .close
'
).
bind
(
'
click
'
,
function
()
{
$
(
"
.modal
"
).
hide
();
});
$
(
'
.btn_import_gitlab_project
'
).
bind
(
'
click
'
,
function
()
{
var
_href
=
$
(
"
a.btn_import_gitlab_project
"
).
attr
(
"
href
"
);
$
(
"
.btn_import_gitlab_project
"
).
attr
(
"
href
"
,
_href
+
'
?namespace_id=
'
+
$
(
"
#project_namespace_id
"
).
val
()
+
'
&path=
'
+
$
(
"
#project_path
"
).
val
());
});
$
(
'
.btn_import_gitlab_project
'
).
attr
(
'
disabled
'
,
$
(
'
#project_path
'
).
val
().
trim
().
length
===
0
);
$importBtnWrapper
.
attr
(
'
title
'
,
importBtnTooltip
);
$
(
'
#new_project
'
).
submit
(
function
(){
var
$path
=
$
(
'
#project_path
'
);
$path
.
val
(
$path
.
val
().
trim
());
});
$
(
'
#project_path
'
).
keyup
(
function
(){
if
(
$
(
this
).
val
().
trim
().
length
!==
0
)
{
$
(
'
.btn_import_gitlab_project
'
).
attr
(
'
disabled
'
,
false
);
$importBtnWrapper
.
attr
(
'
title
'
,
''
);
$importBtnWrapper
.
removeClass
(
'
has-tooltip
'
);
}
else
{
$
(
'
.btn_import_gitlab_project
'
).
attr
(
'
disabled
'
,
true
);
$importBtnWrapper
.
addClass
(
'
has-tooltip
'
);
}
});
$
(
'
#project_import_url
'
).
disable
();
$
(
'
.import_git
'
).
click
(
function
(
event
)
{
$projectImportUrl
=
$
(
'
#project_import_url
'
);
$projectImportUrl
.
attr
(
'
disabled
'
,
!
$projectImportUrl
.
attr
(
'
disabled
'
));
});
app/views/projects/pipelines/charts/_pipeline_times.haml
View file @
1782aa70
-
content_for
:page_specific_javascripts
do
=
webpack_bundle_tag
(
'pipelines_times'
)
%div
%div
%p
.light
%p
.light
=
_
(
"Commit duration in minutes for last 30 commits"
)
=
_
(
"Commit duration in minutes for last 30 commits"
)
%canvas
#build_timesChart
{
height:
200
}
%canvas
#build_timesChart
{
height:
200
}
:javascript
%script
#pipelinesTimesChartsData
{
type:
"application/json"
}=
{
:labels
=>
@charts
[
:pipeline_times
].
labels
,
:values
=>
@charts
[
:pipeline_times
].
pipeline_times
}.
to_json
.
html_safe
var
data
=
{
labels
:
#{
@charts
[
:pipeline_times
].
labels
.
to_json
}
,
datasets
:
[
{
fillColor
:
"
rgba(220,220,220,0.5)
"
,
strokeColor
:
"
rgba(220,220,220,1)
"
,
barStrokeWidth
:
1
,
barValueSpacing
:
1
,
barDatasetSpacing
:
1
,
data
:
#{
@charts
[
:pipeline_times
].
pipeline_times
.
to_json
}
}
]
}
var
ctx
=
$
(
"
#build_timesChart
"
).
get
(
0
).
getContext
(
"
2d
"
);
var
options
=
{
scaleOverlay
:
true
,
responsive
:
true
,
maintainAspectRatio
:
false
};
if
(
window
.
innerWidth
<
768
)
{
// Scale fonts if window width lower than 768px (iPad portrait)
options
.
scaleFontSize
=
8
}
new
Chart
(
ctx
).
Bar
(
data
,
options
);
app/views/projects/pipelines/charts/_pipelines.haml
View file @
1782aa70
-
content_for
:page_specific_javascripts
do
=
webpack_bundle_tag
(
'pipelines_charts'
)
%h4
=
_
(
"Pipelines charts"
)
%h4
=
_
(
"Pipelines charts"
)
%p
%p
...
@@ -26,31 +29,8 @@
...
@@ -26,31 +29,8 @@
=
_
(
"Jobs for last year"
)
=
_
(
"Jobs for last year"
)
%canvas
#yearChart
.padded
{
height:
250
}
%canvas
#yearChart
.padded
{
height:
250
}
-
[
:week
,
:month
,
:year
].
each
do
|
scope
|
%script
#pipelinesChartsData
{
type:
"application/json"
}
:javascript
-
chartData
=
[]
var
data
=
{
-
[
:week
,
:month
,
:year
].
each
do
|
scope
|
labels
:
#{
@charts
[
scope
].
labels
.
to_json
}
,
-
chartData
.
push
({
'scope'
=>
scope
,
'labels'
=>
@charts
[
scope
].
labels
,
'totalValues'
=>
@charts
[
scope
].
total
,
'successValues'
=>
@charts
[
scope
].
success
})
datasets
:
[
=
chartData
.
to_json
.
html_safe
{
fillColor
:
"
#7f8fa4
"
,
strokeColor
:
"
#7f8fa4
"
,
pointColor
:
"
#7f8fa4
"
,
pointStrokeColor
:
"
#EEE
"
,
data
:
#{
@charts
[
scope
].
total
.
to_json
}
},
{
fillColor
:
"
#44aa22
"
,
strokeColor
:
"
#44aa22
"
,
pointColor
:
"
#44aa22
"
,
pointStrokeColor
:
"
#fff
"
,
data
:
#{
@charts
[
scope
].
success
.
to_json
}
}
]
}
var
ctx
=
$
(
"
##{scope}Chart
"
).
get
(
0
).
getContext
(
"
2d
"
);
var
options
=
{
scaleOverlay
:
true
,
responsive
:
true
,
maintainAspectRatio
:
false
};
if
(
window
.
innerWidth
<
768
)
{
// Scale fonts if window width lower than 768px (iPad portrait)
options
.
scaleFontSize
=
8
}
new
Chart
(
ctx
).
Line
(
data
,
options
);
app/views/projects/pipelines/new.html.haml
View file @
1782aa70
...
@@ -20,7 +20,4 @@
...
@@ -20,7 +20,4 @@
=
f
.
submit
'Create pipeline'
,
class:
'btn btn-create'
,
tabindex:
3
=
f
.
submit
'Create pipeline'
,
class:
'btn btn-create'
,
tabindex:
3
=
link_to
'Cancel'
,
project_pipelines_path
(
@project
),
class:
'btn btn-cancel'
=
link_to
'Cancel'
,
project_pipelines_path
(
@project
),
class:
'btn btn-cancel'
:javascript
%script
#availableRefs
{
type:
"application/json"
}=
@project
.
repository
.
ref_names
.
to_json
.
html_safe
var
availableRefs
=
#{
@project
.
repository
.
ref_names
.
to_json
}
;
new
NewBranchForm
(
$
(
'
.js-new-pipeline-form
'
),
availableRefs
)
app/views/projects/tags/new.html.haml
View file @
1782aa70
...
@@ -40,7 +40,4 @@
...
@@ -40,7 +40,4 @@
.form-actions
.form-actions
=
button_tag
'Create tag'
,
class:
'btn btn-create'
,
tabindex:
3
=
button_tag
'Create tag'
,
class:
'btn btn-create'
,
tabindex:
3
=
link_to
'Cancel'
,
project_tags_path
(
@project
),
class:
'btn btn-cancel'
=
link_to
'Cancel'
,
project_tags_path
(
@project
),
class:
'btn btn-cancel'
%script
#availableRefs
{
type:
"application/json"
}=
@project
.
repository
.
ref_names
.
to_json
.
html_safe
:javascript
window
.
gl
=
window
.
gl
||
{
};
window
.
gl
.
availableRefs
=
#{
@project
.
repository
.
ref_names
.
to_json
}
;
app/views/projects/tree/_tree_content.html.haml
View file @
1782aa70
.tree-content-holder
.tree-content-holder
.js-tree-content
{
'data-logs-path'
:
@logs_path
}
.table-holder
.table-holder
%table
.table
#tree-slider
{
class:
"table_#{@hex_path} tree-table"
}
%table
.table
#tree-slider
{
class:
"table_#{@hex_path} tree-table"
}
%thead
%thead
...
@@ -22,9 +22,3 @@
...
@@ -22,9 +22,3 @@
-
if
can_edit_tree?
-
if
can_edit_tree?
=
render
'projects/blob/upload'
,
title:
_
(
'Upload New File'
),
placeholder:
_
(
'Upload New File'
),
button_title:
_
(
'Upload file'
),
form_path:
project_create_blob_path
(
@project
,
@id
),
method: :post
=
render
'projects/blob/upload'
,
title:
_
(
'Upload New File'
),
placeholder:
_
(
'Upload New File'
),
button_title:
_
(
'Upload file'
),
form_path:
project_create_blob_path
(
@project
,
@id
),
method: :post
=
render
'projects/blob/new_dir'
=
render
'projects/blob/new_dir'
:javascript
// Load last commit log for each file in tree
$
(
'
#tree-slider
'
).
waitForImages
(
function
()
{
gl
.
utils
.
ajaxGet
(
"
#{
escape_javascript
(
@logs_path
)
}
"
);
});
app/views/projects/wikis/_sidebar.html.haml
View file @
1782aa70
...
@@ -19,6 +19,3 @@
...
@@ -19,6 +19,3 @@
More Pages
More Pages
=
render
'projects/wikis/new'
=
render
'projects/wikis/new'
:javascript
new
Sidebar
();
config/webpack.config.js
View file @
1782aa70
...
@@ -54,8 +54,11 @@ var config = {
...
@@ -54,8 +54,11 @@ var config = {
notebook_viewer
:
'
./blob/notebook_viewer.js
'
,
notebook_viewer
:
'
./blob/notebook_viewer.js
'
,
pdf_viewer
:
'
./blob/pdf_viewer.js
'
,
pdf_viewer
:
'
./blob/pdf_viewer.js
'
,
pipelines
:
'
./pipelines/pipelines_bundle.js
'
,
pipelines
:
'
./pipelines/pipelines_bundle.js
'
,
pipelines_charts
:
'
./pipelines/pipelines_charts.js
'
,
pipelines_details
:
'
./pipelines/pipeline_details_bundle.js
'
,
pipelines_details
:
'
./pipelines/pipeline_details_bundle.js
'
,
pipelines_times
:
'
./pipelines/pipelines_times.js
'
,
profile
:
'
./profile/profile_bundle.js
'
,
profile
:
'
./profile/profile_bundle.js
'
,
project_new
:
'
./projects/project_new.js
'
,
prometheus_metrics
:
'
./prometheus_metrics
'
,
prometheus_metrics
:
'
./prometheus_metrics
'
,
protected_branches
:
'
./protected_branches
'
,
protected_branches
:
'
./protected_branches
'
,
protected_tags
:
'
./protected_tags
'
,
protected_tags
:
'
./protected_tags
'
,
...
...
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