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
0
Merge Requests
0
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
Jérome Perrin
gitlab-ce
Commits
0fc1e04f
Commit
0fc1e04f
authored
7 years ago
by
Luke "Jared" Bennett
Committed by
Clement Ho
7 years ago
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add renderNote animation and added spec
parent
7125c966
No related merge requests found
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
196 additions
and
32 deletions
+196
-32
app/assets/javascripts/notes.js
app/assets/javascripts/notes.js
+15
-7
app/assets/stylesheets/framework/animations.scss
app/assets/stylesheets/framework/animations.scss
+14
-0
app/assets/stylesheets/framework/variables.scss
app/assets/stylesheets/framework/variables.scss
+5
-0
changelogs/unreleased/29977-style-comments-and-system-notes-real-time-updates.yml
...977-style-comments-and-system-notes-real-time-updates.yml
+4
-0
features/project/issues/issues.feature
features/project/issues/issues.feature
+0
-6
features/steps/project/issues/issues.rb
features/steps/project/issues/issues.rb
+0
-11
spec/features/issues/note_polling_spec.rb
spec/features/issues/note_polling_spec.rb
+6
-8
spec/javascripts/notes_spec.js
spec/javascripts/notes_spec.js
+152
-0
No files found.
app/assets/javascripts/notes.js
View file @
0fc1e04f
...
@@ -308,8 +308,10 @@ require('./task_list');
...
@@ -308,8 +308,10 @@ require('./task_list');
if
(
this
.
isNewNote
(
note
))
{
if
(
this
.
isNewNote
(
note
))
{
this
.
note_ids
.
push
(
note
.
id
);
this
.
note_ids
.
push
(
note
.
id
);
$notesList
=
$
(
'
ul.main-notes-list
'
);
$notesList
.
append
(
note
.
html
).
syntaxHighlight
();
$notesList
=
window
.
$
(
'
ul.main-notes-list
'
);
Notes
.
animateAppendNote
(
note
.
html
,
$notesList
);
// Update datetime format on the recent note
// Update datetime format on the recent note
gl
.
utils
.
localTimeAgo
(
$notesList
.
find
(
"
#note_
"
+
note
.
id
+
"
.js-timeago
"
),
false
);
gl
.
utils
.
localTimeAgo
(
$notesList
.
find
(
"
#note_
"
+
note
.
id
+
"
.js-timeago
"
),
false
);
this
.
collapseLongCommitList
();
this
.
collapseLongCommitList
();
...
@@ -348,7 +350,7 @@ require('./task_list');
...
@@ -348,7 +350,7 @@ require('./task_list');
lineType
=
this
.
isParallelView
()
?
form
.
find
(
'
#line_type
'
).
val
()
:
'
old
'
;
lineType
=
this
.
isParallelView
()
?
form
.
find
(
'
#line_type
'
).
val
()
:
'
old
'
;
diffAvatarContainer
=
row
.
prevAll
(
'
.line_holder
'
).
first
().
find
(
'
.js-avatar-container.
'
+
lineType
+
'
_line
'
);
diffAvatarContainer
=
row
.
prevAll
(
'
.line_holder
'
).
first
().
find
(
'
.js-avatar-container.
'
+
lineType
+
'
_line
'
);
// is this the first note of discussion?
// is this the first note of discussion?
discussionContainer
=
$
(
"
.notes[data-discussion-id='
"
+
note
.
discussion_id
+
"
']
"
);
discussionContainer
=
window
.
$
(
`.notes[data-discussion-id="
${
note
.
discussion_id
}
"]`
);
if
(
!
discussionContainer
.
length
)
{
if
(
!
discussionContainer
.
length
)
{
discussionContainer
=
form
.
closest
(
'
.discussion
'
).
find
(
'
.notes
'
);
discussionContainer
=
form
.
closest
(
'
.discussion
'
).
find
(
'
.notes
'
);
}
}
...
@@ -370,14 +372,13 @@ require('./task_list');
...
@@ -370,14 +372,13 @@ require('./task_list');
row
.
find
(
contentContainerClass
+
'
.content
'
).
append
(
$notes
.
closest
(
'
.content
'
).
children
());
row
.
find
(
contentContainerClass
+
'
.content
'
).
append
(
$notes
.
closest
(
'
.content
'
).
children
());
}
}
}
}
// Init discussion on 'Discussion' page if it is merge request page
// Init discussion on 'Discussion' page if it is merge request page
if
(
$
(
'
body
'
).
attr
(
'
data-page
'
).
indexOf
(
'
projects:merge_request
'
)
===
0
||
!
note
.
diff_discussion_html
)
{
if
(
window
.
$
(
'
body
'
).
attr
(
'
data-page
'
).
indexOf
(
'
projects:merge_request
'
)
===
0
||
!
note
.
diff_discussion_html
)
{
$
(
'
ul.main-notes-list
'
).
append
(
$
(
note
.
discussion_html
).
renderGFM
(
));
Notes
.
animateAppendNote
(
note
.
discussion_html
,
window
.
$
(
'
ul.main-notes-list
'
));
}
}
}
else
{
}
else
{
// append new note to all matching discussions
// append new note to all matching discussions
discussionContainer
.
append
(
$
(
note
.
html
).
renderGFM
()
);
Notes
.
animateAppendNote
(
note
.
html
,
discussionContainer
);
}
}
if
(
typeof
gl
.
diffNotesCompileComponents
!==
'
undefined
'
&&
note
.
discussion_resolvable
)
{
if
(
typeof
gl
.
diffNotesCompileComponents
!==
'
undefined
'
&&
note
.
discussion_resolvable
)
{
...
@@ -1063,6 +1064,13 @@ require('./task_list');
...
@@ -1063,6 +1064,13 @@ require('./task_list');
return
$form
;
return
$form
;
};
};
Notes
.
animateAppendNote
=
function
(
noteHTML
,
$notesList
)
{
const
$note
=
window
.
$
(
noteHTML
);
$note
.
addClass
(
'
fade-in
'
).
renderGFM
();
$notesList
.
append
(
$note
);
};
return
Notes
;
return
Notes
;
})();
})();
}).
call
(
window
);
}).
call
(
window
);
This diff is collapsed.
Click to expand it.
app/assets/stylesheets/framework/animations.scss
View file @
0fc1e04f
...
@@ -145,3 +145,17 @@ a {
...
@@ -145,3 +145,17 @@ a {
.dropdown-menu-nav
a
{
.dropdown-menu-nav
a
{
transition
:
none
;
transition
:
none
;
}
}
@keyframes
fadeIn
{
0
%
{
opacity
:
0
;
}
100
%
{
opacity
:
1
;
}
}
.fade-in
{
animation
:
fadeIn
$fade-in-duration
1
;
}
This diff is collapsed.
Click to expand it.
app/assets/stylesheets/framework/variables.scss
View file @
0fc1e04f
...
@@ -457,6 +457,11 @@ $label-inverse-bg: #333;
...
@@ -457,6 +457,11 @@ $label-inverse-bg: #333;
$label-remove-border
:
rgba
(
0
,
0
,
0
,
.1
);
$label-remove-border
:
rgba
(
0
,
0
,
0
,
.1
);
$label-border-radius
:
100px
;
$label-border-radius
:
100px
;
/*
* Animation
*/
$fade-in-duration
:
200ms
;
/*
/*
* Lint
* Lint
*/
*/
...
...
This diff is collapsed.
Click to expand it.
changelogs/unreleased/29977-style-comments-and-system-notes-real-time-updates.yml
0 → 100644
View file @
0fc1e04f
---
title
:
Added quick-update (fade-in) animation to newly rendered notes
merge_request
:
10623
author
:
This diff is collapsed.
Click to expand it.
features/project/issues/issues.feature
View file @
0fc1e04f
...
@@ -177,9 +177,3 @@ Feature: Project Issues
...
@@ -177,9 +177,3 @@ Feature: Project Issues
And
I should not see labels field
And
I should not see labels field
And
I submit new issue
"500 error on profile"
And
I submit new issue
"500 error on profile"
Then
I should see issue
"500 error on profile"
Then
I should see issue
"500 error on profile"
@javascript
Scenario
:
Another user adds a comment to issue I'm currently viewing
Given
I visit issue page
"Release 0.4"
And
another user adds a comment with text
"Yay!"
to issue
"Release 0.4"
Then
I should see a new comment with text
"Yay!"
This diff is collapsed.
Click to expand it.
features/steps/project/issues/issues.rb
View file @
0fc1e04f
...
@@ -345,17 +345,6 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps
...
@@ -345,17 +345,6 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps
end
end
end
end
step
'another user adds a comment with text "Yay!" to issue "Release 0.4"'
do
issue
=
Issue
.
find_by!
(
title:
'Release 0.4'
)
create
(
:note_on_issue
,
noteable:
issue
,
project:
project
,
note:
'Yay!'
)
end
step
'I should see a new comment with text "Yay!"'
do
page
.
within
'#notes'
do
expect
(
page
).
to
have_content
(
'Yay!'
)
end
end
def
filter_issue
(
text
)
def
filter_issue
(
text
)
fill_in
'issuable_search'
,
with:
text
fill_in
'issuable_search'
,
with:
text
end
end
...
...
This diff is collapsed.
Click to expand it.
spec/features/issues/note_polling_spec.rb
View file @
0fc1e04f
require
'spec_helper'
require
'spec_helper'
feature
'Issue notes polling'
do
feature
'Issue notes polling'
,
:feature
,
:js
do
let
!
(
:project
)
{
create
(
:
project
,
:public
)
}
let
(
:project
)
{
create
(
:empty_
project
,
:public
)
}
let
!
(
:issue
)
{
create
(
:issue
,
project:
project
)
}
let
(
:issue
)
{
create
(
:issue
,
project:
project
)
}
b
ackground
do
b
efore
do
visit
namespace_project_issue_path
(
project
.
namespace
,
project
,
issue
)
visit
namespace_project_issue_path
(
project
.
namespace
,
project
,
issue
)
end
end
scenario
'Another user adds a comment to an issue'
,
js:
true
do
it
'should display the new comment'
do
note
=
create
(
:note
,
noteable:
issue
,
project:
project
,
note
=
create
(
:note
,
noteable:
issue
,
project:
project
,
note:
'Looks good!'
)
note:
'Looks good!'
)
page
.
execute_script
(
'notes.refresh();'
)
page
.
execute_script
(
'notes.refresh();'
)
expect
(
page
).
to
have_selector
(
"#note_
#{
note
.
id
}
"
,
text:
'Looks good!'
)
expect
(
page
).
to
have_selector
(
"#note_
#{
note
.
id
}
"
,
text:
'Looks good!'
)
...
...
This diff is collapsed.
Click to expand it.
spec/javascripts/notes_spec.js
View file @
0fc1e04f
...
@@ -72,5 +72,157 @@ require('~/lib/utils/text_utility');
...
@@ -72,5 +72,157 @@ require('~/lib/utils/text_utility');
expect
(
this
.
autoSizeSpy
).
toHaveBeenTriggered
();
expect
(
this
.
autoSizeSpy
).
toHaveBeenTriggered
();
});
});
});
});
describe
(
'
renderNote
'
,
()
=>
{
let
notes
;
let
note
;
let
$notesList
;
beforeEach
(()
=>
{
note
=
{
discussion_html
:
null
,
valid
:
true
,
html
:
'
<div></div>
'
,
};
$notesList
=
jasmine
.
createSpyObj
(
'
$notesList
'
,
[
'
find
'
]);
notes
=
jasmine
.
createSpyObj
(
'
notes
'
,
[
'
refresh
'
,
'
isNewNote
'
,
'
collapseLongCommitList
'
,
'
updateNotesCount
'
,
]);
notes
.
taskList
=
jasmine
.
createSpyObj
(
'
tasklist
'
,
[
'
init
'
]);
notes
.
note_ids
=
[];
spyOn
(
window
,
'
$
'
).
and
.
returnValue
(
$notesList
);
spyOn
(
gl
.
utils
,
'
localTimeAgo
'
);
spyOn
(
Notes
,
'
animateAppendNote
'
);
notes
.
isNewNote
.
and
.
returnValue
(
true
);
Notes
.
prototype
.
renderNote
.
call
(
notes
,
note
);
});
it
(
'
should query for the notes list
'
,
()
=>
{
expect
(
window
.
$
).
toHaveBeenCalledWith
(
'
ul.main-notes-list
'
);
});
it
(
'
should call .animateAppendNote
'
,
()
=>
{
expect
(
Notes
.
animateAppendNote
).
toHaveBeenCalledWith
(
note
.
html
,
$notesList
);
});
});
describe
(
'
renderDiscussionNote
'
,
()
=>
{
let
discussionContainer
;
let
note
;
let
notes
;
let
$form
;
let
row
;
beforeEach
(()
=>
{
note
=
{
html
:
'
<li></li>
'
,
discussion_html
:
'
<div></div>
'
,
discussion_id
:
1
,
discussion_resolvable
:
false
,
diff_discussion_html
:
false
,
};
$form
=
jasmine
.
createSpyObj
(
'
$form
'
,
[
'
closest
'
,
'
find
'
]);
row
=
jasmine
.
createSpyObj
(
'
row
'
,
[
'
prevAll
'
,
'
first
'
,
'
find
'
]);
notes
=
jasmine
.
createSpyObj
(
'
notes
'
,
[
'
isNewNote
'
,
'
isParallelView
'
,
'
updateNotesCount
'
,
]);
notes
.
note_ids
=
[];
spyOn
(
gl
.
utils
,
'
localTimeAgo
'
);
spyOn
(
Notes
,
'
animateAppendNote
'
);
notes
.
isNewNote
.
and
.
returnValue
(
true
);
notes
.
isParallelView
.
and
.
returnValue
(
false
);
row
.
prevAll
.
and
.
returnValue
(
row
);
row
.
first
.
and
.
returnValue
(
row
);
row
.
find
.
and
.
returnValue
(
row
);
});
describe
(
'
Discussion root note
'
,
()
=>
{
let
$notesList
;
let
body
;
beforeEach
(()
=>
{
body
=
jasmine
.
createSpyObj
(
'
body
'
,
[
'
attr
'
]);
discussionContainer
=
{
length
:
0
};
spyOn
(
window
,
'
$
'
).
and
.
returnValues
(
discussionContainer
,
body
,
$notesList
);
$form
.
closest
.
and
.
returnValues
(
row
,
$form
);
$form
.
find
.
and
.
returnValues
(
discussionContainer
);
body
.
attr
.
and
.
returnValue
(
''
);
Notes
.
prototype
.
renderDiscussionNote
.
call
(
notes
,
note
,
$form
);
});
it
(
'
should query for the notes list
'
,
()
=>
{
expect
(
window
.
$
.
calls
.
argsFor
(
2
)).
toEqual
([
'
ul.main-notes-list
'
]);
});
it
(
'
should call Notes.animateAppendNote
'
,
()
=>
{
expect
(
Notes
.
animateAppendNote
).
toHaveBeenCalledWith
(
note
.
discussion_html
,
$notesList
);
});
});
describe
(
'
Discussion sub note
'
,
()
=>
{
beforeEach
(()
=>
{
discussionContainer
=
{
length
:
1
};
spyOn
(
window
,
'
$
'
).
and
.
returnValues
(
discussionContainer
);
$form
.
closest
.
and
.
returnValues
(
row
);
Notes
.
prototype
.
renderDiscussionNote
.
call
(
notes
,
note
,
$form
);
});
it
(
'
should query foor the discussion container
'
,
()
=>
{
expect
(
window
.
$
).
toHaveBeenCalledWith
(
`.notes[data-discussion-id="
${
note
.
discussion_id
}
"]`
);
});
it
(
'
should call Notes.animateAppendNote
'
,
()
=>
{
expect
(
Notes
.
animateAppendNote
).
toHaveBeenCalledWith
(
note
.
html
,
discussionContainer
);
});
});
});
describe
(
'
animateAppendNote
'
,
()
=>
{
let
noteHTML
;
let
$note
;
let
$notesList
;
beforeEach
(()
=>
{
noteHTML
=
'
<div></div>
'
;
$note
=
jasmine
.
createSpyObj
(
'
$note
'
,
[
'
addClass
'
,
'
renderGFM
'
,
'
removeClass
'
]);
$notesList
=
jasmine
.
createSpyObj
(
'
$notesList
'
,
[
'
append
'
]);
spyOn
(
window
,
'
$
'
).
and
.
returnValue
(
$note
);
spyOn
(
window
,
'
setTimeout
'
).
and
.
callThrough
();
$note
.
addClass
.
and
.
returnValue
(
$note
);
$note
.
renderGFM
.
and
.
returnValue
(
$note
);
Notes
.
animateAppendNote
(
noteHTML
,
$notesList
);
});
it
(
'
should init the note jquery object
'
,
()
=>
{
expect
(
window
.
$
).
toHaveBeenCalledWith
(
noteHTML
);
});
it
(
'
should call addClass
'
,
()
=>
{
expect
(
$note
.
addClass
).
toHaveBeenCalledWith
(
'
fade-in
'
);
});
it
(
'
should call renderGFM
'
,
()
=>
{
expect
(
$note
.
renderGFM
).
toHaveBeenCalledWith
();
});
it
(
'
should append note to the notes list
'
,
()
=>
{
expect
(
$notesList
.
append
).
toHaveBeenCalledWith
(
$note
);
});
});
});
});
}).
call
(
window
);
}).
call
(
window
);
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