diff options
author | Jacob Schatz <jschatz@gitlab.com> | 2017-07-07 20:23:27 +0000 |
---|---|---|
committer | Jacob Schatz <jschatz@gitlab.com> | 2017-07-07 20:23:27 +0000 |
commit | 5f8f555a6649c8463c66551af2948f1e56e7ce6a (patch) | |
tree | 58c43d06e544ebe4ef39d6cd85ecbf7b45763ce1 /app/assets | |
parent | 5b257778a7fc2365e0117769dd9551edcf1a7dae (diff) | |
parent | 63fc393566e284c0b981221a09c717f75f35a0d2 (diff) | |
download | gitlab-ce-5f8f555a6649c8463c66551af2948f1e56e7ce6a.tar.gz |
Merge branch '30281-report-abusive-content-from-an-issue-or-merge-request' into 'master'
Resolve "Report abusive content from an issue or merge request"
Closes #30281
See merge request !11786
Diffstat (limited to 'app/assets')
-rw-r--r-- | app/assets/javascripts/close_reopen_report_toggle.js | 97 | ||||
-rw-r--r-- | app/assets/javascripts/comment_type_toggle.js | 5 | ||||
-rw-r--r-- | app/assets/javascripts/helpers/issuables_helper.js | 27 | ||||
-rw-r--r-- | app/assets/javascripts/issue.js | 51 | ||||
-rw-r--r-- | app/assets/javascripts/merge_request.js | 10 | ||||
-rw-r--r-- | app/assets/stylesheets/framework/buttons.scss | 18 | ||||
-rw-r--r-- | app/assets/stylesheets/framework/dropdowns.scss | 71 | ||||
-rw-r--r-- | app/assets/stylesheets/framework/filters.scss | 17 | ||||
-rw-r--r-- | app/assets/stylesheets/pages/issuable.scss | 25 | ||||
-rw-r--r-- | app/assets/stylesheets/pages/note_form.scss | 51 |
10 files changed, 303 insertions, 69 deletions
diff --git a/app/assets/javascripts/close_reopen_report_toggle.js b/app/assets/javascripts/close_reopen_report_toggle.js new file mode 100644 index 00000000000..882d20671cc --- /dev/null +++ b/app/assets/javascripts/close_reopen_report_toggle.js @@ -0,0 +1,97 @@ +import DropLab from './droplab/drop_lab'; +import ISetter from './droplab/plugins/input_setter'; + +// Todo: Remove this when fixing issue in input_setter plugin +const InputSetter = Object.assign({}, ISetter); + +class CloseReopenReportToggle { + constructor(opts = {}) { + this.dropdownTrigger = opts.dropdownTrigger; + this.dropdownList = opts.dropdownList; + this.button = opts.button; + } + + initDroplab() { + this.reopenItem = this.dropdownList.querySelector('.reopen-item'); + this.closeItem = this.dropdownList.querySelector('.close-item'); + + this.droplab = new DropLab(); + + const config = this.setConfig(); + + this.droplab.init(this.dropdownTrigger, this.dropdownList, [InputSetter], config); + } + + updateButton(isClosed) { + this.toggleButtonType(isClosed); + + this.button.blur(); + } + + toggleButtonType(isClosed) { + const [showItem, hideItem] = this.getButtonTypes(isClosed); + + showItem.classList.remove('hidden'); + showItem.classList.add('droplab-item-selected'); + + hideItem.classList.add('hidden'); + hideItem.classList.remove('droplab-item-selected'); + + showItem.click(); + } + + getButtonTypes(isClosed) { + return isClosed ? [this.reopenItem, this.closeItem] : [this.closeItem, this.reopenItem]; + } + + setDisable(shouldDisable = true) { + if (shouldDisable) { + this.button.setAttribute('disabled', 'true'); + this.dropdownTrigger.setAttribute('disabled', 'true'); + } else { + this.button.removeAttribute('disabled'); + this.dropdownTrigger.removeAttribute('disabled'); + } + } + + setConfig() { + const config = { + InputSetter: [ + { + input: this.button, + valueAttribute: 'data-text', + inputAttribute: 'data-value', + }, + { + input: this.button, + valueAttribute: 'data-text', + inputAttribute: 'title', + }, + { + input: this.button, + valueAttribute: 'data-button-class', + inputAttribute: 'class', + }, + { + input: this.dropdownTrigger, + valueAttribute: 'data-toggle-class', + inputAttribute: 'class', + }, + { + input: this.button, + valueAttribute: 'data-url', + inputAttribute: 'href', + }, + { + input: this.button, + valueAttribute: 'data-method', + inputAttribute: 'data-method', + }, + ], + }; + + return config; + } +} + +export default CloseReopenReportToggle; diff --git a/app/assets/javascripts/comment_type_toggle.js b/app/assets/javascripts/comment_type_toggle.js index df0ba86198c..c74184949df 100644 --- a/app/assets/javascripts/comment_type_toggle.js +++ b/app/assets/javascripts/comment_type_toggle.js @@ -1,5 +1,8 @@ import DropLab from './droplab/drop_lab'; -import InputSetter from './droplab/plugins/input_setter'; +import ISetter from './droplab/plugins/input_setter'; + +// Todo: Remove this when fixing issue in input_setter plugin +const InputSetter = Object.assign({}, ISetter); class CommentTypeToggle { constructor(opts = {}) { diff --git a/app/assets/javascripts/helpers/issuables_helper.js b/app/assets/javascripts/helpers/issuables_helper.js new file mode 100644 index 00000000000..52d0f7e43fc --- /dev/null +++ b/app/assets/javascripts/helpers/issuables_helper.js @@ -0,0 +1,27 @@ +import CloseReopenReportToggle from '../close_reopen_report_toggle'; + +function initCloseReopenReport() { + const container = document.querySelector('.js-issuable-close-dropdown'); + + if (!container) return undefined; + + const dropdownTrigger = container.querySelector('.js-issuable-close-toggle'); + const dropdownList = container.querySelector('.js-issuable-close-menu'); + const button = container.querySelector('.js-issuable-close-button'); + + const closeReopenReportToggle = new CloseReopenReportToggle({ + dropdownTrigger, + dropdownList, + button, + }); + + closeReopenReportToggle.initDroplab(); + + return closeReopenReportToggle; +} + +const IssuablesHelper = { + initCloseReopenReport, +}; + +export default IssuablesHelper; diff --git a/app/assets/javascripts/issue.js b/app/assets/javascripts/issue.js index 7490cd31f58..2bee4fb045a 100644 --- a/app/assets/javascripts/issue.js +++ b/app/assets/javascripts/issue.js @@ -6,6 +6,7 @@ import '~/lib/utils/text_utility'; import './flash'; import TaskList from './task_list'; import CreateMergeRequestDropdown from './create_merge_request_dropdown'; +import IssuablesHelper from './helpers/issuables_helper'; class Issue { constructor() { @@ -28,6 +29,11 @@ class Issue { Issue.initMergeRequests(); Issue.initRelatedBranches(); + this.closeButtons = $('a.btn-close'); + this.reopenButtons = $('a.btn-reopen'); + + this.initCloseReopenReport(); + if (Issue.createMrDropdownWrap) { this.createMergeRequestDropdown = new CreateMergeRequestDropdown(Issue.createMrDropdownWrap); } @@ -35,13 +41,8 @@ class Issue { initIssueBtnEventListeners() { const issueFailMessage = 'Unable to update this issue at this time.'; - const closeButtons = $('a.btn-close'); - const isClosedBadge = $('div.status-box-closed'); - const isOpenBadge = $('div.status-box-open'); - const projectIssuesCounter = $('.issue_counter'); - const reopenButtons = $('a.btn-reopen'); - return closeButtons.add(reopenButtons).on('click', (e) => { + return $(document).on('click', 'a.btn-close, a.btn-reopen', (e) => { var $button, shouldSubmit, url; e.preventDefault(); e.stopImmediatePropagation(); @@ -50,7 +51,9 @@ class Issue { if (shouldSubmit) { Issue.submitNoteForm($button.closest('form')); } - $button.prop('disabled', true); + + this.disableCloseReopenButton($button); + url = $button.attr('href'); return $.ajax({ type: 'PUT', @@ -58,15 +61,19 @@ class Issue { }) .fail(() => new Flash(issueFailMessage)) .done((data) => { + const isClosedBadge = $('div.status-box-closed'); + const isOpenBadge = $('div.status-box-open'); + const projectIssuesCounter = $('.issue_counter'); + if ('id' in data) { $(document).trigger('issuable:change'); const isClosed = $button.hasClass('btn-close'); - closeButtons.toggleClass('hidden', isClosed); - reopenButtons.toggleClass('hidden', !isClosed); isClosedBadge.toggleClass('hidden', !isClosed); isOpenBadge.toggleClass('hidden', isClosed); + this.toggleCloseReopenButton(isClosed); + let numProjectIssues = Number(projectIssuesCounter.text().replace(/[^\d]/, '')); numProjectIssues = isClosed ? numProjectIssues - 1 : numProjectIssues + 1; projectIssuesCounter.text(gl.text.addDelimiter(numProjectIssues)); @@ -83,12 +90,34 @@ class Issue { } else { new Flash(issueFailMessage); } - - $button.prop('disabled', false); + }) + .then(() => { + this.disableCloseReopenButton($button, false); }); }); } + initCloseReopenReport() { + this.closeReopenReportToggle = IssuablesHelper.initCloseReopenReport(); + + if (this.closeButtons) this.closeButtons = this.closeButtons.not('.issuable-close-button'); + if (this.reopenButtons) this.reopenButtons = this.reopenButtons.not('.issuable-close-button'); + } + + disableCloseReopenButton($button, shouldDisable) { + if (this.closeReopenReportToggle) { + this.closeReopenReportToggle.setDisable(shouldDisable); + } else { + $button.prop('disabled', shouldDisable); + } + } + + toggleCloseReopenButton(isClosed) { + if (this.closeReopenReportToggle) this.closeReopenReportToggle.updateButton(isClosed); + this.closeButtons.toggleClass('hidden', isClosed); + this.reopenButtons.toggleClass('hidden', !isClosed); + } + static submitNoteForm(form) { var noteText; noteText = form.find("textarea.js-note-text").val(); diff --git a/app/assets/javascripts/merge_request.js b/app/assets/javascripts/merge_request.js index 7ba9efc5387..0db2abe507d 100644 --- a/app/assets/javascripts/merge_request.js +++ b/app/assets/javascripts/merge_request.js @@ -4,6 +4,7 @@ import 'vendor/jquery.waitforimages'; import TaskList from './task_list'; import './merge_request_tabs'; +import IssuablesHelper from './helpers/issuables_helper'; (function() { this.MergeRequest = (function() { @@ -21,9 +22,12 @@ import './merge_request_tabs'; return _this.showAllCommits(); }; })(this)); + this.initTabs(); this.initMRBtnListeners(); this.initCommitMessageListeners(); + this.closeReopenReportToggle = IssuablesHelper.initCloseReopenReport(); + if ($("a.btn-close").length) { this.taskList = new TaskList({ dataType: 'merge_request', @@ -64,11 +68,15 @@ import './merge_request_tabs'; if (shouldSubmit && $this.data('submitted')) { return; } + + if (this.closeReopenReportToggle) this.closeReopenReportToggle.setDisable(); + if (shouldSubmit) { if ($this.hasClass('btn-comment-and-close') || $this.hasClass('btn-comment-and-reopen')) { e.preventDefault(); e.stopImmediatePropagation(); - return _this.submitNoteForm($this.closest('form'), $this); + + _this.submitNoteForm($this.closest('form'), $this); } } }); diff --git a/app/assets/stylesheets/framework/buttons.scss b/app/assets/stylesheets/framework/buttons.scss index 4369ae78bde..6eabdc63d9e 100644 --- a/app/assets/stylesheets/framework/buttons.scss +++ b/app/assets/stylesheets/framework/buttons.scss @@ -20,17 +20,29 @@ color: $text; border-color: $border; + > .icon { + color: $text; + } + &:hover, &:focus { background-color: $hover-background; border-color: $hover-border; color: $hover-text; + + > .icon { + color: $hover-text; + } } &:active { background-color: $active-background; border-color: $active-border; color: $hover-text; + + > .icon { + color: $hover-text; + } } } @@ -163,7 +175,8 @@ @include btn-orange; } - &.btn-close { + &.btn-close, + &.btn-close-color { @include btn-outline($white-light, $orange-600, $orange-500, $orange-500, $white-light, $orange-600, $orange-600, $orange-700); } @@ -181,7 +194,8 @@ float: right; } - &.btn-reopen { + &.btn-reopen, + .btn-reopen-color { /* should be same as parent class for now */ } diff --git a/app/assets/stylesheets/framework/dropdowns.scss b/app/assets/stylesheets/framework/dropdowns.scss index 4f54ca24940..dc4ed42544f 100644 --- a/app/assets/stylesheets/framework/dropdowns.scss +++ b/app/assets/stylesheets/framework/dropdowns.scss @@ -295,9 +295,74 @@ } } -.filtered-search-box-input-container .dropdown-menu, -.filtered-search-box-input-container .dropdown-menu-nav, -.comment-type-dropdown .dropdown-menu { +.droplab-dropdown { + .description { + display: inline-block; + white-space: normal; + margin-left: 5px; + } + + .dropdown-toggle > i { + pointer-events: none; + } + + li { + padding: $gl-btn-padding $gl-btn-padding 2px; + cursor: pointer; + + > a, + > button { + display: flex; + margin: 0; + padding: 0; + border-radius: 0; + text-overflow: inherit; + background-color: inherit; + color: inherit; + border: inherit; + text-align: left; + + &:hover, + &:focus { + background-color: inherit; + color: inherit; + } + + &.btn .fa:not(:last-child) { + margin-left: 5px; + } + } + + &:hover, + &:focus { + background-color: $dropdown-hover-color; + color: $white-light; + } + + &.droplab-item-selected i { + visibility: visible; + } + + .icon { + visibility: hidden; + } + } + + .icon { + display: inline-block; + vertical-align: top; + padding-top: 2px; + } + + .divider { + margin: 0 8px; + padding: 0; + border-top: $gray-darkest; + } +} + +.droplab-dropdown .dropdown-menu, +.droplab-dropdown .dropdown-menu-nav { display: none; opacity: 1; visibility: visible; diff --git a/app/assets/stylesheets/framework/filters.scss b/app/assets/stylesheets/framework/filters.scss index 767cf5ffea5..f05348ee4e3 100644 --- a/app/assets/stylesheets/framework/filters.scss +++ b/app/assets/stylesheets/framework/filters.scss @@ -70,6 +70,13 @@ .input-token { max-width: 200px; + padding: 0; + + &:hover, + &:focus { + background-color: inherit; + color: inherit; + } } .input-token:only-child, @@ -156,6 +163,16 @@ } } +.droplab-dropdown li.filtered-search-token { + padding: 0; + + &:hover, + &:focus { + background-color: inherit; + color: inherit; + } +} + .filtered-search-term { .name { background-color: inherit; diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss index 47f50083726..56a4b53ed61 100644 --- a/app/assets/stylesheets/pages/issuable.scss +++ b/app/assets/stylesheets/pages/issuable.scss @@ -799,3 +799,28 @@ } } } + +.issuable-close-button, +.issuable-close-toggle { + @include transition(border-color, color); +} + +.issuable-close-dropdown { + .dropdown-menu { + min-width: 270px; + left: auto; + right: 0; + } + + .description { + margin-bottom: 10px; + + .text { + margin: 0; + } + } + + .dropdown-toggle > .icon { + margin: 0 3px; + } +} diff --git a/app/assets/stylesheets/pages/note_form.scss b/app/assets/stylesheets/pages/note_form.scss index 9877ed2cfd6..cdb1e65e4be 100644 --- a/app/assets/stylesheets/pages/note_form.scss +++ b/app/assets/stylesheets/pages/note_form.scss @@ -356,7 +356,6 @@ color: $white-light; padding-right: 2px; margin-top: 2px; - pointer-events: none; } } @@ -366,56 +365,6 @@ width: 298px; } - .description { - display: inline-block; - white-space: normal; - margin-left: 8px; - padding-right: 33px; - } - - li { - padding-top: 6px; - - & > a { - margin: 0; - padding: 0; - color: inherit; - border-radius: 0; - text-overflow: inherit; - - &:hover, - &:focus { - background-color: inherit; - color: inherit; - } - } - - &:hover, - &:focus { - background-color: $dropdown-hover-color; - color: $white-light; - } - - &.droplab-item-selected i { - visibility: visible; - } - - i { - visibility: hidden; - } - } - - i { - display: inline-block; - vertical-align: top; - padding-top: 2px; - } - - .divider { - margin: 0 8px; - padding: 0; - border-top: $gray-darkest; - } @media (max-width: $screen-xs-max) { display: flex; |