summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGrzegorz Bizon <grzesiek.bizon@gmail.com>2017-07-20 12:42:01 +0200
committerGrzegorz Bizon <grzesiek.bizon@gmail.com>2017-07-20 12:42:01 +0200
commit9c10683b01f9b32275a04bf9ed4e84795a527db7 (patch)
tree534423909af0d036eb2973cb97b3d95e672a5c75
parent54efa041d70707eb28326bb23220ebe8d6efb8aa (diff)
parent001dd56e7bfd04d22f5437569ba8aa60a0317a3e (diff)
downloadgitlab-ce-9c10683b01f9b32275a04bf9ed4e84795a527db7.tar.gz
Merge branch 'master' into backstage/gb/migrate-stages-statuses
* master: Fix background migration cleanup specs Fix JS; make buttons sr accessibile; fix overlay Isolate stage_id reference clean up migration Fix eslint Make sidebar accessible on mobile Add mobile navigation on project page Fix database schema version number Fix background migrations module specs Remove migration dependency from stage_id migration Remove obsolete argument from bg migrations code Add specs for stage_id reference cleanup migration Add pending set of specs for stage_id cleanup migration Rename stage_id reference clean up migration Implement build stage_id reference migration clean up
-rw-r--r--app/assets/javascripts/layout_nav.js7
-rw-r--r--app/assets/javascripts/new_sidebar.js23
-rw-r--r--app/assets/stylesheets/new_nav.scss3
-rw-r--r--app/assets/stylesheets/new_sidebar.scss116
-rw-r--r--app/views/layouts/_page.html.haml2
-rw-r--r--app/views/layouts/nav/_breadcrumbs.html.haml4
-rw-r--r--app/views/layouts/nav/_new_admin_sidebar.html.haml12
-rw-r--r--app/views/layouts/nav/_new_group_sidebar.html.haml14
-rw-r--r--app/views/layouts/nav/_new_profile_sidebar.html.haml12
-rw-r--r--app/views/layouts/nav/_new_project_sidebar.html.haml14
-rw-r--r--db/migrate/20170710083355_clean_stage_id_reference_migration.rb18
-rw-r--r--lib/gitlab/background_migration.rb2
-rw-r--r--spec/lib/gitlab/background_migration_spec.rb6
-rw-r--r--spec/migrations/clean_stage_id_reference_migration_spec.rb34
14 files changed, 220 insertions, 47 deletions
diff --git a/app/assets/javascripts/layout_nav.js b/app/assets/javascripts/layout_nav.js
index 71064ccc539..6186ffe20b3 100644
--- a/app/assets/javascripts/layout_nav.js
+++ b/app/assets/javascripts/layout_nav.js
@@ -1,5 +1,7 @@
/* eslint-disable func-names, space-before-function-paren, no-var, prefer-arrow-callback, no-unused-vars, one-var, one-var-declaration-per-line, vars-on-top, max-len */
import _ from 'underscore';
+import Cookies from 'js-cookie';
+import NewNavSidebar from './new_sidebar';
(function() {
var hideEndFade;
@@ -53,6 +55,11 @@ import _ from 'underscore';
}
$(() => {
+ if (Cookies.get('new_nav') === 'true') {
+ const newNavSidebar = new NewNavSidebar();
+ newNavSidebar.bindEvents();
+ }
+
$(window).on('scroll', _.throttle(applyScrollNavClass, 100));
});
}).call(window);
diff --git a/app/assets/javascripts/new_sidebar.js b/app/assets/javascripts/new_sidebar.js
new file mode 100644
index 00000000000..5f98aff8ced
--- /dev/null
+++ b/app/assets/javascripts/new_sidebar.js
@@ -0,0 +1,23 @@
+export default class NewNavSidebar {
+ constructor() {
+ this.initDomElements();
+ }
+
+ initDomElements() {
+ this.$sidebar = $('.nav-sidebar');
+ this.$overlay = $('.mobile-overlay');
+ this.$openSidebar = $('.toggle-mobile-nav');
+ this.$closeSidebar = $('.close-nav-button');
+ }
+
+ bindEvents() {
+ this.$openSidebar.on('click', () => this.toggleSidebarNav(true));
+ this.$closeSidebar.on('click', () => this.toggleSidebarNav(false));
+ this.$overlay.on('click', () => this.toggleSidebarNav(false));
+ }
+
+ toggleSidebarNav(show) {
+ this.$sidebar.toggleClass('nav-sidebar-expanded', show);
+ this.$overlay.toggleClass('mobile-nav-open', show);
+ }
+}
diff --git a/app/assets/stylesheets/new_nav.scss b/app/assets/stylesheets/new_nav.scss
index 2ee831e5e32..e1873506bec 100644
--- a/app/assets/stylesheets/new_nav.scss
+++ b/app/assets/stylesheets/new_nav.scss
@@ -275,8 +275,6 @@ header.navbar-gitlab-new {
.breadcrumbs {
display: flex;
min-height: 60px;
- padding-top: $gl-padding-top;
- padding-bottom: $gl-padding-top;
color: $gl-text-color;
border-bottom: 1px solid $border-color;
@@ -300,6 +298,7 @@ header.navbar-gitlab-new {
display: flex;
width: 100%;
position: relative;
+ align-items: center;
.dropdown-menu-projects {
margin-top: -$gl-padding;
diff --git a/app/assets/stylesheets/new_sidebar.scss b/app/assets/stylesheets/new_sidebar.scss
index bd9a5d7392d..ce8f4c41cb5 100644
--- a/app/assets/stylesheets/new_sidebar.scss
+++ b/app/assets/stylesheets/new_sidebar.scss
@@ -26,41 +26,75 @@ $new-sidebar-width: 220px;
}
.context-header {
- border-bottom: 1px solid $border-color;
- font-weight: 600;
- display: flex;
- align-items: center;
- padding: 10px 16px 10px 10px;
- color: $gl-text-color;
+ position: relative;
- .avatar-container {
- flex: 0 0 40px;
- background-color: $white-light;
- }
-
- &:hover {
- background-color: $hover-background;
- color: $hover-color;
- border-color: $hover-background;
+ a {
+ border-bottom: 1px solid $border-color;
+ font-weight: 600;
+ display: flex;
+ align-items: center;
+ padding: 10px 16px 10px 10px;
+ color: $gl-text-color;
- .avatar-container {
- border-color: transparent;
+ @media (max-width: $screen-xs-max) {
+ padding-right: 30px;
}
- .settings-avatar {
- background-color: $indigo-500;
+ &:hover {
+ background-color: $hover-background;
+ color: $hover-color;
+ border-color: $hover-background;
- i {
- color: $hover-color;
+ .avatar-container {
+ border-color: transparent;
+ }
+
+ .settings-avatar {
+ background-color: $indigo-500;
+
+ i {
+ color: $hover-color;
+ }
}
}
}
+ .avatar-container {
+ flex: 0 0 40px;
+ background-color: $white-light;
+ }
+
.project-title,
.group-title {
overflow: hidden;
text-overflow: ellipsis;
}
+
+
+ &:hover {
+ .close-nav-button {
+ color: $white-light;
+ }
+ }
+
+ .close-nav-button {
+ display: none;
+ position: absolute;
+ top: 0;
+ right: 0;
+ height: 100%;
+ background-color: transparent;
+ border: 0;
+ padding: 0 10px;
+
+ @media (max-width: $screen-xs-max) {
+ display: block;
+ }
+
+ &:hover {
+ color: $gl-text-color;
+ }
+ }
}
.settings-avatar {
@@ -79,7 +113,7 @@ $new-sidebar-width: 220px;
position: fixed;
z-index: 400;
width: $new-sidebar-width;
- transition: width $sidebar-transition-duration;
+ transition: left $sidebar-transition-duration;
top: 50px;
bottom: 0;
left: 0;
@@ -87,6 +121,10 @@ $new-sidebar-width: 220px;
background-color: $gray-normal;
box-shadow: inset -2px 0 0 $border-color;
+ &.nav-sidebar-expanded {
+ left: 0;
+ }
+
a {
transition: none;
text-decoration: none;
@@ -117,7 +155,7 @@ $new-sidebar-width: 220px;
}
@media (max-width: $screen-xs-max) {
- width: 0;
+ left: (-$new-sidebar-width);
}
}
@@ -183,6 +221,38 @@ $new-sidebar-width: 220px;
}
}
+.toggle-mobile-nav {
+ display: none;
+ background-color: transparent;
+ border: 0;
+ padding: 6px 16px;
+ margin: 0 16px 0 -15px;
+ height: 46px;
+ border-right: 1px solid $gl-text-color-quaternary;
+
+ i {
+ font-size: 20px;
+ color: $gl-text-color-secondary;
+ }
+
+ @media (max-width: $screen-xs-max) {
+ display: inline-block;
+ }
+}
+
+.mobile-overlay {
+ display: none;
+
+ &.mobile-nav-open {
+ display: block;
+ position: fixed;
+ background-color: $black-transparent;
+ height: 100%;
+ width: 100%;
+ z-index: 300;
+ }
+}
+
// Make issue boards full-height now that sub-nav is gone
diff --git a/app/views/layouts/_page.html.haml b/app/views/layouts/_page.html.haml
index e90197320f2..873220cc73d 100644
--- a/app/views/layouts/_page.html.haml
+++ b/app/views/layouts/_page.html.haml
@@ -10,6 +10,8 @@
- if content_for?(:sub_nav)
= yield :sub_nav
.content-wrapper{ class: "#{(layout_nav_class unless show_new_nav?)}" }
+ - if show_new_nav?
+ .mobile-overlay
.alert-wrapper
= render "layouts/broadcast"
- if show_new_nav?
diff --git a/app/views/layouts/nav/_breadcrumbs.html.haml b/app/views/layouts/nav/_breadcrumbs.html.haml
index 9aed0efae1c..4db84771f4e 100644
--- a/app/views/layouts/nav/_breadcrumbs.html.haml
+++ b/app/views/layouts/nav/_breadcrumbs.html.haml
@@ -3,6 +3,10 @@
%nav.breadcrumbs{ role: "navigation" }
.breadcrumbs-container{ class: [container_class, @content_class] }
+ - if defined?(@new_sidebar)
+ = button_tag class: 'toggle-mobile-nav', type: 'button' do
+ %span.sr-only Open sidebar
+ = icon ('bars')
.breadcrumbs-links.js-title-container
- unless hide_top_links
.title
diff --git a/app/views/layouts/nav/_new_admin_sidebar.html.haml b/app/views/layouts/nav/_new_admin_sidebar.html.haml
index 5cc636e89ef..95443de40c2 100644
--- a/app/views/layouts/nav/_new_admin_sidebar.html.haml
+++ b/app/views/layouts/nav/_new_admin_sidebar.html.haml
@@ -1,8 +1,12 @@
.nav-sidebar
- = link_to admin_root_path, title: 'Admin Overview', class: 'context-header' do
- .avatar-container.s40.settings-avatar
- = icon('wrench')
- .project-title Admin Area
+ .context-header
+ = link_to admin_root_path, title: 'Admin Overview' do
+ .avatar-container.s40.settings-avatar
+ = icon('wrench')
+ .project-title Admin Area
+ = button_tag class: 'close-nav-button', type: 'button' do
+ %span.sr-only Close sidebar
+ = icon ('times')
%ul.sidebar-top-level-items
= nav_link(controller: %w(dashboard admin projects users groups jobs runners cohorts), html_options: {class: 'home'}) do
= link_to admin_root_path, title: 'Overview', class: 'shortcuts-tree' do
diff --git a/app/views/layouts/nav/_new_group_sidebar.html.haml b/app/views/layouts/nav/_new_group_sidebar.html.haml
index 6e0c45739f1..a7897c09e79 100644
--- a/app/views/layouts/nav/_new_group_sidebar.html.haml
+++ b/app/views/layouts/nav/_new_group_sidebar.html.haml
@@ -1,9 +1,13 @@
.nav-sidebar
- = link_to group_path(@group), title: @group.name, class: 'context-header' do
- .avatar-container.s40.group-avatar
- = image_tag group_icon(@group), class: "avatar s40 avatar-tile"
- .group-title
- = @group.name
+ .context-header
+ = link_to group_path(@group), title: @group.name do
+ .avatar-container.s40.group-avatar
+ = image_tag group_icon(@group), class: "avatar s40 avatar-tile"
+ .group-title
+ = @group.name
+ = button_tag class: 'close-nav-button', type: 'button' do
+ %span.sr-only Close sidebar
+ = icon ('times')
%ul.sidebar-top-level-items
= nav_link(path: ['groups#show', 'groups#activity', 'groups#subgroups'], html_options: { class: 'home' }) do
= link_to group_path(@group), title: 'About group' do
diff --git a/app/views/layouts/nav/_new_profile_sidebar.html.haml b/app/views/layouts/nav/_new_profile_sidebar.html.haml
index 033ea149cfb..239e6b949e2 100644
--- a/app/views/layouts/nav/_new_profile_sidebar.html.haml
+++ b/app/views/layouts/nav/_new_profile_sidebar.html.haml
@@ -1,8 +1,12 @@
.nav-sidebar
- = link_to profile_path, title: 'Profile Settings', class: 'context-header' do
- .avatar-container.s40.settings-avatar
- = icon('user')
- .project-title User Settings
+ .context-header
+ = link_to profile_path, title: 'Profile Settings' do
+ .avatar-container.s40.settings-avatar
+ = icon('user')
+ .project-title User Settings
+ = button_tag class: 'close-nav-button', type: 'button' do
+ %span.sr-only Close sidebar
+ = icon ('times')
%ul.sidebar-top-level-items
= nav_link(path: 'profiles#show', html_options: {class: 'home'}) do
= link_to profile_path, title: 'Profile Settings' do
diff --git a/app/views/layouts/nav/_new_project_sidebar.html.haml b/app/views/layouts/nav/_new_project_sidebar.html.haml
index 882123c0b0a..21f175291fa 100644
--- a/app/views/layouts/nav/_new_project_sidebar.html.haml
+++ b/app/views/layouts/nav/_new_project_sidebar.html.haml
@@ -1,10 +1,14 @@
.nav-sidebar
- can_edit = can?(current_user, :admin_project, @project)
- = link_to project_path(@project), title: @project.name, class: 'context-header' do
- .avatar-container.s40.project-avatar
- = project_icon(@project, alt: @project.name, class: 'avatar s40 avatar-tile')
- .project-title
- = @project.name
+ .context-header
+ = link_to project_path(@project), title: @project.name do
+ .avatar-container.s40.project-avatar
+ = project_icon(@project, alt: @project.name, class: 'avatar s40 avatar-tile')
+ .project-title
+ = @project.name
+ = button_tag class: 'close-nav-button', type: 'button' do
+ %span.sr-only Close sidebar
+ = icon ('times')
%ul.sidebar-top-level-items
= nav_link(path: ['projects#show', 'projects#activity', 'cycle_analytics#show'], html_options: { class: 'home' }) do
= link_to project_path(@project), title: 'About project', class: 'shortcuts-project' do
diff --git a/db/migrate/20170710083355_clean_stage_id_reference_migration.rb b/db/migrate/20170710083355_clean_stage_id_reference_migration.rb
new file mode 100644
index 00000000000..681203eaf40
--- /dev/null
+++ b/db/migrate/20170710083355_clean_stage_id_reference_migration.rb
@@ -0,0 +1,18 @@
+class CleanStageIdReferenceMigration < ActiveRecord::Migration
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ ##
+ # `MigrateStageIdReferenceInBackground` background migration cleanup.
+ #
+ def up
+ Gitlab::BackgroundMigration.steal('MigrateBuildStageIdReference')
+ end
+
+ def down
+ # noop
+ end
+end
diff --git a/lib/gitlab/background_migration.rb b/lib/gitlab/background_migration.rb
index b0741b1fba7..d3f66877672 100644
--- a/lib/gitlab/background_migration.rb
+++ b/lib/gitlab/background_migration.rb
@@ -26,7 +26,7 @@ module Gitlab
next unless migration_class == steal_class
begin
- perform(migration_class, migration_args, retries: 3) if job.delete
+ perform(migration_class, migration_args) if job.delete
rescue Exception # rubocop:disable Lint/RescueException
BackgroundMigrationWorker # enqueue this migration again
.perform_async(migration_class, migration_args)
diff --git a/spec/lib/gitlab/background_migration_spec.rb b/spec/lib/gitlab/background_migration_spec.rb
index cfa59280139..4ad69aeba43 100644
--- a/spec/lib/gitlab/background_migration_spec.rb
+++ b/spec/lib/gitlab/background_migration_spec.rb
@@ -25,7 +25,7 @@ describe Gitlab::BackgroundMigration do
expect(queue[0]).to receive(:delete).and_return(true)
expect(described_class).to receive(:perform)
- .with('Foo', [10, 20], anything)
+ .with('Foo', [10, 20])
described_class.steal('Foo')
end
@@ -93,9 +93,9 @@ describe Gitlab::BackgroundMigration do
it 'steals from the scheduled sets queue first' do
Sidekiq::Testing.disable! do
expect(described_class).to receive(:perform)
- .with('Object', [1], anything).ordered
+ .with('Object', [1]).ordered
expect(described_class).to receive(:perform)
- .with('Object', [2], anything).ordered
+ .with('Object', [2]).ordered
BackgroundMigrationWorker.perform_async('Object', [2])
BackgroundMigrationWorker.perform_in(10.minutes, 'Object', [1])
diff --git a/spec/migrations/clean_stage_id_reference_migration_spec.rb b/spec/migrations/clean_stage_id_reference_migration_spec.rb
new file mode 100644
index 00000000000..9a581df28a2
--- /dev/null
+++ b/spec/migrations/clean_stage_id_reference_migration_spec.rb
@@ -0,0 +1,34 @@
+require 'spec_helper'
+require Rails.root.join('db', 'migrate', '20170710083355_clean_stage_id_reference_migration.rb')
+
+describe CleanStageIdReferenceMigration, :migration, :sidekiq, :redis do
+ let(:migration_class) { 'MigrateBuildStageIdReference' }
+ let(:migration) { spy('migration') }
+
+ before do
+ allow(Gitlab::BackgroundMigration.const_get(migration_class))
+ .to receive(:new).and_return(migration)
+ end
+
+ context 'when there are pending background migrations' do
+ it 'processes pending jobs synchronously' do
+ Sidekiq::Testing.disable! do
+ BackgroundMigrationWorker.perform_in(2.minutes, migration_class, [1, 1])
+ BackgroundMigrationWorker.perform_async(migration_class, [1, 1])
+
+ migrate!
+
+ expect(migration).to have_received(:perform).with(1, 1).twice
+ end
+ end
+ end
+ context 'when there are no background migrations pending' do
+ it 'does nothing' do
+ Sidekiq::Testing.disable! do
+ migrate!
+
+ expect(migration).not_to have_received(:perform)
+ end
+ end
+ end
+end