summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Greiling <mike@pixelcog.com>2019-06-26 22:53:06 +0000
committerMike Greiling <mike@pixelcog.com>2019-06-26 22:53:06 +0000
commitc95b671b894b0195b1c82336b710feb19485a333 (patch)
tree5e8d00a0346590ba933cfb337ca4392f564f114a
parent0f045c423973a82238770ac960d17ab5d9b645c0 (diff)
parent63fdd2c60d228937c24eb402c87f9a559c0b0db1 (diff)
downloadgitlab-ce-c95b671b894b0195b1c82336b710feb19485a333.tar.gz
Merge branch '63247-add-conf-toast-and-link' into 'master'
Resolve "Including a link to the posted comment for visual review app review feature" Closes #63247 See merge request gitlab-org/gitlab-ce!29719
-rw-r--r--app/assets/javascripts/visual_review_toolbar/components/comment.js50
-rw-r--r--app/assets/javascripts/visual_review_toolbar/components/constants.js8
-rw-r--r--app/assets/javascripts/visual_review_toolbar/components/index.js16
-rw-r--r--app/assets/javascripts/visual_review_toolbar/components/login.js3
-rw-r--r--app/assets/javascripts/visual_review_toolbar/components/note.js14
-rw-r--r--app/assets/javascripts/visual_review_toolbar/components/utils.js6
-rw-r--r--app/assets/javascripts/visual_review_toolbar/components/wrapper.js36
-rw-r--r--app/assets/javascripts/visual_review_toolbar/index.js9
-rw-r--r--app/assets/javascripts/visual_review_toolbar/store/state.js3
-rw-r--r--app/assets/javascripts/visual_review_toolbar/styles/toolbar.css48
-rw-r--r--changelogs/unreleased/63247-add-conf-toast-and-link.yml5
11 files changed, 147 insertions, 51 deletions
diff --git a/app/assets/javascripts/visual_review_toolbar/components/comment.js b/app/assets/javascripts/visual_review_toolbar/components/comment.js
index 2fec96d1435..04bfb5e9532 100644
--- a/app/assets/javascripts/visual_review_toolbar/components/comment.js
+++ b/app/assets/javascripts/visual_review_toolbar/components/comment.js
@@ -1,54 +1,62 @@
import { BLACK, COMMENT_BOX, MUTED, LOGOUT } from './constants';
-import { clearNote, note, postError } from './note';
-import { buttonClearStyles, selectCommentBox, selectCommentButton, selectNote } from './utils';
+import { clearNote, postError } from './note';
+import {
+ buttonClearStyles,
+ selectCommentBox,
+ selectCommentButton,
+ selectNote,
+ selectNoteContainer,
+} from './utils';
const comment = `
<div>
<textarea id="${COMMENT_BOX}" name="${COMMENT_BOX}" rows="3" placeholder="Enter your feedback or idea" class="gitlab-input" aria-required="true"></textarea>
- ${note}
<p class="gitlab-metadata-note">Additional metadata will be included: browser, OS, current page, user agent, and viewport dimensions.</p>
</div>
<div class="gitlab-button-wrapper">
- <button class="gitlab-button gitlab-button-secondary" style="${buttonClearStyles}" type="button" id="${LOGOUT}"> Logout </button>
+ <button class="gitlab-button gitlab-button-secondary" style="${buttonClearStyles}" type="button" id="${LOGOUT}"> Log out </button>
<button class="gitlab-button gitlab-button-success" style="${buttonClearStyles}" type="button" id="gitlab-comment-button"> Send feedback </button>
</div>
`;
-const resetCommentBox = () => {
- const commentBox = selectCommentBox();
+const resetCommentButton = () => {
const commentButton = selectCommentButton();
/* eslint-disable-next-line @gitlab/i18n/no-non-i18n-strings */
commentButton.innerText = 'Send feedback';
commentButton.classList.replace('gitlab-button-secondary', 'gitlab-button-success');
commentButton.style.opacity = 1;
+};
+const resetCommentBox = () => {
+ const commentBox = selectCommentBox();
commentBox.style.pointerEvents = 'auto';
commentBox.style.color = BLACK;
};
-const resetCommentButton = () => {
+const resetCommentText = () => {
const commentBox = selectCommentBox();
- const currentNote = selectNote();
-
commentBox.value = '';
- currentNote.innerText = '';
};
const resetComment = () => {
- resetCommentBox();
resetCommentButton();
+ resetCommentBox();
+ resetCommentText();
};
-const confirmAndClear = mergeRequestId => {
+const confirmAndClear = feedbackInfo => {
const commentButton = selectCommentButton();
const currentNote = selectNote();
+ const noteContainer = selectNoteContainer();
/* eslint-disable-next-line @gitlab/i18n/no-non-i18n-strings */
commentButton.innerText = 'Feedback sent';
- /* eslint-disable-next-line @gitlab/i18n/no-non-i18n-strings */
- currentNote.innerText = `Your comment was successfully posted to merge request #${mergeRequestId}`;
- setTimeout(resetComment, 2000);
+ noteContainer.style.visibility = 'visible';
+ currentNote.insertAdjacentHTML('beforeend', feedbackInfo);
+
+ setTimeout(resetComment, 1000);
+ setTimeout(clearNote, 6000);
};
const setInProgressState = () => {
@@ -71,6 +79,7 @@ const postComment = ({
innerWidth,
innerHeight,
projectId,
+ projectPath,
mergeRequestId,
mrUrl,
token,
@@ -86,6 +95,7 @@ const postComment = ({
/* eslint-disable-next-line @gitlab/i18n/no-non-i18n-strings */
postError('Your comment appears to be empty.', COMMENT_BOX);
resetCommentBox();
+ resetCommentButton();
return;
}
@@ -114,18 +124,24 @@ const postComment = ({
})
.then(response => {
if (response.ok) {
- confirmAndClear(mergeRequestId);
- return;
+ return response.json();
}
throw new Error(`${response.status}: ${response.statusText}`);
})
+ .then(data => {
+ const commentId = data.notes[0].id;
+ const feedbackLink = `${mrUrl}/${projectPath}/merge_requests/${mergeRequestId}#note_${commentId}`;
+ const feedbackInfo = `Feedback sent. View at <a class="gitlab-link" href="${feedbackLink}">${projectPath} #${mergeRequestId} (comment ${commentId})</a>`;
+ confirmAndClear(feedbackInfo);
+ })
.catch(err => {
postError(
`Your comment could not be sent. Please try again. Error: ${err.message}`,
COMMENT_BOX,
);
resetCommentBox();
+ resetCommentButton();
});
};
diff --git a/app/assets/javascripts/visual_review_toolbar/components/constants.js b/app/assets/javascripts/visual_review_toolbar/components/constants.js
index 32ed1153515..07fcb179d15 100644
--- a/app/assets/javascripts/visual_review_toolbar/components/constants.js
+++ b/app/assets/javascripts/visual_review_toolbar/components/constants.js
@@ -2,10 +2,12 @@
const COLLAPSE_BUTTON = 'gitlab-collapse';
const COMMENT_BOX = 'gitlab-comment';
const COMMENT_BUTTON = 'gitlab-comment-button';
-const FORM = 'gitlab-form-wrapper';
+const FORM = 'gitlab-form';
+const FORM_CONTAINER = 'gitlab-form-wrapper';
const LOGIN = 'gitlab-login';
const LOGOUT = 'gitlab-logout-button';
const NOTE = 'gitlab-validation-note';
+const NOTE_CONTAINER = 'gitlab-note-wrapper';
const REMEMBER_TOKEN = 'gitlab-remember_token';
const REVIEW_CONTAINER = 'gitlab-review-container';
const TOKEN_BOX = 'gitlab-token';
@@ -16,16 +18,18 @@ const BLACK = 'rgba(46, 46, 46, 1)';
const CLEAR = 'rgba(255, 255, 255, 0)';
const MUTED = 'rgba(223, 223, 223, 0.5)';
const RED = 'rgba(219, 59, 33, 1)';
-const WHITE = 'rgba(255, 255, 255, 1)';
+const WHITE = 'rgba(250, 250, 250, 1)';
export {
COLLAPSE_BUTTON,
COMMENT_BOX,
COMMENT_BUTTON,
FORM,
+ FORM_CONTAINER,
LOGIN,
LOGOUT,
NOTE,
+ NOTE_CONTAINER,
REMEMBER_TOKEN,
REVIEW_CONTAINER,
TOKEN_BOX,
diff --git a/app/assets/javascripts/visual_review_toolbar/components/index.js b/app/assets/javascripts/visual_review_toolbar/components/index.js
index 43581818152..50b52d7d3a2 100644
--- a/app/assets/javascripts/visual_review_toolbar/components/index.js
+++ b/app/assets/javascripts/visual_review_toolbar/components/index.js
@@ -1,22 +1,32 @@
import { comment, postComment } from './comment';
-import { COLLAPSE_BUTTON, COMMENT_BUTTON, LOGIN, LOGOUT, REVIEW_CONTAINER } from './constants';
+import {
+ COLLAPSE_BUTTON,
+ COMMENT_BUTTON,
+ FORM_CONTAINER,
+ LOGIN,
+ LOGOUT,
+ REVIEW_CONTAINER,
+} from './constants';
import { authorizeUser, login } from './login';
+import { note } from './note';
import { selectContainer } from './utils';
-import { form, logoutUser, toggleForm } from './wrapper';
+import { buttonAndForm, logoutUser, toggleForm } from './wrapper';
import { collapseButton } from './wrapper_icons';
export {
authorizeUser,
+ buttonAndForm,
collapseButton,
comment,
- form,
login,
logoutUser,
+ note,
postComment,
selectContainer,
toggleForm,
COLLAPSE_BUTTON,
COMMENT_BUTTON,
+ FORM_CONTAINER,
LOGIN,
LOGOUT,
REVIEW_CONTAINER,
diff --git a/app/assets/javascripts/visual_review_toolbar/components/login.js b/app/assets/javascripts/visual_review_toolbar/components/login.js
index ce713cdc520..0a71299f041 100644
--- a/app/assets/javascripts/visual_review_toolbar/components/login.js
+++ b/app/assets/javascripts/visual_review_toolbar/components/login.js
@@ -1,5 +1,5 @@
import { LOGIN, REMEMBER_TOKEN, TOKEN_BOX } from './constants';
-import { clearNote, note, postError } from './note';
+import { clearNote, postError } from './note';
import { buttonClearStyles, selectRemember, selectToken } from './utils';
import { addCommentForm } from './wrapper';
@@ -7,7 +7,6 @@ const login = `
<div>
<label for="${TOKEN_BOX}" class="gitlab-label">Enter your <a class="gitlab-link" href="https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html">personal access token</a></label>
<input class="gitlab-input" type="password" id="${TOKEN_BOX}" name="${TOKEN_BOX}" aria-required="true" autocomplete="current-password">
- ${note}
</div>
<div class="gitlab-checkbox-wrapper">
<input type="checkbox" id="${REMEMBER_TOKEN}" name="${REMEMBER_TOKEN}" value="remember">
diff --git a/app/assets/javascripts/visual_review_toolbar/components/note.js b/app/assets/javascripts/visual_review_toolbar/components/note.js
index dfebf58fd95..0150f640aae 100644
--- a/app/assets/javascripts/visual_review_toolbar/components/note.js
+++ b/app/assets/javascripts/visual_review_toolbar/components/note.js
@@ -1,14 +1,19 @@
-import { NOTE, RED } from './constants';
-import { selectById, selectNote } from './utils';
+import { NOTE, NOTE_CONTAINER, RED } from './constants';
+import { selectById, selectNote, selectNoteContainer } from './utils';
const note = `
- <p id=${NOTE} class='gitlab-message'></p>
+ <div id="${NOTE_CONTAINER}" style="visibility: hidden;">
+ <p id="${NOTE}" class="gitlab-message"></p>
+ </div>
`;
const clearNote = inputId => {
const currentNote = selectNote();
+ const noteContainer = selectNoteContainer();
+
currentNote.innerText = '';
currentNote.style.color = '';
+ noteContainer.style.visibility = 'hidden';
if (inputId) {
const field = document.getElementById(inputId);
@@ -18,10 +23,13 @@ const clearNote = inputId => {
const postError = (message, inputId) => {
const currentNote = selectNote();
+ const noteContainer = selectNoteContainer();
const field = selectById(inputId);
field.style.borderColor = RED;
currentNote.style.color = RED;
currentNote.innerText = message;
+ noteContainer.style.visibility = 'visible';
+ setTimeout(clearNote.bind(null, inputId), 5000);
};
export { clearNote, note, postError };
diff --git a/app/assets/javascripts/visual_review_toolbar/components/utils.js b/app/assets/javascripts/visual_review_toolbar/components/utils.js
index 7bc2e5a905b..00f4460925d 100644
--- a/app/assets/javascripts/visual_review_toolbar/components/utils.js
+++ b/app/assets/javascripts/visual_review_toolbar/components/utils.js
@@ -5,7 +5,9 @@ import {
COMMENT_BOX,
COMMENT_BUTTON,
FORM,
+ FORM_CONTAINER,
NOTE,
+ NOTE_CONTAINER,
REMEMBER_TOKEN,
REVIEW_CONTAINER,
TOKEN_BOX,
@@ -24,7 +26,9 @@ const selectCommentBox = () => document.getElementById(COMMENT_BOX);
const selectCommentButton = () => document.getElementById(COMMENT_BUTTON);
const selectContainer = () => document.getElementById(REVIEW_CONTAINER);
const selectForm = () => document.getElementById(FORM);
+const selectFormContainer = () => document.getElementById(FORM_CONTAINER);
const selectNote = () => document.getElementById(NOTE);
+const selectNoteContainer = () => document.getElementById(NOTE_CONTAINER);
const selectRemember = () => document.getElementById(REMEMBER_TOKEN);
const selectToken = () => document.getElementById(TOKEN_BOX);
@@ -36,7 +40,9 @@ export {
selectCommentBox,
selectCommentButton,
selectForm,
+ selectFormContainer,
selectNote,
+ selectNoteContainer,
selectRemember,
selectToken,
};
diff --git a/app/assets/javascripts/visual_review_toolbar/components/wrapper.js b/app/assets/javascripts/visual_review_toolbar/components/wrapper.js
index 233b7ec496c..f2eaf1d7916 100644
--- a/app/assets/javascripts/visual_review_toolbar/components/wrapper.js
+++ b/app/assets/javascripts/visual_review_toolbar/components/wrapper.js
@@ -1,15 +1,28 @@
import { comment } from './comment';
-import { CLEAR, FORM, WHITE } from './constants';
+import { CLEAR, FORM, FORM_CONTAINER, WHITE } from './constants';
import { login } from './login';
-import { selectCollapseButton, selectContainer, selectForm } from './utils';
+import { clearNote } from './note';
+import {
+ selectCollapseButton,
+ selectForm,
+ selectFormContainer,
+ selectNoteContainer,
+} from './utils';
import { commentIcon, compressIcon } from './wrapper_icons';
const form = content => `
- <form id=${FORM}>
+ <form id="${FORM}">
${content}
</form>
`;
+const buttonAndForm = ({ content, toggleButton }) => `
+ <div id="${FORM_CONTAINER}" class="gitlab-form-open">
+ ${toggleButton}
+ ${form(content)}
+ </div>
+`;
+
const addCommentForm = () => {
const formWrapper = selectForm();
formWrapper.innerHTML = comment;
@@ -31,13 +44,15 @@ function logoutUser() {
return;
}
+ clearNote();
addLoginForm();
}
function toggleForm() {
- const container = selectContainer();
const collapseButton = selectCollapseButton();
const currentForm = selectForm();
+ const formContainer = selectFormContainer();
+ const noteContainer = selectNoteContainer();
const OPEN = 'open';
const CLOSED = 'closed';
@@ -49,7 +64,7 @@ function toggleForm() {
const openButtonClasses = ['gitlab-collapse-closed', 'gitlab-collapse-open'];
const closedButtonClasses = [...openButtonClasses].reverse();
- const openContainerClasses = ['gitlab-closed-wrapper', 'gitlab-open-wrapper'];
+ const openContainerClasses = ['gitlab-wrapper-closed', 'gitlab-wrapper-open'];
const closedContainerClasses = [...openContainerClasses].reverse();
const stateVals = {
@@ -72,11 +87,16 @@ function toggleForm() {
const nextState = collapseButton.classList.contains('gitlab-collapse-open') ? CLOSED : OPEN;
const currentVals = stateVals[nextState];
- container.classList.replace(...currentVals.containerClasses);
- container.style.backgroundColor = currentVals.backgroundColor;
+ formContainer.classList.replace(...currentVals.containerClasses);
+ formContainer.style.backgroundColor = currentVals.backgroundColor;
+ formContainer.classList.toggle('gitlab-form-open');
currentForm.style.display = currentVals.display;
collapseButton.classList.replace(...currentVals.buttonClasses);
collapseButton.innerHTML = currentVals.icon;
+
+ if (noteContainer && noteContainer.innerText.length > 0) {
+ noteContainer.style.display = currentVals.display;
+ }
}
-export { addCommentForm, addLoginForm, form, logoutUser, toggleForm };
+export { addCommentForm, addLoginForm, buttonAndForm, logoutUser, toggleForm };
diff --git a/app/assets/javascripts/visual_review_toolbar/index.js b/app/assets/javascripts/visual_review_toolbar/index.js
index 941d77e25b4..f94eb88835a 100644
--- a/app/assets/javascripts/visual_review_toolbar/index.js
+++ b/app/assets/javascripts/visual_review_toolbar/index.js
@@ -1,6 +1,6 @@
import './styles/toolbar.css';
-import { form, selectContainer, REVIEW_CONTAINER } from './components';
+import { buttonAndForm, note, selectContainer, REVIEW_CONTAINER } from './components';
import { debounce, eventLookup, getInitialView, initializeState, updateWindowSize } from './store';
/*
@@ -20,12 +20,11 @@ import { debounce, eventLookup, getInitialView, initializeState, updateWindowSiz
window.addEventListener('load', () => {
initializeState(window, document);
- const { content, toggleButton } = getInitialView(window);
+ const mainContent = buttonAndForm(getInitialView(window));
const container = document.createElement('div');
-
container.setAttribute('id', REVIEW_CONTAINER);
- container.insertAdjacentHTML('beforeend', toggleButton);
- container.insertAdjacentHTML('beforeend', form(content));
+ container.insertAdjacentHTML('beforeend', note);
+ container.insertAdjacentHTML('beforeend', mainContent);
document.body.insertBefore(container, document.body.firstChild);
diff --git a/app/assets/javascripts/visual_review_toolbar/store/state.js b/app/assets/javascripts/visual_review_toolbar/store/state.js
index f5ede6e85b2..22702d524b8 100644
--- a/app/assets/javascripts/visual_review_toolbar/store/state.js
+++ b/app/assets/javascripts/visual_review_toolbar/store/state.js
@@ -34,7 +34,7 @@ const initializeState = (wind, doc) => {
const browser = getBrowserId(userAgent);
const scriptEl = doc.getElementById('review-app-toolbar-script');
- const { projectId, mergeRequestId, mrUrl } = scriptEl.dataset;
+ const { projectId, mergeRequestId, mrUrl, projectPath } = scriptEl.dataset;
// This mutates our default state object above. It's weird but it makes the linter happy.
Object.assign(state, {
@@ -46,6 +46,7 @@ const initializeState = (wind, doc) => {
mrUrl,
platform,
projectId,
+ projectPath,
userAgent,
});
};
diff --git a/app/assets/javascripts/visual_review_toolbar/styles/toolbar.css b/app/assets/javascripts/visual_review_toolbar/styles/toolbar.css
index 342b3599a44..00a55c0027a 100644
--- a/app/assets/javascripts/visual_review_toolbar/styles/toolbar.css
+++ b/app/assets/javascripts/visual_review_toolbar/styles/toolbar.css
@@ -6,23 +6,42 @@
pointer-events: none;
}
-#gitlab-form-wrapper {
+#gitlab-comment {
+ background-color: #fafafa;
+}
+
+#gitlab-form {
+ display: flex;
+ flex-direction: column;
+ width: 100%;
+ margin-bottom: 0;
+}
+
+#gitlab-note-wrapper {
display: flex;
flex-direction: column;
- width: 100%
+ background-color: #fafafa;
+ border-radius: 4px;
+ margin-bottom: .5rem;
+ padding: 1rem;
+}
+
+#gitlab-form-wrapper {
+ overflow: auto;
+ display: flex;
+ flex-direction: row-reverse;
+ border-radius: 4px;
}
#gitlab-review-container {
max-width: 22rem;
max-height: 22rem;
- overflow: scroll;
+ overflow: auto;
+ display: flex;
+ flex-direction: column;
position: fixed;
bottom: 1rem;
right: 1rem;
- display: flex;
- flex-direction: row-reverse;
- padding: 1rem;
- background-color: #fff;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell,
'Helvetica Neue', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol',
'Noto Color Emoji';
@@ -31,12 +50,12 @@
color: #2e2e2e;
}
-.gitlab-open-wrapper {
+.gitlab-wrapper-open {
max-width: 22rem;
max-height: 22rem;
}
-.gitlab-closed-wrapper {
+.gitlab-wrapper-closed {
max-width: 3.4rem;
max-height: 3.4rem;
}
@@ -47,7 +66,7 @@
}
.gitlab-button-secondary {
- background: none #fff;
+ background: none #fafafa;
margin: 0 .5rem;
border: 1px solid #e3e3e3;
}
@@ -113,6 +132,11 @@
align-items: baseline;
}
+.gitlab-form-open {
+ padding: 1rem;
+ background-color: #fafafa;
+}
+
.gitlab-label {
font-weight: 600;
display: inline-block;
@@ -126,6 +150,10 @@
background-image: none;
}
+.gitlab-link:hover {
+ text-decoration: underline;
+}
+
.gitlab-message {
padding: .25rem 0;
margin: 0;
diff --git a/changelogs/unreleased/63247-add-conf-toast-and-link.yml b/changelogs/unreleased/63247-add-conf-toast-and-link.yml
new file mode 100644
index 00000000000..915cc20dcc8
--- /dev/null
+++ b/changelogs/unreleased/63247-add-conf-toast-and-link.yml
@@ -0,0 +1,5 @@
+---
+title: Include a link back to the MR for Visual Review feedback form
+merge_request: 29719
+author:
+type: changed