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
bf88af0e
Commit
bf88af0e
authored
Jul 13, 2017
by
Fatih Acet
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
IssueNotesRefactor: Implement quick actions with system note placeholders.
parent
d9928d1a
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
108 additions
and
9 deletions
+108
-9
app/assets/javascripts/notes/components/issue_comment_form.vue
...ssets/javascripts/notes/components/issue_comment_form.vue
+54
-8
app/assets/javascripts/notes/components/issue_notes.vue
app/assets/javascripts/notes/components/issue_notes.vue
+8
-1
app/assets/javascripts/notes/components/issue_placeholder_system_note.vue
...cripts/notes/components/issue_placeholder_system_note.vue
+20
-0
app/assets/javascripts/notes/stores/issue_notes_store.js
app/assets/javascripts/notes/stores/issue_notes_store.js
+26
-0
No files found.
app/assets/javascripts/notes/components/issue_comment_form.vue
View file @
bf88af0e
<
script
>
/* global Flash */
import
AjaxCache
from
'
~/lib/utils/ajax_cache
'
;
import
UserAvatarLink
from
'
../../vue_shared/components/user_avatar/user_avatar_link.vue
'
;
import
MarkdownField
from
'
../../vue_shared/components/markdown/field.vue
'
;
import
IssueNoteSignedOutWidget
from
'
./issue_note_signed_out_widget.vue
'
;
import
eventHub
from
'
../event_hub
'
;
const
REGEX_QUICK_ACTIONS
=
/^
\/\w
+.*$/gm
;
export
default
{
props
:
{},
data
()
{
const
{
create_note_path
,
state
}
=
window
.
gl
.
issueData
;
const
{
currentUserData
}
=
window
.
gl
;
...
...
@@ -67,14 +68,14 @@ export default {
}
this
.
$store
.
dispatch
(
'
createNewNote
'
,
data
)
.
then
((
res
)
=>
{
if
(
res
.
errors
)
{
this
.
handleError
();
}
else
{
this
.
discard
();
}
})
.
then
(
this
.
handleNewNoteCreated
)
.
catch
(
this
.
handleError
);
if
(
this
.
hasQuickActions
())
{
this
.
$store
.
commit
(
'
showPlaceholderSystemNote
'
,
{
noteBody
:
this
.
getQuickActionText
(),
});
}
}
if
(
withIssueAction
)
{
...
...
@@ -93,6 +94,26 @@ export default {
$
(
`.js-btn-issue-action.
${
btnClass
}
:visible`
).
trigger
(
'
click
'
);
}
},
handleNewNoteCreated
(
res
)
{
const
{
commands_changes
,
errors
,
valid
}
=
res
;
if
(
!
valid
&&
errors
)
{
const
{
commands_only
}
=
errors
;
if
(
commands_only
)
{
new
Flash
(
commands_only
,
'
notice
'
,
$
(
this
.
$el
));
// eslint-disable-line
$
(
this
.
$refs
.
textarea
).
trigger
(
'
clear-commands-cache.atwho
'
);
this
.
$store
.
dispatch
(
'
poll
'
);
this
.
discard
();
}
else
{
this
.
handleError
();
}
}
else
{
this
.
discard
();
}
this
.
$store
.
commit
(
'
removePlaceholderSystemNote
'
);
},
discard
()
{
// `blur` is needed to clear slash commands autocomplete cache if event fired.
// `focus` is needed to remain cursor in the textarea.
...
...
@@ -117,6 +138,30 @@ export default {
}
}
},
getQuickActionText
()
{
let
text
=
'
Applying command
'
;
const
quickActions
=
AjaxCache
.
get
(
gl
.
GfmAutoComplete
.
dataSources
.
commands
);
const
{
note
}
=
this
;
const
executedCommands
=
quickActions
.
filter
((
command
,
index
)
=>
{
const
commandRegex
=
new
RegExp
(
`/
${
command
.
name
}
`
);
return
commandRegex
.
test
(
note
);
});
if
(
executedCommands
&&
executedCommands
.
length
)
{
if
(
executedCommands
.
length
>
1
)
{
text
=
'
Applying multiple commands
'
;
}
else
{
const
commandDescription
=
executedCommands
[
0
].
description
.
toLowerCase
();
text
=
`Applying command to
${
commandDescription
}
`
;
}
}
return
text
;
},
hasQuickActions
()
{
return
REGEX_QUICK_ACTIONS
.
test
(
this
.
note
);
},
},
mounted
()
{
const
issuableDataEl
=
document
.
getElementById
(
'
js-issuable-app-initial-data
'
);
...
...
@@ -141,6 +186,7 @@ export default {
class=
"notes notes-form timeline new-note"
>
<li
class=
"timeline-entry"
>
<div
class=
"timeline-entry-inner"
>
<div
class=
"flash-container timeline-content"
></div>
<div
class=
"timeline-icon hidden-xs hidden-sm"
>
<user-avatar-link
v-if=
"author"
...
...
app/assets/javascripts/notes/components/issue_notes.vue
View file @
bf88af0e
...
...
@@ -9,6 +9,7 @@ import IssueNote from './issue_note.vue';
import
IssueDiscussion
from
'
./issue_discussion.vue
'
;
import
IssueSystemNote
from
'
./issue_system_note.vue
'
;
import
IssueCommentForm
from
'
./issue_comment_form.vue
'
;
import
PlaceholderSystemNote
from
'
./issue_placeholder_system_note.vue
'
;
Vue
.
use
(
Vuex
);
const
store
=
new
Vuex
.
Store
(
storeOptions
);
...
...
@@ -26,6 +27,7 @@ export default {
IssueDiscussion
,
IssueSystemNote
,
IssueCommentForm
,
PlaceholderSystemNote
,
},
computed
:
{
...
Vuex
.
mapGetters
([
...
...
@@ -35,7 +37,12 @@ export default {
},
methods
:
{
component
(
note
)
{
if
(
note
.
individual_note
)
{
if
(
note
.
placeholderNote
)
{
if
(
note
.
placeholderType
===
'
systemNote
'
)
{
return
PlaceholderSystemNote
;
}
}
else
if
(
note
.
individual_note
)
{
return
note
.
notes
[
0
].
system
?
IssueSystemNote
:
IssueNote
;
}
...
...
app/assets/javascripts/notes/components/issue_placeholder_system_note.vue
0 → 100644
View file @
bf88af0e
<
script
>
export
default
{
props
:
{
note
:
{
type
:
Object
,
required
:
true
,
}
},
};
</
script
>
<
template
>
<li
class=
"note system-note timeline-entry being-posted fade-in-half"
>
<div
class=
"timeline-entry-inner"
>
<div
class=
"timeline-content"
>
<i>
{{
note
.
body
}}
</i>
</div>
</div>
</li>
</
template
>
app/assets/javascripts/notes/stores/issue_notes_store.js
View file @
bf88af0e
...
...
@@ -108,6 +108,32 @@ const mutations = {
setLastFetchedAt
(
storeState
,
fetchedAt
)
{
storeState
.
lastFetchedAt
=
fetchedAt
;
},
showPlaceholderSystemNote
(
storeState
,
data
)
{
storeState
.
notes
.
push
({
placeholderNote
:
true
,
individual_note
:
true
,
placeholderType
:
'
systemNote
'
,
notes
:
[
{
id
:
'
placeholderSystemNote
'
,
body
:
data
.
noteBody
,
},
],
});
},
removePlaceholderSystemNote
(
storeState
)
{
let
index
=
-
1
;
storeState
.
notes
.
forEach
((
n
,
i
)
=>
{
if
(
n
.
placeholderNote
&&
n
.
placeholderType
===
'
systemNote
'
)
{
index
=
i
;
}
});
if
(
index
>
-
1
)
{
storeState
.
notes
.
splice
(
index
,
1
);
}
},
};
const
actions
=
{
...
...
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