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
Boxiang Sun
gitlab-ce
Commits
f5a21c59
Commit
f5a21c59
authored
Jul 28, 2017
by
Filipa Lacerda
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[ci skip] Fix shortcuts for preview
parent
9b87e680
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
174 additions
and
176 deletions
+174
-176
app/assets/javascripts/notes/components/issue_comment_form.vue
...ssets/javascripts/notes/components/issue_comment_form.vue
+95
-93
app/assets/javascripts/notes/components/issue_note_form.vue
app/assets/javascripts/notes/components/issue_note_form.vue
+3
-3
app/assets/javascripts/notes/components/issue_notes_app.vue
app/assets/javascripts/notes/components/issue_notes_app.vue
+5
-4
app/assets/javascripts/notes/index.js
app/assets/javascripts/notes/index.js
+43
-40
app/assets/javascripts/notes/stores/actions.js
app/assets/javascripts/notes/stores/actions.js
+22
-23
app/assets/javascripts/notes/stores/getters.js
app/assets/javascripts/notes/stores/getters.js
+5
-11
app/assets/javascripts/notes/stores/index.js
app/assets/javascripts/notes/stores/index.js
+0
-1
app/views/projects/issues/_discussion.html.haml
app/views/projects/issues/_discussion.html.haml
+1
-1
No files found.
app/assets/javascripts/notes/components/issue_comment_form.vue
View file @
f5a21c59
...
...
@@ -89,10 +89,10 @@
if
(
res
.
errors
.
commands_only
)
{
this
.
discard
();
}
else
{
this
.
handleError
(
);
return
Flash
(
'
Something went wrong while adding your comment. Please try again.
'
);
}
}
else
{
return
Flash
(
'
Something went wrong while adding your comment. Please try again.
'
);
this
.
discard
(
);
}
})
.
catch
(()
=>
{
...
...
@@ -132,7 +132,7 @@
editCurrentUserLastNote
()
{
if
(
this
.
note
===
''
)
{
const
lastNote
=
this
.
getCurrentUserLastNote
(
window
.
gon
.
current_user_id
);
console
.
log
(
lastNote
)
if
(
lastNote
)
{
eventHub
.
$emit
(
'
enterEditMode
'
,
{
noteId
:
lastNote
.
id
,
...
...
@@ -172,102 +172,104 @@
/>
</div>
<div
class=
"js-main-target-form timeline-content timeline-content-form common-note-form"
>
<markdown-field
:markdown-preview-url=
"markdownPreviewUrl"
:markdown-docs=
"markdownDocsUrl"
:quick-actions-docs=
"quickActionsDocsUrl"
:add-spacing-classes=
"false"
>
<textarea
id=
"note-body"
name=
"note[note]"
class=
"note-textarea js-gfm-input js-autosize markdown-area js-note-text"
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.up=
"editCurrentUserLastNote()"
@
keydown.meta.enter=
"handleSave()"
>
</textarea>
</markdown-field>
<div
class=
"note-form-actions"
>
<div
class=
"pull-left btn-group append-right-10 comment-type-dropdown js-comment-type-dropdown droplab-dropdown"
>
<form>
<markdown-field
:markdown-preview-url=
"markdownPreviewUrl"
:markdown-docs=
"markdownDocsUrl"
:quick-actions-docs=
"quickActionsDocsUrl"
:add-spacing-classes=
"false"
>
<textarea
id=
"note-body"
name=
"note[note]"
class=
"note-textarea js-gfm-input js-autosize markdown-area js-note-text"
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.up=
"editCurrentUserLastNote()"
@
keydown.meta.enter=
"handleSave()"
>
</textarea>
</markdown-field>
<div
class=
"note-form-actions"
>
<div
class=
"pull-left btn-group append-right-10 comment-type-dropdown js-comment-type-dropdown droplab-dropdown"
>
<button
@
click=
"handleSave()"
:disabled=
"!note.length"
class=
"btn btn-nr btn-create comment-btn js-comment-button js-comment-submit-button"
type=
"button"
>
{{
commentButtonTitle
}}
</button>
<button
:disabled=
"!note.length"
name=
"button"
type=
"button"
class=
"btn btn-nr comment-btn note-type-toggle js-note-new-discussion dropdown-toggle"
data-toggle=
"dropdown"
aria-label=
"Open comment type dropdown"
>
<i
aria-hidden=
"true"
class=
"fa fa-caret-down toggle-icon"
>
</i>
</button>
<ul
class=
"note-type-dropdown dropdown-open-top dropdown-menu"
>
<li
:class=
"
{ 'droplab-item-selected': noteType === 'comment' }">
<button
type=
"button"
class=
"btn btn-transparent"
@
click.prevent=
"setNoteType('comment')"
>
<i
aria-hidden=
"true"
class=
"fa fa-check icon"
>
</i>
<div
class=
"description"
>
<strong>
Comment
</strong>
<p>
Add a general comment to this issue.
</p>
</div>
</button>
</li>
<li
class=
"divider droplab-item-ignore"
></li>
<li
:class=
"
{ 'droplab-item-selected': noteType === 'discussion' }">
<button
type=
"button"
class=
"btn btn-transparent"
@
click.prevent=
"setNoteType('discussion')"
>
<i
aria-hidden=
"true"
class=
"fa fa-check icon"
>
</i>
<div
class=
"description"
>
<strong>
Start discussion
</strong>
<p>
Discuss a specific suggestion or question.
</p>
</div>
</button>
</li>
</ul>
</div>
<button
@
click=
"handleSave"
:disabled=
"!note.length"
class=
"btn btn-nr btn-create comment-btn js-comment-button js-comment-submit-button"
type=
"button"
>
{{
commentButtonTitle
}}
type=
"button"
@
click=
"handleSave(true)"
v-if=
"canUpdateIssue"
:class=
"actionButtonClassNames"
class=
"btn btn-nr btn-comment btn-comment-and-close"
>
{{
issueActionButtonTitle
}}
</button>
<button
:disabled=
"!note.length"
name=
"button"
type=
"button"
class=
"btn btn-nr comment-btn note-type-toggle js-note-new-discussion dropdown-toggle"
data-toggle=
"dropdown"
aria-label=
"Open comment type dropdown"
>
<i
aria-hidden=
"true"
class=
"fa fa-caret-down toggle-icon"
>
</i>
v-if=
"note.length"
@
click=
"discard"
class=
"btn btn-cancel js-note-discard"
>
Discard draft
</button>
<ul
class=
"note-type-dropdown dropdown-open-top dropdown-menu"
>
<li
:class=
"
{ 'droplab-item-selected': noteType === 'comment' }">
<button
type=
"button"
class=
"btn btn-transparent"
@
click.prevent=
"setNoteType('comment')"
>
<i
aria-hidden=
"true"
class=
"fa fa-check icon"
>
</i>
<div
class=
"description"
>
<strong>
Comment
</strong>
<p>
Add a general comment to this issue.
</p>
</div>
</button>
</li>
<li
class=
"divider droplab-item-ignore"
></li>
<li
:class=
"
{ 'droplab-item-selected': noteType === 'discussion' }">
<button
type=
"button"
class=
"btn btn-transparent"
@
click.prevent=
"setNoteType('discussion')"
>
<i
aria-hidden=
"true"
class=
"fa fa-check icon"
>
</i>
<div
class=
"description"
>
<strong>
Start discussion
</strong>
<p>
Discuss a specific suggestion or question.
</p>
</div>
</button>
</li>
</ul>
</div>
<button
type=
"button"
@
click=
"handleSave(true)"
v-if=
"canUpdateIssue"
:class=
"actionButtonClassNames"
class=
"btn btn-nr btn-comment btn-comment-and-close"
>
{{
issueActionButtonTitle
}}
</button>
<button
type=
"button"
v-if=
"note.length"
@
click=
"discard"
class=
"btn btn-cancel js-note-discard"
>
Discard draft
</button>
</div>
</form>
</div>
</div>
</li>
...
...
app/assets/javascripts/notes/components/issue_note_form.vue
View file @
f5a21c59
...
...
@@ -94,7 +94,6 @@
to ensure information is not lost.
</div>
<form
@
submit=
"handleUpdate"
class=
"edit-note common-note-form"
>
<markdown-field
:markdown-preview-url=
"markdownPreviewUrl"
...
...
@@ -103,7 +102,7 @@
<textarea
id=
"note-body"
name=
"note[note]"
class=
"note-textarea js-gfm-input js-autosize markdown-area
js-note-text
"
class=
"note-textarea js-gfm-input js-autosize markdown-area"
data-supports-slash-commands=
"true"
data-supports-quick-actions=
"true"
aria-label=
"Description"
...
...
@@ -118,7 +117,8 @@
</markdown-field>
<div
class=
"note-form-actions clearfix"
>
<button
type=
"submit"
type=
"button"
@
click=
"handleUpdate"
class=
"btn btn-nr btn-save"
>
{{
saveButtonTitle
}}
</button>
...
...
app/assets/javascripts/notes/components/issue_notes_app.vue
View file @
f5a21c59
...
...
@@ -48,6 +48,7 @@
computed
:
{
...
mapGetters
([
'
notes
'
,
'
notesById
'
,
'
getNotesDataByProp
'
,
]),
},
...
...
@@ -55,7 +56,7 @@
...
mapActions
({
actionFetchNotes
:
'
fetchNotes
'
,
poll
:
'
poll
'
,
t
oggleAward
:
'
toggleAward
'
,
actionT
oggleAward
:
'
toggleAward
'
,
scrollToNoteIfNeeded
:
'
scrollToNoteIfNeeded
'
,
setNotesData
:
'
setNotesData
'
,
setIssueData
:
'
setIssueData
'
,
...
...
@@ -113,11 +114,11 @@
const
{
awardName
,
noteId
}
=
data
;
const
endpoint
=
this
.
notesById
[
noteId
].
toggle_award_path
;
this
.
t
oggleAward
({
endpoint
,
awardName
,
noteId
})
.
catch
(()
=>
Flash
(
'
Something went wrong on our end.
'
));
this
.
actionT
oggleAward
({
endpoint
,
awardName
,
noteId
})
.
catch
((
error
)
=>
Flash
(
'
Something went wrong on our end.
'
));
});
//
TODO: FILIPA: REMOVE JQUERY
//
JQuery is needed here because it is a custom event being dispatched with jQuery.
$
(
document
).
on
(
'
issuable:change
'
,
(
e
,
isClosed
)
=>
{
eventHub
.
$emit
(
'
issueStateChanged
'
,
isClosed
);
});
...
...
app/assets/javascripts/notes/index.js
View file @
f5a21c59
import
Vue
from
'
vue
'
;
import
issueNotesApp
from
'
./components/issue_notes_app.vue
'
;
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
new
Vue
({
el
:
'
#js-vue-notes
'
,
components
:
{
issueNotesApp
,
},
data
()
{
const
notesDataset
=
document
.
getElementById
(
'
js-vue-notes
'
).
dataset
;
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
{
const
vm
=
new
Vue
({
el
:
'
#js-vue-notes
'
,
components
:
{
issueNotesApp
,
},
data
()
{
const
notesDataset
=
document
.
getElementById
(
'
js-vue-notes
'
).
dataset
;
return
{
issueData
:
JSON
.
parse
(
notesDataset
.
issueData
),
currentUserData
:
JSON
.
parse
(
notesDataset
.
currentUserData
),
notesData
:
{
lastFetchedAt
:
notesDataset
.
lastFetchedAt
,
discussionsPath
:
notesDataset
.
discussionsPath
,
newSessionPath
:
notesDataset
.
newSessionPath
,
registerPath
:
notesDataset
.
registerPath
,
notesPath
:
notesDataset
.
notesPath
,
markdownDocs
:
notesDataset
.
markdownDocs
,
quickActionsDocs
:
notesDataset
.
quickActionsDocs
,
},
};
},
render
(
createElement
)
{
return
createElement
(
'
issue-notes-app
'
,
{
attrs
:
{
ref
:
'
notes
'
,
},
props
:
{
issueData
:
this
.
issueData
,
notesData
:
this
.
notesData
,
userData
:
this
.
currentUserData
,
},
});
},
}));
return
{
issueData
:
JSON
.
parse
(
notesDataset
.
issueData
),
currentUserData
:
JSON
.
parse
(
notesDataset
.
currentUserData
),
notesData
:
{
lastFetchedAt
:
notesDataset
.
lastFetchedAt
,
discussionsPath
:
notesDataset
.
discussionsPath
,
newSessionPath
:
notesDataset
.
newSessionPath
,
registerPath
:
notesDataset
.
registerPath
,
notesPath
:
notesDataset
.
notesPath
,
markdownDocs
:
notesDataset
.
markdownDocs
,
quickActionsDocs
:
notesDataset
.
quickActionsDocs
,
},
};
},
render
(
createElement
)
{
return
createElement
(
'
issue-notes-app
'
,
{
attrs
:
{
ref
:
'
notes
'
,
},
props
:
{
issueData
:
this
.
issueData
,
notesData
:
this
.
notesData
,
userData
:
this
.
currentUserData
,
},
});
},
});
// This is used in note_polling_spec
window
.
issueNotes
=
{
refresh
()
{
vm
.
$refs
.
notes
.
$store
.
dispatch
(
'
poll
'
);
},
};
});
// // TODO: FILIPA: FIX THIS
// window.issueNotes = {
// refresh() {
// vm.$refs.notes.$store.dispatch('poll');
// },
// };
app/assets/javascripts/notes/stores/actions.js
View file @
f5a21c59
...
...
@@ -131,32 +131,31 @@ export const saveNote = ({ commit, dispatch }, noteData) => {
});
};
export
const
poll
=
({
commit
,
state
,
getters
})
=>
{
return
service
.
poll
(
state
.
notesData
.
notesPath
,
state
.
lastFetchedAt
)
.
then
(
res
=>
res
.
json
())
.
then
((
res
)
=>
{
if
(
res
.
notes
.
length
)
{
const
{
notesById
}
=
getters
;
res
.
notes
.
forEach
((
note
)
=>
{
if
(
notesById
[
note
.
id
])
{
commit
(
types
.
UPDATE_NOTE
,
note
);
}
else
if
(
note
.
type
===
constants
.
DISCUSSION_NOTE
)
{
const
discussion
=
utils
.
findNoteObjectById
(
state
.
notes
,
note
.
discussion_id
);
if
(
discussion
)
{
commit
(
types
.
ADD_NEW_REPLY_TO_DISCUSSION
,
note
);
}
else
{
commit
(
types
.
ADD_NEW_NOTE
,
note
);
}
export
const
poll
=
({
commit
,
state
,
getters
})
=>
service
.
poll
(
state
.
notesData
.
notesPath
,
state
.
lastFetchedAt
)
.
then
(
res
=>
res
.
json
())
.
then
((
res
)
=>
{
if
(
res
.
notes
.
length
)
{
const
{
notesById
}
=
getters
;
res
.
notes
.
forEach
((
note
)
=>
{
if
(
notesById
[
note
.
id
])
{
commit
(
types
.
UPDATE_NOTE
,
note
);
}
else
if
(
note
.
type
===
constants
.
DISCUSSION_NOTE
)
{
const
discussion
=
utils
.
findNoteObjectById
(
state
.
notes
,
note
.
discussion_id
);
if
(
discussion
)
{
commit
(
types
.
ADD_NEW_REPLY_TO_DISCUSSION
,
note
);
}
else
{
commit
(
types
.
ADD_NEW_NOTE
,
note
);
}
});
}
return
res
;
});
};
}
else
{
commit
(
types
.
ADD_NEW_NOTE
,
note
);
}
});
}
return
res
;
});
export
const
toggleAward
=
({
commit
,
getters
,
dispatch
},
data
)
=>
{
const
{
endpoint
,
awardName
,
noteId
,
skipMutalityCheck
}
=
data
;
...
...
app/assets/javascripts/notes/stores/getters.js
View file @
f5a21c59
...
...
@@ -10,17 +10,10 @@ export const getIssueDataByProp = state => prop => state.issueData[prop];
export
const
getUserData
=
state
=>
state
.
userData
;
export
const
getUserDataByProp
=
state
=>
prop
=>
state
.
notesData
[
prop
];
export
const
notesById
=
(
state
)
=>
{
const
notesByIdObject
=
{};
// TODO: FILIPA: TRANSFORM INTO A REDUCE
state
.
notes
.
forEach
((
note
)
=>
{
note
.
notes
.
forEach
((
n
)
=>
{
notesByIdObject
[
n
.
id
]
=
n
;
});
});
return
notesByIdObject
;
};
export
const
notesById
=
state
=>
state
.
notes
.
reduce
((
acc
,
note
)
=>
{
note
.
notes
.
every
(
n
=>
Object
.
assign
(
acc
,
{
[
n
.
id
]:
n
}));
return
acc
;
},
{});
const
reverseNotes
=
array
=>
array
.
slice
(
0
).
reverse
();
const
isLastNote
=
(
note
,
userId
)
=>
!
note
.
system
&&
note
.
author
.
id
===
userId
;
...
...
@@ -31,6 +24,7 @@ export const getCurrentUserLastNote = state => userId => reverseNotes(state.note
return
acc
;
},
[]).
filter
(
el
=>
el
!==
undefined
)[
0
];
// eslint-disable-next-line no-unused-vars
export
const
getDiscussionLastNote
=
state
=>
(
discussion
,
userId
)
=>
reverseNotes
(
discussion
.
notes
)
.
find
(
el
=>
isLastNote
(
el
,
userId
));
app/assets/javascripts/notes/stores/index.js
View file @
f5a21c59
...
...
@@ -16,7 +16,6 @@ export default new Vuex.Store({
notesData
:
{},
userData
:
{},
issueData
:
{},
paths
:
{},
},
actions
,
getters
,
...
...
app/views/projects/issues/_discussion.html.haml
View file @
f5a21c59
...
...
@@ -9,7 +9,7 @@
new_session_path:
new_session_path
(
:user
,
redirect_to_referer:
'yes'
),
markdown_docs:
help_page_path
(
'user/markdown'
),
quick_actions_docs:
help_page_path
(
'user/project/quick_actions'
),
notes_path:
'
#
{
notes_url
}?
full_data
=
1
'
,
notes_path:
"#{notes_url}?full_data=1"
,
last_fetched_at:
Time
.
now
.
to_i
,
issue_data:
serialize_issuable
(
@issue
),
current_user_data:
UserSerializer
.
new
.
represent
(
current_user
).
to_json
}}
...
...
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