diff options
author | Tim Zallmann <tzallmann@gitlab.com> | 2018-06-07 13:53:24 +0300 |
---|---|---|
committer | Tim Zallmann <tzallmann@gitlab.com> | 2018-06-07 13:53:24 +0300 |
commit | be928829cfddf22c9608e02aa6ca2c03cf0a30b4 (patch) | |
tree | 6c4216b6216c605518743dd7a82b0837379d2c7c /app/assets | |
parent | 7c179bf39ec3d0f8e22ad71608546273bb0760db (diff) | |
parent | a97f4ec3615595694b11676484e9ac1ba5524a9e (diff) |
Merge branch '39549-label-list-page-redesign-with-draggable-labels' into 'master'
Resolve "Label list page redesign with draggable labels"
Closes #39549
See merge request gitlab-org/gitlab-ce!18466
Diffstat (limited to 'app/assets')
-rw-r--r-- | app/assets/javascripts/group_label_subscription.js | 18 | ||||
-rw-r--r-- | app/assets/javascripts/label_manager.js | 15 | ||||
-rw-r--r-- | app/assets/javascripts/project_label_subscription.js | 28 | ||||
-rw-r--r-- | app/assets/stylesheets/framework/variables.scss | 2 | ||||
-rw-r--r-- | app/assets/stylesheets/pages/labels.scss | 229 |
5 files changed, 167 insertions, 125 deletions
diff --git a/app/assets/javascripts/group_label_subscription.js b/app/assets/javascripts/group_label_subscription.js index 5648cb9a888..d33e3a37580 100644 --- a/app/assets/javascripts/group_label_subscription.js +++ b/app/assets/javascripts/group_label_subscription.js @@ -1,7 +1,12 @@ import $ from 'jquery'; +import { __ } from '~/locale'; import axios from './lib/utils/axios_utils'; import flash from './flash'; -import { __ } from './locale'; + +const tooltipTitles = { + group: __('Unsubscribe at group level'), + project: __('Unsubscribe at project level'), +}; export default class GroupLabelSubscription { constructor(container) { @@ -35,6 +40,7 @@ export default class GroupLabelSubscription { this.$unsubscribeButtons.attr('data-url', url); axios.post(url) + .then(() => GroupLabelSubscription.setNewTooltip($btn)) .then(() => this.toggleSubscriptionButtons()) .catch(() => flash(__('There was an error when subscribing to this label.'))); } @@ -44,4 +50,14 @@ export default class GroupLabelSubscription { this.$subscribeButtons.toggleClass('hidden'); this.$unsubscribeButtons.toggleClass('hidden'); } + + static setNewTooltip($button) { + if (!$button.hasClass('js-subscribe-button')) return; + + const type = $button.hasClass('js-group-level') ? 'group' : 'project'; + const newTitle = tooltipTitles[type]; + + $('.js-unsubscribe-button', $button.closest('.label-actions-list')) + .tooltip('hide').attr('title', newTitle).tooltip('_fixTitle'); + } } diff --git a/app/assets/javascripts/label_manager.js b/app/assets/javascripts/label_manager.js index 8c3de6e4045..8b01024b7d4 100644 --- a/app/assets/javascripts/label_manager.js +++ b/app/assets/javascripts/label_manager.js @@ -13,6 +13,7 @@ export default class LabelManager { this.otherLabels = otherLabels || $('.js-other-labels'); this.errorMessage = 'Unable to update label prioritization at this time'; this.emptyState = document.querySelector('#js-priority-labels-empty-state'); + this.$badgeItemTemplate = $('#js-badge-item-template'); this.sortable = Sortable.create(this.prioritizedLabels.get(0), { filter: '.empty-message', forceFallback: true, @@ -63,7 +64,11 @@ export default class LabelManager { $target = this.otherLabels; $from = this.prioritizedLabels; } - $label.detach().appendTo($target); + + const $detachedLabel = $label.detach(); + this.toggleLabelPriorityBadge($detachedLabel, action); + $detachedLabel.appendTo($target); + if ($from.find('li').length) { $from.find('.empty-message').removeClass('hidden'); } @@ -88,6 +93,14 @@ export default class LabelManager { } } + toggleLabelPriorityBadge($label, action) { + if (action === 'remove') { + $('.js-priority-badge', $label).remove(); + } else { + $('.label-links', $label).append(this.$badgeItemTemplate.clone().html()); + } + } + onPrioritySortUpdate() { this.savePrioritySort() .catch(() => flash(this.errorMessage)); diff --git a/app/assets/javascripts/project_label_subscription.js b/app/assets/javascripts/project_label_subscription.js index 6f06944ebb6..9049f87e037 100644 --- a/app/assets/javascripts/project_label_subscription.js +++ b/app/assets/javascripts/project_label_subscription.js @@ -3,6 +3,17 @@ import { __ } from './locale'; import axios from './lib/utils/axios_utils'; import flash from './flash'; +const tooltipTitles = { + group: { + subscribed: __('Unsubscribe at group level'), + unsubscribed: __('Subscribe at group level'), + }, + project: { + subscribed: __('Unsubscribe at project level'), + unsubscribed: __('Subscribe at project level'), + }, +}; + export default class ProjectLabelSubscription { constructor(container) { this.$container = $(container); @@ -15,12 +26,10 @@ export default class ProjectLabelSubscription { event.preventDefault(); const $btn = $(event.currentTarget); - const $span = $btn.find('span'); const url = $btn.attr('data-url'); const oldStatus = $btn.attr('data-status'); $btn.addClass('disabled'); - $span.toggleClass('hidden'); axios.post(url).then(() => { let newStatus; @@ -32,21 +41,28 @@ export default class ProjectLabelSubscription { [newStatus, newAction] = ['unsubscribed', 'Subscribe']; } - $span.toggleClass('hidden'); $btn.removeClass('disabled'); this.$buttons.attr('data-status', newStatus); this.$buttons.find('> span').text(newAction); - this.$buttons.map((button) => { + this.$buttons.map((i, button) => { const $button = $(button); + const originalTitle = $button.attr('data-original-title'); - if ($button.attr('data-original-title')) { - $button.tooltip('hide').attr('data-original-title', newAction).tooltip('_fixTitle'); + if (originalTitle) { + ProjectLabelSubscription.setNewTitle($button, originalTitle, newStatus, newAction); } return button; }); }).catch(() => flash(__('There was an error subscribing to this label.'))); } + + static setNewTitle($button, originalTitle, newStatus) { + const type = /group/.test(originalTitle) ? 'group' : 'project'; + const newTitle = tooltipTitles[type][newStatus]; + + $button.attr('title', newTitle).tooltip('_fixTitle'); + } } diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss index e6e74d55f64..dd7374c503e 100644 --- a/app/assets/stylesheets/framework/variables.scss +++ b/app/assets/stylesheets/framework/variables.scss @@ -808,3 +808,5 @@ $modal-body-height: 134px; Prometheus */ $prometheus-table-row-highlight-color: $theme-gray-100; + +$priority-label-empty-state-width: 114px; diff --git a/app/assets/stylesheets/pages/labels.scss b/app/assets/stylesheets/pages/labels.scss index e178371d21f..785df23a355 100644 --- a/app/assets/stylesheets/pages/labels.scss +++ b/app/assets/stylesheets/pages/labels.scss @@ -57,69 +57,8 @@ border-bottom-left-radius: $border-radius-base; } -.label-row { - .label-name { - display: inline-block; - margin-bottom: 10px; - - @include media-breakpoint-up(sm) { - width: 200px; - margin-left: $gl-padding * 2; - margin-bottom: 0; - } - - .badge { - overflow: hidden; - text-overflow: ellipsis; - max-width: 100%; - } - } - - .label-type { - display: block; - margin-bottom: 10px; - margin-left: 50px; - - @include media-breakpoint-up(sm) { - display: inline-block; - width: 100px; - margin-left: 10px; - margin-bottom: 0; - vertical-align: top; - } - } - - .label-description { - display: block; - margin-bottom: 10px; - - .description-text { - margin-bottom: $gl-padding; - } - - a { - color: $blue-600; - } - - @include media-breakpoint-up(sm) { - display: inline-block; - max-width: 50%; - margin-left: 10px; - margin-bottom: 0; - vertical-align: top; - } - } - - .badge { - padding: 4px $grid-size; - font-size: $label-font-size; - position: relative; - top: ($grid-size / 2); - } -} - .color-label { - padding: 0 $grid-size; + padding: $gl-padding-4 $grid-size; line-height: 16px; border-radius: $label-border-radius; color: $white-light; @@ -133,26 +72,29 @@ } .manage-labels-list { - @media(min-width: map-get($grid-breakpoints, md)) { - &.content-list li { - padding: $gl-padding 0; - } - } - > li:not(.empty-message):not(.is-not-draggable) { background-color: $white-light; - cursor: move; - cursor: -webkit-grab; - cursor: -moz-grab; - - &:active { - cursor: -webkit-grabbing; - cursor: -moz-grabbing; - } + margin-bottom: 5px; + display: flex; + justify-content: space-between; + padding: $gl-padding; + border-radius: $border-radius-default; &.sortable-ghost { opacity: 0.3; } + + .prioritized-labels & { + box-shadow: 0 1px 2px $issue-boards-card-shadow; + cursor: move; + cursor: -webkit-grab; + cursor: -moz-grab; + + &:active { + cursor: -webkit-grabbing; + cursor: -moz-grabbing; + } + } } .btn-action { @@ -170,27 +112,6 @@ } } } - - .dropdown { - @include media-breakpoint-up(sm) { - float: right; - } - } - - @include media-breakpoint-down(xs) { - .dropdown-menu { - min-width: 100%; - } - } -} - -.draggable-handler { - display: inline-block; - vertical-align: top; - margin: 5px 0; - opacity: 0; - transition: opacity .3s; - color: $gray-darkest; } .prioritized-labels { @@ -215,22 +136,6 @@ } } -.toggle-priority { - display: inline-block; - vertical-align: top; - - button { - border-color: transparent; - padding: 5px 8px; - vertical-align: top; - font-size: 14px; - - &:hover { - border-color: transparent; - } - } -} - .filtered-labels { font-size: 0; padding: 12px 16px; @@ -284,10 +189,8 @@ } .label-subscribe-button { - @media(min-width: map-get($grid-breakpoints, md)) { - min-width: 105px; - margin-left: $gl-padding; - } + width: 105px; + font-weight: 200; .label-subscribe-button-icon { &[disabled] { @@ -324,3 +227,95 @@ font-size: $label-font-size; } } + +.labels-container { + background-color: $gray-light; + border-radius: $border-radius-default; + padding: $gl-padding $gl-padding-8; +} + +.label-actions-list { + list-style: none; + flex-shrink: 0; + padding: 0; +} + +.label-badge { + color: $theme-gray-900; + font-weight: $gl-font-weight-normal; + padding: $gl-padding-4 $gl-padding-8; + border-radius: $border-radius-default; + font-size: $label-font-size; +} + +.label-badge-blue { + background-color: $theme-blue-100; +} + +.label-badge-gray { + background-color: $theme-gray-100; +} + +.label-links { + list-style: none; + padding: 0; + white-space: nowrap; +} + +.label-link-item { + padding: 0; +} + +.label-list-item { + .content-list &::before, + .content-list &::after { + content: none; + } + + .label-name { + width: 150px; + flex-shrink: 0; + + .label { + overflow: hidden; + text-overflow: ellipsis; + max-width: 100%; + } + } + + .label-description { + flex-grow: 1; + + a { + color: $blue-600; + } + } + + .label { + padding: 4px $grid-size; + font-size: $label-font-size; + position: relative; + top: $gl-padding-4; + } + + .label-action { + color: $theme-gray-800; + cursor: pointer; + + svg { + fill: $theme-gray-800; + } + + &:hover { + color: $blue-600; + + svg { + fill: $blue-600; + } + } + } +} + +.priority-labels-empty-state .svg-content img { + max-width: $priority-label-empty-state-width; +} |