diff options
author | Shinya Maeda <shinya@gitlab.com> | 2018-06-18 17:29:48 +0900 |
---|---|---|
committer | Shinya Maeda <shinya@gitlab.com> | 2018-06-18 17:29:48 +0900 |
commit | 71e30c011957229dfa4029b9b04e5308ceed4fcd (patch) | |
tree | 2bfbff9907fa37a5bfba3c744439e09c7381c06f /app | |
parent | 1aeedf41f8681bbc638dde8b8a263a7d7cd13a1e (diff) | |
parent | 39208ed6750e31d10e4bad5a33693a83eb599f1f (diff) | |
download | gitlab-ce-71e30c011957229dfa4029b9b04e5308ceed4fcd.tar.gz |
Merge branch 'master' into build-chunks-on-object-storage
Diffstat (limited to 'app')
97 files changed, 343 insertions, 318 deletions
diff --git a/app/assets/javascripts/blob/viewer/index.js b/app/assets/javascripts/blob/viewer/index.js index f61c0be9230..5485248cfaf 100644 --- a/app/assets/javascripts/blob/viewer/index.js +++ b/app/assets/javascripts/blob/viewer/index.js @@ -70,7 +70,7 @@ export default class BlobViewer { const initialViewer = this.$fileHolder[0].querySelector('.blob-viewer:not(.hidden)'); let initialViewerName = initialViewer.getAttribute('data-type'); - if (this.switcher && location.hash.indexOf('#L') === 0) { + if (this.switcher && window.location.hash.indexOf('#L') === 0) { initialViewerName = 'simple'; } diff --git a/app/assets/javascripts/boards/components/board.js b/app/assets/javascripts/boards/components/board.js index 86b888c66c8..7920e08e4d8 100644 --- a/app/assets/javascripts/boards/components/board.js +++ b/app/assets/javascripts/boards/components/board.js @@ -1,6 +1,5 @@ /* eslint-disable comma-dangle, space-before-function-paren, one-var */ -import $ from 'jquery'; import Sortable from 'sortablejs'; import Vue from 'vue'; import AccessorUtilities from '../../lib/utils/accessor'; @@ -57,40 +56,6 @@ gl.issueBoards.Board = Vue.extend({ }); }, deep: true, - }, - detailIssue: { - handler () { - if (!Object.keys(this.detailIssue.issue).length) return; - - const issue = this.list.findIssue(this.detailIssue.issue.id); - - if (issue) { - const offsetLeft = this.$el.offsetLeft; - const boardsList = document.querySelectorAll('.boards-list')[0]; - const left = boardsList.scrollLeft - offsetLeft; - let right = (offsetLeft + this.$el.offsetWidth); - - if (window.innerWidth > 768 && boardsList.classList.contains('is-compact')) { - // -290 here because width of boardsList is animating so therefore - // getting the width here is incorrect - // 290 is the width of the sidebar - right -= (boardsList.offsetWidth - 290); - } else { - right -= boardsList.offsetWidth; - } - - if (right - boardsList.scrollLeft > 0) { - $(boardsList).animate({ - scrollLeft: right - }, this.sortableOptions.animation); - } else if (left > 0) { - $(boardsList).animate({ - scrollLeft: offsetLeft - }, this.sortableOptions.animation); - } - } - }, - deep: true } }, mounted () { diff --git a/app/assets/javascripts/boards/components/board_delete.js b/app/assets/javascripts/boards/components/board_delete.js index 4482b3b3e70..4dd9aebeed9 100644 --- a/app/assets/javascripts/boards/components/board_delete.js +++ b/app/assets/javascripts/boards/components/board_delete.js @@ -17,7 +17,7 @@ gl.issueBoards.BoardDelete = Vue.extend({ deleteBoard () { $(this.$el).tooltip('hide'); - if (confirm('Are you sure you want to delete this list?')) { + if (window.confirm('Are you sure you want to delete this list?')) { this.list.destroy(); } } diff --git a/app/assets/javascripts/boards/stores/boards_store.js b/app/assets/javascripts/boards/stores/boards_store.js index 7dc83843e9b..ffe86468b12 100644 --- a/app/assets/javascripts/boards/stores/boards_store.js +++ b/app/assets/javascripts/boards/stores/boards_store.js @@ -145,6 +145,6 @@ gl.issueBoards.BoardsStore = { return filteredList[0]; }, updateFiltersUrl () { - history.pushState(null, null, `?${this.filter.path}`); + window.history.pushState(null, null, `?${this.filter.path}`); } }; diff --git a/app/assets/javascripts/commits.js b/app/assets/javascripts/commits.js index 7e2a3573f81..9a3ea7a55b6 100644 --- a/app/assets/javascripts/commits.js +++ b/app/assets/javascripts/commits.js @@ -45,7 +45,7 @@ export default class CommitsList { this.content.fadeTo('fast', 1.0); // Change url so if user reload a page - search results are saved - history.replaceState({ + window.history.replaceState({ page: commitsUrl, }, document.title, commitsUrl); }) diff --git a/app/assets/javascripts/deploy_keys/components/app.vue b/app/assets/javascripts/deploy_keys/components/app.vue index 2cfa13fdc75..d91e4809126 100644 --- a/app/assets/javascripts/deploy_keys/components/app.vue +++ b/app/assets/javascripts/deploy_keys/components/app.vue @@ -98,7 +98,7 @@ export default { }, disableKey(deployKey, callback) { // eslint-disable-next-line no-alert - if (confirm(s__('DeployKeys|You are going to remove this deploy key. Are you sure?'))) { + if (window.confirm(s__('DeployKeys|You are going to remove this deploy key. Are you sure?'))) { this.service .disableKey(deployKey.id) .then(this.fetchKeys) diff --git a/app/assets/javascripts/environments/components/environment_stop.vue b/app/assets/javascripts/environments/components/environment_stop.vue index faaaf899a0d..eba58bedd6d 100644 --- a/app/assets/javascripts/environments/components/environment_stop.vue +++ b/app/assets/javascripts/environments/components/environment_stop.vue @@ -40,7 +40,7 @@ methods: { onClick() { // eslint-disable-next-line no-alert - if (confirm('Are you sure you want to stop this environment?')) { + if (window.confirm('Are you sure you want to stop this environment?')) { this.isLoading = true; $(this.$el).tooltip('dispose'); diff --git a/app/assets/javascripts/ide/components/commit_sidebar/list.vue b/app/assets/javascripts/ide/components/commit_sidebar/list.vue index 3d59410cbc2..d0fb0e3d99e 100644 --- a/app/assets/javascripts/ide/components/commit_sidebar/list.vue +++ b/app/assets/javascripts/ide/components/commit_sidebar/list.vue @@ -34,6 +34,10 @@ export default { type: String, required: true, }, + actionBtnIcon: { + type: String, + required: true, + }, itemActionComponent: { type: String, required: true, @@ -53,26 +57,21 @@ export default { required: true, }, }, - data() { - return { - showActionButton: false, - }; - }, computed: { titleText() { return sprintf(__('%{title} changes'), { title: this.title, }); }, + filesLength() { + return this.fileList.length; + }, }, methods: { ...mapActions(['stageAllChanges', 'unstageAllChanges']), actionBtnClicked() { this[this.action](); }, - setShowActionButton(show) { - this.showActionButton = show; - }, }, }; </script> @@ -83,8 +82,6 @@ export default { > <header class="multi-file-commit-panel-header" - @mouseenter="setShowActionButton(true)" - @mouseleave="setShowActionButton(false)" > <div class="multi-file-commit-panel-header-title" @@ -95,24 +92,40 @@ export default { :size="18" /> {{ titleText }} - <span - v-show="!showActionButton" - class="ide-commit-file-count" - > - {{ fileList.length }} - </span> - <button - v-show="showActionButton" - type="button" - class="btn btn-blank btn-link ide-staged-action-btn" - @click="actionBtnClicked" - > - {{ actionBtnText }} - </button> + <div class="d-flex ml-auto"> + <button + v-tooltip + v-show="filesLength" + :class="{ + 'd-flex': filesLength + }" + :title="actionBtnText" + type="button" + class="btn btn-default ide-staged-action-btn p-0 order-1 align-items-center" + data-placement="bottom" + data-container="body" + data-boundary="viewport" + @click="actionBtnClicked" + > + <icon + :name="actionBtnIcon" + :size="12" + class="ml-auto mr-auto" + /> + </button> + <span + :class="{ + 'rounded-right': !filesLength + }" + class="ide-commit-file-count order-0 rounded-left text-center" + > + {{ filesLength }} + </span> + </div> </div> </header> <ul - v-if="fileList.length" + v-if="filesLength" class="multi-file-commit-list list-unstyled append-bottom-0" > <li diff --git a/app/assets/javascripts/ide/components/commit_sidebar/list_item.vue b/app/assets/javascripts/ide/components/commit_sidebar/list_item.vue index 2ecf9af4bf0..5cda7967130 100644 --- a/app/assets/javascripts/ide/components/commit_sidebar/list_item.vue +++ b/app/assets/javascripts/ide/components/commit_sidebar/list_item.vue @@ -1,5 +1,6 @@ <script> import { mapActions } from 'vuex'; +import tooltip from '~/vue_shared/directives/tooltip'; import Icon from '~/vue_shared/components/icon.vue'; import StageButton from './stage_button.vue'; import UnstageButton from './unstage_button.vue'; @@ -11,6 +12,9 @@ export default { StageButton, UnstageButton, }, + directives: { + tooltip, + }, props: { file: { type: Object, @@ -50,6 +54,9 @@ export default { isActive() { return this.activeFileKey === this.fullKey; }, + tooltipTitle() { + return this.file.path === this.file.name ? '' : this.file.path; + }, }, methods: { ...mapActions([ @@ -81,29 +88,30 @@ export default { </script> <template> - <div - :class="{ - 'is-active': isActive - }" - class="multi-file-commit-list-item" - > + <div class="multi-file-commit-list-item position-relative"> <button + v-tooltip + :title="tooltipTitle" + :class="{ + 'is-active': isActive + }" type="button" - class="multi-file-commit-list-path" + class="multi-file-commit-list-path w-100 border-0 ml-0 mr-0" @dblclick="fileAction" @click="openFileInEditor" > - <span class="multi-file-commit-list-file-path"> + <span class="multi-file-commit-list-file-path d-flex align-items-center"> <icon :name="iconName" :size="16" :css-classes="iconClass" - />{{ file.path }} + />{{ file.name }} </span> </button> <component :is="actionComponent" :path="file.path" + class="d-flex position-absolute" /> </div> </template> diff --git a/app/assets/javascripts/ide/components/commit_sidebar/stage_button.vue b/app/assets/javascripts/ide/components/commit_sidebar/stage_button.vue index a786ec80ac2..7014b9f605e 100644 --- a/app/assets/javascripts/ide/components/commit_sidebar/stage_button.vue +++ b/app/assets/javascripts/ide/components/commit_sidebar/stage_button.vue @@ -25,15 +25,17 @@ export default { <template> <div v-once - class="multi-file-discard-btn" + class="multi-file-discard-btn dropdown" > <button v-tooltip :aria-label="__('Stage changes')" :title="__('Stage changes')" type="button" - class="btn btn-blank append-right-5" + class="btn btn-blank append-right-5 d-flex align-items-center" data-container="body" + data-boundary="viewport" + data-placement="bottom" @click.stop="stageChange(path)" > <icon @@ -43,17 +45,31 @@ export default { </button> <button v-tooltip - :aria-label="__('Discard changes')" - :title="__('Discard changes')" + :title="__('More actions')" type="button" - class="btn btn-blank" + class="btn btn-blank d-flex align-items-center" data-container="body" - @click.stop="discardFileChanges(path)" + data-boundary="viewport" + data-placement="bottom" + data-toggle="dropdown" + data-display="static" > <icon :size="12" - name="remove" + name="more" /> </button> + <div class="dropdown-menu dropdown-menu-right"> + <ul> + <li> + <button + type="button" + @click.stop="discardFileChanges(path)" + > + {{ __('Discard changes') }} + </button> + </li> + </ul> + </div> </div> </template> diff --git a/app/assets/javascripts/ide/components/commit_sidebar/unstage_button.vue b/app/assets/javascripts/ide/components/commit_sidebar/unstage_button.vue index 34b366f63ac..9cec73ec00e 100644 --- a/app/assets/javascripts/ide/components/commit_sidebar/unstage_button.vue +++ b/app/assets/javascripts/ide/components/commit_sidebar/unstage_button.vue @@ -32,8 +32,10 @@ export default { :aria-label="__('Unstage changes')" :title="__('Unstage changes')" type="button" - class="btn btn-blank" + class="btn btn-blank d-flex align-items-center" data-container="body" + data-boundary="viewport" + data-placement="bottom" @click="unstageChange(path)" > <icon diff --git a/app/assets/javascripts/ide/components/repo_commit_section.vue b/app/assets/javascripts/ide/components/repo_commit_section.vue index 01df0019fd4..c2c678ff0be 100644 --- a/app/assets/javascripts/ide/components/repo_commit_section.vue +++ b/app/assets/javascripts/ide/components/repo_commit_section.vue @@ -93,23 +93,25 @@ export default { :title="__('Unstaged')" :key-prefix="$options.stageKeys.unstaged" :file-list="changedFiles" - :action-btn-text="__('Stage all')" + :action-btn-text="__('Stage all changes')" :active-file-key="activeFileKey" - class="is-first" - icon-name="unstaged" action="stageAllChanges" + action-btn-icon="mobile-issue-close" item-action-component="stage-button" + class="is-first" + icon-name="unstaged" /> <commit-files-list :title="__('Staged')" :key-prefix="$options.stageKeys.staged" :file-list="stagedFiles" - :action-btn-text="__('Unstage all')" + :action-btn-text="__('Unstage all changes')" :staged-list="true" :active-file-key="activeFileKey" - icon-name="staged" action="unstageAllChanges" + action-btn-icon="history" item-action-component="unstage-button" + icon-name="staged" /> </template> <empty-state diff --git a/app/assets/javascripts/ide/lib/diff/diff_worker.js b/app/assets/javascripts/ide/lib/diff/diff_worker.js index e74c4046330..f09930e8158 100644 --- a/app/assets/javascripts/ide/lib/diff/diff_worker.js +++ b/app/assets/javascripts/ide/lib/diff/diff_worker.js @@ -1,8 +1,10 @@ import { computeDiff } from './diff'; +// eslint-disable-next-line no-restricted-globals self.addEventListener('message', (e) => { const data = e.data; + // eslint-disable-next-line no-restricted-globals self.postMessage({ path: data.path, changes: computeDiff(data.originalContent, data.newContent), diff --git a/app/assets/javascripts/ide/lib/editor_options.js b/app/assets/javascripts/ide/lib/editor_options.js index 9f895d49f2e..e35595ab1fd 100644 --- a/app/assets/javascripts/ide/lib/editor_options.js +++ b/app/assets/javascripts/ide/lib/editor_options.js @@ -12,5 +12,6 @@ export const defaultEditorOptions = { export default [ { readOnly: model => !!model.file.file_lock, + quickSuggestions: model => !(model.language === 'markdown'), }, ]; diff --git a/app/assets/javascripts/ide/services/index.js b/app/assets/javascripts/ide/services/index.js index e8b51f2b516..da9de25302a 100644 --- a/app/assets/javascripts/ide/services/index.js +++ b/app/assets/javascripts/ide/services/index.js @@ -9,7 +9,7 @@ export default { return Vue.http.get(endpoint, { params: { format: 'json' } }); }, getFileData(endpoint) { - return Vue.http.get(endpoint, { params: { format: 'json' } }); + return Vue.http.get(endpoint, { params: { format: 'json', viewer: 'none' } }); }, getRawFileData(file) { if (file.tempFile) { diff --git a/app/assets/javascripts/ide/stores/modules/commit/actions.js b/app/assets/javascripts/ide/stores/modules/commit/actions.js index 0a0db4033c8..7219abc4185 100644 --- a/app/assets/javascripts/ide/stores/modules/commit/actions.js +++ b/app/assets/javascripts/ide/stores/modules/commit/actions.js @@ -49,31 +49,6 @@ export const setLastCommitMessage = ({ rootState, commit }, data) => { commit(rootTypes.SET_LAST_COMMIT_MSG, commitMsg, { root: true }); }; -export const checkCommitStatus = ({ rootState }) => - service - .getBranchData(rootState.currentProjectId, rootState.currentBranchId) - .then(({ data }) => { - const { id } = data.commit; - const selectedBranch = - rootState.projects[rootState.currentProjectId].branches[rootState.currentBranchId]; - - if (selectedBranch.workingReference !== id) { - return true; - } - - return false; - }) - .catch(() => - flash( - __('Error checking branch data. Please try again.'), - 'alert', - document, - null, - false, - true, - ), - ); - export const updateFilesAfterCommit = ({ commit, dispatch, rootState }, { data }) => { const selectedProject = rootState.projects[rootState.currentProjectId]; const lastCommit = { @@ -128,24 +103,17 @@ export const updateFilesAfterCommit = ({ commit, dispatch, rootState }, { data } export const commitChanges = ({ commit, state, getters, dispatch, rootState, rootGetters }) => { const newBranch = state.commitAction !== consts.COMMIT_TO_CURRENT_BRANCH; - const payload = createCommitPayload(getters.branchName, newBranch, state, rootState); - const getCommitStatus = newBranch ? Promise.resolve(false) : dispatch('checkCommitStatus'); + const payload = createCommitPayload({ + branch: getters.branchName, + newBranch, + state, + rootState, + }); commit(types.UPDATE_LOADING, true); - return getCommitStatus - .then( - branchChanged => - new Promise(resolve => { - if (branchChanged) { - // show the modal with a Bootstrap call - $('#ide-create-branch-modal').modal('show'); - } else { - resolve(); - } - }), - ) - .then(() => service.commit(rootState.currentProjectId, payload)) + return service + .commit(rootState.currentProjectId, payload) .then(({ data }) => { commit(types.UPDATE_LOADING, false); @@ -220,12 +188,16 @@ export const commitChanges = ({ commit, state, getters, dispatch, rootState, roo ); }) .catch(err => { - let errMsg = __('Error committing changes. Please try again.'); - if (err.response.data && err.response.data.message) { - errMsg += ` (${stripHtml(err.response.data.message)})`; + if (err.response.status === 400) { + $('#ide-create-branch-modal').modal('show'); + } else { + let errMsg = __('Error committing changes. Please try again.'); + if (err.response.data && err.response.data.message) { + errMsg += ` (${stripHtml(err.response.data.message)})`; + } + flash(errMsg, 'alert', document, null, false, true); + window.dispatchEvent(new Event('resize')); } - flash(errMsg, 'alert', document, null, false, true); - window.dispatchEvent(new Event('resize')); commit(types.UPDATE_LOADING, false); }); diff --git a/app/assets/javascripts/ide/stores/mutations/file.js b/app/assets/javascripts/ide/stores/mutations/file.js index 5826f6cb828..46547820425 100644 --- a/app/assets/javascripts/ide/stores/mutations/file.js +++ b/app/assets/javascripts/ide/stores/mutations/file.js @@ -47,6 +47,7 @@ export default { baseRaw: null, html: data.html, size: data.size, + lastCommitSha: data.last_commit_sha, }); }, [types.SET_FILE_RAW_DATA](state, { file, raw }) { diff --git a/app/assets/javascripts/ide/stores/utils.js b/app/assets/javascripts/ide/stores/utils.js index a04a33cd12d..10368a4d97c 100644 --- a/app/assets/javascripts/ide/stores/utils.js +++ b/app/assets/javascripts/ide/stores/utils.js @@ -17,6 +17,7 @@ export const dataStructure = () => ({ changed: false, staged: false, lastCommitPath: '', + lastCommitSha: '', lastCommit: { id: '', url: '', @@ -104,7 +105,7 @@ export const setPageTitle = title => { document.title = title; }; -export const createCommitPayload = (branch, newBranch, state, rootState) => ({ +export const createCommitPayload = ({ branch, newBranch, state, rootState }) => ({ branch, commit_message: state.commitMessage, actions: rootState.stagedFiles.map(f => ({ @@ -112,6 +113,7 @@ export const createCommitPayload = (branch, newBranch, state, rootState) => ({ file_path: f.path, content: f.content, encoding: f.base64 ? 'base64' : 'text', + last_commit_id: newBranch ? undefined : f.lastCommitSha, })), start_branch: newBranch ? rootState.currentBranchId : undefined, }); diff --git a/app/assets/javascripts/ide/stores/workers/files_decorator_worker.js b/app/assets/javascripts/ide/stores/workers/files_decorator_worker.js index 0a1c253c637..fa35c215880 100644 --- a/app/assets/javascripts/ide/stores/workers/files_decorator_worker.js +++ b/app/assets/javascripts/ide/stores/workers/files_decorator_worker.js @@ -1,6 +1,7 @@ import { viewerInformationForPath } from '~/vue_shared/components/content_viewer/lib/viewer_utils'; import { decorateData, sortTree } from '../utils'; +// eslint-disable-next-line no-restricted-globals self.addEventListener('message', e => { const { data, projectId, branchId, tempFile = false, content = '', base64 = false } = e.data; @@ -89,6 +90,7 @@ self.addEventListener('message', e => { return acc; }, {}); + // eslint-disable-next-line no-restricted-globals self.postMessage({ entries, treeList: sortTree(treeList), diff --git a/app/assets/javascripts/issue_show/components/app.vue b/app/assets/javascripts/issue_show/components/app.vue index e87a8ed7fea..b6364318537 100644 --- a/app/assets/javascripts/issue_show/components/app.vue +++ b/app/assets/javascripts/issue_show/components/app.vue @@ -226,7 +226,7 @@ .then(res => res.data) .then(data => this.checkForSpam(data)) .then((data) => { - if (location.pathname !== data.web_url) { + if (window.location.pathname !== data.web_url) { visitUrl(data.web_url); } diff --git a/app/assets/javascripts/issue_show/components/edit_actions.vue b/app/assets/javascripts/issue_show/components/edit_actions.vue index 8cb0ab22bfb..597c6d69a81 100644 --- a/app/assets/javascripts/issue_show/components/edit_actions.vue +++ b/app/assets/javascripts/issue_show/components/edit_actions.vue @@ -38,7 +38,7 @@ }, deleteIssuable() { // eslint-disable-next-line no-alert - if (confirm('Issue will be removed! Are you sure?')) { + if (window.confirm('Issue will be removed! Are you sure?')) { this.deleteLoading = true; eventHub.$emit('delete.issuable'); diff --git a/app/assets/javascripts/issue_show/components/locked_warning.vue b/app/assets/javascripts/issue_show/components/locked_warning.vue index 1c2789f154a..ad0d40faf32 100644 --- a/app/assets/javascripts/issue_show/components/locked_warning.vue +++ b/app/assets/javascripts/issue_show/components/locked_warning.vue @@ -2,7 +2,7 @@ export default { computed: { currentPath() { - return location.pathname; + return window.location.pathname; }, }, }; diff --git a/app/assets/javascripts/lazy_loader.js b/app/assets/javascripts/lazy_loader.js index dbbf1637a47..9482d131344 100644 --- a/app/assets/javascripts/lazy_loader.js +++ b/app/assets/javascripts/lazy_loader.js @@ -44,8 +44,8 @@ export default class LazyLoader { requestAnimationFrame(() => this.checkElementsInView()); } checkElementsInView() { - const scrollTop = pageYOffset; - const visHeight = scrollTop + innerHeight + SCROLL_THRESHOLD; + const scrollTop = window.pageYOffset; + const visHeight = scrollTop + window.innerHeight + SCROLL_THRESHOLD; // Loading Images which are in the current viewport or close to them this.lazyImages = this.lazyImages.filter((selectedImage) => { diff --git a/app/assets/javascripts/lib/utils/bootstrap_linked_tabs.js b/app/assets/javascripts/lib/utils/bootstrap_linked_tabs.js index 3873f4528ce..c28ed04f94f 100644 --- a/app/assets/javascripts/lib/utils/bootstrap_linked_tabs.js +++ b/app/assets/javascripts/lib/utils/bootstrap_linked_tabs.js @@ -93,7 +93,7 @@ export default class LinkedTabs { const newState = `${copySource}${this.currentLocation.search}${this.currentLocation.hash}`; - history.replaceState({ + window.history.replaceState({ url: newState, }, document.title, newState); return newState; diff --git a/app/assets/javascripts/lib/utils/common_utils.js b/app/assets/javascripts/lib/utils/common_utils.js index d55d0585031..d0b0e5e1ba1 100644 --- a/app/assets/javascripts/lib/utils/common_utils.js +++ b/app/assets/javascripts/lib/utils/common_utils.js @@ -197,7 +197,10 @@ export const insertText = (target, text) => { // eslint-disable-next-line no-param-reassign target.value = newText; // eslint-disable-next-line no-param-reassign - target.selectionStart = target.selectionEnd = selectionStart + insertedText.length; + target.selectionStart = selectionStart + insertedText.length; + + // eslint-disable-next-line no-param-reassign + target.selectionEnd = selectionStart + insertedText.length; // Trigger autosave target.dispatchEvent(new Event('input')); diff --git a/app/assets/javascripts/lib/utils/number_utils.js b/app/assets/javascripts/lib/utils/number_utils.js index a02c79b787e..f086d962221 100644 --- a/app/assets/javascripts/lib/utils/number_utils.js +++ b/app/assets/javascripts/lib/utils/number_utils.js @@ -12,7 +12,7 @@ export function formatRelevantDigits(number) { let digitsLeft = ''; let relevantDigits = 0; let formattedNumber = ''; - if (!isNaN(Number(number))) { + if (!Number.isNaN(Number(number))) { digitsLeft = number.toString().split('.')[0]; switch (digitsLeft.length) { case 1: diff --git a/app/assets/javascripts/line_highlighter.js b/app/assets/javascripts/line_highlighter.js index f2323f57455..303c5d8a894 100644 --- a/app/assets/javascripts/line_highlighter.js +++ b/app/assets/javascripts/line_highlighter.js @@ -35,7 +35,7 @@ const LineHighlighter = function(options = {}) { options.highlightLineClass = options.highlightLineClass || 'hll'; options.fileHolderSelector = options.fileHolderSelector || '.file-holder'; options.scrollFileHolder = options.scrollFileHolder || false; - options.hash = options.hash || location.hash; + options.hash = options.hash || window.location.hash; this.options = options; this._hash = options.hash; @@ -145,6 +145,8 @@ LineHighlighter.prototype.highlightRange = function(range) { var i, lineNumber, ref, ref1, results; if (range[1]) { results = []; + + // eslint-disable-next-line no-multi-assign for (lineNumber = i = ref = range[0], ref1 = range[1]; ref <= ref1 ? i <= ref1 : i >= ref1; lineNumber = ref <= ref1 ? (i += 1) : (i -= 1)) { results.push(this.highlightLine(lineNumber)); } @@ -170,7 +172,7 @@ LineHighlighter.prototype.setHash = function(firstLineNumber, lastLineNumber) { // // This method is stubbed in tests. LineHighlighter.prototype.__setLocationHash__ = function(value) { - return history.pushState({ + return window.history.pushState({ url: value // We're using pushState instead of assigning location.hash directly to // prevent the page from scrolling on the hashchange event diff --git a/app/assets/javascripts/merge_conflicts/merge_conflicts_bundle.js b/app/assets/javascripts/merge_conflicts/merge_conflicts_bundle.js index 326d4523cce..491858c3602 100644 --- a/app/assets/javascripts/merge_conflicts/merge_conflicts_bundle.js +++ b/app/assets/javascripts/merge_conflicts/merge_conflicts_bundle.js @@ -1,13 +1,9 @@ -/* eslint-disable new-cap, comma-dangle, no-new */ - import $ from 'jquery'; import Vue from 'vue'; -import Flash from '../flash'; +import createFlash from '../flash'; import initIssuableSidebar from '../init_issuable_sidebar'; import './merge_conflict_store'; import MergeConflictsService from './merge_conflict_service'; -import './mixins/line_conflict_utils'; -import './mixins/line_conflict_actions'; import './components/diff_file_editor'; import './components/inline_conflict_lines'; import './components/parallel_conflict_lines'; @@ -19,7 +15,7 @@ export default function initMergeConflicts() { const mergeConflictsStore = gl.mergeConflicts.mergeConflictsStore; const mergeConflictsService = new MergeConflictsService({ conflictsPath: conflictsEl.dataset.conflictsPath, - resolveConflictsPath: conflictsEl.dataset.resolveConflictsPath + resolveConflictsPath: conflictsEl.dataset.resolveConflictsPath, }); initIssuableSidebar(); @@ -29,17 +25,26 @@ export default function initMergeConflicts() { components: { 'diff-file-editor': gl.mergeConflicts.diffFileEditor, 'inline-conflict-lines': gl.mergeConflicts.inlineConflictLines, - 'parallel-conflict-lines': gl.mergeConflicts.parallelConflictLines + 'parallel-conflict-lines': gl.mergeConflicts.parallelConflictLines, }, data: mergeConflictsStore.state, computed: { - conflictsCountText() { return mergeConflictsStore.getConflictsCountText(); }, - readyToCommit() { return mergeConflictsStore.isReadyToCommit(); }, - commitButtonText() { return mergeConflictsStore.getCommitButtonText(); }, - showDiffViewTypeSwitcher() { return mergeConflictsStore.fileTextTypePresent(); } + conflictsCountText() { + return mergeConflictsStore.getConflictsCountText(); + }, + readyToCommit() { + return mergeConflictsStore.isReadyToCommit(); + }, + commitButtonText() { + return mergeConflictsStore.getCommitButtonText(); + }, + showDiffViewTypeSwitcher() { + return mergeConflictsStore.fileTextTypePresent(); + }, }, created() { - mergeConflictsService.fetchConflictsData() + mergeConflictsService + .fetchConflictsData() .then(({ data }) => { if (data.type === 'error') { mergeConflictsStore.setFailedRequest(data.message); @@ -87,9 +92,9 @@ export default function initMergeConflicts() { }) .catch(() => { mergeConflictsStore.setSubmitState(false); - new Flash('Failed to save merge conflicts resolutions. Please try again!'); + createFlash('Failed to save merge conflicts resolutions. Please try again!'); }); - } - } + }, + }, }); } diff --git a/app/assets/javascripts/milestone.js b/app/assets/javascripts/milestone.js index 325fa570f37..6da04020881 100644 --- a/app/assets/javascripts/milestone.js +++ b/app/assets/javascripts/milestone.js @@ -18,13 +18,13 @@ export default class Milestone { return $('a[data-toggle="tab"]').on('show.bs.tab', (e) => { const $target = $(e.target); - location.hash = $target.attr('href'); + window.location.hash = $target.attr('href'); this.loadTab($target); }); } // eslint-disable-next-line class-methods-use-this loadInitialTab() { - const $target = $(`.js-milestone-tabs a[href="${location.hash}"]`); + const $target = $(`.js-milestone-tabs a[href="${window.location.hash}"]`); if ($target.length) { $target.tab('show'); diff --git a/app/assets/javascripts/monitoring/components/dashboard.vue b/app/assets/javascripts/monitoring/components/dashboard.vue index 21934021852..e1c8b6a6d4a 100644 --- a/app/assets/javascripts/monitoring/components/dashboard.vue +++ b/app/assets/javascripts/monitoring/components/dashboard.vue @@ -139,7 +139,7 @@ export default { this.updateAspectRatio = true; }, toggleAspectRatio() { - this.updatedAspectRatios = this.updatedAspectRatios += 1; + this.updatedAspectRatios += 1; if (this.store.getMetricsCount() === this.updatedAspectRatios) { this.updateAspectRatio = !this.updateAspectRatio; this.updatedAspectRatios = 0; diff --git a/app/assets/javascripts/monitoring/components/graph.vue b/app/assets/javascripts/monitoring/components/graph.vue index 20400154100..e5680a0499f 100644 --- a/app/assets/javascripts/monitoring/components/graph.vue +++ b/app/assets/javascripts/monitoring/components/graph.vue @@ -154,7 +154,7 @@ export default { point.x = e.clientX; point.y = e.clientY; point = point.matrixTransform(this.$refs.graphData.getScreenCTM().inverse()); - point.x = point.x += 7; + point.x += 7; const firstTimeSeries = this.timeSeries[0]; const timeValueOverlay = firstTimeSeries.timeSeriesScaleX.invert(point.x); const overlayIndex = bisectDate(firstTimeSeries.values, timeValueOverlay, 1); diff --git a/app/assets/javascripts/monitoring/components/graph/flag.vue b/app/assets/javascripts/monitoring/components/graph/flag.vue index 282c5c24384..92fe98508ad 100644 --- a/app/assets/javascripts/monitoring/components/graph/flag.vue +++ b/app/assets/javascripts/monitoring/components/graph/flag.vue @@ -97,7 +97,7 @@ export default { ? this.deploymentFlagData.seriesIndex : indexFromCoordinates; const value = series.values[index] && series.values[index].value; - if (isNaN(value)) { + if (Number.isNaN(value)) { return '-'; } return `${formatRelevantDigits(value)}${this.unitOfDisplay}`; diff --git a/app/assets/javascripts/monitoring/utils/multiple_time_series.js b/app/assets/javascripts/monitoring/utils/multiple_time_series.js index 4d3f1f1a7cc..ed3a27dd68b 100644 --- a/app/assets/javascripts/monitoring/utils/multiple_time_series.js +++ b/app/assets/javascripts/monitoring/utils/multiple_time_series.js @@ -73,7 +73,7 @@ function queryTimeSeries(query, graphWidth, graphHeight, graphHeightOffset, xDom timeSeriesScaleX.ticks(d3.timeMinute, 60); timeSeriesScaleY.domain(yDom); - const defined = d => !isNaN(d.value) && d.value != null; + const defined = d => !Number.isNaN(d.value) && d.value != null; const lineFunction = d3 .line() diff --git a/app/assets/javascripts/network/branch_graph.js b/app/assets/javascripts/network/branch_graph.js index bd007c707f2..e4096ddb00d 100644 --- a/app/assets/javascripts/network/branch_graph.js +++ b/app/assets/javascripts/network/branch_graph.js @@ -112,6 +112,8 @@ export default (function() { fill: "#444" }); ref = this.days; + + // eslint-disable-next-line no-multi-assign for (mm = j = 0, len = ref.length; j < len; mm = (j += 1)) { day = ref[mm]; if (cuday !== day[0] || cumonth !== day[1]) { @@ -285,6 +287,8 @@ export default (function() { r = this.r; ref = commit.parents; results = []; + + // eslint-disable-next-line no-multi-assign for (i = j = 0, len = ref.length; j < len; i = (j += 1)) { parent = ref[i]; parentCommit = this.preparedCommits[parent[0]]; diff --git a/app/assets/javascripts/notes.js b/app/assets/javascripts/notes.js index 55f1d0b496c..27c5dedcf0b 100644 --- a/app/assets/javascripts/notes.js +++ b/app/assets/javascripts/notes.js @@ -315,7 +315,7 @@ export default class Notes { if (discussionNoteForm.length) { if ($textarea.val() !== '') { if ( - !confirm('Are you sure you want to cancel creating this comment?') + !window.confirm('Are you sure you want to cancel creating this comment?') ) { return; } @@ -329,7 +329,7 @@ export default class Notes { newText = $textarea.val(); if (originalText !== newText) { if ( - !confirm('Are you sure you want to cancel editing this comment?') + !window.confirm('Are you sure you want to cancel editing this comment?') ) { return; } diff --git a/app/assets/javascripts/notes/components/noteable_discussion.vue b/app/assets/javascripts/notes/components/noteable_discussion.vue index f9f5041a9f9..3f865431155 100644 --- a/app/assets/javascripts/notes/components/noteable_discussion.vue +++ b/app/assets/javascripts/notes/components/noteable_discussion.vue @@ -152,7 +152,7 @@ export default { const msg = 'Are you sure you want to cancel creating this comment?'; // eslint-disable-next-line no-alert - if (!confirm(msg)) { + if (!window.confirm(msg)) { return; } } diff --git a/app/assets/javascripts/notes/components/noteable_note.vue b/app/assets/javascripts/notes/components/noteable_note.vue index ec3ee407f0a..713f93456b1 100644 --- a/app/assets/javascripts/notes/components/noteable_note.vue +++ b/app/assets/javascripts/notes/components/noteable_note.vue @@ -77,7 +77,7 @@ export default { }, deleteHandler() { // eslint-disable-next-line no-alert - if (confirm('Are you sure you want to delete this comment?')) { + if (window.confirm('Are you sure you want to delete this comment?')) { this.isDeleting = true; this.deleteNote(this.note) @@ -129,7 +129,7 @@ export default { formCancelHandler(shouldConfirm, isDirty) { if (shouldConfirm && isDirty) { // eslint-disable-next-line no-alert - if (!confirm('Are you sure you want to cancel editing this comment?')) + if (!window.confirm('Are you sure you want to cancel editing this comment?')) return; } this.$refs.noteBody.resetAutoSave(); diff --git a/app/assets/javascripts/pages/projects/graphs/show/stat_graph_contributors.js b/app/assets/javascripts/pages/projects/graphs/show/stat_graph_contributors.js index 653e2502d01..37336a8cb69 100644 --- a/app/assets/javascripts/pages/projects/graphs/show/stat_graph_contributors.js +++ b/app/assets/javascripts/pages/projects/graphs/show/stat_graph_contributors.js @@ -36,7 +36,9 @@ export default (function() { var author_graph, author_header; author_header = _this.create_author_header(d); $(".contributors-list").append(author_header); - _this.authors[d.author_name] = author_graph = new ContributorsAuthorGraph(d.dates); + + author_graph = new ContributorsAuthorGraph(d.dates); + _this.authors[d.author_name] = author_graph; return author_graph.draw(); }; })(this)); diff --git a/app/assets/javascripts/pages/projects/graphs/show/stat_graph_contributors_util.js b/app/assets/javascripts/pages/projects/graphs/show/stat_graph_contributors_util.js index 77135ad1f0e..165446a4db6 100644 --- a/app/assets/javascripts/pages/projects/graphs/show/stat_graph_contributors_util.js +++ b/app/assets/javascripts/pages/projects/graphs/show/stat_graph_contributors_util.js @@ -111,10 +111,15 @@ export default { parse_log_entry: function(log_entry, field, date_range) { var parsed_entry; parsed_entry = {}; + parsed_entry.author_name = log_entry.author_name; parsed_entry.author_email = log_entry.author_email; parsed_entry.dates = {}; - parsed_entry.commits = parsed_entry.additions = parsed_entry.deletions = 0; + + parsed_entry.commits = 0; + parsed_entry.additions = 0; + parsed_entry.deletions = 0; + _.each(_.omit(log_entry, 'author_name', 'author_email'), (function(_this) { return function(value, key) { if (_this.in_range(value.date, date_range)) { diff --git a/app/assets/javascripts/pages/users/user_tabs.js b/app/assets/javascripts/pages/users/user_tabs.js index f88a6b27c18..a2ca03536f2 100644 --- a/app/assets/javascripts/pages/users/user_tabs.js +++ b/app/assets/javascripts/pages/users/user_tabs.js @@ -187,7 +187,7 @@ export default class UserTabs { let newState = source; newState = newState.replace(/\/+$/, ''); newState += this.windowLocation.search + this.windowLocation.hash; - history.replaceState( + window.history.replaceState( { url: newState, }, diff --git a/app/assets/javascripts/pipelines/components/graph/action_component.vue b/app/assets/javascripts/pipelines/components/graph/action_component.vue index db0505a55fe..1f152ed438d 100644 --- a/app/assets/javascripts/pipelines/components/graph/action_component.vue +++ b/app/assets/javascripts/pipelines/components/graph/action_component.vue @@ -91,6 +91,7 @@ export default { class="js-ci-action btn btn-blank btn-transparent ci-action-icon-container ci-action-icon-wrapper" data-container="body" + data-boundary="viewport" @click="onClickAction" > <icon :name="actionIcon"/> diff --git a/app/assets/javascripts/pipelines/components/graph/dropdown_job_component.vue b/app/assets/javascripts/pipelines/components/graph/dropdown_job_component.vue index 04120d45834..e047d10ac93 100644 --- a/app/assets/javascripts/pipelines/components/graph/dropdown_job_component.vue +++ b/app/assets/javascripts/pipelines/components/graph/dropdown_job_component.vue @@ -87,6 +87,7 @@ export default { data-toggle="dropdown" data-container="body" data-boundary="viewport" + data-display="static" class="dropdown-menu-toggle build-content" > diff --git a/app/assets/javascripts/pipelines/components/stage.vue b/app/assets/javascripts/pipelines/components/stage.vue index 4dd2fb9fbed..b9231c002fd 100644 --- a/app/assets/javascripts/pipelines/components/stage.vue +++ b/app/assets/javascripts/pipelines/components/stage.vue @@ -165,6 +165,7 @@ export default { class="mini-pipeline-graph-dropdown-toggle js-builds-dropdown-button" data-placement="top" data-toggle="dropdown" + data-display="static" type="button" aria-haspopup="true" aria-expanded="false" diff --git a/app/assets/javascripts/profile/gl_crop.js b/app/assets/javascripts/profile/gl_crop.js index 8f93156cdd1..ba120c4bbdf 100644 --- a/app/assets/javascripts/profile/gl_crop.js +++ b/app/assets/javascripts/profile/gl_crop.js @@ -139,6 +139,8 @@ import _ from 'underscore'; var array, binary, i, k, len, v; binary = atob(dataURL.split(',')[1]); array = []; + + // eslint-disable-next-line no-multi-assign for (k = i = 0, len = binary.length; i < len; k = (i += 1)) { v = binary[k]; array.push(binary.charCodeAt(k)); diff --git a/app/assets/javascripts/project_find_file.js b/app/assets/javascripts/project_find_file.js index 4c4acd487f8..17497283695 100644 --- a/app/assets/javascripts/project_find_file.js +++ b/app/assets/javascripts/project_find_file.js @@ -91,6 +91,8 @@ export default class ProjectFindFile { var blobItemUrl, filePath, html, i, j, len, matches, results; this.element.find(".tree-table > tbody").empty(); results = []; + + // eslint-disable-next-line no-multi-assign for (i = j = 0, len = filePaths.length; j < len; i = (j += 1)) { filePath = filePaths[i]; if (i === 20) { @@ -150,7 +152,7 @@ export default class ProjectFindFile { } goToTree() { - return location.href = this.options.treeUrl; + return window.location.href = this.options.treeUrl; } goToBlob() { diff --git a/app/assets/javascripts/project_import.js b/app/assets/javascripts/project_import.js index d2d26d6f67e..5a0d2b642eb 100644 --- a/app/assets/javascripts/project_import.js +++ b/app/assets/javascripts/project_import.js @@ -2,7 +2,7 @@ import { visitUrl } from './lib/utils/url_utility'; export default function projectImport() { setTimeout(() => { - visitUrl(location.href); + visitUrl(window.location.href); }, 5000); } diff --git a/app/assets/javascripts/prometheus_metrics/prometheus_metrics.js b/app/assets/javascripts/prometheus_metrics/prometheus_metrics.js index 1a75fdd75db..078ccbbbac2 100644 --- a/app/assets/javascripts/prometheus_metrics/prometheus_metrics.js +++ b/app/assets/javascripts/prometheus_metrics/prometheus_metrics.js @@ -107,7 +107,7 @@ export default class PrometheusMetrics { if (data && data.success) { stop(data); } else { - this.backOffRequestCounter = this.backOffRequestCounter += 1; + this.backOffRequestCounter += 1; if (this.backOffRequestCounter < 3) { next(); } else { diff --git a/app/assets/javascripts/search_autocomplete.js b/app/assets/javascripts/search_autocomplete.js index 2da022fde63..ef3c71eeafe 100644 --- a/app/assets/javascripts/search_autocomplete.js +++ b/app/assets/javascripts/search_autocomplete.js @@ -438,7 +438,7 @@ export default class SearchAutocomplete { } onClick(item, $el, e) { - if (location.pathname.indexOf(item.url) !== -1) { + if (window.location.pathname.indexOf(item.url) !== -1) { if (!e.metaKey) e.preventDefault(); if (!this.badgePresent) { if (item.category === 'Projects') { diff --git a/app/assets/javascripts/settings_panels.js b/app/assets/javascripts/settings_panels.js index eecde4550f9..37b4a2a4c63 100644 --- a/app/assets/javascripts/settings_panels.js +++ b/app/assets/javascripts/settings_panels.js @@ -42,8 +42,8 @@ export default function initSettingsPanels() { } }); - if (location.hash) { - const $target = $(location.hash); + if (window.location.hash) { + const $target = $(window.location.hash); if ($target.length && $target.hasClass('settings')) { expandSection($target); } diff --git a/app/assets/javascripts/shortcuts_find_file.js b/app/assets/javascripts/shortcuts_find_file.js index 1e246a56b85..8658081c6c2 100644 --- a/app/assets/javascripts/shortcuts_find_file.js +++ b/app/assets/javascripts/shortcuts_find_file.js @@ -13,8 +13,8 @@ export default class ShortcutsFindFile extends ShortcutsNavigation { element === this.projectFindFile.inputElement[0] && (combo === 'up' || combo === 'down' || combo === 'esc' || combo === 'enter') ) { - // when press up/down key in textbox, cusor prevent to move to home/end - event.preventDefault(); + // when press up/down key in textbox, cursor prevent to move to home/end + e.preventDefault(); return false; } diff --git a/app/assets/javascripts/sidebar/components/confidential/confidential_issue_sidebar.vue b/app/assets/javascripts/sidebar/components/confidential/confidential_issue_sidebar.vue index 1b866cca4b1..2b8d6207dea 100644 --- a/app/assets/javascripts/sidebar/components/confidential/confidential_issue_sidebar.vue +++ b/app/assets/javascripts/sidebar/components/confidential/confidential_issue_sidebar.vue @@ -54,7 +54,7 @@ export default { updateConfidentialAttribute(confidential) { this.service .update('issue', { confidential }) - .then(() => location.reload()) + .then(() => window.location.reload()) .catch(() => { Flash( __( diff --git a/app/assets/javascripts/sidebar/components/lock/lock_issue_sidebar.vue b/app/assets/javascripts/sidebar/components/lock/lock_issue_sidebar.vue index 10bedf8af1f..8bbc59f623a 100644 --- a/app/assets/javascripts/sidebar/components/lock/lock_issue_sidebar.vue +++ b/app/assets/javascripts/sidebar/components/lock/lock_issue_sidebar.vue @@ -76,7 +76,7 @@ export default { .update(this.issuableType, { discussion_locked: locked, }) - .then(() => location.reload()) + .then(() => window.location.reload()) .catch(() => Flash( this.__( diff --git a/app/assets/javascripts/sidebar/sidebar_mediator.js b/app/assets/javascripts/sidebar/sidebar_mediator.js index d86557e870a..d9ca5e46770 100644 --- a/app/assets/javascripts/sidebar/sidebar_mediator.js +++ b/app/assets/javascripts/sidebar/sidebar_mediator.js @@ -80,7 +80,7 @@ export default class SidebarMediator { return this.service.moveIssue(this.store.moveToProjectId) .then(response => response.json()) .then((data) => { - if (location.pathname !== data.web_url) { + if (window.location.pathname !== data.web_url) { visitUrl(data.web_url); } }); diff --git a/app/assets/javascripts/snippet/snippet_embed.js b/app/assets/javascripts/snippet/snippet_embed.js index 81ec483f2d9..873a506a92f 100644 --- a/app/assets/javascripts/snippet/snippet_embed.js +++ b/app/assets/javascripts/snippet/snippet_embed.js @@ -1,5 +1,5 @@ export default () => { - const { protocol, host, pathname } = location; + const { protocol, host, pathname } = window.location; const shareBtn = document.querySelector('.js-share-btn'); const embedBtn = document.querySelector('.js-embed-btn'); const snippetUrlArea = document.querySelector('.js-snippet-url-area'); diff --git a/app/assets/javascripts/users_select.js b/app/assets/javascripts/users_select.js index cd954f75613..349614460e1 100644 --- a/app/assets/javascripts/users_select.js +++ b/app/assets/javascripts/users_select.js @@ -259,6 +259,7 @@ function UsersSelect(currentUser, els, options = {}) { showDivider = 0; if (firstUser) { // Move current user to the front of the list + // eslint-disable-next-line no-multi-assign for (index = j = 0, len = users.length; j < len; index = (j += 1)) { obj = users[index]; if (obj.username === firstUser) { @@ -561,6 +562,8 @@ function UsersSelect(currentUser, els, options = {}) { if (firstUser) { // Move current user to the front of the list ref = data.results; + + // eslint-disable-next-line no-multi-assign for (index = j = 0, len = ref.length; j < len; index = (j += 1)) { obj = ref[index]; if (obj.username === firstUser) { diff --git a/app/assets/javascripts/vue_merge_request_widget/components/memory_usage.vue b/app/assets/javascripts/vue_merge_request_widget/components/memory_usage.vue index f012f9c6772..5e76f6b1cac 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/memory_usage.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/memory_usage.vue @@ -105,7 +105,7 @@ export default { MRWidgetService.fetchMetrics(this.metricsUrl) .then((res) => { if (res.status === statusCodes.NO_CONTENT) { - this.backOffRequestCounter = this.backOffRequestCounter += 1; + this.backOffRequestCounter += 1; /* eslint-disable no-unused-expressions */ this.backOffRequestCounter < 3 ? next() : stop(res); } else { diff --git a/app/assets/stylesheets/bootstrap_migration.scss b/app/assets/stylesheets/bootstrap_migration.scss index 5da0e672288..d92b6f9fe09 100644 --- a/app/assets/stylesheets/bootstrap_migration.scss +++ b/app/assets/stylesheets/bootstrap_migration.scss @@ -128,11 +128,6 @@ table { border-spacing: 0; } -.tooltip { - // Fix bootstrap4 bug whereby tooltips flicker when they are hovered over their borders - pointer-events: none; -} - .popover { font-size: 14px; } @@ -264,15 +259,36 @@ pre code { white-space: pre-wrap; } +.alert, +.flash-notice { + border-radius: 0; +} + +.alert-success { + background-color: $green-500; + border-color: $green-500; +} + +.alert-info { + background-color: $blue-500; + border-color: $blue-500; +} + +.alert-warning { + background-color: $orange-500; + border-color: $orange-500; +} + .alert-danger { background-color: $red-500; border-color: $red-500; } +.alert-success, +.alert-info, .alert-warning, .alert-danger, .flash-notice { - border-radius: 0; color: $white-light; h4, diff --git a/app/assets/stylesheets/framework/layout.scss b/app/assets/stylesheets/framework/layout.scss index 55c0bc76f23..52b5f059f20 100644 --- a/app/assets/stylesheets/framework/layout.scss +++ b/app/assets/stylesheets/framework/layout.scss @@ -54,10 +54,6 @@ body { &.limit-container-width { max-width: $limited-layout-width; } - - &.limit-container-width-sm { - max-width: $limited-layout-width-sm; - } } .alert-wrapper { diff --git a/app/assets/stylesheets/framework/secondary_navigation_elements.scss b/app/assets/stylesheets/framework/secondary_navigation_elements.scss index 2d9e9e6a67d..9dbb04e5443 100644 --- a/app/assets/stylesheets/framework/secondary_navigation_elements.scss +++ b/app/assets/stylesheets/framework/secondary_navigation_elements.scss @@ -347,7 +347,7 @@ .empty-state .project-item-select-holder.btn-group { float: none; - display: inline-block; + justify-content: center; .btn { // overrides styles applied to plain `.empty-state .btn` diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss index 04d2a049f7d..f30f296d41f 100644 --- a/app/assets/stylesheets/framework/variables.scss +++ b/app/assets/stylesheets/framework/variables.scss @@ -244,10 +244,11 @@ $tooltip-font-size: 12px; /* * Padding */ -$gl-padding-24: 24px; -$gl-padding: 16px; -$gl-padding-8: 8px; $gl-padding-4: 4px; +$gl-padding-8: 8px; +$gl-padding: 16px; +$gl-padding-24: 24px; +$gl-padding-32: 32px; $gl-col-padding: 15px; $gl-input-padding: 10px; $gl-vert-padding: 6px; @@ -265,7 +266,6 @@ $header-height: 40px; $ide-statusbar-height: 25px; $fixed-layout-width: 1280px; $limited-layout-width: 990px; -$limited-layout-width-sm: 790px; $container-text-max-width: 540px; $gl-avatar-size: 40px; $error-exclamation-point: $red-500; @@ -834,3 +834,4 @@ $font-family-sans-serif: $regular_font; $font-family-monospace: $monospace_font; $input-line-height: 20px; $btn-line-height: 20px; +$table-accent-bg: $gray-light; diff --git a/app/assets/stylesheets/pages/commits.scss b/app/assets/stylesheets/pages/commits.scss index a4ca82de90e..dc8842212e0 100644 --- a/app/assets/stylesheets/pages/commits.scss +++ b/app/assets/stylesheets/pages/commits.scss @@ -193,6 +193,10 @@ display: inline-flex; } + .ci-status-icon svg { + vertical-align: text-bottom; + } + > .ci-status-link, > .btn, > .commit-sha-group { diff --git a/app/assets/stylesheets/pages/labels.scss b/app/assets/stylesheets/pages/labels.scss index 73eb399d7bb..79cac7f4ff0 100644 --- a/app/assets/stylesheets/pages/labels.scss +++ b/app/assets/stylesheets/pages/labels.scss @@ -280,7 +280,7 @@ width: 150px; flex-shrink: 0; - .label { + .badge { overflow: hidden; text-overflow: ellipsis; max-width: 100%; diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss index 4e1768f556a..52332ac97dd 100644 --- a/app/assets/stylesheets/pages/pipelines.scss +++ b/app/assets/stylesheets/pages/pipelines.scss @@ -1001,7 +1001,7 @@ button.mini-pipeline-graph-dropdown-toggle { /** * Center dropdown menu in mini graph */ - &.dropdown-menu { + .dropdown &.dropdown-menu { transform: translate(-80%, 0); @media (min-width: map-get($grid-breakpoints, md)) { diff --git a/app/assets/stylesheets/pages/profiles/preferences.scss b/app/assets/stylesheets/pages/profiles/preferences.scss index babe81cb0f7..a353f301d07 100644 --- a/app/assets/stylesheets/pages/profiles/preferences.scss +++ b/app/assets/stylesheets/pages/profiles/preferences.scss @@ -16,7 +16,7 @@ .application-theme { label { - margin: 0 $gl-padding $gl-padding 0; + margin: 0 $gl-padding-32 $gl-padding 0; text-align: center; } @@ -24,7 +24,7 @@ font-size: 0; height: 48px; border-radius: 4px; - min-width: 135px; + min-width: 112px; margin-bottom: $gl-padding-8; &.ui-indigo { @@ -75,7 +75,8 @@ .syntax-theme { label { - margin-right: 20px; + margin-right: $gl-padding-32; + margin-bottom: $gl-padding; text-align: center; .preview { @@ -84,7 +85,6 @@ img { border-radius: 4px; - max-width: 100%; } } diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss index 7ac0eaec645..aa83e5bdebc 100644 --- a/app/assets/stylesheets/pages/projects.scss +++ b/app/assets/stylesheets/pages/projects.scss @@ -858,7 +858,6 @@ pre.light-well { .git-clone-holder { width: 380px; - height: 28px; .btn-clipboard { border: 1px solid $border-color; diff --git a/app/assets/stylesheets/pages/repo.scss b/app/assets/stylesheets/pages/repo.scss index 4b8a3db1d06..0a56153203c 100644 --- a/app/assets/stylesheets/pages/repo.scss +++ b/app/assets/stylesheets/pages/repo.scss @@ -540,36 +540,12 @@ margin-right: -$grid-size; min-height: 60px; - .multi-file-commit-list-item { - margin-left: 0; - margin-right: 0; - } - &.form-text.text-muted { margin-left: 0; right: 0; } } -.multi-file-commit-list-item { - &.is-active { - background-color: $white-normal; - } - - .multi-file-discard-btn { - display: none; - margin-top: -2px; - margin-left: auto; - color: $gl-link-color; - } - - &:hover { - .multi-file-discard-btn { - display: flex; - } - } -} - .multi-file-addition, .multi-file-addition-solid { color: $green-500; @@ -599,7 +575,7 @@ } } -.multi-file-commit-list-item, +.multi-file-commit-list-path, .ide-file-list .file { display: flex; align-items: center; @@ -616,11 +592,9 @@ } .multi-file-commit-list-path { - padding: 0; - background: none; - border: 0; - text-align: left; - width: 100%; + &.is-active { + background-color: $white-normal; + } &:hover, &:focus { @@ -635,7 +609,7 @@ } .multi-file-commit-list-file-path { - @include str-truncated(100%); + @include str-truncated(calc(100% - 30px)); &:hover { text-decoration: underline; @@ -646,6 +620,16 @@ } } +.multi-file-discard-btn { + top: 4px; + right: 8px; + bottom: 4px; + + svg { + top: 0; + } +} + .multi-file-commit-form { position: relative; background-color: $white-light; @@ -840,18 +824,20 @@ } .ide-staged-action-btn { - margin-left: auto; - line-height: 22px; + width: 22px; + margin-left: -1px; + border-top-left-radius: 0; + border-bottom-left-radius: 0; + + > svg { + top: 0; + } } .ide-commit-file-count { min-width: 22px; - margin-left: auto; background-color: $gray-light; - border-radius: $border-radius-default; border: 1px solid $white-dark; - line-height: 20px; - text-align: center; } .ide-commit-radios { diff --git a/app/assets/stylesheets/pages/settings.scss b/app/assets/stylesheets/pages/settings.scss index 1f8e61257a9..4abb145067a 100644 --- a/app/assets/stylesheets/pages/settings.scss +++ b/app/assets/stylesheets/pages/settings.scss @@ -52,7 +52,7 @@ .settings-content { max-height: 1px; - overflow-y: scroll; + overflow-y: hidden; padding-right: 110px; animation: collapseMaxHeight 300ms ease-out; // Keep the section from expanding when we scroll over it diff --git a/app/controllers/concerns/internal_redirect.rb b/app/controllers/concerns/internal_redirect.rb index 7409b2e89a5..10b9852e329 100644 --- a/app/controllers/concerns/internal_redirect.rb +++ b/app/controllers/concerns/internal_redirect.rb @@ -23,6 +23,10 @@ module InternalRedirect nil end + def sanitize_redirect(url_or_path) + safe_redirect_path(url_or_path) || safe_redirect_path_for_url(url_or_path) + end + def host_allowed?(uri) uri.host == request.host && uri.port == request.port diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb index 0c1c286a0a4..7c65f1f5dfe 100644 --- a/app/controllers/projects/blob_controller.rb +++ b/app/controllers/projects/blob_controller.rb @@ -197,15 +197,14 @@ class Projects::BlobController < Projects::ApplicationController end def show_json - json = blob_json(@blob) - return render_404 unless json - + set_last_commit_sha path_segments = @path.split('/') path_segments.pop tree_path = path_segments.join('/') - render json: json.merge( + json = { id: @blob.id, + last_commit_sha: @last_commit_sha, path: blob.path, name: blob.name, extension: blob.extension, @@ -221,6 +220,10 @@ class Projects::BlobController < Projects::ApplicationController commits_path: project_commits_path(project, @id), tree_path: project_tree_path(project, File.join(@ref, tree_path)), permalink: project_blob_path(project, File.join(@commit.id, @path)) - ) + } + + json.merge!(blob_json(@blob) || {}) unless params[:viewer] == 'none' + + render json: json end end diff --git a/app/controllers/projects/milestones_controller.rb b/app/controllers/projects/milestones_controller.rb index 2494b56981d..f85dcfe6bfc 100644 --- a/app/controllers/projects/milestones_controller.rb +++ b/app/controllers/projects/milestones_controller.rb @@ -123,9 +123,9 @@ class Projects::MilestonesController < Projects::ApplicationController def search_params if request.format.json? && @project.group && can?(current_user, :read_group, @project.group) - groups = @project.group.self_and_ancestors + groups = @project.group.self_and_ancestors_ids end - params.permit(:state).merge(project_ids: @project.id, group_ids: groups&.select(:id)) + params.permit(:state).merge(project_ids: @project.id, group_ids: groups) end end diff --git a/app/graphql/resolvers/merge_request_resolver.rb b/app/graphql/resolvers/merge_request_resolver.rb index b1857ab09f7..9f2d348e95f 100644 --- a/app/graphql/resolvers/merge_request_resolver.rb +++ b/app/graphql/resolvers/merge_request_resolver.rb @@ -1,15 +1,14 @@ module Resolvers class MergeRequestResolver < BaseResolver - prepend FullPathResolver - - type Types::ProjectType, null: true - argument :iid, GraphQL::ID_TYPE, required: true, description: 'The IID of the merge request, e.g., "1"' - def resolve(full_path:, iid:) - project = model_by_full_path(Project, full_path) + type Types::MergeRequestType, null: true + + alias_method :project, :object + + def resolve(iid:) return unless project.present? BatchLoader.for(iid.to_s).batch(key: project.id) do |iids, loader| diff --git a/app/graphql/types/project_type.rb b/app/graphql/types/project_type.rb index 9e885d5845a..d9058ae7431 100644 --- a/app/graphql/types/project_type.rb +++ b/app/graphql/types/project_type.rb @@ -61,5 +61,12 @@ module Types field :request_access_enabled, GraphQL::BOOLEAN_TYPE, null: true field :only_allow_merge_if_all_discussions_are_resolved, GraphQL::BOOLEAN_TYPE, null: true field :printing_merge_request_link_enabled, GraphQL::BOOLEAN_TYPE, null: true + + field :merge_request, + Types::MergeRequestType, + null: true, + resolver: Resolvers::MergeRequestResolver do + authorize :read_merge_request + end end end diff --git a/app/graphql/types/query_type.rb b/app/graphql/types/query_type.rb index be79c78bf67..010ec2d7942 100644 --- a/app/graphql/types/query_type.rb +++ b/app/graphql/types/query_type.rb @@ -9,13 +9,6 @@ module Types authorize :read_project end - field :merge_request, Types::MergeRequestType, - null: true, - resolver: Resolvers::MergeRequestResolver, - description: "Find a merge request" do - authorize :read_merge_request - end - field :echo, GraphQL::STRING_TYPE, null: false, function: Functions::Echo.new end end diff --git a/app/services/ci/register_job_service.rb b/app/services/ci/register_job_service.rb index 925775aea0b..9bdbb2c0d99 100644 --- a/app/services/ci/register_job_service.rb +++ b/app/services/ci/register_job_service.rb @@ -25,14 +25,12 @@ module Ci valid = true - if Feature.enabled?('ci_job_request_with_tags_matcher') - # pick builds that does not have other tags than runner's one - builds = builds.matches_tag_ids(runner.tags.ids) + # pick builds that does not have other tags than runner's one + builds = builds.matches_tag_ids(runner.tags.ids) - # pick builds that have at least one tag - unless runner.run_untagged? - builds = builds.with_any_tags - end + # pick builds that have at least one tag + unless runner.run_untagged? + builds = builds.with_any_tags end builds.find do |build| diff --git a/app/uploaders/favicon_uploader.rb b/app/uploaders/favicon_uploader.rb index 09afc63a5aa..3639375d474 100644 --- a/app/uploaders/favicon_uploader.rb +++ b/app/uploaders/favicon_uploader.rb @@ -1,17 +1,6 @@ class FaviconUploader < AttachmentUploader EXTENSION_WHITELIST = %w[png ico].freeze - include CarrierWave::MiniMagick - - version :favicon_main do - process resize_to_fill: [32, 32] - process convert: 'png' - - def full_filename(filename) - filename_for_different_format(super(filename), 'png') - end - end - def extension_whitelist EXTENSION_WHITELIST end diff --git a/app/views/admin/appearances/_form.html.haml b/app/views/admin/appearances/_form.html.haml index 94db374040c..a0861870ba4 100644 --- a/app/views/admin/appearances/_form.html.haml +++ b/app/views/admin/appearances/_form.html.haml @@ -25,7 +25,7 @@ = f.label :favicon, 'Favicon', class: 'col-sm-2 col-form-label' .col-sm-10 - if @appearance.favicon? - = image_tag @appearance.favicon.favicon_main.url, class: 'appearance-light-logo-preview' + = image_tag @appearance.favicon_url, class: 'appearance-light-logo-preview' - if @appearance.persisted? %br = link_to 'Remove favicon', favicon_admin_appearances_path, data: { confirm: "Favicon will be removed. Are you sure?"}, method: :delete, class: "btn btn-inverted btn-remove btn-sm remove-logo" @@ -33,9 +33,9 @@ = f.hidden_field :favicon_cache = f.file_field :favicon, class: '' .hint - Maximum file size is 1MB. Allowed image formats are #{favicon_extension_whitelist}. + Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are #{favicon_extension_whitelist}. %br - The resulting favicons will be cropped to be square and scaled down to a size of 32x32 px. + Images with incorrect dimensions are not resized automatically, and may result in unexpected behavior. %fieldset.sign-in %legend diff --git a/app/views/explore/projects/_filter.html.haml b/app/views/explore/projects/_filter.html.haml index 845f4046d0d..6abb56ba6d2 100644 --- a/app/views/explore/projects/_filter.html.haml +++ b/app/views/explore/projects/_filter.html.haml @@ -1,6 +1,6 @@ - if current_user .dropdown - %button.dropdown-toggle{ href: '#', "data-toggle" => "dropdown" } + %button.dropdown-toggle{ href: '#', "data-toggle" => "dropdown", 'data-display' => 'static' } = icon('globe') %span.light Visibility: - if params[:visibility_level].present? diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml index 8b0ef3cd87a..5a88619f769 100644 --- a/app/views/groups/show.html.haml +++ b/app/views/groups/show.html.haml @@ -18,7 +18,7 @@ - if can_create_subgroups .btn-group.new-project-subgroup.droplab-dropdown.js-new-project-subgroup{ data: { project_path: new_project_path(namespace_id: @group.id), subgroup_path: new_group_path(parent_id: @group.id) } } %input.btn.btn-success.dropdown-primary.js-new-group-child{ type: "button", value: new_project_label, data: { action: "new-project" } } - %button.btn.btn-success.dropdown-toggle.js-dropdown-toggle{ type: "button", data: { "dropdown-trigger" => "#new-project-or-subgroup-dropdown" } } + %button.btn.btn-success.dropdown-toggle.js-dropdown-toggle{ type: "button", data: { "dropdown-trigger" => "#new-project-or-subgroup-dropdown", 'display' => 'static' } } = icon("caret-down", class: "dropdown-btn-icon") %ul#new-project-or-subgroup-dropdown.dropdown-menu.dropdown-menu-right{ data: { dropdown: true } } %li.droplab-item-selected{ role: "button", data: { value: "new-project", text: new_project_label } } diff --git a/app/views/help/ui.html.haml b/app/views/help/ui.html.haml index de8369ed7b9..b32b602ceb3 100644 --- a/app/views/help/ui.html.haml +++ b/app/views/help/ui.html.haml @@ -443,8 +443,6 @@ .col-md-6 .alert.alert-success = lorem - .alert.alert-primary - = lorem .alert.alert-info = lorem .col-md-6 diff --git a/app/views/import/gitlab_projects/new.html.haml b/app/views/import/gitlab_projects/new.html.haml index f311ac98ac6..cc672a5ea7c 100644 --- a/app/views/import/gitlab_projects/new.html.haml +++ b/app/views/import/gitlab_projects/new.html.haml @@ -20,7 +20,7 @@ - else .input-group-prepend.static-namespace.has-tooltip{ title: user_url(current_user.username) + '/' } - .input-group-text + .input-group-text.border-0 #{user_url(current_user.username)}/ = hidden_field_tag :namespace_id, value: current_user.namespace_id .form-group.col-12.col-sm-6.project-path diff --git a/app/views/layouts/header/_new_dropdown.haml b/app/views/layouts/header/_new_dropdown.haml index db8137cc248..d35df706036 100644 --- a/app/views/layouts/header/_new_dropdown.haml +++ b/app/views/layouts/header/_new_dropdown.haml @@ -1,5 +1,5 @@ %li.header-new.dropdown - = link_to new_project_path, class: "header-new-dropdown-toggle has-tooltip qa-new-menu-toggle", title: "New...", ref: 'tooltip', aria: { label: "New..." }, data: { toggle: 'dropdown', placement: 'bottom', container: 'body' } do + = link_to new_project_path, class: "header-new-dropdown-toggle has-tooltip qa-new-menu-toggle", title: "New...", ref: 'tooltip', aria: { label: "New..." }, data: { toggle: 'dropdown', placement: 'bottom', container: 'body', display: 'static' } do = sprite_icon('plus-square', size: 16) = sprite_icon('angle-down', css_class: 'caret-down') .dropdown-menu.dropdown-menu-right diff --git a/app/views/projects/_new_project_fields.html.haml b/app/views/projects/_new_project_fields.html.haml index cfbd0459e3e..6f957533287 100644 --- a/app/views/projects/_new_project_fields.html.haml +++ b/app/views/projects/_new_project_fields.html.haml @@ -16,7 +16,7 @@ - else .input-group-prepend.static-namespace.has-tooltip{ title: user_url(current_user.username) + '/' } - .input-group-text + .input-group-text.border-0 #{user_url(current_user.username)}/ = f.hidden_field :namespace_id, value: current_user.namespace_id .form-group.project-path.col-sm-6 diff --git a/app/views/projects/buttons/_download.html.haml b/app/views/projects/buttons/_download.html.haml index c75093c4c24..f7551434d47 100644 --- a/app/views/projects/buttons/_download.html.haml +++ b/app/views/projects/buttons/_download.html.haml @@ -3,7 +3,7 @@ - if !project.empty_repo? && can?(current_user, :download_code, project) - archive_prefix = "#{project.path}-#{ref.tr('/', '-')}" .project-action-button.dropdown.inline> - %button.btn.has-tooltip{ title: s_('DownloadSource|Download'), 'data-toggle' => 'dropdown', 'aria-label' => s_('DownloadSource|Download') } + %button.btn.has-tooltip{ title: s_('DownloadSource|Download'), 'data-toggle' => 'dropdown', 'aria-label' => s_('DownloadSource|Download'), 'data-display' => 'static' } = sprite_icon('download') = icon("caret-down") %span.sr-only= _('Select Archive Format') diff --git a/app/views/projects/buttons/_dropdown.html.haml b/app/views/projects/buttons/_dropdown.html.haml index 84245d72f4a..8b9c52f0802 100644 --- a/app/views/projects/buttons/_dropdown.html.haml +++ b/app/views/projects/buttons/_dropdown.html.haml @@ -8,7 +8,7 @@ - if show_menu .project-action-button.dropdown.inline - %a.btn.dropdown-toggle.has-tooltip{ href: '#', title: _('Create new...'), 'data-toggle' => 'dropdown', 'data-container' => 'body', 'aria-label' => _('Create new...') } + %a.btn.dropdown-toggle.has-tooltip{ href: '#', title: _('Create new...'), 'data-toggle' => 'dropdown', 'data-container' => 'body', 'aria-label' => _('Create new...'), 'data-display' => 'static' } = icon('plus') = icon("caret-down") %ul.dropdown-menu.dropdown-menu-right.project-home-dropdown diff --git a/app/views/projects/clusters/gcp/_form.html.haml b/app/views/projects/clusters/gcp/_form.html.haml index 59c4eeec17a..b8e40b0a38b 100644 --- a/app/views/projects/clusters/gcp/_form.html.haml +++ b/app/views/projects/clusters/gcp/_form.html.haml @@ -1,4 +1,10 @@ = javascript_include_tag 'https://apis.google.com/js/api.js' +- external_link_icon = icon('external-link') +- zones_link_url = 'https://cloud.google.com/compute/docs/regions-zones/regions-zones' +- machine_type_link_url = 'https://cloud.google.com/compute/docs/machine-types' +- pricing_link_url = 'https://cloud.google.com/compute/pricing#machinetype' +- help_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe +- help_link_end = ' %{external_link_icon}</a>'.html_safe % { external_link_icon: external_link_icon } %p - link_to_help_page = link_to(s_('ClusterIntegration|help page'), help_page_path('user/project/clusters/index'), target: '_blank', rel: 'noopener noreferrer') @@ -7,15 +13,15 @@ = form_for @cluster, html: { class: 'js-gke-cluster-creation prepend-top-20', data: { token: token_in_session } }, url: gcp_namespace_project_clusters_path(@project.namespace, @project), as: :cluster do |field| = form_errors(@cluster) .form-group - = field.label :name, s_('ClusterIntegration|Kubernetes cluster name') + = field.label :name, s_('ClusterIntegration|Kubernetes cluster name'), class: 'label-light' = field.text_field :name, class: 'form-control', placeholder: s_('ClusterIntegration|Kubernetes cluster name') .form-group - = field.label :environment_scope, s_('ClusterIntegration|Environment scope') + = field.label :environment_scope, s_('ClusterIntegration|Environment scope'), class: 'label-light' = field.text_field :environment_scope, class: 'form-control', readonly: !has_multiple_clusters?(@project), placeholder: s_('ClusterIntegration|Environment scope') = field.fields_for :provider_gcp, @cluster.provider_gcp do |provider_gcp_field| .form-group - = provider_gcp_field.label :gcp_project_id, s_('ClusterIntegration|Google Cloud Platform project') + = provider_gcp_field.label :gcp_project_id, s_('ClusterIntegration|Google Cloud Platform project'), class: 'label-light' .js-gcp-project-id-dropdown-entry-point{ data: { docsUrl: 'https://console.cloud.google.com/home/dashboard' } } = provider_gcp_field.hidden_field :gcp_project_id .dropdown @@ -26,8 +32,7 @@ %span.form-text.text-muted .form-group - = provider_gcp_field.label :zone, s_('ClusterIntegration|Zone') - = link_to(s_('ClusterIntegration|See zones'), 'https://cloud.google.com/compute/docs/regions-zones/regions-zones', target: '_blank', rel: 'noopener noreferrer') + = provider_gcp_field.label :zone, s_('ClusterIntegration|Zone'), class: 'label-light' .js-gcp-zone-dropdown-entry-point = provider_gcp_field.hidden_field :zone .dropdown @@ -35,13 +40,15 @@ %span.dropdown-toggle-text = _('Select project to choose zone') = icon('chevron-down') + %p.form-text.text-muted + = s_('ClusterIntegration|Learn more about %{help_link_start}zones%{help_link_end}.').html_safe % { help_link_start: help_link_start % { url: zones_link_url }, help_link_end: help_link_end } .form-group - = provider_gcp_field.label :num_nodes, s_('ClusterIntegration|Number of nodes') + = provider_gcp_field.label :num_nodes, s_('ClusterIntegration|Number of nodes'), class: 'label-light' = provider_gcp_field.text_field :num_nodes, class: 'form-control', placeholder: '3' .form-group - = provider_gcp_field.label :machine_type, s_('ClusterIntegration|Machine type') + = provider_gcp_field.label :machine_type, s_('ClusterIntegration|Machine type'), class: 'label-light' .js-gcp-machine-type-dropdown-entry-point = provider_gcp_field.hidden_field :machine_type .dropdown @@ -49,6 +56,8 @@ %span.dropdown-toggle-text = _('Select project and zone to choose machine type') = icon('chevron-down') + %p.form-text.text-muted + = s_('ClusterIntegration|Learn more about %{help_link_start_machine_type}machine types%{help_link_end} and %{help_link_start_pricing}pricing%{help_link_end}.').html_safe % { help_link_start_machine_type: help_link_start % { url: machine_type_link_url }, help_link_start_pricing: help_link_start % { url: pricing_link_url }, help_link_end: help_link_end } .form-group = field.submit s_('ClusterIntegration|Create Kubernetes cluster'), class: 'js-gke-cluster-creation-submit btn btn-success', disabled: true diff --git a/app/views/projects/empty.html.haml b/app/views/projects/empty.html.haml index 69753427d17..d47dc3d8143 100644 --- a/app/views/projects/empty.html.haml +++ b/app/views/projects/empty.html.haml @@ -1,3 +1,4 @@ +- @content_class = "limit-container-width" unless fluid_layout - @no_container = true - breadcrumb_title _("Details") @@ -6,7 +7,7 @@ = render "home_panel" .project-empty-note-panel - %div{ class: [container_class, ("limit-container-width-sm" unless fluid_layout)] } + %div{ class: [container_class, ("limit-container-width" unless fluid_layout)] } .prepend-top-20 %h4 = _('The repository for this project is empty') @@ -36,7 +37,7 @@ = render 'stat_anchor_list', anchors: @project.empty_repo_statistics_buttons - if can?(current_user, :push_code, @project) - %div{ class: [container_class, ("limit-container-width-sm" unless fluid_layout)] } + %div{ class: [container_class, ("limit-container-width" unless fluid_layout)] } .prepend-top-20 .empty_wrapper %h3#repo-command-line-instructions.page-title-empty diff --git a/app/views/projects/issues/_new_branch.html.haml b/app/views/projects/issues/_new_branch.html.haml index 76438fae663..acb1a446ec4 100644 --- a/app/views/projects/issues/_new_branch.html.haml +++ b/app/views/projects/issues/_new_branch.html.haml @@ -18,7 +18,7 @@ %button.btn.js-create-merge-request.btn-success.btn-inverted{ type: 'button', data: { action: data_action } } = value - %button.btn.create-merge-request-dropdown-toggle.dropdown-toggle.btn-success.btn-inverted.js-dropdown-toggle{ type: 'button', data: { dropdown: { trigger: '#create-merge-request-dropdown' } } } + %button.btn.create-merge-request-dropdown-toggle.dropdown-toggle.btn-success.btn-inverted.js-dropdown-toggle{ type: 'button', data: { dropdown: { trigger: '#create-merge-request-dropdown' }, display: 'static' } } = icon('caret-down') .droplab-dropdown diff --git a/app/views/projects/merge_requests/diffs/_version_controls.html.haml b/app/views/projects/merge_requests/diffs/_version_controls.html.haml index 1c26f0405d2..52bf584d550 100644 --- a/app/views/projects/merge_requests/diffs/_version_controls.html.haml +++ b/app/views/projects/merge_requests/diffs/_version_controls.html.haml @@ -3,7 +3,7 @@ .mr-version-menus-container.content-block Changes between %span.dropdown.inline.mr-version-dropdown - %a.dropdown-toggle.btn.btn-default{ data: {toggle: :dropdown} } + %a.dropdown-toggle.btn.btn-default{ data: { toggle: :dropdown, display: 'static' } } %span - if @merge_request_diff.latest? latest version @@ -36,7 +36,7 @@ - if @merge_request_diff.base_commit_sha and %span.dropdown.inline.mr-version-compare-dropdown - %a.btn.btn-default.dropdown-toggle{ data: {toggle: :dropdown} } + %a.btn.btn-default.dropdown-toggle{ data: { toggle: :dropdown, display: 'static' } } - if @start_version version #{version_index(@start_version)} - else diff --git a/app/views/projects/wikis/edit.html.haml b/app/views/projects/wikis/edit.html.haml index 35c7dc2984a..d80d2957466 100644 --- a/app/views/projects/wikis/edit.html.haml +++ b/app/views/projects/wikis/edit.html.haml @@ -1,4 +1,4 @@ -- @content_class = "limit-container-width limit-container-width-sm" unless fluid_layout +- @content_class = "limit-container-width" unless fluid_layout - page_title _("Edit"), @page.title.capitalize, _("Wiki") = wiki_page_errors(@error) diff --git a/app/views/projects/wikis/git_access.html.haml b/app/views/projects/wikis/git_access.html.haml index 909987d8090..8c2cbd495a0 100644 --- a/app/views/projects/wikis/git_access.html.haml +++ b/app/views/projects/wikis/git_access.html.haml @@ -1,4 +1,4 @@ -- @content_class = "limit-container-width limit-container-width-sm" unless fluid_layout +- @content_class = "limit-container-width" unless fluid_layout - page_title s_("WikiClone|Git Access"), _("Wiki") .wiki-page-header.has-sidebar-toggle diff --git a/app/views/projects/wikis/show.html.haml b/app/views/projects/wikis/show.html.haml index ff72c8bb75d..a08973c7f32 100644 --- a/app/views/projects/wikis/show.html.haml +++ b/app/views/projects/wikis/show.html.haml @@ -1,4 +1,4 @@ -- @content_class = "limit-container-width limit-container-width-sm" unless fluid_layout +- @content_class = "limit-container-width" unless fluid_layout - breadcrumb_title @page.title.capitalize - wiki_breadcrumb_dropdown_links(@page.slug) - page_title @page.title.capitalize, _("Wiki") diff --git a/app/views/shared/_clone_panel.html.haml b/app/views/shared/_clone_panel.html.haml index 5fc02ba3160..3655c2a1d42 100644 --- a/app/views/shared/_clone_panel.html.haml +++ b/app/views/shared/_clone_panel.html.haml @@ -11,7 +11,7 @@ %span = default_clone_protocol.upcase = icon('caret-down') - %ul.dropdown-menu.dropdown-menu-selectable.dropdown-menu-right.clone-options-dropdown + %ul.dropdown-menu.dropdown-menu-selectable.clone-options-dropdown %li = ssh_clone_button(project) %li diff --git a/app/views/shared/boards/components/sidebar/_labels.html.haml b/app/views/shared/boards/components/sidebar/_labels.html.haml index a112a9f1f7e..daee691e358 100644 --- a/app/views/shared/boards/components/sidebar/_labels.html.haml +++ b/app/views/shared/boards/components/sidebar/_labels.html.haml @@ -9,7 +9,7 @@ None %a{ href: "#", "v-for" => "label in issue.labels" } - %span.badge.color-label.has-tooltip{ ":style" => "{ backgroundColor: label.color, color: label.textColor }" } + .badge.color-label.has-tooltip{ ":style" => "{ backgroundColor: label.color, color: label.textColor }" } {{ label.title }} - if can_admin_issue? .selectbox diff --git a/app/views/shared/issuable/_milestone_dropdown.html.haml b/app/views/shared/issuable/_milestone_dropdown.html.haml index 955b8866c2c..37625a4a163 100644 --- a/app/views/shared/issuable/_milestone_dropdown.html.haml +++ b/app/views/shared/issuable/_milestone_dropdown.html.haml @@ -1,6 +1,8 @@ - project = @target_project || @project - extra_class = extra_class || '' - show_menu_above = show_menu_above || false +- selected = local_assigns.fetch(:selected, nil) + - selected_text = selected.try(:title) || params[:milestone_title] - dropdown_title = local_assigns.fetch(:dropdown_title, "Filter by milestone") - if selected.present? || params[:milestone_title].present? diff --git a/app/views/shared/issuable/_sidebar_assignees.html.haml b/app/views/shared/issuable/_sidebar_assignees.html.haml index ed3ef6155db..8a13c7a3b83 100644 --- a/app/views/shared/issuable/_sidebar_assignees.html.haml +++ b/app/views/shared/issuable/_sidebar_assignees.html.haml @@ -50,7 +50,7 @@ - data[:multi_select] = true - data['dropdown-title'] = title - data['dropdown-header'] = dropdown_options[:data][:'dropdown-header'] - - data['max-select'] = dropdown_options[:data][:'max-select'] + - data['max-select'] = dropdown_options[:data][:'max-select'] if dropdown_options[:data][:'max-select'] - options[:data].merge!(data) = dropdown_tag(title, options: options) diff --git a/app/views/shared/issuable/form/_metadata.html.haml b/app/views/shared/issuable/form/_metadata.html.haml index 01fbc163a14..bd87bb38e77 100644 --- a/app/views/shared/issuable/form/_metadata.html.haml +++ b/app/views/shared/issuable/form/_metadata.html.haml @@ -25,7 +25,10 @@ = form.hidden_field :label_ids, multiple: true, value: '' .col-sm-10{ class: "#{"col-md-8" if has_due_date} #{'issuable-form-padding-top' if !has_labels}" } .issuable-form-select-holder - = render "shared/issuable/label_dropdown", classes: ["js-issuable-form-dropdown"], selected: issuable.labels, data_options: { field_name: "#{issuable.class.model_name.param_key}[label_ids][]", show_any: false}, dropdown_title: "Select label" + = render "shared/issuable/label_dropdown", classes: ["js-issuable-form-dropdown"], selected: issuable.labels, data_options: { field_name: "#{issuable.class.model_name.param_key}[label_ids][]", show_any: false }, dropdown_title: "Select label" + + = render_if_exists "shared/issuable/form/weight", issuable: issuable, form: form + - if has_due_date .col-lg-6 .form-group.row diff --git a/app/views/shared/notifications/_button.html.haml b/app/views/shared/notifications/_button.html.haml index e99d8d0973f..09ddf732ada 100644 --- a/app/views/shared/notifications/_button.html.haml +++ b/app/views/shared/notifications/_button.html.haml @@ -6,14 +6,14 @@ .js-notification-toggle-btns %div{ class: ("btn-group" if notification_setting.custom?) } - if notification_setting.custom? - %button.dropdown-new.btn.btn-default.has-tooltip.notifications-btn#notifications-button{ type: "button", title: "Notification setting", "aria-label" => "Notification setting: #{notification_title(notification_setting.level)}", data: { container: "body", toggle: "modal", target: "#" + notifications_menu_identifier("modal", notification_setting) } } + %button.dropdown-new.btn.btn-default.has-tooltip.notifications-btn#notifications-button{ type: "button", title: "Notification setting", "aria-label" => "Notification setting: #{notification_title(notification_setting.level)}", data: { container: "body", toggle: "modal", target: "#" + notifications_menu_identifier("modal", notification_setting), display: 'static' } } = icon("bell", class: "js-notification-loading") = notification_title(notification_setting.level) %button.btn.dropdown-toggle{ data: { toggle: "dropdown", target: notifications_menu_identifier("dropdown", notification_setting) } } = icon('caret-down') .sr-only Toggle dropdown - else - %button.dropdown-new.btn.btn-default.has-tooltip.notifications-btn#notifications-button{ type: "button", title: "Notification setting", "aria-label" => "Notification setting: #{notification_title(notification_setting.level)}", data: { container: "body", toggle: "dropdown", target: notifications_menu_identifier("dropdown", notification_setting) } } + %button.dropdown-new.btn.btn-default.has-tooltip.notifications-btn#notifications-button{ type: "button", title: "Notification setting", "aria-label" => "Notification setting: #{notification_title(notification_setting.level)}", data: { container: "body", toggle: "dropdown", target: notifications_menu_identifier("dropdown", notification_setting), display: 'static' } } = icon("bell", class: "js-notification-loading") = notification_title(notification_setting.level) = icon("caret-down") |