diff options
author | Grzegorz Bizon <grzesiek.bizon@gmail.com> | 2017-07-20 12:42:01 +0200 |
---|---|---|
committer | Grzegorz Bizon <grzesiek.bizon@gmail.com> | 2017-07-20 12:42:01 +0200 |
commit | 9c10683b01f9b32275a04bf9ed4e84795a527db7 (patch) | |
tree | 534423909af0d036eb2973cb97b3d95e672a5c75 | |
parent | 54efa041d70707eb28326bb23220ebe8d6efb8aa (diff) | |
parent | 001dd56e7bfd04d22f5437569ba8aa60a0317a3e (diff) | |
download | gitlab-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.js | 7 | ||||
-rw-r--r-- | app/assets/javascripts/new_sidebar.js | 23 | ||||
-rw-r--r-- | app/assets/stylesheets/new_nav.scss | 3 | ||||
-rw-r--r-- | app/assets/stylesheets/new_sidebar.scss | 116 | ||||
-rw-r--r-- | app/views/layouts/_page.html.haml | 2 | ||||
-rw-r--r-- | app/views/layouts/nav/_breadcrumbs.html.haml | 4 | ||||
-rw-r--r-- | app/views/layouts/nav/_new_admin_sidebar.html.haml | 12 | ||||
-rw-r--r-- | app/views/layouts/nav/_new_group_sidebar.html.haml | 14 | ||||
-rw-r--r-- | app/views/layouts/nav/_new_profile_sidebar.html.haml | 12 | ||||
-rw-r--r-- | app/views/layouts/nav/_new_project_sidebar.html.haml | 14 | ||||
-rw-r--r-- | db/migrate/20170710083355_clean_stage_id_reference_migration.rb | 18 | ||||
-rw-r--r-- | lib/gitlab/background_migration.rb | 2 | ||||
-rw-r--r-- | spec/lib/gitlab/background_migration_spec.rb | 6 | ||||
-rw-r--r-- | spec/migrations/clean_stage_id_reference_migration_spec.rb | 34 |
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 |