From 544c785b159f54c973dfa994c47628a3e427774e Mon Sep 17 00:00:00 2001 From: Clement Ho Date: Fri, 18 Aug 2017 17:45:37 -0500 Subject: [PATCH 1/5] [skip ci] add feature highlight --- app/assets/javascripts/feature_highlight.js | 66 +++++++++++++++++++ app/assets/javascripts/main.js | 1 + app/assets/stylesheets/framework.scss | 1 + .../framework/feature_highlight.scss | 66 +++++++++++++++++++ .../nav/_new_project_sidebar.html.haml | 24 +++++++ app/views/shared/icons/_icon_thumbs_up.svg | 1 + 6 files changed, 159 insertions(+) create mode 100644 app/assets/javascripts/feature_highlight.js create mode 100644 app/assets/stylesheets/framework/feature_highlight.scss create mode 100644 app/views/shared/icons/_icon_thumbs_up.svg diff --git a/app/assets/javascripts/feature_highlight.js b/app/assets/javascripts/feature_highlight.js new file mode 100644 index 00000000000000..a83310c74f255e --- /dev/null +++ b/app/assets/javascripts/feature_highlight.js @@ -0,0 +1,66 @@ +import Cookies from 'js-cookie'; + +const highlightOrder = ['issue-list', 'issue-boards']; + +const mouseenter = function() { + const $featureHighlight = $(this); + $featureHighlight.popover('show'); + $('.popover').on('mouseleave', () => $featureHighlight.popover('hide')); +} + +const mouseleave = function() { + const $featureHighlight = $(this); + if (!$('.popover:hover').length) { + $featureHighlight.popover('hide'); + } +} + +const dismiss = function(cookieId) { + Cookies.set(`feature-highlighted-${cookieId}`, true); + this.popover('hide'); + this.hide(); +} + +const setupDismissButton = function() { + const popoverId = this.getAttribute('aria-describedby'); + const cookieId = this.dataset.highlight; + const $popover = $(this); + + document.querySelector(`#${popoverId} .dismiss-feature-highlight`) + .addEventListener('click', dismiss.bind($popover, cookieId)); +} + +const initFeatureHighlight = (id) => { + const $selector = $(`.js-feature-highlight[data-highlight=${id}]`); + const $parent = $selector.parent(); + const $popoverContent = $parent.siblings('.feature-highlight-popover-content'); + + // Setup popover + $selector.data('content', $popoverContent[0].outerHTML); + $selector.popover({ html: true }); + + $selector.on('mouseenter', mouseenter); + $selector.on('mouseleave', mouseleave); + $selector.on('inserted.bs.popover', setupDismissButton); + + // Override css as we are now ready to explicitly show + // the feature highlight + $selector.show(); +} + +const featureHighlightManager = () => { + highlightOrder.some((id, index) => { + const element = document.querySelector(`.js-feature-highlight[data-highlight=${id}]`); + const previouslyDismissed = Cookies.get(`feature-highlighted-${id}`) === 'true'; + if (element && !previouslyDismissed) { + initFeatureHighlight(id); + return true; + } + + return false; + }); +}; + +featureHighlightManager(); + +export default featureHighlightManager; diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js index 97ce2803ee6ae3..b927601becc38f 100644 --- a/app/assets/javascripts/main.js +++ b/app/assets/javascripts/main.js @@ -102,6 +102,7 @@ import './label_manager'; import './labels'; import './labels_select'; import './layout_nav'; +import './feature_highlight'; import LazyLoader from './lazy_loader'; import './line_highlighter'; import './logo'; diff --git a/app/assets/stylesheets/framework.scss b/app/assets/stylesheets/framework.scss index 31eb1c54519b71..f16201c9d52816 100644 --- a/app/assets/stylesheets/framework.scss +++ b/app/assets/stylesheets/framework.scss @@ -51,3 +51,4 @@ @import "framework/snippets"; @import "framework/memory_graph"; @import "framework/responsive-tables"; +@import "framework/feature_highlight"; diff --git a/app/assets/stylesheets/framework/feature_highlight.scss b/app/assets/stylesheets/framework/feature_highlight.scss new file mode 100644 index 00000000000000..8cd62e0b2f7638 --- /dev/null +++ b/app/assets/stylesheets/framework/feature_highlight.scss @@ -0,0 +1,66 @@ +.feature-highlight { + display: none; + margin-left: 16px; + width: 8px; + height: 8px; + background-color: $blue-500; + border-radius: 50%; + cursor: pointer; + box-shadow: 0 0 0 rgba(31, 120, 209, 0.4); + @include webkit-prefix(animation, pulse-highlight 2s infinite); + + &:hover { + @include webkit-prefix(animation, none); + } +} + +.feature-highlight-popover-content { + display: none; + + hr { + margin: $gl-padding*0.5 0; + } + + // Extend btn-link because it is being overriden by default + .btn-link { + @extend .btn-link; + + &:hover { + @extend .btn-link:hover; + } + + &:focus { + @extend .btn-link:focus; + } + + &:active { + @extend .btn-link:active; + } + + svg path { + fill: currentColor; + } + } + + .dismiss-feature-highlight { + padding: 0; + } +} + +.popover .feature-highlight-popover-content { + display: block; +} + +@include keyframes(pulse-highlight) { + 0% { + @include webkit-prefix(box-shadow, 0 0 0 0 rgba(31, 120, 209, 0.4)); + } + + 70% { + @include webkit-prefix(box-shadow, 0 0 0 10px rgba(31, 120, 209, 0)); + } + + 100% { + @include webkit-prefix(box-shadow, 0 0 0 0 rgba(31, 120, 209, 0)); + } +} diff --git a/app/views/layouts/nav/_new_project_sidebar.html.haml b/app/views/layouts/nav/_new_project_sidebar.html.haml index 115d08230235f8..54eb7da642c4ff 100644 --- a/app/views/layouts/nav/_new_project_sidebar.html.haml +++ b/app/views/layouts/nav/_new_project_sidebar.html.haml @@ -92,11 +92,35 @@ = link_to project_issues_path(@project), title: 'Issues' do %span List + .feature-highlight.js-feature-highlight{ data: { trigger: 'manual', container: 'body', toggle: 'popover', animation: 'false', placement: 'right', highlight: 'issue-list' } } + .feature-highlight-popover-content + Use + = link_to 'Issue List', project_boards_path(@project) + to test this + %hr + %button.btn.btn-link.dismiss-feature-highlight{ type: 'button'} + Got it! Don't show this again + = render 'shared/icons/icon_thumbs_up.svg' = nav_link(controller: :boards) do = link_to project_boards_path(@project), title: 'Boards' do %span Boards + .feature-highlight.js-feature-highlight{ data: { trigger: 'manual', container: 'body', toggle: 'popover', animation: 'false', placement: 'right', highlight: 'issue-boards' } } + .feature-highlight-popover-content + Use + = link_to 'Issue Boards', project_boards_path(@project) + to create customized software development workflows like + %strong + Scrum + or + %strong + Kanban + %hr + %button.btn.btn-link.dismiss-feature-highlight{ type: 'button'} + Got it! Don't show this again + = render 'shared/icons/icon_thumbs_up.svg' + = nav_link(controller: :labels) do = link_to project_labels_path(@project), title: 'Labels' do diff --git a/app/views/shared/icons/_icon_thumbs_up.svg b/app/views/shared/icons/_icon_thumbs_up.svg new file mode 100644 index 00000000000000..7267462418eb53 --- /dev/null +++ b/app/views/shared/icons/_icon_thumbs_up.svg @@ -0,0 +1 @@ + -- GitLab From 0417097c0dd1ceac498ac32f9b59e170e6f525f6 Mon Sep 17 00:00:00 2001 From: Clement Ho Date: Fri, 18 Aug 2017 19:35:44 -0500 Subject: [PATCH 2/5] [skip ci] hide feature highlight for fly out menu --- app/assets/javascripts/feature_highlight.js | 5 ++--- .../stylesheets/framework/feature_highlight.scss | 11 ++++++++++- app/views/layouts/nav/_new_project_sidebar.html.haml | 4 ++-- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/app/assets/javascripts/feature_highlight.js b/app/assets/javascripts/feature_highlight.js index a83310c74f255e..050a0b5a74b4b3 100644 --- a/app/assets/javascripts/feature_highlight.js +++ b/app/assets/javascripts/feature_highlight.js @@ -43,9 +43,8 @@ const initFeatureHighlight = (id) => { $selector.on('mouseleave', mouseleave); $selector.on('inserted.bs.popover', setupDismissButton); - // Override css as we are now ready to explicitly show - // the feature highlight - $selector.show(); + // Display feature highlight + $selector.removeAttr('disabled') } const featureHighlightManager = () => { diff --git a/app/assets/stylesheets/framework/feature_highlight.scss b/app/assets/stylesheets/framework/feature_highlight.scss index 8cd62e0b2f7638..e234f754a04b60 100644 --- a/app/assets/stylesheets/framework/feature_highlight.scss +++ b/app/assets/stylesheets/framework/feature_highlight.scss @@ -1,5 +1,4 @@ .feature-highlight { - display: none; margin-left: 16px; width: 8px; height: 8px; @@ -12,6 +11,16 @@ &:hover { @include webkit-prefix(animation, none); } + + &[disabled] { + display: none; + } +} + +.is-showing-fly-out { + .feature-highlight { + display: none; + } } .feature-highlight-popover-content { diff --git a/app/views/layouts/nav/_new_project_sidebar.html.haml b/app/views/layouts/nav/_new_project_sidebar.html.haml index 54eb7da642c4ff..8c011020a1c840 100644 --- a/app/views/layouts/nav/_new_project_sidebar.html.haml +++ b/app/views/layouts/nav/_new_project_sidebar.html.haml @@ -92,7 +92,7 @@ = link_to project_issues_path(@project), title: 'Issues' do %span List - .feature-highlight.js-feature-highlight{ data: { trigger: 'manual', container: 'body', toggle: 'popover', animation: 'false', placement: 'right', highlight: 'issue-list' } } + .feature-highlight.js-feature-highlight{ disabled: true, data: { trigger: 'manual', container: 'body', toggle: 'popover', animation: 'false', placement: 'right', highlight: 'issue-list' } } .feature-highlight-popover-content Use = link_to 'Issue List', project_boards_path(@project) @@ -106,7 +106,7 @@ = link_to project_boards_path(@project), title: 'Boards' do %span Boards - .feature-highlight.js-feature-highlight{ data: { trigger: 'manual', container: 'body', toggle: 'popover', animation: 'false', placement: 'right', highlight: 'issue-boards' } } + .feature-highlight.js-feature-highlight{ disabled: true, data: { trigger: 'manual', container: 'body', toggle: 'popover', animation: 'false', placement: 'right', highlight: 'issue-boards' } } .feature-highlight-popover-content Use = link_to 'Issue Boards', project_boards_path(@project) -- GitLab From 7c5e0d551bcdd453386fdfd06937bca646ddbc4f Mon Sep 17 00:00:00 2001 From: Clement Ho Date: Mon, 21 Aug 2017 12:21:13 -0500 Subject: [PATCH 3/5] [skip ci] refactor code --- app/assets/javascripts/feature_highlight.js | 65 ------------------- .../feature_highlight/feature_highlight.js | 34 ++++++++++ .../feature_highlight_manager.js | 46 +++++++++++++ .../feature_highlight_options.js | 8 +++ app/assets/javascripts/main.js | 2 +- 5 files changed, 89 insertions(+), 66 deletions(-) delete mode 100644 app/assets/javascripts/feature_highlight.js create mode 100644 app/assets/javascripts/feature_highlight/feature_highlight.js create mode 100644 app/assets/javascripts/feature_highlight/feature_highlight_manager.js create mode 100644 app/assets/javascripts/feature_highlight/feature_highlight_options.js diff --git a/app/assets/javascripts/feature_highlight.js b/app/assets/javascripts/feature_highlight.js deleted file mode 100644 index 050a0b5a74b4b3..00000000000000 --- a/app/assets/javascripts/feature_highlight.js +++ /dev/null @@ -1,65 +0,0 @@ -import Cookies from 'js-cookie'; - -const highlightOrder = ['issue-list', 'issue-boards']; - -const mouseenter = function() { - const $featureHighlight = $(this); - $featureHighlight.popover('show'); - $('.popover').on('mouseleave', () => $featureHighlight.popover('hide')); -} - -const mouseleave = function() { - const $featureHighlight = $(this); - if (!$('.popover:hover').length) { - $featureHighlight.popover('hide'); - } -} - -const dismiss = function(cookieId) { - Cookies.set(`feature-highlighted-${cookieId}`, true); - this.popover('hide'); - this.hide(); -} - -const setupDismissButton = function() { - const popoverId = this.getAttribute('aria-describedby'); - const cookieId = this.dataset.highlight; - const $popover = $(this); - - document.querySelector(`#${popoverId} .dismiss-feature-highlight`) - .addEventListener('click', dismiss.bind($popover, cookieId)); -} - -const initFeatureHighlight = (id) => { - const $selector = $(`.js-feature-highlight[data-highlight=${id}]`); - const $parent = $selector.parent(); - const $popoverContent = $parent.siblings('.feature-highlight-popover-content'); - - // Setup popover - $selector.data('content', $popoverContent[0].outerHTML); - $selector.popover({ html: true }); - - $selector.on('mouseenter', mouseenter); - $selector.on('mouseleave', mouseleave); - $selector.on('inserted.bs.popover', setupDismissButton); - - // Display feature highlight - $selector.removeAttr('disabled') -} - -const featureHighlightManager = () => { - highlightOrder.some((id, index) => { - const element = document.querySelector(`.js-feature-highlight[data-highlight=${id}]`); - const previouslyDismissed = Cookies.get(`feature-highlighted-${id}`) === 'true'; - if (element && !previouslyDismissed) { - initFeatureHighlight(id); - return true; - } - - return false; - }); -}; - -featureHighlightManager(); - -export default featureHighlightManager; diff --git a/app/assets/javascripts/feature_highlight/feature_highlight.js b/app/assets/javascripts/feature_highlight/feature_highlight.js new file mode 100644 index 00000000000000..a9a0d91855f83c --- /dev/null +++ b/app/assets/javascripts/feature_highlight/feature_highlight.js @@ -0,0 +1,34 @@ +import Cookies from 'js-cookie'; + +export const getCookieName = cookieId => `feature-highlighted-${cookieId}`; +export const getSelector = highlightId => `.js-feature-highlight[data-highlight=${highlightId}]`; + +export const dismiss = function dismiss(cookieId) { + Cookies.set(getCookieName(cookieId), true); + this.popover('hide'); + this.hide(); +}; + +export const mouseenter = function mouseenter() { + const $featureHighlight = $(this); + $featureHighlight.popover('show'); + + document.querySelector('.popover') + .addEventListener('mouseleave', () => $featureHighlight.popover('hide')); +}; + +export const mouseleave = function mouseleave() { + if (!document.querySelector('.popover:hover')) { + const $featureHighlight = $(this); + $featureHighlight.popover('hide'); + } +}; + +export const setupDismissButton = function setupDismissButton() { + const popoverId = this.getAttribute('aria-describedby'); + const cookieId = this.dataset.highlight; + const $popover = $(this); + + document.querySelector(`#${popoverId} .dismiss-feature-highlight`) + .addEventListener('click', dismiss.bind($popover, cookieId)); +}; diff --git a/app/assets/javascripts/feature_highlight/feature_highlight_manager.js b/app/assets/javascripts/feature_highlight/feature_highlight_manager.js new file mode 100644 index 00000000000000..66b2ee440a3054 --- /dev/null +++ b/app/assets/javascripts/feature_highlight/feature_highlight_manager.js @@ -0,0 +1,46 @@ +import Cookies from 'js-cookie'; +import { + getCookieName, + getSelector, + setupDismissButton, + mouseenter, + mouseleave, +} from './feature_highlight'; + +export default class FeatureHighlightManager { + constructor(highlightOrder) { + this.highlightOrder = highlightOrder; + } + + init() { + const featureId = this.highlightOrder.find(FeatureHighlightManager.shouldHighlightFeature); + + if (featureId) { + FeatureHighlightManager.highlightFeature(featureId); + } + } + + static shouldHighlightFeature(id) { + const element = document.querySelector(getSelector(id)); + const previouslyDismissed = Cookies.get(getCookieName(id)) === 'true'; + + return element && !previouslyDismissed; + } + + static highlightFeature(id) { + const $selector = $(getSelector(id)); + const $parent = $selector.parent(); + const $popoverContent = $parent.siblings('.feature-highlight-popover-content'); + + // Setup popover, load template from HTML + $selector.data('content', $popoverContent[0].outerHTML); + $selector.popover({ html: true }); + + $selector.on('mouseenter', mouseenter); + $selector.on('mouseleave', mouseleave); + $selector.on('inserted.bs.popover', setupDismissButton); + + // Display feature highlight + $selector.removeAttr('disabled'); + } +} diff --git a/app/assets/javascripts/feature_highlight/feature_highlight_options.js b/app/assets/javascripts/feature_highlight/feature_highlight_options.js new file mode 100644 index 00000000000000..d52fdf6e996ae0 --- /dev/null +++ b/app/assets/javascripts/feature_highlight/feature_highlight_options.js @@ -0,0 +1,8 @@ +import FeatureHighlightManager from './feature_highlight_manager'; + +const highlightOrder = ['issue-list', 'issue-boards']; + +document.addEventListener('DOMContentLoaded', () => { + const featureHighlight = new FeatureHighlightManager(highlightOrder); + featureHighlight.init(); +}); diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js index b927601becc38f..e74f2a8eb1c7fa 100644 --- a/app/assets/javascripts/main.js +++ b/app/assets/javascripts/main.js @@ -102,7 +102,7 @@ import './label_manager'; import './labels'; import './labels_select'; import './layout_nav'; -import './feature_highlight'; +import './feature_highlight/feature_highlight_options'; import LazyLoader from './lazy_loader'; import './line_highlighter'; import './logo'; -- GitLab From 0ff94ed712ca6c05b4bb2960528eca11ee7eceef Mon Sep 17 00:00:00 2001 From: Clement Ho Date: Mon, 21 Aug 2017 14:17:51 -0500 Subject: [PATCH 4/5] [skip ci] more code cleanup --- .../feature_highlight/graphic-boards.png | Bin 0 -> 1564 bytes .../feature_highlight/feature_highlight.js | 2 +- .../feature_highlight_manager.js | 17 ++++++++- .../feature_highlight_options.js | 2 +- .../framework/feature_highlight.scss | 30 ++++++++++++++- .../nav/_new_project_sidebar.html.haml | 35 +++++++----------- 6 files changed, 59 insertions(+), 27 deletions(-) create mode 100644 app/assets/images/feature_highlight/graphic-boards.png diff --git a/app/assets/images/feature_highlight/graphic-boards.png b/app/assets/images/feature_highlight/graphic-boards.png new file mode 100644 index 0000000000000000000000000000000000000000..f0550a383746036811565d58329dbeb9f75a3750 GIT binary patch literal 1564 zcmeAS@N?(olHy`uVBq!ia0y~yU~FMvVA#OH%)r24@&DyJ1_p+`0X`wF3}C>?%Jlc| z-)Lhq0||-01=|1q{rjD(=AfeZB}YBmf5+cEji)Kf`JwwtBKQ9-H-3<;@-18KZ=OcB z|L#oRZJ#q#qnxJy$Wi~3tNu4nJwJF)j{nxe;C(-T{`~*{|Gy6}-oO3vCs*y$r%&1b zyZ=4B{P6b2zeiRa-tqX~-@o6!ef#(B>Az<;{~llSr_|uztNZ`%p8k7j&!6eZ$96v{ zirD}5)%TZAzdn8V`Ty4spFe)Mef9mX53ettd^xr8+}F>)-P`(`85kJkN`m}?8F)GV zu`vF6cwcD7wEmc1Po5aA3fez&g4uz+ODF1Tf75cdVPIhS;OXKRQgQ3et>~;41BTXz zDsIO=zKgNi+b8kqk=mXAn{FwIOxoxqU!<0LZabrJor{IWqlHsh0;4X>3h`8!%JnOo zIm{tI$cOV&#?Bp6a+4WnZL1OA@=fW@d9f8wp5NSRViCDQSo@BfMf8TC3E~fv9@??& z6!hZ$u6CmLLe!413DOHU7W68ZAIfXE%~_fVf5_{43(672ki3MK9hfdY~%vlg;qI}0igD2uB$G@-D%-4;Z z%KsiZ5Zdz~cE54K-L#fWx#pS6-*RZC*#}sauAeWtBS-s?37cuI>jfb<_igdJ1fLnM zsQe*#vPJlK-AgwK=HIqVRfjrXO_uOv(G~ywYeKr(1|9n=U4nmtmlOp)XH&5^I<(=J zl8xj7tyGrwBB_Ruo(B`|XEB$hu>2SKeW&5+EWtg&SJ>X2;JByB$M$ZjVA7A@oq|d~ zexK~05Yz1W&$;Cx-yin)=A;(?vNvh0P6AvDJ}mk!kfd~LHRq!D|D&3(EMgNsx0E~V zxlSyn{Ey;j0k*}r6r4UJ{@eZFeRsl?$qGLrr?5YCYEf|JP>AU;;AUoQNmne8DQ!4# z^bRAF{}nlbBPRvFEN55Pq9}3IA>&5tuP+QOZLtzh9T*r{1R%r?eWx>dw~8(Ms8M*DhiWohDSvR2-ad-a;24u^t`XyfA*%q)7( z_yj5zeQPM_IWNVb(7?dNq0kV(#K$WLp+$@a*qY z4_Q*NzelI`|92~9Ze2yzsX4nB{hw8~>FMH==k!)ua%ju#HwrzWEf8i?H*@wfmc+AX z8#bLf8#J|EAtN>fWH!Xz9!!o8{~tHH{6aZp8KdJHHbV}k{`G-JkIKg{=E|>|Inyn_ zZe?Jr`N{J>i_K47UvX&u6X`l}t%IKX+(gCaKgkX${0L^sOJsyFHaUnYaD*@(vbMK2 z{we+W%^9QRTMgyQ(>_Iqq|aIsb>;9mAGNf&x2@b=`EuFAH5`JQxEIEA)U-`Mv_aqp z4>L!g;IV3h$Ddx7aHlaTYB@=}WlZlXzVCyxISms$B&t-T)5#BiumKyQbP<{tZlwNJXFi_@f{u9V!H|A1!` z*Ta`SpHrs%Jr~~6ZhV%x<$u|`2P_T}ZA>rJE^U?;`F`KqhC{5Y!n5PcUrwg}xH{)| zdlcT-e$bWq8y@~Rx*(=^eNVvR{dbP(w13ddo|BoEtl&_=#>B!AuHeAo>XFB9s@Ljwb&lWdD{`Jr9aEpH3;K&8B=tDnm{r-UW|Cl `feature-highlighted-${cookieId}`; export const getSelector = highlightId => `.js-feature-highlight[data-highlight=${highlightId}]`; -export const dismiss = function dismiss(cookieId) { +const dismiss = function dismiss(cookieId) { Cookies.set(getCookieName(cookieId), true); this.popover('hide'); this.hide(); diff --git a/app/assets/javascripts/feature_highlight/feature_highlight_manager.js b/app/assets/javascripts/feature_highlight/feature_highlight_manager.js index 66b2ee440a3054..303b375c5395e6 100644 --- a/app/assets/javascripts/feature_highlight/feature_highlight_manager.js +++ b/app/assets/javascripts/feature_highlight/feature_highlight_manager.js @@ -17,6 +17,10 @@ export default class FeatureHighlightManager { if (featureId) { FeatureHighlightManager.highlightFeature(featureId); + window.addEventListener('scroll', () => { + const $featureHighlight = $(getSelector(featureId)); + $featureHighlight.popover('hide'); + }); } } @@ -32,9 +36,18 @@ export default class FeatureHighlightManager { const $parent = $selector.parent(); const $popoverContent = $parent.siblings('.feature-highlight-popover-content'); - // Setup popover, load template from HTML + // Setup popover $selector.data('content', $popoverContent[0].outerHTML); - $selector.popover({ html: true }); + $selector.popover({ + html: true, + // Override the existing template to add custom CSS classes + template: ` + + `, + }); $selector.on('mouseenter', mouseenter); $selector.on('mouseleave', mouseleave); diff --git a/app/assets/javascripts/feature_highlight/feature_highlight_options.js b/app/assets/javascripts/feature_highlight/feature_highlight_options.js index d52fdf6e996ae0..51e2eec2165feb 100644 --- a/app/assets/javascripts/feature_highlight/feature_highlight_options.js +++ b/app/assets/javascripts/feature_highlight/feature_highlight_options.js @@ -1,6 +1,6 @@ import FeatureHighlightManager from './feature_highlight_manager'; -const highlightOrder = ['issue-list', 'issue-boards']; +const highlightOrder = ['issue-boards']; document.addEventListener('DOMContentLoaded', () => { const featureHighlight = new FeatureHighlightManager(highlightOrder); diff --git a/app/assets/stylesheets/framework/feature_highlight.scss b/app/assets/stylesheets/framework/feature_highlight.scss index e234f754a04b60..9102272c430809 100644 --- a/app/assets/stylesheets/framework/feature_highlight.scss +++ b/app/assets/stylesheets/framework/feature_highlight.scss @@ -1,4 +1,6 @@ .feature-highlight { + @include webkit-prefix(animation, pulse-highlight 2s infinite); + margin-left: 16px; width: 8px; height: 8px; @@ -6,7 +8,6 @@ border-radius: 50%; cursor: pointer; box-shadow: 0 0 0 rgba(31, 120, 209, 0.4); - @include webkit-prefix(animation, pulse-highlight 2s infinite); &:hover { @include webkit-prefix(animation, none); @@ -27,7 +28,7 @@ display: none; hr { - margin: $gl-padding*0.5 0; + margin: $gl-padding * 0.5 0; } // Extend btn-link because it is being overriden by default @@ -54,12 +55,37 @@ .dismiss-feature-highlight { padding: 0; } + + img { + width: 100%; + padding: 25px 14px 0; + background-color: rgb(239, 237, 249); + border-top-left-radius: 2px; + border-top-right-radius: 2px; + border-bottom: 1px solid #e1e1e1; + } } .popover .feature-highlight-popover-content { display: block; } +.feature-highlight-popover { + padding: 0; + + .popover-content { + padding: 0; + } + + &.popover > .arrow::after { + border-right-color: rgb(239, 237, 249); + } +} + +.feature-highlight-popover-sub-content { + padding: 9px 14px; +} + @include keyframes(pulse-highlight) { 0% { @include webkit-prefix(box-shadow, 0 0 0 0 rgba(31, 120, 209, 0.4)); diff --git a/app/views/layouts/nav/_new_project_sidebar.html.haml b/app/views/layouts/nav/_new_project_sidebar.html.haml index 8c011020a1c840..ec061ff6cdb5a1 100644 --- a/app/views/layouts/nav/_new_project_sidebar.html.haml +++ b/app/views/layouts/nav/_new_project_sidebar.html.haml @@ -92,15 +92,6 @@ = link_to project_issues_path(@project), title: 'Issues' do %span List - .feature-highlight.js-feature-highlight{ disabled: true, data: { trigger: 'manual', container: 'body', toggle: 'popover', animation: 'false', placement: 'right', highlight: 'issue-list' } } - .feature-highlight-popover-content - Use - = link_to 'Issue List', project_boards_path(@project) - to test this - %hr - %button.btn.btn-link.dismiss-feature-highlight{ type: 'button'} - Got it! Don't show this again - = render 'shared/icons/icon_thumbs_up.svg' = nav_link(controller: :boards) do = link_to project_boards_path(@project), title: 'Boards' do @@ -108,18 +99,20 @@ Boards .feature-highlight.js-feature-highlight{ disabled: true, data: { trigger: 'manual', container: 'body', toggle: 'popover', animation: 'false', placement: 'right', highlight: 'issue-boards' } } .feature-highlight-popover-content - Use - = link_to 'Issue Boards', project_boards_path(@project) - to create customized software development workflows like - %strong - Scrum - or - %strong - Kanban - %hr - %button.btn.btn-link.dismiss-feature-highlight{ type: 'button'} - Got it! Don't show this again - = render 'shared/icons/icon_thumbs_up.svg' + %img{ :alt => "Issue Boards", :src => image_path('feature_highlight/graphic-boards.png') } + .feature-highlight-popover-sub-content + Use + = link_to 'Issue Boards', project_boards_path(@project) + to create customized software development workflows like + %strong + Scrum + or + %strong + Kanban + %hr + %button.btn.btn-link.dismiss-feature-highlight{ type: 'button'} + Got it! Don't show this again + = render 'shared/icons/icon_thumbs_up.svg' = nav_link(controller: :labels) do -- GitLab From be6a27581f5cd8c9993a581f106fac204ac91b97 Mon Sep 17 00:00:00 2001 From: Clement Ho Date: Mon, 21 Aug 2017 14:37:31 -0500 Subject: [PATCH 5/5] [skip ci] disable animation when hovering over popover --- .../feature_highlight/feature_highlight.js | 20 ++++++++++++++----- .../feature_highlight_manager.js | 3 ++- .../framework/feature_highlight.scss | 3 ++- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/app/assets/javascripts/feature_highlight/feature_highlight.js b/app/assets/javascripts/feature_highlight/feature_highlight.js index 27ec1f9cc2349c..f65cb3211a609e 100644 --- a/app/assets/javascripts/feature_highlight/feature_highlight.js +++ b/app/assets/javascripts/feature_highlight/feature_highlight.js @@ -3,24 +3,34 @@ import Cookies from 'js-cookie'; export const getCookieName = cookieId => `feature-highlighted-${cookieId}`; export const getSelector = highlightId => `.js-feature-highlight[data-highlight=${highlightId}]`; -const dismiss = function dismiss(cookieId) { - Cookies.set(getCookieName(cookieId), true); +export const showPopover = function showPopover() { + this.popover('show'); + this.addClass('disable-animation'); +}; + +export const hidePopover = function hidePopover() { this.popover('hide'); + this.removeClass('disable-animation'); +}; + +export const dismiss = function dismiss(cookieId) { + Cookies.set(getCookieName(cookieId), true); + hidePopover.call(this); this.hide(); }; export const mouseenter = function mouseenter() { const $featureHighlight = $(this); - $featureHighlight.popover('show'); + showPopover.call($featureHighlight); document.querySelector('.popover') - .addEventListener('mouseleave', () => $featureHighlight.popover('hide')); + .addEventListener('mouseleave', hidePopover.bind($featureHighlight)); }; export const mouseleave = function mouseleave() { if (!document.querySelector('.popover:hover')) { const $featureHighlight = $(this); - $featureHighlight.popover('hide'); + hidePopover.call($featureHighlight); } }; diff --git a/app/assets/javascripts/feature_highlight/feature_highlight_manager.js b/app/assets/javascripts/feature_highlight/feature_highlight_manager.js index 303b375c5395e6..d5588d2c52b6c2 100644 --- a/app/assets/javascripts/feature_highlight/feature_highlight_manager.js +++ b/app/assets/javascripts/feature_highlight/feature_highlight_manager.js @@ -2,6 +2,7 @@ import Cookies from 'js-cookie'; import { getCookieName, getSelector, + hidePopover, setupDismissButton, mouseenter, mouseleave, @@ -19,7 +20,7 @@ export default class FeatureHighlightManager { FeatureHighlightManager.highlightFeature(featureId); window.addEventListener('scroll', () => { const $featureHighlight = $(getSelector(featureId)); - $featureHighlight.popover('hide'); + hidePopover.call($featureHighlight); }); } } diff --git a/app/assets/stylesheets/framework/feature_highlight.scss b/app/assets/stylesheets/framework/feature_highlight.scss index 9102272c430809..07579a69f1876a 100644 --- a/app/assets/stylesheets/framework/feature_highlight.scss +++ b/app/assets/stylesheets/framework/feature_highlight.scss @@ -9,7 +9,8 @@ cursor: pointer; box-shadow: 0 0 0 rgba(31, 120, 209, 0.4); - &:hover { + &:hover, + &.disable-animation { @include webkit-prefix(animation, none); } -- GitLab