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
e57093ff
Commit
e57093ff
authored
Jun 23, 2017
by
Fatih Acet
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
IssueNotesRefactor: Implement main note form.
parent
998299e2
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
226 additions
and
9 deletions
+226
-9
app/assets/javascripts/notes/components/issue_comment_form.vue
...ssets/javascripts/notes/components/issue_comment_form.vue
+191
-0
app/assets/javascripts/notes/components/issue_discussion.vue
app/assets/javascripts/notes/components/issue_discussion.vue
+3
-2
app/assets/javascripts/notes/components/issue_note_form.vue
app/assets/javascripts/notes/components/issue_note_form.vue
+2
-1
app/assets/javascripts/notes/components/issue_notes.vue
app/assets/javascripts/notes/components/issue_notes.vue
+8
-4
app/assets/javascripts/notes/services/issue_notes_service.js
app/assets/javascripts/notes/services/issue_notes_service.js
+3
-0
app/assets/javascripts/notes/stores/issue_notes_store.js
app/assets/javascripts/notes/stores/issue_notes_store.js
+13
-0
app/assets/stylesheets/framework/dropdowns.scss
app/assets/stylesheets/framework/dropdowns.scss
+4
-0
app/views/projects/issues/_discussion.html.haml
app/views/projects/issues/_discussion.html.haml
+2
-2
No files found.
app/assets/javascripts/notes/components/issue_comment_form.vue
0 → 100644
View file @
e57093ff
<
script
>
/* global Flash */
import
UserAvatarLink
from
'
../../vue_shared/components/user_avatar/user_avatar_link.vue
'
;
import
MarkdownField
from
'
../../vue_shared/components/markdown/field.vue
'
;
export
default
{
props
:
{},
data
()
{
return
{
note
:
''
,
markdownPreviewUrl
:
''
,
markdownDocsUrl
:
''
,
// FIXME: @fatihacet - Fix the mock data below.
noteType
:
'
comment
'
,
issueState
:
'
open
'
,
endpoint
:
'
/gitlab-org/gitlab-ce/notes
'
,
author
:
{
avatar_url
:
'
http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon
'
,
id
:
1
,
name
:
'
Administrator
'
,
path
:
'
/root
'
,
state
:
'
active
'
,
username
:
'
root
'
,
},
};
},
components
:
{
UserAvatarLink
,
MarkdownField
,
},
computed
:
{
commentButtonTitle
()
{
return
this
.
noteType
===
'
comment
'
?
'
Comment
'
:
'
Start discussion
'
;
},
issueActionButtonTitle
()
{
if
(
this
.
note
.
length
)
{
const
actionText
=
this
.
issueState
===
'
open
'
?
'
close
'
:
'
reopen
'
;
return
this
.
noteType
===
'
comment
'
?
`Comment &
${
actionText
}
issue`
:
`Start discussion &
${
actionText
}
issue`
;
}
return
this
.
issueState
===
'
open
'
?
'
Close issue
'
:
'
Reopen issue
'
;
},
},
methods
:
{
handleSave
()
{
const
data
=
{
endpoint
:
`
${
this
.
endpoint
}
?full_data=1`
,
noteData
:
{
target_type
:
'
issue
'
,
target_id
:
'
89
'
,
note
:
{
noteable_type
:
'
Issue
'
,
noteable_id
:
89
,
note
:
this
.
note
,
}
},
};
if
(
this
.
noteType
===
'
discussion
'
)
{
data
.
noteData
.
note
.
type
=
'
DiscussionNote
'
;
}
this
.
$store
.
dispatch
(
'
createNewNote
'
,
data
)
.
then
(()
=>
{
this
.
discard
();
})
.
catch
(()
=>
{
new
Flash
(
'
Something went wrong while adding your comment. Please try again.
'
);
// eslint-disable-line
});
},
discard
()
{
this
.
note
=
''
;
this
.
$refs
.
textarea
.
focus
();
},
setNoteType
(
type
)
{
this
.
noteType
=
type
;
},
},
mounted
()
{
const
issuableDataEl
=
document
.
getElementById
(
'
js-issuable-app-initial-data
'
);
const
issueData
=
JSON
.
parse
(
issuableDataEl
.
innerHTML
.
replace
(
/"/g
,
'
"
'
));
const
{
markdownDocs
,
markdownPreviewUrl
}
=
issueData
;
this
.
markdownDocsUrl
=
markdownDocs
;
this
.
markdownPreviewUrl
=
markdownPreviewUrl
;
},
};
</
script
>
<
template
>
<ul
class=
"notes notes-form timeline new-note"
>
<li
class=
"timeline-entry"
>
<div
class=
"timeline-icon hidden-xs hidden-sm"
>
<user-avatar-link
:linkHref=
"author.path"
:imgSrc=
"author.avatar_url"
:imgAlt=
"author.name"
:imgSize=
"40"
/>
</div>
<div
class=
"timeline-content timeline-content-form common-note-form"
>
<markdown-field
:markdown-preview-url=
"markdownPreviewUrl"
:markdown-docs=
"markdownDocsUrl"
:addSpacingClasses=
"false"
>
<textarea
id=
"note-body"
class=
"note-textarea js-gfm-input js-autosize markdown-area"
data-supports-slash-commands=
"true"
data-supports-quick-actions=
"true"
aria-label=
"Description"
v-model=
"note"
ref=
"textarea"
slot=
"textarea"
placeholder=
"Write a comment or drag your files here..."
@
keydown.meta.enter=
"handleSave"
>
</textarea>
</markdown-field>
<div
class=
"note-form-actions clearfix"
>
<div
class=
"pull-left btn-group append-right-10 comment-type-dropdown js-comment-type-dropdown"
>
<input
@
click=
"handleSave"
:disabled=
"!note.length"
:value=
"commentButtonTitle"
class=
"btn btn-nr btn-create comment-btn js-comment-button js-comment-submit-button"
type=
"submit"
/>
<button
:disabled=
"!note.length"
name=
"button"
type=
"button"
class=
"btn btn-nr comment-btn note-type-toggle js-note-new-discussion"
data-toggle=
"dropdown"
aria-label=
"Open comment type dropdown"
>
<i
aria-hidden=
"true"
class=
"fa fa-caret-down toggle-icon"
></i>
</button>
<ul
class=
"dropdown-menu note-type-dropdown dropdown-open-top"
>
<li
:class=
"
{ 'item-selected': noteType === 'comment' }"
@click.prevent="setNoteType('comment')">
<a
href=
"#"
>
<i
aria-hidden=
"true"
class=
"fa fa-check"
></i>
<div
class=
"description"
>
<strong>
Comment
</strong>
<p>
Add a general comment to this issue.
</p>
</div>
</a>
</li>
<li
class=
"divider"
></li>
<li
:class=
"
{ 'item-selected': noteType === 'discussion' }"
@click.prevent="setNoteType('discussion')">
<a
href=
"#"
>
<i
aria-hidden=
"true"
class=
"fa fa-check"
></i>
<div
class=
"description"
>
<strong>
Start discussion
</strong>
<p>
Discuss a specific suggestion or question.
</p>
</div>
</a>
</li>
</ul>
</div>
<a
:class=
"
{'btn-reopen': issueState === 'closed', 'btn-close': issueState === 'open'}"
class="btn btn-nr btn-comment">
{{
issueActionButtonTitle
}}
</a>
<a
v-if=
"note.length"
@
click=
"discard"
class=
"btn btn-cancel js-note-discard"
role=
"button"
>
Discard draft
</a>
</div>
</div>
</li>
</ul>
</
template
>
app/assets/javascripts/notes/components/issue_discussion.vue
View file @
e57093ff
...
@@ -49,8 +49,9 @@ export default {
...
@@ -49,8 +49,9 @@ export default {
this
.
signInLink
=
signInLink
.
getAttribute
(
'
href
'
);
this
.
signInLink
=
signInLink
.
getAttribute
(
'
href
'
);
}
}
const
newNotePath
=
document
.
querySelector
(
'
.js-main-target-form
'
).
getAttribute
(
'
action
'
);
// TODO: @fatihacet - Reimplement this when we have data for it.
this
.
newNotePath
=
`
${
newNotePath
}
?full_data=1`
;
// const newNotePath = document.querySelector('.js-main-target-form').getAttribute('action');
// this.newNotePath = `${newNotePath}?full_data=1`;
},
},
methods
:
{
methods
:
{
toggleDiscussion
()
{
toggleDiscussion
()
{
...
...
app/assets/javascripts/notes/components/issue_note_form.vue
View file @
e57093ff
...
@@ -61,7 +61,8 @@ export default {
...
@@ -61,7 +61,8 @@ export default {
<textarea
<textarea
id=
"note-body"
id=
"note-body"
class=
"note-textarea js-gfm-input js-autosize markdown-area"
class=
"note-textarea js-gfm-input js-autosize markdown-area"
data-supports-slash-commands=
"false"
data-supports-slash-commands=
"true"
data-supports-quick-actions=
"true"
aria-label=
"Description"
aria-label=
"Description"
v-model=
"note"
v-model=
"note"
ref=
"textarea"
ref=
"textarea"
...
...
app/assets/javascripts/notes/components/issue_notes.vue
View file @
e57093ff
...
@@ -7,6 +7,7 @@ import storeOptions from '../stores/issue_notes_store';
...
@@ -7,6 +7,7 @@ import storeOptions from '../stores/issue_notes_store';
import
IssueNote
from
'
./issue_note.vue
'
;
import
IssueNote
from
'
./issue_note.vue
'
;
import
IssueDiscussion
from
'
./issue_discussion.vue
'
;
import
IssueDiscussion
from
'
./issue_discussion.vue
'
;
import
IssueSystemNote
from
'
./issue_system_note.vue
'
;
import
IssueSystemNote
from
'
./issue_system_note.vue
'
;
import
IssueCommentForm
from
'
./issue_comment_form.vue
'
;
Vue
.
use
(
Vuex
);
Vue
.
use
(
Vuex
);
const
store
=
new
Vuex
.
Store
(
storeOptions
);
const
store
=
new
Vuex
.
Store
(
storeOptions
);
...
@@ -23,6 +24,7 @@ export default {
...
@@ -23,6 +24,7 @@ export default {
IssueNote
,
IssueNote
,
IssueDiscussion
,
IssueDiscussion
,
IssueSystemNote
,
IssueSystemNote
,
IssueCommentForm
,
},
},
methods
:
{
methods
:
{
component
(
note
)
{
component
(
note
)
{
...
@@ -55,17 +57,19 @@ export default {
...
@@ -55,17 +57,19 @@ export default {
v-if=
"isLoading"
v-if=
"isLoading"
class=
"loading"
>
class=
"loading"
>
<i
<i
aria-hidden=
"true
"
class=
"fa fa-spinner fa-spin
"
class=
"fa fa-spinner fa-spin
"
></i>
aria-hidden=
"true
"
></i>
</div>
</div>
<ul
<ul
class=
"notes main-notes-list timeline"
v-if=
"!isLoading"
id=
"notes-list"
>
id=
"notes-list"
class=
"notes main-notes-list timeline"
>
<component
<component
v-for=
"note in $store.getters.notes"
v-for=
"note in $store.getters.notes"
:is=
"component(note)"
:is=
"component(note)"
:note=
"componentData(note)"
:note=
"componentData(note)"
:key=
"note.id"
/>
:key=
"note.id"
/>
</ul>
</ul>
<issue-comment-form
v-if=
"!isLoading"
/>
</div>
</div>
</
template
>
</
template
>
app/assets/javascripts/notes/services/issue_notes_service.js
View file @
e57093ff
...
@@ -16,4 +16,7 @@ export default {
...
@@ -16,4 +16,7 @@ export default {
updateNote
(
endpoint
,
data
)
{
updateNote
(
endpoint
,
data
)
{
return
Vue
.
http
.
put
(
endpoint
,
data
,
{
emulateJSON
:
true
});
return
Vue
.
http
.
put
(
endpoint
,
data
,
{
emulateJSON
:
true
});
},
},
createNewNote
(
endpoint
,
data
)
{
return
Vue
.
http
.
post
(
endpoint
,
data
,
{
emulateJSON
:
true
});
}
};
};
app/assets/javascripts/notes/stores/issue_notes_store.js
View file @
e57093ff
...
@@ -52,6 +52,10 @@ const mutations = {
...
@@ -52,6 +52,10 @@ const mutations = {
noteObj
.
notes
.
splice
(
noteObj
.
notes
.
indexOf
(
comment
),
1
,
note
);
noteObj
.
notes
.
splice
(
noteObj
.
notes
.
indexOf
(
comment
),
1
,
note
);
}
}
},
},
addNewNote
(
storeState
,
note
)
{
// TODO: @fatihacet - When we get the correct data from server update the store
// storeState.notes.push(note);
},
};
};
const
actions
=
{
const
actions
=
{
...
@@ -90,6 +94,15 @@ const actions = {
...
@@ -90,6 +94,15 @@ const actions = {
context
.
commit
(
'
updateNote
'
,
res
);
context
.
commit
(
'
updateNote
'
,
res
);
});
});
},
},
createNewNote
(
context
,
data
)
{
const
{
endpoint
,
noteData
}
=
data
;
return
service
.
createNewNote
(
endpoint
,
noteData
)
.
then
(
res
=>
res
.
json
())
.
then
((
res
)
=>
{
context
.
commit
(
'
addNewNote
'
,
res
);
});
},
};
};
export
default
{
export
default
{
...
...
app/assets/stylesheets/framework/dropdowns.scss
View file @
e57093ff
...
@@ -369,6 +369,10 @@
...
@@ -369,6 +369,10 @@
transform
:
translateY
(
0
);
transform
:
translateY
(
0
);
}
}
.comment-type-dropdown.open
.dropdown-menu
{
display
:
block
;
}
.filtered-search-box-input-container
{
.filtered-search-box-input-container
{
.dropdown-menu
,
.dropdown-menu
,
.dropdown-menu-nav
{
.dropdown-menu-nav
{
...
...
app/views/projects/issues/_discussion.html.haml
View file @
e57093ff
...
@@ -10,5 +10,5 @@
...
@@ -10,5 +10,5 @@
=
webpack_bundle_tag
'notes'
=
webpack_bundle_tag
'notes'
#notes
{
style:
"margin-top: 150px"
}
/
#notes{style: "margin-top: 150px"}
=
render
'shared/notes/notes_with_form'
,
:autocomplete
=>
true
/
= render 'shared/notes/notes_with_form', :autocomplete => true
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