From ac4b0b94fe3cbbeadb5c8c3884f42a63ede12dc9 Mon Sep 17 00:00:00 2001 From: Jose Ivan Vargas Date: Tue, 14 Feb 2017 19:49:36 -0600 Subject: [PATCH] Port of user-callouts to EE --- app/assets/javascripts/dispatcher.js.es6 | 5 +++ app/assets/javascripts/user_callout.js | 35 +++++++++++++++++ app/assets/stylesheets/pages/profile.scss | 39 +++++++++++++++++++ app/views/dashboard/projects/index.html.haml | 2 + app/views/shared/_user_callout.html.haml | 14 +++++++ .../shared/icons/_icon_customization.svg | 1 + app/views/users/show.html.haml | 2 + changelogs/unreleased/user-callouts.yml | 4 ++ spec/features/user_callout_spec.rb | 37 ++++++++++++++++++ .../fixtures/user_callout.html.haml | 13 +++++++ spec/javascripts/user_callout_spec.js | 36 +++++++++++++++++ 11 files changed, 188 insertions(+) create mode 100644 app/assets/javascripts/user_callout.js create mode 100644 app/views/shared/_user_callout.html.haml create mode 100644 app/views/shared/icons/_icon_customization.svg create mode 100644 changelogs/unreleased/user-callouts.yml create mode 100644 spec/features/user_callout_spec.rb create mode 100644 spec/javascripts/fixtures/user_callout.html.haml create mode 100644 spec/javascripts/user_callout_spec.js diff --git a/app/assets/javascripts/dispatcher.js.es6 b/app/assets/javascripts/dispatcher.js.es6 index 5865164f9d19ab..55db9339cf0132 100644 --- a/app/assets/javascripts/dispatcher.js.es6 +++ b/app/assets/javascripts/dispatcher.js.es6 @@ -38,6 +38,7 @@ /* global AdminEmailSelect */ const ShortcutsBlob = require('./shortcuts_blob'); +const UserCallout = require('./user_callout'); (function() { var Dispatcher; @@ -284,6 +285,9 @@ const ShortcutsBlob = require('./shortcuts_blob'); case 'ci:lints:show': new gl.CILintEditor(); break; + case 'users:show': + new UserCallout(); + break; } switch (path.first()) { case 'sessions': @@ -323,6 +327,7 @@ const ShortcutsBlob = require('./shortcuts_blob'); case 'dashboard': case 'root': shortcut_handler = new ShortcutsDashboardNavigation(); + new UserCallout(); break; case 'profiles': new NotificationsForm(); diff --git a/app/assets/javascripts/user_callout.js b/app/assets/javascripts/user_callout.js new file mode 100644 index 00000000000000..9aa565074e4c54 --- /dev/null +++ b/app/assets/javascripts/user_callout.js @@ -0,0 +1,35 @@ +/* eslint-disable arrow-parens, class-methods-use-this, no-param-reassign */ +/* global Cookies */ + +const userCalloutElementName = '.user-callout'; +const closeButton = '.close-user-callout'; +const userCalloutBtn = '.user-callout-btn'; + +const USER_CALLOUT_COOKIE = 'user_callout_dismissed'; + +class UserCallout { + constructor() { + this.isCalloutDismissed = Cookies.get(USER_CALLOUT_COOKIE); + this.init(); + this.isUserCalloutDismissed(); + } + + init() { + $(document) + .on('click', closeButton, () => this.closeAndDismissCallout()) + .on('click', userCalloutBtn, () => this.closeAndDismissCallout()); + } + + closeAndDismissCallout() { + $(userCalloutElementName).hide(); + Cookies.set(USER_CALLOUT_COOKIE, '1'); + } + + isUserCalloutDismissed() { + if (!this.isCalloutDismissed) { + $(userCalloutElementName).show(); + } + } +} + +module.exports = UserCallout; diff --git a/app/assets/stylesheets/pages/profile.scss b/app/assets/stylesheets/pages/profile.scss index 8031c4467a47db..dd252bf1e57c65 100644 --- a/app/assets/stylesheets/pages/profile.scss +++ b/app/assets/stylesheets/pages/profile.scss @@ -277,3 +277,42 @@ table.u2f-registrations { padding-left: 18px; } } + +.user-callout { + display: none; + margin: 24px auto 0; + + .bordered-box { + border: 1px solid $border-color; + border-radius: $border-radius-default; + } + + .landing { + margin-bottom: $gl-padding; + + .close { + margin-right: 20px; + } + + .dismiss-icon { + float: right; + cursor: pointer; + color: $cycle-analytics-dismiss-icon-color; + } + + .svg-container { + text-align: center; + + svg { + width: 136px; + height: 136px; + } + } + } + + @media(max-width: $screen-xs-max) { + .inner-content { + padding-left: 30px; + } + } +} diff --git a/app/views/dashboard/projects/index.html.haml b/app/views/dashboard/projects/index.html.haml index 4f36a4a1c739f9..8276cce693c3dc 100644 --- a/app/views/dashboard/projects/index.html.haml +++ b/app/views/dashboard/projects/index.html.haml @@ -5,6 +5,8 @@ - page_title "Projects" - header_title "Projects", dashboard_projects_path += render partial: 'shared/user_callout' + - if @projects.any? || params[:filter_projects] = render 'dashboard/projects_head' diff --git a/app/views/shared/_user_callout.html.haml b/app/views/shared/_user_callout.html.haml new file mode 100644 index 00000000000000..3f31025156841b --- /dev/null +++ b/app/views/shared/_user_callout.html.haml @@ -0,0 +1,14 @@ +.user-callout + .bordered-box.landing.content-block + %button.btn.btn-default.close.close-user-callout{ type: "button" } + = icon("times", class: "dismiss-icon") + .row + .col-sm-3.col-xs-12.svg-container + = custom_icon('icon_customization') + .col-sm-8.col-xs-12.inner-content + %h4 + Customize your experience + %p + Change syntax themes, default project pages, and more in preferences. + + = link_to "Check it out", profile_preferences_path, class: 'btn user-callout-btn' diff --git a/app/views/shared/icons/_icon_customization.svg b/app/views/shared/icons/_icon_customization.svg new file mode 100644 index 00000000000000..b257920803978b --- /dev/null +++ b/app/views/shared/icons/_icon_customization.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml index dc2fea450bd5d1..d89001efb07a7d 100644 --- a/app/views/users/show.html.haml +++ b/app/views/users/show.html.haml @@ -97,6 +97,8 @@ = link_to user_snippets_path, data: {target: 'div#snippets', action: 'snippets', toggle: 'tab'} do Snippets + %div{ class: container_class } + = render partial: 'shared/user_callout' %div{ class: container_class } .tab-content #activity.tab-pane diff --git a/changelogs/unreleased/user-callouts.yml b/changelogs/unreleased/user-callouts.yml new file mode 100644 index 00000000000000..f6ce06a3d8f58e --- /dev/null +++ b/changelogs/unreleased/user-callouts.yml @@ -0,0 +1,4 @@ +--- +title: Added user callouts to the projects dashboard and user profile +merge_request: +author: diff --git a/spec/features/user_callout_spec.rb b/spec/features/user_callout_spec.rb new file mode 100644 index 00000000000000..336c4092c98943 --- /dev/null +++ b/spec/features/user_callout_spec.rb @@ -0,0 +1,37 @@ +require 'spec_helper' + +describe 'User Callouts', js: true do + let(:user) { create(:user) } + let(:project) { create(:empty_project, path: 'gitlab', name: 'sample') } + + before do + login_as(user) + project.team << [user, :master] + end + + it 'takes you to the profile preferences when the link is clicked' do + visit dashboard_projects_path + click_link 'Check it out' + expect(current_path).to eq profile_preferences_path + end + + describe 'user callout should appear in two routes' do + it 'shows up on the user profile' do + visit user_path(user) + expect(find('.user-callout')).to have_content 'Customize your experience' + end + + it 'shows up on the dashboard projects' do + visit dashboard_projects_path + expect(find('.user-callout')).to have_content 'Customize your experience' + end + end + + it 'hides the user callout when click on the dismiss icon' do + visit user_path(user) + within('.user-callout') do + find('.close-user-callout').click + end + expect(page).not_to have_selector('#user-callout') + end +end diff --git a/spec/javascripts/fixtures/user_callout.html.haml b/spec/javascripts/fixtures/user_callout.html.haml new file mode 100644 index 00000000000000..ad564469a270c3 --- /dev/null +++ b/spec/javascripts/fixtures/user_callout.html.haml @@ -0,0 +1,13 @@ +.user-callout + .bordered-box.landing.content-block + %button.btn.btn-default.close.close-user-callout{ type: "button" } + %i.fa.fa-times.dismiss-icon + .row + .col-sm-3.col-xs-12.svg-container + .col-sm-8.col-xs-12.inner-content + %h4 + Customize your experience + %p + Change syntax themes, default project pages, and more in preferences. + %a{ href: 'foo', class:'user-callout-btn' } + Check it out diff --git a/spec/javascripts/user_callout_spec.js b/spec/javascripts/user_callout_spec.js new file mode 100644 index 00000000000000..ba5a2656da5295 --- /dev/null +++ b/spec/javascripts/user_callout_spec.js @@ -0,0 +1,36 @@ +/* esint-disable space-before-function-paren, arrow-body-style */ +const UserCallout = require('~/user_callout'); + +const USER_CALLOUT_COOKIE = 'user_callout_dismissed'; +const Cookie = window.Cookies; + +describe('UserCallout', function () { + const fixtureName = 'static/user_callout.html.raw'; + preloadFixtures(fixtureName); + + beforeEach(() => { + loadFixtures(fixtureName); + this.userCallout = new UserCallout(); + this.closeButton = $('.close-user-callout'); + this.userCalloutContainer = $('.user-callout'); + this.userCalloutBtn = $('.user-callout-btn'); + Cookie.set(USER_CALLOUT_COOKIE, 0); + }); + + it('shows when cookie is set to false', () => { + expect(Cookie.get(USER_CALLOUT_COOKIE)).toBeDefined(); + expect(this.userCalloutContainer.is(':visible')).toBe(true); + }); + + it('hides when user clicks on the dismiss-icon', () => { + this.closeButton.click(); + expect(this.userCalloutContainer.is(':visible')).toBe(false); + expect(Cookie.get(USER_CALLOUT_COOKIE)).toBe('1'); + }); + + it('hides when user clicks on the "check it out" button', () => { + this.userCalloutBtn.click(); + expect(this.userCalloutContainer.is(':visible')).toBe(false); + expect(Cookie.get(USER_CALLOUT_COOKIE)).toBe('1'); + }); +}); -- GitLab