summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacob Schatz <jschatz@gitlab.com>2016-08-18 20:24:28 +0000
committerJacob Schatz <jschatz@gitlab.com>2016-08-18 20:24:28 +0000
commit07989af1ef9c86a0c25513a7735133db4fbd5719 (patch)
treec5e6fea4409f33e5e9af256d7842fde66ee3db6b
parent2b487edc98186e7f46c93ef7e6d029902aa82ebe (diff)
parent32060d45a2ceea3dc3e367e6b489cd94967c76c5 (diff)
downloadgitlab-ce-07989af1ef9c86a0c25513a7735133db4fbd5719.tar.gz
Merge branch '13664-abuse-report-page-should-have-a-maximum-width' into 'master'
Abuse Reports message truncation ## What does this MR do? Adds dynamic message truncation to abuse reports ## Are there points in the code the reviewer needs to double check? Is the new UI OK? ## Why was this MR needed? Admin UX ## What are the relevant issue numbers? Closes #13664. ## Screenshots (if relevant) **UPDATED:** ![Screen_Shot_2016-07-07_at_03.02.43](/uploads/2e1a1122e0194f8ffa48054c18523ccd/Screen_Shot_2016-07-07_at_03.02.43.png) ## Does this MR meet the acceptance criteria? - [ ] [CHANGELOG](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CHANGELOG) entry added - [ ] [Documentation created/updated](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/development/doc_styleguide.md) - [ ] API support added - Tests - [ ] Added for this feature/bug - [ ] All builds are passing - [x] Conform by the [style guides](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#style-guides) - [x] Branch has no merge conflicts with `master` (if you do - rebase it please) - [x] [Squashed related commits together](https://git-scm.com/book/en/Git-Tools-Rewriting-History#Squashing-Commits) Closes #13664 See merge request !5032
-rw-r--r--app/assets/javascripts/abuse_reports.js.es639
-rw-r--r--app/assets/javascripts/dispatcher.js3
-rw-r--r--app/assets/javascripts/lib/utils/text_utility.js5
-rw-r--r--app/assets/stylesheets/pages/admin.scss42
-rw-r--r--app/views/admin/abuse_reports/_abuse_report.html.haml17
-rw-r--r--app/views/admin/abuse_reports/index.html.haml33
-rw-r--r--spec/javascripts/abuse_reports_spec.js.es641
-rw-r--r--spec/javascripts/fixtures/abuse_reports.html.haml16
8 files changed, 172 insertions, 24 deletions
diff --git a/app/assets/javascripts/abuse_reports.js.es6 b/app/assets/javascripts/abuse_reports.js.es6
new file mode 100644
index 00000000000..748084b0307
--- /dev/null
+++ b/app/assets/javascripts/abuse_reports.js.es6
@@ -0,0 +1,39 @@
+window.gl = window.gl || {};
+((global) => {
+ const MAX_MESSAGE_LENGTH = 500;
+ const MESSAGE_CELL_SELECTOR = '.abuse-reports .message';
+
+ class AbuseReports {
+ constructor() {
+ $(MESSAGE_CELL_SELECTOR).each(this.truncateLongMessage);
+ $(document)
+ .off('click', MESSAGE_CELL_SELECTOR)
+ .on('click', MESSAGE_CELL_SELECTOR, this.toggleMessageTruncation);
+ }
+
+ truncateLongMessage() {
+ const $messageCellElement = $(this);
+ const reportMessage = $messageCellElement.text();
+ if (reportMessage.length > MAX_MESSAGE_LENGTH) {
+ $messageCellElement.data('original-message', reportMessage);
+ $messageCellElement.data('message-truncated', 'true');
+ $messageCellElement.text(global.text.truncate(reportMessage, MAX_MESSAGE_LENGTH));
+ }
+ }
+
+ toggleMessageTruncation() {
+ const $messageCellElement = $(this);
+ const originalMessage = $messageCellElement.data('original-message');
+ if (!originalMessage) return;
+ if ($messageCellElement.data('message-truncated') === 'true') {
+ $messageCellElement.data('message-truncated', 'false');
+ $messageCellElement.text(originalMessage);
+ } else {
+ $messageCellElement.data('message-truncated', 'true');
+ $messageCellElement.text(`${originalMessage.substr(0, (MAX_MESSAGE_LENGTH - 3))}...`);
+ }
+ }
+ }
+
+ global.AbuseReports = AbuseReports;
+})(window.gl);
diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js
index 1163edd8547..74c4ab563f9 100644
--- a/app/assets/javascripts/dispatcher.js
+++ b/app/assets/javascripts/dispatcher.js
@@ -196,6 +196,9 @@
case 'edit':
new Labels();
}
+ case 'abuse_reports':
+ new gl.AbuseReports();
+ break;
}
break;
case 'dashboard':
diff --git a/app/assets/javascripts/lib/utils/text_utility.js b/app/assets/javascripts/lib/utils/text_utility.js
index 130479642f3..b6636de5767 100644
--- a/app/assets/javascripts/lib/utils/text_utility.js
+++ b/app/assets/javascripts/lib/utils/text_utility.js
@@ -104,9 +104,12 @@
return self.updateText($this.closest('.md-area').find('textarea'), $this.data('md-tag'), $this.data('md-block'), !$this.data('md-prepend'));
});
};
- return gl.text.removeListeners = function(form) {
+ gl.text.removeListeners = function(form) {
return $('.js-md', form).off();
};
+ return gl.text.truncate = function(string, maxLength) {
+ return string.substr(0, (maxLength - 3)) + '...';
+ };
})(window);
}).call(this);
diff --git a/app/assets/stylesheets/pages/admin.scss b/app/assets/stylesheets/pages/admin.scss
index 5607239d92d..c9cdfdcd29c 100644
--- a/app/assets/stylesheets/pages/admin.scss
+++ b/app/assets/stylesheets/pages/admin.scss
@@ -72,7 +72,6 @@
margin-bottom: 20px;
}
-
// Users List
.users-list {
@@ -98,3 +97,44 @@
}
}
}
+
+.abuse-reports {
+ .table {
+ table-layout: fixed;
+ }
+ .subheading {
+ padding-bottom: $gl-padding;
+ }
+ .message {
+ word-wrap: break-word;
+ }
+ .btn {
+ white-space: normal;
+ padding: $gl-btn-padding;
+ }
+ th {
+ width: 15%;
+ &.wide {
+ width: 55%;
+ }
+ }
+ @media (max-width: $screen-sm-max) {
+ th {
+ width: 100%;
+ }
+ td {
+ width: 100%;
+ float: left;
+ }
+ }
+
+ .no-reports {
+ .emoji-icon {
+ margin-left: $btn-side-margin;
+ margin-top: 3px;
+ }
+ span {
+ font-size: 19px;
+ }
+ }
+}
diff --git a/app/views/admin/abuse_reports/_abuse_report.html.haml b/app/views/admin/abuse_reports/_abuse_report.html.haml
index dd2e7ebd030..56bf6194914 100644
--- a/app/views/admin/abuse_reports/_abuse_report.html.haml
+++ b/app/views/admin/abuse_reports/_abuse_report.html.haml
@@ -1,6 +1,8 @@
- reporter = abuse_report.reporter
- user = abuse_report.user
%tr
+ %th.visible-xs-block.visible-sm-block
+ %strong User
%td
- if user
= link_to user.name, user
@@ -9,6 +11,7 @@
- else
(removed)
%td
+ %strong.subheading.visible-xs-block.visible-sm-block Reported by
- if reporter
= link_to reporter.name, reporter
- else
@@ -16,16 +19,16 @@
.light.small
= time_ago_with_tooltip(abuse_report.created_at)
%td
- = markdown(abuse_report.message.squish!, pipeline: :single_line, author: reporter)
+ %strong.subheading.visible-xs-block.visible-sm-block Message
+ .message
+ = markdown(abuse_report.message.squish!, pipeline: :single_line, author: reporter)
%td
- if user
= link_to 'Remove user & report', admin_abuse_report_path(abuse_report, remove_user: true),
- data: { confirm: "USER #{user.name} WILL BE REMOVED! Are you sure?" }, remote: true, method: :delete, class: "btn btn-xs btn-remove js-remove-tr"
-
- %td
+ data: { confirm: "USER #{user.name} WILL BE REMOVED! Are you sure?" }, remote: true, method: :delete, class: "btn btn-sm btn-block btn-remove js-remove-tr"
- if user && !user.blocked?
- = link_to 'Block user', block_admin_user_path(user), data: {confirm: 'USER WILL BE BLOCKED! Are you sure?'}, method: :put, class: "btn btn-xs"
+ = link_to 'Block user', block_admin_user_path(user), data: {confirm: 'USER WILL BE BLOCKED! Are you sure?'}, method: :put, class: "btn btn-sm btn-block"
- else
- .btn.btn-xs.disabled
+ .btn.btn-sm.disabled.btn-block
Already Blocked
- = link_to 'Remove report', [:admin, abuse_report], remote: true, method: :delete, class: "btn btn-xs btn-close js-remove-tr"
+ = link_to 'Remove report', [:admin, abuse_report], remote: true, method: :delete, class: "btn btn-sm btn-block btn-close js-remove-tr"
diff --git a/app/views/admin/abuse_reports/index.html.haml b/app/views/admin/abuse_reports/index.html.haml
index bc4a9cedb2c..7bbc75db9ff 100644
--- a/app/views/admin/abuse_reports/index.html.haml
+++ b/app/views/admin/abuse_reports/index.html.haml
@@ -1,17 +1,20 @@
-- page_title "Abuse Reports"
+- page_title 'Abuse Reports'
%h3.page-title Abuse Reports
%hr
-- if @abuse_reports.present?
- .table-holder
- %table.table
- %thead
- %tr
- %th User
- %th Reported by
- %th Message
- %th Primary action
- %th
- = render @abuse_reports
- = paginate @abuse_reports
-- else
- %h4 There are no abuse reports
+.abuse-reports
+ - if @abuse_reports.present?
+ .table-holder
+ %table.table
+ %thead.hidden-sm.hidden-xs
+ %tr
+ %th User
+ %th Reported by
+ %th.wide Message
+ %th Action
+ = render @abuse_reports
+ - else
+ .no-reports
+ %span.pull-left
+ There are no abuse reports!
+ .pull-left
+ = emoji_icon 'tada'
diff --git a/spec/javascripts/abuse_reports_spec.js.es6 b/spec/javascripts/abuse_reports_spec.js.es6
new file mode 100644
index 00000000000..6bcfdf191c2
--- /dev/null
+++ b/spec/javascripts/abuse_reports_spec.js.es6
@@ -0,0 +1,41 @@
+/*= require abuse_reports */
+
+/*= require jquery */
+
+((global) => {
+ const FIXTURE = 'abuse_reports.html';
+ const MAX_MESSAGE_LENGTH = 500;
+
+ function assertMaxLength($message) {
+ expect($message.text().length).toEqual(MAX_MESSAGE_LENGTH);
+ }
+
+ describe('Abuse Reports', function() {
+ fixture.preload(FIXTURE);
+
+ beforeEach(function() {
+ fixture.load(FIXTURE);
+ new global.AbuseReports();
+ });
+
+ it('should truncate long messages', function() {
+ const $longMessage = $('#long');
+ expect($longMessage.data('original-message')).toEqual(jasmine.anything());
+ assertMaxLength($longMessage);
+ });
+
+ it('should not truncate short messages', function() {
+ const $shortMessage = $('#short');
+ expect($shortMessage.data('original-message')).not.toEqual(jasmine.anything());
+ });
+
+ it('should allow clicking a truncated message to expand and collapse the full message', function() {
+ const $longMessage = $('#long');
+ $longMessage.click();
+ expect($longMessage.data('original-message').length).toEqual($longMessage.text().length);
+ $longMessage.click();
+ assertMaxLength($longMessage);
+ });
+ });
+
+})(window.gl);
diff --git a/spec/javascripts/fixtures/abuse_reports.html.haml b/spec/javascripts/fixtures/abuse_reports.html.haml
new file mode 100644
index 00000000000..2ec302abcb7
--- /dev/null
+++ b/spec/javascripts/fixtures/abuse_reports.html.haml
@@ -0,0 +1,16 @@
+.abuse-reports
+ .message#long
+ Cat ipsum dolor sit amet, hide head under blanket so no one can see.
+ Gate keepers of hell eat and than sleep on your face but hunt by meowing
+ loudly at 5am next to human slave food dispenser cats go for world
+ domination or chase laser, yet poop on grasses chirp at birds. Cat is love,
+ cat is life chase after silly colored fish toys around the house climb a
+ tree, wait for a fireman jump to fireman then scratch his face fall asleep
+ on the washing machine lies down always hungry so caticus cuteicus. Sit on
+ human. Spot something, big eyes, big eyes, crouch, shake butt, prepare to
+ pounce sleep in the bathroom sink hiss at vacuum cleaner hide head under
+ blanket so no one can see throwup on your pillow.
+ .message#short
+ Cat ipsum dolor sit amet, groom yourself 4 hours - checked, have your
+ beauty sleep 18 hours - checked, be fabulous for the rest of the day -
+ checked! for shake treat bag.