Merge branch 'user-callouts' into 'master'
Added user-callouts Closes #27269 See merge request !9249
This commit is contained in:
commit
e96851fceb
|
@ -36,6 +36,7 @@
|
|||
/* global Shortcuts */
|
||||
|
||||
const ShortcutsBlob = require('./shortcuts_blob');
|
||||
const UserCallout = require('./user_callout');
|
||||
|
||||
(function() {
|
||||
var Dispatcher;
|
||||
|
@ -277,6 +278,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':
|
||||
|
@ -313,6 +317,7 @@ const ShortcutsBlob = require('./shortcuts_blob');
|
|||
case 'dashboard':
|
||||
case 'root':
|
||||
shortcut_handler = new ShortcutsDashboardNavigation();
|
||||
new UserCallout();
|
||||
break;
|
||||
case 'profiles':
|
||||
new NotificationsForm();
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
/* global Cookies */
|
||||
|
||||
const userCalloutElementName = '.user-callout';
|
||||
const closeButton = '.close-user-callout';
|
||||
const userCalloutBtn = '.user-callout-btn';
|
||||
const userCalloutSvgAttrName = 'callout-svg';
|
||||
|
||||
const USER_CALLOUT_COOKIE = 'user_callout_dismissed';
|
||||
|
||||
const USER_CALLOUT_TEMPLATE = `
|
||||
<div class="bordered-box landing content-block">
|
||||
<button class="btn btn-default close close-user-callout" type="button">
|
||||
<i class="fa fa-times dismiss-icon"></i>
|
||||
</button>
|
||||
<div class="row">
|
||||
<div class="col-sm-3 col-xs-12 svg-container">
|
||||
</div>
|
||||
<div class="col-sm-8 col-xs-12 inner-content">
|
||||
<h4>
|
||||
Customize your experience
|
||||
</h4>
|
||||
<p>
|
||||
Change syntax themes, default project pages, and more in preferences.
|
||||
</p>
|
||||
<a class="btn user-callout-btn" href="/profile/preferences">Check it out</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
|
||||
class UserCallout {
|
||||
constructor() {
|
||||
this.isCalloutDismissed = Cookies.get(USER_CALLOUT_COOKIE);
|
||||
this.userCalloutBody = $(userCalloutElementName);
|
||||
this.userCalloutSvg = $(userCalloutElementName).attr(userCalloutSvgAttrName);
|
||||
$(userCalloutElementName).removeAttr(userCalloutSvgAttrName);
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
const $template = $(USER_CALLOUT_TEMPLATE);
|
||||
if (!this.isCalloutDismissed || this.isCalloutDismissed === 'false') {
|
||||
$template.find('.svg-container').append(this.userCalloutSvg);
|
||||
this.userCalloutBody.append($template);
|
||||
$template.find(closeButton).on('click', e => this.dismissCallout(e));
|
||||
$template.find(userCalloutBtn).on('click', e => this.dismissCallout(e));
|
||||
}
|
||||
}
|
||||
|
||||
dismissCallout(e) {
|
||||
Cookies.set(USER_CALLOUT_COOKIE, 'true');
|
||||
const $currentTarget = $(e.currentTarget);
|
||||
if ($currentTarget.hasClass('close-user-callout')) {
|
||||
this.userCalloutBody.empty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = UserCallout;
|
|
@ -277,3 +277,41 @@ table.u2f-registrations {
|
|||
padding-left: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
.user-callout {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
- page_title "Projects"
|
||||
- header_title "Projects", dashboard_projects_path
|
||||
|
||||
.user-callout{ 'callout-svg' => custom_icon('icon_customization') }
|
||||
|
||||
- if @projects.any? || params[:filter_projects]
|
||||
= render 'dashboard/projects_head'
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 112 90" xmlns:xlink="http://www.w3.org/1999/xlink"><g fill="none" fill-rule="evenodd"><rect width="112" height="90" fill="#fff" rx="6"/><path fill="#eee" fill-rule="nonzero" d="m4 6.01v77.98c0 1.11.899 2.01 2 2.01h100c1.105 0 2-.898 2-2.01v-77.98c0-1.11-.899-2.01-2-2.01h-100c-1.105 0-2 .898-2 2.01m-4 0c0-3.319 2.686-6.01 6-6.01h100c3.315 0 6 2.694 6 6.01v77.98c0 3.319-2.686 6.01-6 6.01h-100c-3.315 0-6-2.694-6-6.01v-77.98"/><g transform="translate(26 35)"><rect width="4" height="39" x="5" fill="#eee" rx="2" id="0"/><rect width="4" height="21" x="5" y="18" fill="#fef0ea" rx="2"/><circle cx="7" cy="13" r="5" fill="#fff"/><path fill="#fb722e" fill-rule="nonzero" d="m7 20c-3.866 0-7-3.134-7-7 0-3.866 3.134-7 7-7 3.866 0 7 3.134 7 7 0 3.866-3.134 7-7 7m0-4c1.657 0 3-1.343 3-3 0-1.657-1.343-3-3-3-1.657 0-3 1.343-3 3 0 1.657 1.343 3 3 3"/></g><g transform="translate(49 35)"><use xlink:href="#0"/><rect width="4" height="21" x="5" y="18" fill="#b5a7dd" rx="2"/><circle cx="7" cy="25" r="5" fill="#fff"/><path fill="#6b4fbb" fill-rule="nonzero" d="m7 32c-3.866 0-7-3.134-7-7 0-3.866 3.134-7 7-7 3.866 0 7 3.134 7 7 0 3.866-3.134 7-7 7m0-4c1.657 0 3-1.343 3-3 0-1.657-1.343-3-3-3-1.657 0-3 1.343-3 3 0 1.657 1.343 3 3 3"/></g><g transform="translate(72 33)"><rect width="4" height="39" x="5" y="2" fill="#eee" rx="2"/><rect width="4" height="34" x="5" y="7" fill="#fef0ea" rx="2"/><circle cx="7" cy="7" r="5" fill="#fff"/><path fill="#fb722e" fill-rule="nonzero" d="m7 14c-3.866 0-7-3.134-7-7 0-3.866 3.134-7 7-7 3.866 0 7 3.134 7 7 0 3.866-3.134 7-7 7m0-4c1.657 0 3-1.343 3-3 0-1.657-1.343-3-3-3-1.657 0-3 1.343-3 3 0 1.657 1.343 3 3 3"/></g><g fill="#6b4fbb"><circle cx="13.5" cy="11.5" r="2.5"/><circle cx="23.5" cy="11.5" r="2.5" opacity=".5"/><circle cx="33.5" cy="11.5" r="2.5" opacity=".5"/></g><path fill="#eee" d="m0 19h111v4h-111z"/></g></svg>
|
After Width: | Height: | Size: 1.9 KiB |
|
@ -98,6 +98,7 @@
|
|||
Snippets
|
||||
|
||||
%div{ class: container_class }
|
||||
.user-callout{ 'callout-svg' => custom_icon('icon_customization') }
|
||||
.tab-content
|
||||
#activity.tab-pane
|
||||
.row-content-block.calender-block.white.second-block.hidden-xs
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Added user callouts to the projects dashboard and user profile
|
||||
merge_request:
|
||||
author:
|
|
@ -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
|
|
@ -0,0 +1,2 @@
|
|||
.user-callout{ 'callout-svg' => custom_icon('icon_customization') }
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
const UserCallout = require('~/user_callout');
|
||||
|
||||
const USER_CALLOUT_COOKIE = 'user_callout_dismissed';
|
||||
const Cookie = window.Cookies;
|
||||
|
||||
describe('UserCallout', () => {
|
||||
const fixtureName = 'static/user_callout.html.raw';
|
||||
preloadFixtures(fixtureName);
|
||||
|
||||
beforeEach(function () {
|
||||
loadFixtures(fixtureName);
|
||||
this.userCallout = new UserCallout();
|
||||
this.closeButton = $('.close-user-callout');
|
||||
this.userCalloutBtn = $('.user-callout-btn');
|
||||
this.userCalloutContainer = $('.user-callout');
|
||||
Cookie.set(USER_CALLOUT_COOKIE, 'false');
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
Cookie.set(USER_CALLOUT_COOKIE, 'false');
|
||||
});
|
||||
|
||||
it('shows when cookie is set to false', function () {
|
||||
expect(Cookie.get(USER_CALLOUT_COOKIE)).toBeDefined();
|
||||
expect(this.userCalloutContainer.is(':visible')).toBe(true);
|
||||
});
|
||||
|
||||
it('hides when user clicks on the dismiss-icon', function () {
|
||||
this.closeButton.click();
|
||||
expect(Cookie.get(USER_CALLOUT_COOKIE)).toBe('true');
|
||||
});
|
||||
|
||||
it('hides when user clicks on the "check it out" button', function () {
|
||||
this.userCalloutBtn.click();
|
||||
expect(Cookie.get(USER_CALLOUT_COOKIE)).toBe('true');
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue