From 87a36a74ff0e011a69d49f4b2411cae17f975ca9 Mon Sep 17 00:00:00 2001 From: "Ricketts, M (Mike)" Date: Fri, 22 Dec 2017 13:39:06 +0000 Subject: Remove .ssh/environment file that now breaks the gitlab:check rake task --- changelogs/unreleased/38540-ssh-env-file.yml | 6 ++++++ lib/tasks/gitlab/shell.rake | 10 ---------- 2 files changed, 6 insertions(+), 10 deletions(-) create mode 100644 changelogs/unreleased/38540-ssh-env-file.yml diff --git a/changelogs/unreleased/38540-ssh-env-file.yml b/changelogs/unreleased/38540-ssh-env-file.yml new file mode 100644 index 00000000000..5ada0ede76d --- /dev/null +++ b/changelogs/unreleased/38540-ssh-env-file.yml @@ -0,0 +1,6 @@ +--- +title: 'Closes #38540 - Remove .ssh/environment file that now breaks the gitlab:check + rake task' +merge_request: +author: +type: fixed diff --git a/lib/tasks/gitlab/shell.rake b/lib/tasks/gitlab/shell.rake index 0e6aed32c52..12ae4199b69 100644 --- a/lib/tasks/gitlab/shell.rake +++ b/lib/tasks/gitlab/shell.rake @@ -54,16 +54,6 @@ namespace :gitlab do # (Re)create hooks Rake::Task['gitlab:shell:create_hooks'].invoke - # Required for debian packaging with PKGR: Setup .ssh/environment with - # the current PATH, so that the correct ruby version gets loaded - # Requires to set "PermitUserEnvironment yes" in sshd config (should not - # be an issue since it is more than likely that there are no "normal" - # user accounts on a gitlab server). The alternative is for the admin to - # install a ruby (1.9.3+) in the global path. - File.open(File.join(user_home, ".ssh", "environment"), "w+") do |f| - f.puts "PATH=#{ENV['PATH']}" - end - Gitlab::Shell.ensure_secret_token! end -- cgit v1.2.1 From 8139895b4362817cf947431fab9c95ce223b87ae Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Mon, 25 Dec 2017 18:20:50 +0800 Subject: Use `Gitlab::Utils::Override` over defined?(super) --- doc/development/ee_features.md | 17 ++-- lib/gitlab/utils/override.rb | 111 +++++++++++++++++++++++ lib/tasks/dev.rake | 5 ++ lib/tasks/lint.rake | 12 +++ scripts/static-analysis | 5 +- spec/lib/gitlab/utils/override_spec.rb | 158 +++++++++++++++++++++++++++++++++ 6 files changed, 299 insertions(+), 9 deletions(-) create mode 100644 lib/gitlab/utils/override.rb create mode 100644 spec/lib/gitlab/utils/override_spec.rb diff --git a/doc/development/ee_features.md b/doc/development/ee_features.md index 1af839a27e1..b4b5b47c099 100644 --- a/doc/development/ee_features.md +++ b/doc/development/ee_features.md @@ -87,9 +87,9 @@ still having access the class's implementation with `super`. There are a few gotchas with it: -- you should always add a `raise NotImplementedError unless defined?(super)` - guard clause in the "overrider" method to ensure that if the method gets - renamed in CE, the EE override won't be silently forgotten. +- you should always `extend ::Gitlab::Utils::Override` and use `override` to + guard the "overrider" method to ensure that if the method gets renamed in + CE, the EE override won't be silently forgotten. - when the "overrider" would add a line in the middle of the CE implementation, you should refactor the CE method and split it in smaller methods. Or create a "hook" method that is empty in CE, @@ -134,6 +134,9 @@ There are a few gotchas with it: guards: ``` ruby module EE::Base + extend ::Gitlab::Utils::Override + + override :do_something def do_something # Follow the above pattern to call super and extend it end @@ -174,10 +177,11 @@ implementation: ```ruby module EE - class ApplicationController - def after_sign_out_path_for(resource) - raise NotImplementedError unless defined?(super) + module ApplicationController + extend ::Gitlab::Utils::Override + override :after_sign_out_path_for + def after_sign_out_path_for(resource) if Gitlab::Geo.secondary? Gitlab::Geo.primary_node.oauth_logout_url(@geo_logout_state) else @@ -209,7 +213,6 @@ In EE, the implementation `ee/app/models/ee/users.rb` would be: ```ruby def full_private_access? - raise NotImplementedError unless defined?(super) super || auditor? end ``` diff --git a/lib/gitlab/utils/override.rb b/lib/gitlab/utils/override.rb new file mode 100644 index 00000000000..8bf6bcb1fe2 --- /dev/null +++ b/lib/gitlab/utils/override.rb @@ -0,0 +1,111 @@ +module Gitlab + module Utils + module Override + class Extension + def self.verify_class!(klass, method_name) + instance_method_defined?(klass, method_name) || + raise( + NotImplementedError.new( + "#{klass}\##{method_name} doesn't exist!")) + end + + def self.instance_method_defined?(klass, name, include_super: true) + klass.instance_methods(include_super).include?(name) || + klass.private_instance_methods(include_super).include?(name) + end + + attr_reader :subject + + def initialize(subject) + @subject = subject + end + + def add_method_name(method_name) + method_names << method_name + end + + def add_class(klass) + classes << klass + end + + def verify! + classes.each do |klass| + index = klass.ancestors.index(subject) + parents = klass.ancestors.drop(index + 1) + + method_names.each do |method_name| + parents.any? do |parent| + self.class.instance_method_defined?( + parent, method_name, include_super: false) + end || + raise( + NotImplementedError.new( + "#{klass}\##{method_name} doesn't exist!")) + end + end + end + + private + + def method_names + @method_names ||= [] + end + + def classes + @classes ||= [] + end + end + + # Instead of writing patterns like this: + # + # def f + # raise NotImplementedError unless defined?(super) + # + # true + # end + # + # We could write it like: + # + # extend ::Gitlab::Utils::Override + # + # override :f + # def f + # true + # end + # + # This would make sure we're overriding something. See: + # https://gitlab.com/gitlab-org/gitlab-ee/issues/1819 + def override(method_name) + return unless ENV['STATIC_VERIFICATION'] + + if is_a?(Class) + Extension.verify_class!(self, method_name) + else # We delay the check for modules + Override.extensions[self] ||= Extension.new(self) + Override.extensions[self].add_method_name(method_name) + end + end + + def included(base = nil) + return super if base.nil? # Rails concern, ignoring it + + super + + if base.is_a?(Class) # We could check for Class in `override` + # This could be `nil` if `override` was never called + Override.extensions[self]&.add_class(base) + end + end + + alias_method :prepended, :included + + def self.extensions + @extensions ||= {} + end + + def self.verify! + extensions.values.each(&:verify!) + end + end + end +end diff --git a/lib/tasks/dev.rake b/lib/tasks/dev.rake index e65609d7001..4beb94eeb8e 100644 --- a/lib/tasks/dev.rake +++ b/lib/tasks/dev.rake @@ -7,4 +7,9 @@ namespace :dev do Rake::Task["gitlab:setup"].invoke Rake::Task["gitlab:shell:setup"].invoke end + + desc "GitLab | Eager load application" + task load: :environment do + Rails.application.eager_load! + end end diff --git a/lib/tasks/lint.rake b/lib/tasks/lint.rake index 7b63e93db0e..3ab406eff2c 100644 --- a/lib/tasks/lint.rake +++ b/lib/tasks/lint.rake @@ -1,5 +1,17 @@ unless Rails.env.production? namespace :lint do + task :static_verification_env do + ENV['STATIC_VERIFICATION'] = 'true' + end + + desc "GitLab | lint | Static verification" + task static_verification: %w[ + lint:static_verification_env + dev:load + ] do + Gitlab::Utils::Override.verify! + end + desc "GitLab | lint | Lint JavaScript files using ESLint" task :javascript do Rake::Task['eslint'].invoke diff --git a/scripts/static-analysis b/scripts/static-analysis index 2a2bc67800d..9690b42c788 100755 --- a/scripts/static-analysis +++ b/scripts/static-analysis @@ -10,9 +10,10 @@ tasks = [ %w[bundle exec license_finder], %w[yarn run eslint], %w[bundle exec rubocop --parallel], - %w[scripts/lint-conflicts.sh], %w[bundle exec rake gettext:lint], - %w[scripts/lint-changelog-yaml] + %w[bundle exec rake lint:static_verification], + %w[scripts/lint-changelog-yaml], + %w[scripts/lint-conflicts.sh] ] failed_tasks = tasks.reduce({}) do |failures, task| diff --git a/spec/lib/gitlab/utils/override_spec.rb b/spec/lib/gitlab/utils/override_spec.rb new file mode 100644 index 00000000000..7c97cee982a --- /dev/null +++ b/spec/lib/gitlab/utils/override_spec.rb @@ -0,0 +1,158 @@ +require 'spec_helper' + +describe Gitlab::Utils::Override do + let(:base) { Struct.new(:good) } + + let(:derived) { Class.new(base).tap { |m| m.extend described_class } } + let(:extension) { Module.new.tap { |m| m.extend described_class } } + + let(:prepending_class) { base.tap { |m| m.prepend extension } } + let(:including_class) { base.tap { |m| m.include extension } } + + let(:klass) { subject } + + def good(mod) + mod.module_eval do + override :good + def good + super.succ + end + end + + mod + end + + def bad(mod) + mod.module_eval do + override :bad + def bad + true + end + end + + mod + end + + shared_examples 'checking as intended' do + it 'checks ok for overriding method' do + good(subject) + result = klass.new(0).good + + expect(result).to eq(1) + described_class.verify! + end + + it 'raises NotImplementedError when it is not overriding anything' do + expect do + bad(subject) + klass.new(0).bad + described_class.verify! + end.to raise_error(NotImplementedError) + end + end + + shared_examples 'nothing happened' do + it 'does not complain when it is overriding something' do + good(subject) + result = klass.new(0).good + + expect(result).to eq(1) + described_class.verify! + end + + it 'does not complain when it is not overriding anything' do + bad(subject) + result = klass.new(0).bad + + expect(result).to eq(true) + described_class.verify! + end + end + + before do + # Make sure we're not touching the internal cache + allow(described_class).to receive(:extensions).and_return({}) + end + + describe '#override' do + context 'when STATIC_VERIFICATION is set' do + before do + stub_env('STATIC_VERIFICATION', 'true') + end + + context 'when subject is a class' do + subject { derived } + + it_behaves_like 'checking as intended' + end + + context 'when subject is a module, and class is prepending it' do + subject { extension } + let(:klass) { prepending_class } + + it_behaves_like 'checking as intended' + end + + context 'when subject is a module, and class is including it' do + subject { extension } + let(:klass) { including_class } + + it 'raises NotImplementedError because it is not overriding it' do + expect do + good(subject) + klass.new(0).good + described_class.verify! + end.to raise_error(NotImplementedError) + end + + it 'raises NotImplementedError when it is not overriding anything' do + expect do + bad(subject) + klass.new(0).bad + described_class.verify! + end.to raise_error(NotImplementedError) + end + end + end + end + + context 'when STATIC_VERIFICATION is not set' do + before do + stub_env('STATIC_VERIFICATION', nil) + end + + context 'when subject is a class' do + subject { derived } + + it_behaves_like 'nothing happened' + end + + context 'when subject is a module, and class is prepending it' do + subject { extension } + let(:klass) { prepending_class } + + it_behaves_like 'nothing happened' + end + + context 'when subject is a module, and class is including it' do + subject { extension } + let(:klass) { including_class } + + it 'does not complain when it is overriding something' do + good(subject) + result = klass.new(0).good + + expect(result).to eq(0) + described_class.verify! + end + + it 'does not complain when it is not overriding anything' do + bad(subject) + result = klass.new(0).bad + + expect(result).to eq(true) + described_class.verify! + end + end + end +end -- cgit v1.2.1 From f4bd9c0b5e1eafe6de855d73bfb606909229f382 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Tue, 26 Dec 2017 14:36:33 +0800 Subject: Skip sha_attribute if we're checking statically --- app/models/concerns/sha_attribute.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/models/concerns/sha_attribute.rb b/app/models/concerns/sha_attribute.rb index 67ecf470f7e..703a72c355c 100644 --- a/app/models/concerns/sha_attribute.rb +++ b/app/models/concerns/sha_attribute.rb @@ -3,6 +3,7 @@ module ShaAttribute module ClassMethods def sha_attribute(name) + return if ENV['STATIC_VERIFICATION'] return unless table_exists? column = columns.find { |c| c.name == name.to_s } -- cgit v1.2.1 From b9f0883bc5a735f2168bddb9239dcaa2aa16c306 Mon Sep 17 00:00:00 2001 From: Sean McGivern Date: Tue, 9 Jan 2018 11:55:57 +0000 Subject: Fix double execution of COUNT query on group pages Calling `finder.execute.count` twice will perform two queries, but these are all in the same file, so it's easy to just reuse them. --- app/views/layouts/nav/sidebar/_group.html.haml | 12 ++++++------ ...nt-query-for-issues-and-mrs-runs-twice-on-group-index.yml | 5 +++++ 2 files changed, 11 insertions(+), 6 deletions(-) create mode 100644 changelogs/unreleased/41546-count-query-for-issues-and-mrs-runs-twice-on-group-index.yml diff --git a/app/views/layouts/nav/sidebar/_group.html.haml b/app/views/layouts/nav/sidebar/_group.html.haml index 0c27b09f7b1..96aae06a9df 100644 --- a/app/views/layouts/nav/sidebar/_group.html.haml +++ b/app/views/layouts/nav/sidebar/_group.html.haml @@ -1,5 +1,5 @@ -- issues = IssuesFinder.new(current_user, group_id: @group.id, state: 'opened').execute -- merge_requests = MergeRequestsFinder.new(current_user, group_id: @group.id, state: 'opened', non_archived: true).execute +- issues_count = IssuesFinder.new(current_user, group_id: @group.id, state: 'opened').execute.count +- merge_requests_count = MergeRequestsFinder.new(current_user, group_id: @group.id, state: 'opened', non_archived: true).execute.count .nav-sidebar{ class: ("sidebar-collapsed-desktop" if collapsed_sidebar?) } .nav-sidebar-inner-scroll @@ -39,14 +39,14 @@ = sprite_icon('issues') %span.nav-item-name Issues - %span.badge.count= number_with_delimiter(issues.count) + %span.badge.count= number_with_delimiter(issues_count) %ul.sidebar-sub-level-items = nav_link(path: ['groups#issues', 'labels#index', 'milestones#index'], html_options: { class: "fly-out-top-item" } ) do = link_to issues_group_path(@group) do %strong.fly-out-top-item-name #{ _('Issues') } - %span.badge.count.issue_counter.fly-out-badge= number_with_delimiter(issues.count) + %span.badge.count.issue_counter.fly-out-badge= number_with_delimiter(issues_count) %li.divider.fly-out-top-item = nav_link(path: 'groups#issues', html_options: { class: 'home' }) do = link_to issues_group_path(@group), title: 'List' do @@ -69,13 +69,13 @@ = sprite_icon('git-merge') %span.nav-item-name Merge Requests - %span.badge.count= number_with_delimiter(merge_requests.count) + %span.badge.count= number_with_delimiter(merge_requests_count) %ul.sidebar-sub-level-items.is-fly-out-only = nav_link(path: 'groups#merge_requests', html_options: { class: "fly-out-top-item" } ) do = link_to merge_requests_group_path(@group) do %strong.fly-out-top-item-name #{ _('Merge Requests') } - %span.badge.count.merge_counter.js-merge-counter.fly-out-badge= number_with_delimiter(merge_requests.count) + %span.badge.count.merge_counter.js-merge-counter.fly-out-badge= number_with_delimiter(merge_requests_count) = nav_link(path: 'group_members#index') do = link_to group_group_members_path(@group) do .nav-icon-container diff --git a/changelogs/unreleased/41546-count-query-for-issues-and-mrs-runs-twice-on-group-index.yml b/changelogs/unreleased/41546-count-query-for-issues-and-mrs-runs-twice-on-group-index.yml new file mode 100644 index 00000000000..7e42dc20ae8 --- /dev/null +++ b/changelogs/unreleased/41546-count-query-for-issues-and-mrs-runs-twice-on-group-index.yml @@ -0,0 +1,5 @@ +--- +title: Fix double query execution on groups page +merge_request: 16314 +author: +type: performance -- cgit v1.2.1 From d19b68b6edb8b3801ce5c00efe27d22ae3afd962 Mon Sep 17 00:00:00 2001 From: Maurizio De Santis Date: Mon, 8 Jan 2018 23:16:55 +0100 Subject: Update 'removed assignee' note to include old assignee reference --- app/services/system_note_service.rb | 23 ++++++++-------------- ...gnee-note-to-include-old-assignee-reference.yml | 5 +++++ spec/services/system_note_service_spec.rb | 2 +- 3 files changed, 14 insertions(+), 16 deletions(-) create mode 100644 changelogs/unreleased/16301-update-removed-assignee-note-to-include-old-assignee-reference.yml diff --git a/app/services/system_note_service.rb b/app/services/system_note_service.rb index 30a5aab13bf..06b23cd7076 100644 --- a/app/services/system_note_service.rb +++ b/app/services/system_note_service.rb @@ -68,21 +68,14 @@ module SystemNoteService # # Returns the created Note object def change_issue_assignees(issue, project, author, old_assignees) - body = - if issue.assignees.any? && old_assignees.any? - unassigned_users = old_assignees - issue.assignees - added_users = issue.assignees.to_a - old_assignees - - text_parts = [] - text_parts << "assigned to #{added_users.map(&:to_reference).to_sentence}" if added_users.any? - text_parts << "unassigned #{unassigned_users.map(&:to_reference).to_sentence}" if unassigned_users.any? - - text_parts.join(' and ') - elsif old_assignees.any? - "removed assignee" - elsif issue.assignees.any? - "assigned to #{issue.assignees.map(&:to_reference).to_sentence}" - end + unassigned_users = old_assignees - issue.assignees + added_users = issue.assignees.to_a - old_assignees + + text_parts = [] + text_parts << "assigned to #{added_users.map(&:to_reference).to_sentence}" if added_users.any? + text_parts << "unassigned #{unassigned_users.map(&:to_reference).to_sentence}" if unassigned_users.any? + + body = text_parts.join(' and ') create_note(NoteSummary.new(issue, project, author, body, action: 'assignee')) end diff --git a/changelogs/unreleased/16301-update-removed-assignee-note-to-include-old-assignee-reference.yml b/changelogs/unreleased/16301-update-removed-assignee-note-to-include-old-assignee-reference.yml new file mode 100644 index 00000000000..e94b4f8bb26 --- /dev/null +++ b/changelogs/unreleased/16301-update-removed-assignee-note-to-include-old-assignee-reference.yml @@ -0,0 +1,5 @@ +--- +title: "Update 'removed assignee' note to include old assignee reference" +merge_request: 16301 +author: Maurizio De Santis +type: changed diff --git a/spec/services/system_note_service_spec.rb b/spec/services/system_note_service_spec.rb index 4e640a82dfc..7c1bfa4295d 100644 --- a/spec/services/system_note_service_spec.rb +++ b/spec/services/system_note_service_spec.rb @@ -158,7 +158,7 @@ describe SystemNoteService do end it 'builds a correct phrase when assignee removed' do - expect(build_note([assignee1], [])).to eq 'removed assignee' + expect(build_note([assignee1], [])).to eq "unassigned @#{assignee1.username}" end it 'builds a correct phrase when assignees changed' do -- cgit v1.2.1 From c99c481aa68057e4e50f95516754e094fce17284 Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Wed, 10 Jan 2018 14:29:10 +0100 Subject: Update the grpc gem to 1.8.3 --- Gemfile.lock | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 40c4f73b8a6..c5bd319d659 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -340,6 +340,8 @@ GEM representable (~> 3.0) retriable (>= 2.0, < 4.0) google-protobuf (3.4.1.1) + googleapis-common-protos-types (1.0.1) + google-protobuf (~> 3.0) googleauth (0.5.3) faraday (~> 0.12) jwt (~> 1.4) @@ -366,9 +368,10 @@ GEM rake grape_logging (1.7.0) grape - grpc (1.4.5) + grpc (1.8.3) google-protobuf (~> 3.1) - googleauth (~> 0.5.1) + googleapis-common-protos-types (~> 1.0.0) + googleauth (>= 0.5.1, < 0.7) haml (4.0.7) tilt haml_lint (0.26.0) -- cgit v1.2.1 From 9d7e0e49189519f2659906348507da969cfbab14 Mon Sep 17 00:00:00 2001 From: Joshua Lambert Date: Wed, 10 Jan 2018 17:28:50 -0500 Subject: Update AutoDevOps template with browser performance fix --- vendor/gitlab-ci-yml/Auto-DevOps.gitlab-ci.yml | 30 +++++++++++++++----------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/vendor/gitlab-ci-yml/Auto-DevOps.gitlab-ci.yml b/vendor/gitlab-ci-yml/Auto-DevOps.gitlab-ci.yml index 75de266369d..eec356b9f47 100644 --- a/vendor/gitlab-ci-yml/Auto-DevOps.gitlab-ci.yml +++ b/vendor/gitlab-ci-yml/Auto-DevOps.gitlab-ci.yml @@ -90,10 +90,14 @@ codequality: performance: stage: performance - image: - name: sitespeedio/sitespeed.io:6.0.3 - entrypoint: [""] + image: docker:latest + variables: + DOCKER_DRIVER: overlay2 + allow_failure: true + services: + - docker:dind script: + - setup_docker - performance artifacts: paths: @@ -112,7 +116,7 @@ sast: - sast . artifacts: paths: [gl-sast-report.json] - + sast:container: image: docker:latest variables: @@ -260,7 +264,7 @@ production: export CI_APPLICATION_TAG=$CI_COMMIT_SHA export CI_CONTAINER_NAME=ci_job_build_${CI_JOB_ID} export TILLER_NAMESPACE=$KUBE_NAMESPACE - + function sast_container() { docker run -d --name db arminc/clair-db:latest docker run -p 6060:6060 --link db:postgres -d --name clair arminc/clair-local-scan:v2.0.1 @@ -466,26 +470,26 @@ production: --docker-email="$GITLAB_USER_EMAIL" \ -o yaml --dry-run | kubectl replace -n "$KUBE_NAMESPACE" --force -f - } - + function performance() { export CI_ENVIRONMENT_URL=$(cat environment_url.txt) - + mkdir gitlab-exporter wget -O gitlab-exporter/index.js https://gitlab.com/gitlab-org/gl-performance/raw/10-3/index.js - + mkdir sitespeed-results - + if [ -f .gitlab-urls.txt ] then sed -i -e 's@^@'"$CI_ENVIRONMENT_URL"'@' .gitlab-urls.txt - /start.sh --plugins.add gitlab-exporter --outputFolder sitespeed-results .gitlab-urls.txt + docker run --shm-size=1g --rm -v "$(pwd)":/sitespeed.io sitespeedio/sitespeed.io:6.0.3 --plugins.add ./gitlab-exporter --outputFolder sitespeed-results .gitlab-urls.txt else - /start.sh --plugins.add gitlab-exporter --outputFolder sitespeed-results $CI_ENVIRONMENT_URL + docker run --shm-size=1g --rm -v "$(pwd)":/sitespeed.io sitespeedio/sitespeed.io:6.0.3 --plugins.add ./gitlab-exporter --outputFolder sitespeed-results "$CI_ENVIRONMENT_URL" fi - + mv sitespeed-results/data/performance.json performance.json } - + function persist_environment_url() { echo $CI_ENVIRONMENT_URL > environment_url.txt } -- cgit v1.2.1 From acefbad292e741cb2a60bd3eab81d9b05fd27961 Mon Sep 17 00:00:00 2001 From: Clement Ho Date: Thu, 11 Jan 2018 00:02:24 -0600 Subject: Refactor dispatcher project branches create path --- app/assets/javascripts/dispatcher.js | 8 +++++++- app/assets/javascripts/pages/projects/branches/create/index.js | 3 +++ app/assets/javascripts/pages/projects/branches/new/index.js | 3 +++ 3 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 app/assets/javascripts/pages/projects/branches/create/index.js create mode 100644 app/assets/javascripts/pages/projects/branches/new/index.js diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js index a282b67b0fc..10c4931b7d6 100644 --- a/app/assets/javascripts/dispatcher.js +++ b/app/assets/javascripts/dispatcher.js @@ -266,8 +266,14 @@ import Activities from './activities'; initChangesDropdown(document.querySelector('.navbar-gitlab').offsetHeight - paddingTop); break; case 'projects:branches:new': + import('./pages/projects/branches/new') + .then(callDefault) + .catch(fail); + break; case 'projects:branches:create': - new NewBranchForm($('.js-create-branch-form'), JSON.parse(document.getElementById('availableRefs').innerHTML)); + import('./pages/projects/branches/new') + .then(callDefault) + .catch(fail); break; case 'projects:branches:index': AjaxLoadingSpinner.init(); diff --git a/app/assets/javascripts/pages/projects/branches/create/index.js b/app/assets/javascripts/pages/projects/branches/create/index.js new file mode 100644 index 00000000000..ae5e033e97e --- /dev/null +++ b/app/assets/javascripts/pages/projects/branches/create/index.js @@ -0,0 +1,3 @@ +import NewBranchForm from '~/new_branch_form'; + +export default () => new NewBranchForm($('.js-create-branch-form'), JSON.parse(document.getElementById('availableRefs').innerHTML)); diff --git a/app/assets/javascripts/pages/projects/branches/new/index.js b/app/assets/javascripts/pages/projects/branches/new/index.js new file mode 100644 index 00000000000..ae5e033e97e --- /dev/null +++ b/app/assets/javascripts/pages/projects/branches/new/index.js @@ -0,0 +1,3 @@ +import NewBranchForm from '~/new_branch_form'; + +export default () => new NewBranchForm($('.js-create-branch-form'), JSON.parse(document.getElementById('availableRefs').innerHTML)); -- cgit v1.2.1 From 80eb68e07daf5e59fec9497f187dd7a2f1dfe587 Mon Sep 17 00:00:00 2001 From: Jacob Schatz Date: Thu, 11 Jan 2018 07:46:13 -0500 Subject: Refactor dispatcher for snippets:* --- app/assets/javascripts/dispatcher.js | 19 ++++++++++++++++--- app/assets/javascripts/pages/snippets/create/index.js | 7 +++++++ app/assets/javascripts/pages/snippets/edit/index.js | 7 +++++++ app/assets/javascripts/pages/snippets/new/index.js | 7 +++++++ app/assets/javascripts/pages/snippets/update/index.js | 7 +++++++ 5 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 app/assets/javascripts/pages/snippets/create/index.js create mode 100644 app/assets/javascripts/pages/snippets/edit/index.js create mode 100644 app/assets/javascripts/pages/snippets/new/index.js create mode 100644 app/assets/javascripts/pages/snippets/update/index.js diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js index e35f53081ec..f67eb9c5895 100644 --- a/app/assets/javascripts/dispatcher.js +++ b/app/assets/javascripts/dispatcher.js @@ -307,11 +307,24 @@ import Activities from './activities'; new ZenMode(); break; case 'snippets:new': + import('./pages/snippets/new') + .then(callDefault) + .catch(fail); + break; case 'snippets:edit': + import('./pages/snippets/edit') + .then(callDefault) + .catch(fail); + break; case 'snippets:create': + import('./pages/snippets/create') + .then(callDefault) + .catch(fail); + break; case 'snippets:update': - new GLForm($('.snippet-form'), false); - new ZenMode(); + import('./pages/snippets/update') + .then(callDefault) + .catch(fail); break; case 'projects:releases:edit': new ZenMode(); @@ -562,7 +575,7 @@ import Activities from './activities'; import('./pages/admin/conversational_development_index/show').then(m => m.default()).catch(fail); break; case 'snippets:show': - import('./pages/snippets/show').then(m => m.default()).catch(fail); + import('./pages/snippets/show').then(callDefault).catch(fail); break; case 'import:fogbugz:new_user_map': import('./pages/import/fogbugz/new_user_map').then(m => m.default()).catch(fail); diff --git a/app/assets/javascripts/pages/snippets/create/index.js b/app/assets/javascripts/pages/snippets/create/index.js new file mode 100644 index 00000000000..f7dbd021688 --- /dev/null +++ b/app/assets/javascripts/pages/snippets/create/index.js @@ -0,0 +1,7 @@ +import GLForm from '~/gl_form'; +import ZenMode from '~/zen_mode'; + +export default function () { + new GLForm($('.snippet-form'), false); // eslint-disable-line no-new + new ZenMode(); // eslint-disable-line no-new +} diff --git a/app/assets/javascripts/pages/snippets/edit/index.js b/app/assets/javascripts/pages/snippets/edit/index.js new file mode 100644 index 00000000000..f7dbd021688 --- /dev/null +++ b/app/assets/javascripts/pages/snippets/edit/index.js @@ -0,0 +1,7 @@ +import GLForm from '~/gl_form'; +import ZenMode from '~/zen_mode'; + +export default function () { + new GLForm($('.snippet-form'), false); // eslint-disable-line no-new + new ZenMode(); // eslint-disable-line no-new +} diff --git a/app/assets/javascripts/pages/snippets/new/index.js b/app/assets/javascripts/pages/snippets/new/index.js new file mode 100644 index 00000000000..f7dbd021688 --- /dev/null +++ b/app/assets/javascripts/pages/snippets/new/index.js @@ -0,0 +1,7 @@ +import GLForm from '~/gl_form'; +import ZenMode from '~/zen_mode'; + +export default function () { + new GLForm($('.snippet-form'), false); // eslint-disable-line no-new + new ZenMode(); // eslint-disable-line no-new +} diff --git a/app/assets/javascripts/pages/snippets/update/index.js b/app/assets/javascripts/pages/snippets/update/index.js new file mode 100644 index 00000000000..f7dbd021688 --- /dev/null +++ b/app/assets/javascripts/pages/snippets/update/index.js @@ -0,0 +1,7 @@ +import GLForm from '~/gl_form'; +import ZenMode from '~/zen_mode'; + +export default function () { + new GLForm($('.snippet-form'), false); // eslint-disable-line no-new + new ZenMode(); // eslint-disable-line no-new +} -- cgit v1.2.1 From d08610c3a654177b3e5b90a2e5f9b2f74bc8d002 Mon Sep 17 00:00:00 2001 From: Jacob Schatz Date: Thu, 11 Jan 2018 08:23:25 -0500 Subject: Refactor projects:l* --- app/assets/javascripts/dispatcher.js | 14 ++++++++++++-- .../javascripts/pages/projects/labels/edit/index.js | 5 +++++ .../javascripts/pages/projects/labels/index/index.js | 19 +++++++++++++++++++ .../javascripts/pages/projects/labels/new/index.js | 5 +++++ 4 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 app/assets/javascripts/pages/projects/labels/edit/index.js create mode 100644 app/assets/javascripts/pages/projects/labels/index/index.js create mode 100644 app/assets/javascripts/pages/projects/labels/new/index.js diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js index e35f53081ec..0794edd5f69 100644 --- a/app/assets/javascripts/dispatcher.js +++ b/app/assets/javascripts/dispatcher.js @@ -483,11 +483,21 @@ import Activities from './activities'; case 'groups:labels:new': case 'groups:labels:edit': case 'projects:labels:new': + import('./pages/projects/labels/new') + .then(callDefault) + .catch(fail); + break; case 'projects:labels:edit': - new Labels(); + import('./pages/projects/labels/new') + .then(callDefault) + .catch(fail); break; - case 'groups:labels:index': case 'projects:labels:index': + import('./pages/projects/labels/index') + .then(callDefault) + .catch(fail); + break; + case 'groups:labels:index': if ($('.prioritized-labels').length) { new LabelManager(); } diff --git a/app/assets/javascripts/pages/projects/labels/edit/index.js b/app/assets/javascripts/pages/projects/labels/edit/index.js new file mode 100644 index 00000000000..75dc1ef1859 --- /dev/null +++ b/app/assets/javascripts/pages/projects/labels/edit/index.js @@ -0,0 +1,5 @@ +import Labels from '~/labels'; + +export default function () { + new Labels(); // eslint-disable-line no-new +} diff --git a/app/assets/javascripts/pages/projects/labels/index/index.js b/app/assets/javascripts/pages/projects/labels/index/index.js new file mode 100644 index 00000000000..c258be4f908 --- /dev/null +++ b/app/assets/javascripts/pages/projects/labels/index/index.js @@ -0,0 +1,19 @@ +/* eslint-disable no-new */ +import LabelManager from '~/label_manager'; +import GroupLabelSubscription from '~/group_label_subscription'; +import ProjectLabelSubscription from '~/project_label_subscription'; + +export default () => { + if ($('.prioritized-labels').length) { + new LabelManager(); + } + $('.label-subscription').each((i, el) => { + const $el = $(el); + + if ($el.find('.dropdown-group-label').length) { + new GroupLabelSubscription($el); + } else { + new ProjectLabelSubscription($el); + } + }); +}; diff --git a/app/assets/javascripts/pages/projects/labels/new/index.js b/app/assets/javascripts/pages/projects/labels/new/index.js new file mode 100644 index 00000000000..75dc1ef1859 --- /dev/null +++ b/app/assets/javascripts/pages/projects/labels/new/index.js @@ -0,0 +1,5 @@ +import Labels from '~/labels'; + +export default function () { + new Labels(); // eslint-disable-line no-new +} -- cgit v1.2.1 From b4b267b7395ca524f4251f6eefe91e502b086ab0 Mon Sep 17 00:00:00 2001 From: Ahmad Sherif Date: Tue, 9 Jan 2018 13:53:35 +0100 Subject: Migrate Repository#can_be_merged? to Gitaly --- app/models/repository.rb | 21 ++++++--- lib/gitlab/git/conflict/resolver.rb | 2 +- .../gitaly_client/conflict_files_stitcher.rb | 47 +++++++++++++++++++ lib/gitlab/gitaly_client/conflicts_service.rb | 38 ++------------- .../gitaly_client/conflict_files_stitcher_spec.rb | 54 ++++++++++++++++++++++ .../gitlab/gitaly_client/conflicts_service_spec.rb | 33 +------------ spec/models/repository_spec.rb | 38 +++++++++------ 7 files changed, 147 insertions(+), 86 deletions(-) create mode 100644 lib/gitlab/gitaly_client/conflict_files_stitcher.rb create mode 100644 spec/lib/gitlab/gitaly_client/conflict_files_stitcher_spec.rb diff --git a/app/models/repository.rb b/app/models/repository.rb index 9c879e2006b..b5d118f1c4c 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -831,13 +831,12 @@ class Repository end def can_be_merged?(source_sha, target_branch) - our_commit = rugged.branches[target_branch].target - their_commit = rugged.lookup(source_sha) - - if our_commit && their_commit - !rugged.merge_commits(our_commit, their_commit).conflicts? - else - false + raw_repository.gitaly_migrate(:can_be_merged) do |is_enabled| + if is_enabled + gitaly_can_be_merged?(source_sha, find_branch(target_branch).target) + else + rugged_can_be_merged?(source_sha, target_branch) + end end end @@ -1128,6 +1127,14 @@ class Repository Gitlab::Git::Repository.new(project.repository_storage, disk_path + '.git', Gitlab::GlRepository.gl_repository(project, is_wiki)) end + def gitaly_can_be_merged?(their_commit, our_commit) + !raw_repository.gitaly_conflicts_client(our_commit, their_commit).conflicts? + end + + def rugged_can_be_merged?(their_commit, our_commit) + !rugged.merge_commits(our_commit, their_commit).conflicts? + end + def find_commits_by_message_by_shelling_out(query, ref, path, limit, offset) ref ||= root_ref diff --git a/lib/gitlab/git/conflict/resolver.rb b/lib/gitlab/git/conflict/resolver.rb index 74c9874d590..07b7e811a34 100644 --- a/lib/gitlab/git/conflict/resolver.rb +++ b/lib/gitlab/git/conflict/resolver.rb @@ -15,7 +15,7 @@ module Gitlab @conflicts ||= begin @target_repository.gitaly_migrate(:conflicts_list_conflict_files) do |is_enabled| if is_enabled - gitaly_conflicts_client(@target_repository).list_conflict_files + gitaly_conflicts_client(@target_repository).list_conflict_files.to_a else rugged_list_conflict_files end diff --git a/lib/gitlab/gitaly_client/conflict_files_stitcher.rb b/lib/gitlab/gitaly_client/conflict_files_stitcher.rb new file mode 100644 index 00000000000..97c13d1fdb0 --- /dev/null +++ b/lib/gitlab/gitaly_client/conflict_files_stitcher.rb @@ -0,0 +1,47 @@ +module Gitlab + module GitalyClient + class ConflictFilesStitcher + include Enumerable + + def initialize(rpc_response) + @rpc_response = rpc_response + end + + def each + current_file = nil + + @rpc_response.each do |msg| + msg.files.each do |gitaly_file| + if gitaly_file.header + yield current_file if current_file + + current_file = file_from_gitaly_header(gitaly_file.header) + else + current_file.content << gitaly_file.content + end + end + end + + yield current_file if current_file + end + + private + + def file_from_gitaly_header(header) + Gitlab::Git::Conflict::File.new( + Gitlab::GitalyClient::Util.git_repository(header.repository), + header.commit_oid, + conflict_from_gitaly_file_header(header), + '' + ) + end + + def conflict_from_gitaly_file_header(header) + { + ours: { path: header.our_path, mode: header.our_mode }, + theirs: { path: header.their_path } + } + end + end + end +end diff --git a/lib/gitlab/gitaly_client/conflicts_service.rb b/lib/gitlab/gitaly_client/conflicts_service.rb index 40f032cf873..2565d537aff 100644 --- a/lib/gitlab/gitaly_client/conflicts_service.rb +++ b/lib/gitlab/gitaly_client/conflicts_service.rb @@ -20,7 +20,11 @@ module Gitlab ) response = GitalyClient.call(@repository.storage, :conflicts_service, :list_conflict_files, request) - files_from_response(response).to_a + GitalyClient::ConflictFilesStitcher.new(response) + end + + def conflicts? + list_conflict_files.any? end def resolve_conflicts(target_repository, resolution, source_branch, target_branch) @@ -58,38 +62,6 @@ module Gitlab user: Gitlab::Git::User.from_gitlab(resolution.user).to_gitaly ) end - - def files_from_response(response) - files = [] - - response.each do |msg| - msg.files.each do |gitaly_file| - if gitaly_file.header - files << file_from_gitaly_header(gitaly_file.header) - else - files.last.content << gitaly_file.content - end - end - end - - files - end - - def file_from_gitaly_header(header) - Gitlab::Git::Conflict::File.new( - Gitlab::GitalyClient::Util.git_repository(header.repository), - header.commit_oid, - conflict_from_gitaly_file_header(header), - '' - ) - end - - def conflict_from_gitaly_file_header(header) - { - ours: { path: header.our_path, mode: header.our_mode }, - theirs: { path: header.their_path } - } - end end end end diff --git a/spec/lib/gitlab/gitaly_client/conflict_files_stitcher_spec.rb b/spec/lib/gitlab/gitaly_client/conflict_files_stitcher_spec.rb new file mode 100644 index 00000000000..1c933410bd5 --- /dev/null +++ b/spec/lib/gitlab/gitaly_client/conflict_files_stitcher_spec.rb @@ -0,0 +1,54 @@ +require 'spec_helper' + +describe Gitlab::GitalyClient::ConflictFilesStitcher do + describe 'enumeration' do + it 'combines segregated ConflictFile messages together' do + target_project = create(:project, :repository) + target_repository = target_project.repository.raw + target_gitaly_repository = target_repository.gitaly_repository + + our_path_1 = 'our/path/1' + their_path_1 = 'their/path/1' + our_mode_1 = 0744 + commit_oid_1 = 'f00' + content_1 = 'content of the first file' + + our_path_2 = 'our/path/2' + their_path_2 = 'their/path/2' + our_mode_2 = 0600 + commit_oid_2 = 'ba7' + content_2 = 'content of the second file' + + header_1 = double(repository: target_gitaly_repository, commit_oid: commit_oid_1, + our_path: our_path_1, their_path: their_path_1, our_mode: our_mode_1) + header_2 = double(repository: target_gitaly_repository, commit_oid: commit_oid_2, + our_path: our_path_2, their_path: their_path_2, our_mode: our_mode_2) + + messages = [ + double(files: [double(header: header_1), double(header: nil, content: content_1[0..5])]), + double(files: [double(header: nil, content: content_1[6..-1])]), + double(files: [double(header: header_2)]), + double(files: [double(header: nil, content: content_2[0..5]), double(header: nil, content: content_2[6..10])]), + double(files: [double(header: nil, content: content_2[11..-1])]) + ] + + conflict_files = described_class.new(messages).to_a + + expect(conflict_files.size).to be(2) + + expect(conflict_files[0].content).to eq(content_1) + expect(conflict_files[0].their_path).to eq(their_path_1) + expect(conflict_files[0].our_path).to eq(our_path_1) + expect(conflict_files[0].our_mode).to be(our_mode_1) + expect(conflict_files[0].repository).to eq(target_repository) + expect(conflict_files[0].commit_oid).to eq(commit_oid_1) + + expect(conflict_files[1].content).to eq(content_2) + expect(conflict_files[1].their_path).to eq(their_path_2) + expect(conflict_files[1].our_path).to eq(our_path_2) + expect(conflict_files[1].our_mode).to be(our_mode_2) + expect(conflict_files[1].repository).to eq(target_repository) + expect(conflict_files[1].commit_oid).to eq(commit_oid_2) + end + end +end diff --git a/spec/lib/gitlab/gitaly_client/conflicts_service_spec.rb b/spec/lib/gitlab/gitaly_client/conflicts_service_spec.rb index b9641de7eda..e4fe01a671f 100644 --- a/spec/lib/gitlab/gitaly_client/conflicts_service_spec.rb +++ b/spec/lib/gitlab/gitaly_client/conflicts_service_spec.rb @@ -19,41 +19,12 @@ describe Gitlab::GitalyClient::ConflictsService do their_commit_oid: their_commit_oid ) end - let(:our_path) { 'our/path' } - let(:their_path) { 'their/path' } - let(:our_mode) { 0744 } - let(:header) do - double(repository: target_gitaly_repository, commit_oid: our_commit_oid, - our_path: our_path, our_mode: 0744, their_path: their_path) - end - let(:response) do - [ - double(files: [double(header: header), double(content: 'foo', header: nil)]), - double(files: [double(content: 'bar', header: nil)]) - ] - end - let(:file) { subject[0] } - - subject { client.list_conflict_files } it 'sends an RPC request' do expect_any_instance_of(Gitaly::ConflictsService::Stub).to receive(:list_conflict_files) - .with(request, kind_of(Hash)).and_return([]) - - subject - end - - it 'forms a Gitlab::Git::ConflictFile collection from the response' do - allow_any_instance_of(Gitaly::ConflictsService::Stub).to receive(:list_conflict_files) - .with(request, kind_of(Hash)).and_return(response) + .with(request, kind_of(Hash)).and_return([].to_enum) - expect(subject.size).to be(1) - expect(file.content).to eq('foobar') - expect(file.their_path).to eq(their_path) - expect(file.our_path).to eq(our_path) - expect(file.our_mode).to be(our_mode) - expect(file.repository).to eq(target_repository) - expect(file.commit_oid).to eq(our_commit_oid) + client.list_conflict_files end end diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb index c0db2c1b386..859b53ac560 100644 --- a/spec/models/repository_spec.rb +++ b/spec/models/repository_spec.rb @@ -358,28 +358,38 @@ describe Repository do end describe '#can_be_merged?' do - context 'mergeable branches' do - subject { repository.can_be_merged?('0b4bc9a49b562e85de7cc9e834518ea6828729b9', 'master') } + shared_examples 'can be merged' do + context 'mergeable branches' do + subject { repository.can_be_merged?('0b4bc9a49b562e85de7cc9e834518ea6828729b9', 'master') } - it { is_expected.to be_truthy } - end + it { is_expected.to be_truthy } + end - context 'non-mergeable branches' do - subject { repository.can_be_merged?('bb5206fee213d983da88c47f9cf4cc6caf9c66dc', 'feature') } + context 'non-mergeable branches' do + subject { repository.can_be_merged?('bb5206fee213d983da88c47f9cf4cc6caf9c66dc', 'feature') } - it { is_expected.to be_falsey } - end + it { is_expected.to be_falsey } + end - context 'non merged branch' do - subject { repository.merged_to_root_ref?('fix') } + context 'non merged branch' do + subject { repository.merged_to_root_ref?('fix') } - it { is_expected.to be_falsey } + it { is_expected.to be_falsey } + end + + context 'non existent branch' do + subject { repository.merged_to_root_ref?('non_existent_branch') } + + it { is_expected.to be_nil } + end end - context 'non existent branch' do - subject { repository.merged_to_root_ref?('non_existent_branch') } + context 'when Gitaly can_be_merged feature is enabled' do + it_behaves_like 'can be merged' + end - it { is_expected.to be_nil } + context 'when Gitaly can_be_merged feature is disabled', :disable_gitaly do + it_behaves_like 'can be merged' end end -- cgit v1.2.1 From f716049998ec41d8f26caedd65ebd1a247179926 Mon Sep 17 00:00:00 2001 From: Clement Ho Date: Thu, 11 Jan 2018 11:39:54 -0600 Subject: Code improvements --- app/assets/javascripts/dispatcher.js | 4 +++- app/assets/javascripts/pages/projects/labels/edit/index.js | 4 +--- app/assets/javascripts/pages/projects/labels/index/index.js | 7 +++---- app/assets/javascripts/pages/projects/labels/new/index.js | 4 +--- 4 files changed, 8 insertions(+), 11 deletions(-) diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js index 0794edd5f69..e8ec6daf687 100644 --- a/app/assets/javascripts/dispatcher.js +++ b/app/assets/javascripts/dispatcher.js @@ -482,13 +482,15 @@ import Activities from './activities'; break; case 'groups:labels:new': case 'groups:labels:edit': + new Labels(); + break; case 'projects:labels:new': import('./pages/projects/labels/new') .then(callDefault) .catch(fail); break; case 'projects:labels:edit': - import('./pages/projects/labels/new') + import('./pages/projects/labels/edit') .then(callDefault) .catch(fail); break; diff --git a/app/assets/javascripts/pages/projects/labels/edit/index.js b/app/assets/javascripts/pages/projects/labels/edit/index.js index 75dc1ef1859..72c5e4744ac 100644 --- a/app/assets/javascripts/pages/projects/labels/edit/index.js +++ b/app/assets/javascripts/pages/projects/labels/edit/index.js @@ -1,5 +1,3 @@ import Labels from '~/labels'; -export default function () { - new Labels(); // eslint-disable-line no-new -} +export default () => new Labels(); diff --git a/app/assets/javascripts/pages/projects/labels/index/index.js b/app/assets/javascripts/pages/projects/labels/index/index.js index c258be4f908..82a5b4d0760 100644 --- a/app/assets/javascripts/pages/projects/labels/index/index.js +++ b/app/assets/javascripts/pages/projects/labels/index/index.js @@ -1,19 +1,18 @@ -/* eslint-disable no-new */ import LabelManager from '~/label_manager'; import GroupLabelSubscription from '~/group_label_subscription'; import ProjectLabelSubscription from '~/project_label_subscription'; export default () => { if ($('.prioritized-labels').length) { - new LabelManager(); + new LabelManager(); // eslint-disable-line no-new } $('.label-subscription').each((i, el) => { const $el = $(el); if ($el.find('.dropdown-group-label').length) { - new GroupLabelSubscription($el); + new GroupLabelSubscription($el); // eslint-disable-line no-new } else { - new ProjectLabelSubscription($el); + new ProjectLabelSubscription($el); // eslint-disable-line no-new } }); }; diff --git a/app/assets/javascripts/pages/projects/labels/new/index.js b/app/assets/javascripts/pages/projects/labels/new/index.js index 75dc1ef1859..72c5e4744ac 100644 --- a/app/assets/javascripts/pages/projects/labels/new/index.js +++ b/app/assets/javascripts/pages/projects/labels/new/index.js @@ -1,5 +1,3 @@ import Labels from '~/labels'; -export default function () { - new Labels(); // eslint-disable-line no-new -} +export default () => new Labels(); -- cgit v1.2.1 From b64b7d70038fcf38495f67bc2f9cb320c2c168e7 Mon Sep 17 00:00:00 2001 From: Greg Stark Date: Thu, 11 Jan 2018 13:22:52 +0000 Subject: Use simple Next/Prev paging for jobs to avoid large count queries on arbitrarily large sets of historical jobs --- app/controllers/projects/jobs_controller.rb | 2 +- app/views/projects/jobs/_table.html.haml | 2 +- changelogs/unreleased/disable-pages-on-jobs.yml | 6 ++++++ 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 changelogs/unreleased/disable-pages-on-jobs.yml diff --git a/app/controllers/projects/jobs_controller.rb b/app/controllers/projects/jobs_controller.rb index 4865ec3dfe5..8b54ba3ad7c 100644 --- a/app/controllers/projects/jobs_controller.rb +++ b/app/controllers/projects/jobs_controller.rb @@ -29,7 +29,7 @@ class Projects::JobsController < Projects::ApplicationController :project, :tags ]) - @builds = @builds.page(params[:page]).per(30) + @builds = @builds.page(params[:page]).per(30).without_count end def cancel_all diff --git a/app/views/projects/jobs/_table.html.haml b/app/views/projects/jobs/_table.html.haml index 82806f022ee..d124d3ebfc1 100644 --- a/app/views/projects/jobs/_table.html.haml +++ b/app/views/projects/jobs/_table.html.haml @@ -22,4 +22,4 @@ = render partial: "projects/ci/builds/build", collection: builds, as: :build, locals: { commit_sha: true, ref: true, pipeline_link: true, stage: true, allow_retry: true, admin: admin } - = paginate builds, theme: 'gitlab' + = paginate_collection(builds) diff --git a/changelogs/unreleased/disable-pages-on-jobs.yml b/changelogs/unreleased/disable-pages-on-jobs.yml new file mode 100644 index 00000000000..629768efce1 --- /dev/null +++ b/changelogs/unreleased/disable-pages-on-jobs.yml @@ -0,0 +1,6 @@ +--- +title: Use simple Next/Prev paging for jobs to avoid large count queries on arbitrarily + large sets of historical jobs +merge_request: +author: +type: performance -- cgit v1.2.1 From c0fdcb9b401d9c19357517cacf16eb857652bf42 Mon Sep 17 00:00:00 2001 From: Clement Ho Date: Thu, 11 Jan 2018 11:47:17 -0600 Subject: Code improvements --- app/assets/javascripts/dispatcher.js | 4 +++- app/assets/javascripts/pages/snippets/create/index.js | 2 +- app/assets/javascripts/pages/snippets/edit/index.js | 2 +- app/assets/javascripts/pages/snippets/new/index.js | 2 +- app/assets/javascripts/pages/snippets/update/index.js | 2 +- 5 files changed, 7 insertions(+), 5 deletions(-) diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js index f67eb9c5895..3212b7e02f5 100644 --- a/app/assets/javascripts/dispatcher.js +++ b/app/assets/javascripts/dispatcher.js @@ -575,7 +575,9 @@ import Activities from './activities'; import('./pages/admin/conversational_development_index/show').then(m => m.default()).catch(fail); break; case 'snippets:show': - import('./pages/snippets/show').then(callDefault).catch(fail); + import('./pages/snippets/show') + .then(callDefault) + .catch(fail); break; case 'import:fogbugz:new_user_map': import('./pages/import/fogbugz/new_user_map').then(m => m.default()).catch(fail); diff --git a/app/assets/javascripts/pages/snippets/create/index.js b/app/assets/javascripts/pages/snippets/create/index.js index f7dbd021688..a403452aa30 100644 --- a/app/assets/javascripts/pages/snippets/create/index.js +++ b/app/assets/javascripts/pages/snippets/create/index.js @@ -1,7 +1,7 @@ import GLForm from '~/gl_form'; import ZenMode from '~/zen_mode'; -export default function () { +export default () => { new GLForm($('.snippet-form'), false); // eslint-disable-line no-new new ZenMode(); // eslint-disable-line no-new } diff --git a/app/assets/javascripts/pages/snippets/edit/index.js b/app/assets/javascripts/pages/snippets/edit/index.js index f7dbd021688..a403452aa30 100644 --- a/app/assets/javascripts/pages/snippets/edit/index.js +++ b/app/assets/javascripts/pages/snippets/edit/index.js @@ -1,7 +1,7 @@ import GLForm from '~/gl_form'; import ZenMode from '~/zen_mode'; -export default function () { +export default () => { new GLForm($('.snippet-form'), false); // eslint-disable-line no-new new ZenMode(); // eslint-disable-line no-new } diff --git a/app/assets/javascripts/pages/snippets/new/index.js b/app/assets/javascripts/pages/snippets/new/index.js index f7dbd021688..a403452aa30 100644 --- a/app/assets/javascripts/pages/snippets/new/index.js +++ b/app/assets/javascripts/pages/snippets/new/index.js @@ -1,7 +1,7 @@ import GLForm from '~/gl_form'; import ZenMode from '~/zen_mode'; -export default function () { +export default () => { new GLForm($('.snippet-form'), false); // eslint-disable-line no-new new ZenMode(); // eslint-disable-line no-new } diff --git a/app/assets/javascripts/pages/snippets/update/index.js b/app/assets/javascripts/pages/snippets/update/index.js index f7dbd021688..a403452aa30 100644 --- a/app/assets/javascripts/pages/snippets/update/index.js +++ b/app/assets/javascripts/pages/snippets/update/index.js @@ -1,7 +1,7 @@ import GLForm from '~/gl_form'; import ZenMode from '~/zen_mode'; -export default function () { +export default () => { new GLForm($('.snippet-form'), false); // eslint-disable-line no-new new ZenMode(); // eslint-disable-line no-new } -- cgit v1.2.1 From dc7465107fd5133324ae4a4cbf8315e80f5a5367 Mon Sep 17 00:00:00 2001 From: Clement Ho Date: Thu, 11 Jan 2018 11:51:12 -0600 Subject: Fix eslint --- app/assets/javascripts/pages/snippets/create/index.js | 2 +- app/assets/javascripts/pages/snippets/edit/index.js | 2 +- app/assets/javascripts/pages/snippets/new/index.js | 2 +- app/assets/javascripts/pages/snippets/update/index.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/assets/javascripts/pages/snippets/create/index.js b/app/assets/javascripts/pages/snippets/create/index.js index a403452aa30..f996d3cd74e 100644 --- a/app/assets/javascripts/pages/snippets/create/index.js +++ b/app/assets/javascripts/pages/snippets/create/index.js @@ -4,4 +4,4 @@ import ZenMode from '~/zen_mode'; export default () => { new GLForm($('.snippet-form'), false); // eslint-disable-line no-new new ZenMode(); // eslint-disable-line no-new -} +}; diff --git a/app/assets/javascripts/pages/snippets/edit/index.js b/app/assets/javascripts/pages/snippets/edit/index.js index a403452aa30..f996d3cd74e 100644 --- a/app/assets/javascripts/pages/snippets/edit/index.js +++ b/app/assets/javascripts/pages/snippets/edit/index.js @@ -4,4 +4,4 @@ import ZenMode from '~/zen_mode'; export default () => { new GLForm($('.snippet-form'), false); // eslint-disable-line no-new new ZenMode(); // eslint-disable-line no-new -} +}; diff --git a/app/assets/javascripts/pages/snippets/new/index.js b/app/assets/javascripts/pages/snippets/new/index.js index a403452aa30..f996d3cd74e 100644 --- a/app/assets/javascripts/pages/snippets/new/index.js +++ b/app/assets/javascripts/pages/snippets/new/index.js @@ -4,4 +4,4 @@ import ZenMode from '~/zen_mode'; export default () => { new GLForm($('.snippet-form'), false); // eslint-disable-line no-new new ZenMode(); // eslint-disable-line no-new -} +}; diff --git a/app/assets/javascripts/pages/snippets/update/index.js b/app/assets/javascripts/pages/snippets/update/index.js index a403452aa30..f996d3cd74e 100644 --- a/app/assets/javascripts/pages/snippets/update/index.js +++ b/app/assets/javascripts/pages/snippets/update/index.js @@ -4,4 +4,4 @@ import ZenMode from '~/zen_mode'; export default () => { new GLForm($('.snippet-form'), false); // eslint-disable-line no-new new ZenMode(); // eslint-disable-line no-new -} +}; -- cgit v1.2.1 From cb4cbcdca7d1437181a5e7ae980ca1cfc8aab831 Mon Sep 17 00:00:00 2001 From: Clement Ho Date: Thu, 11 Jan 2018 12:24:29 -0600 Subject: Refactor dispatcher project mr index path --- app/assets/javascripts/dispatcher.js | 5 +++++ .../pages/projects/merge_requests/index/index.js | 16 ++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 app/assets/javascripts/pages/projects/merge_requests/index/index.js diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js index 72a6426e901..43f395d16e4 100644 --- a/app/assets/javascripts/dispatcher.js +++ b/app/assets/javascripts/dispatcher.js @@ -152,6 +152,11 @@ import Activities from './activities'; new UsersSelect(); break; case 'projects:merge_requests:index': + import('./pages/projects/merge_requests/index') + .then(callDefault) + .catch(fail); + shortcut_handler = true; + break; case 'projects:issues:index': if (filteredSearchEnabled) { const filteredSearchManager = new gl.FilteredSearchManager(page === 'projects:issues:index' ? 'issues' : 'merge_requests'); diff --git a/app/assets/javascripts/pages/projects/merge_requests/index/index.js b/app/assets/javascripts/pages/projects/merge_requests/index/index.js new file mode 100644 index 00000000000..a52bea03aa2 --- /dev/null +++ b/app/assets/javascripts/pages/projects/merge_requests/index/index.js @@ -0,0 +1,16 @@ +import IssuableIndex from '~/issuable_index'; +import ShortcutsNavigation from '~/shortcuts_navigation'; +import UsersSelect from '~/users_select'; + +export default () => { + const filteredSearchEnabled = gl.FilteredSearchManager && document.querySelector('.filtered-search'); + + if (filteredSearchEnabled) { + const filteredSearchManager = new gl.FilteredSearchManager('merge_requests'); + filteredSearchManager.setup(); + } + + new IssuableIndex('merge_request_'); // eslint-disable-line no-new + new ShortcutsNavigation(); // eslint-disable-line no-new + new UsersSelect(); // eslint-disable-line no-new +}; -- cgit v1.2.1 From b312ceda3988054e36d189ac2a11c121c7ad74a3 Mon Sep 17 00:00:00 2001 From: Mayra Cabrera Date: Tue, 9 Jan 2018 09:46:57 -0600 Subject: Fixes minor aspects on Prometheus description - Change Gitlab to GitLab - Remove trailing space on GitLab Integration link --- app/assets/javascripts/clusters/components/applications.vue | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/assets/javascripts/clusters/components/applications.vue b/app/assets/javascripts/clusters/components/applications.vue index 25cef44c1b8..4177bff6e88 100644 --- a/app/assets/javascripts/clusters/components/applications.vue +++ b/app/assets/javascripts/clusters/components/applications.vue @@ -80,8 +80,7 @@ which incur additional costs. See %{pricingLink}`)), { gitlabIntegrationLink: ` - ${_.escape(s__('ClusterIntegration|Gitlab Integration'))} - `, + ${_.escape(s__('ClusterIntegration|GitLab Integration'))}`, }, false, ); -- cgit v1.2.1 From dddd261c34d9a06f35957219b7813b32438c718b Mon Sep 17 00:00:00 2001 From: Filipa Lacerda Date: Thu, 11 Jan 2018 19:07:42 +0000 Subject: Fix boolean prop being provided as string --- app/assets/javascripts/jobs/components/header.vue | 6 +++- spec/javascripts/jobs/header_spec.js | 34 +++++++++++++++++------ 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/app/assets/javascripts/jobs/components/header.vue b/app/assets/javascripts/jobs/components/header.vue index 9e3f659db5f..321a4872ccc 100644 --- a/app/assets/javascripts/jobs/components/header.vue +++ b/app/assets/javascripts/jobs/components/header.vue @@ -30,8 +30,12 @@ shouldRenderContent() { return !this.isLoading && Object.keys(this.job).length; }, + /** + * When job has not started the key will be `false` + * When job started the key will be a string with a date. + */ jobStarted() { - return this.job.started; + return !this.job.started === false; }, }, watch: { diff --git a/spec/javascripts/jobs/header_spec.js b/spec/javascripts/jobs/header_spec.js index 83395ea451e..a9df0418d5d 100644 --- a/spec/javascripts/jobs/header_spec.js +++ b/spec/javascripts/jobs/header_spec.js @@ -31,6 +31,7 @@ describe('Job details header', () => { email: 'foo@bar.com', avatar_url: 'link', }, + started: '2018-01-08T09:48:27.319Z', new_issue_path: 'path', }, isLoading: false, @@ -43,15 +44,32 @@ describe('Job details header', () => { vm.$destroy(); }); - it('should render provided job information', () => { - expect( - vm.$el.querySelector('.header-main-content').textContent.replace(/\s+/g, ' ').trim(), - ).toEqual('failed Job #123 triggered 3 weeks ago by Foo'); + describe('triggered job', () => { + beforeEach(() => { + vm = mountComponent(HeaderComponent, props); + }); + + it('should render provided job information', () => { + expect( + vm.$el.querySelector('.header-main-content').textContent.replace(/\s+/g, ' ').trim(), + ).toEqual('failed Job #123 triggered 3 weeks ago by Foo'); + }); + + it('should render new issue link', () => { + expect( + vm.$el.querySelector('.js-new-issue').getAttribute('href'), + ).toEqual(props.job.new_issue_path); + }); }); - it('should render new issue link', () => { - expect( - vm.$el.querySelector('.js-new-issue').getAttribute('href'), - ).toEqual(props.job.new_issue_path); + describe('created job', () => { + it('should render created key', () => { + props.job.started = false; + vm = mountComponent(HeaderComponent, props); + + expect( + vm.$el.querySelector('.header-main-content').textContent.replace(/\s+/g, ' ').trim(), + ).toEqual('failed Job #123 created 3 weeks ago by Foo'); + }); }); }); -- cgit v1.2.1 From e4335a1a1e4a1df07b184b761a0093fe4d62670e Mon Sep 17 00:00:00 2001 From: Clement Ho Date: Thu, 11 Jan 2018 15:46:27 -0600 Subject: Fix eslint so that pipeline doesnt fail after mege --- app/assets/javascripts/dispatcher.js | 1 - 1 file changed, 1 deletion(-) diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js index a1e0c42e711..06cacfefb76 100644 --- a/app/assets/javascripts/dispatcher.js +++ b/app/assets/javascripts/dispatcher.js @@ -6,7 +6,6 @@ import Milestone from './milestone'; import IssuableForm from './issuable_form'; import LabelsSelect from './labels_select'; import MilestoneSelect from './milestone_select'; -import NewBranchForm from './new_branch_form'; import NotificationsForm from './notifications_form'; import notificationsDropdown from './notifications_dropdown'; import groupAvatar from './group_avatar'; -- cgit v1.2.1 From af8fb46ffb1f046a0266cf693a076a08b808cae2 Mon Sep 17 00:00:00 2001 From: Simon Knox Date: Fri, 12 Jan 2018 15:43:06 +1100 Subject: dynamic imports for projects:e/f/i --- app/assets/javascripts/dispatcher.js | 60 +++++++++++----------- .../javascripts/pages/projects/edit/index.js | 8 +++ .../pages/projects/find_file/show/index.js | 12 +++++ .../javascripts/pages/projects/forks/new/index.js | 3 ++ .../pages/projects/imports/show/index.js | 3 ++ .../pages/projects/issues/edit/index.js | 16 ++++++ .../pages/projects/issues/index/index.js | 18 +++++++ .../javascripts/pages/projects/issues/new/index.js | 16 ++++++ .../pages/projects/issues/show/index.js | 13 +++++ 9 files changed, 120 insertions(+), 29 deletions(-) create mode 100644 app/assets/javascripts/pages/projects/edit/index.js create mode 100644 app/assets/javascripts/pages/projects/find_file/show/index.js create mode 100644 app/assets/javascripts/pages/projects/forks/new/index.js create mode 100644 app/assets/javascripts/pages/projects/imports/show/index.js create mode 100644 app/assets/javascripts/pages/projects/issues/edit/index.js create mode 100644 app/assets/javascripts/pages/projects/issues/index/index.js create mode 100644 app/assets/javascripts/pages/projects/issues/new/index.js create mode 100644 app/assets/javascripts/pages/projects/issues/show/index.js diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js index f8fedab36a1..0f3f0bcdcd1 100644 --- a/app/assets/javascripts/dispatcher.js +++ b/app/assets/javascripts/dispatcher.js @@ -18,7 +18,6 @@ import projectAvatar from './project_avatar'; import MergeRequest from './merge_request'; import Compare from './compare'; import initCompareAutocomplete from './compare_autocomplete'; -import ProjectFindFile from './project_find_file'; import ProjectNew from './project_new'; import projectImport from './project_import'; import Labels from './labels'; @@ -33,7 +32,6 @@ import SecretValues from './behaviors/secret_values'; import DeleteModal from './branches/branches_delete_modal'; import Group from './group'; import ProjectsList from './projects_list'; -import setupProjectEdit from './project_edit'; import MiniPipelineGraph from './mini_pipeline_graph_dropdown'; import BlobLinePermalinkUpdater from './blob/blob_line_permalink_updater'; import BlobForkSuggestion from './blob/blob_fork_suggestion'; @@ -63,7 +61,6 @@ import GlFieldErrors from './gl_field_errors'; import GLForm from './gl_form'; import Shortcuts from './shortcuts'; import ShortcutsNavigation from './shortcuts_navigation'; -import ShortcutsFindFile from './shortcuts_find_file'; import ShortcutsIssuable from './shortcuts_issuable'; import U2FAuthenticate from './u2f/authenticate'; import Members from './members'; @@ -153,22 +150,26 @@ import Activities from './activities'; shortcut_handler = true; break; case 'projects:merge_requests:index': - case 'projects:issues:index': if (filteredSearchEnabled) { - const filteredSearchManager = new gl.FilteredSearchManager(page === 'projects:issues:index' ? 'issues' : 'merge_requests'); + const filteredSearchManager = new gl.FilteredSearchManager('merge_requests'); filteredSearchManager.setup(); } - const pagePrefix = page === 'projects:merge_requests:index' ? 'merge_request_' : 'issue_'; - new IssuableIndex(pagePrefix); + new IssuableIndex('merge_request_'); shortcut_handler = new ShortcutsNavigation(); new UsersSelect(); break; + case 'projects:issues:index': + import('./pages/projects/issues/index') + .then(callDefault) + .catch(fail); + shortcut_handler = true; + break; case 'projects:issues:show': - new Issue(); - shortcut_handler = new ShortcutsIssuable(); - new ZenMode(); - initIssuableSidebar(); + import('./pages/projects/issues/show') + .then(callDefault) + .catch(fail); + shortcut_handler = true; break; case 'dashboard:milestones:index': import('./pages/dashboard/milestones/index') @@ -252,13 +253,16 @@ import Activities from './activities'; new DeleteModal(); break; case 'projects:issues:new': + import('./pages/projects/issues/new') + .then(callDefault) + .catch(fail); + shortcut_handler = true; + break; case 'projects:issues:edit': - shortcut_handler = new ShortcutsNavigation(); - new GLForm($('.issue-form'), true); - new IssuableForm($('.issue-form')); - new LabelsSelect(); - new MilestoneSelect(); - new IssuableTemplateSelectors(); + import('./pages/projects/issues/edit') + .then(callDefault) + .catch(fail); + shortcut_handler = true; break; case 'projects:merge_requests:creations:new': const mrNewCompareNode = document.querySelector('.js-merge-request-new-compare'); @@ -376,12 +380,14 @@ import Activities from './activities'; }); break; case 'projects:edit': - setupProjectEdit(); - // Initialize expandable settings panels - initSettingsPanels(); + import('./pages/projects/edit') + .then(callDefault) + .catch(fail); break; case 'projects:imports:show': - projectImport(); + import('./pages/projects/imports/show') + .then(callDefault) + .catch(fail); break; case 'projects:pipelines:new': case 'projects:pipelines:create': @@ -450,13 +456,9 @@ import Activities from './activities'; }); break; case 'projects:find_file:show': - const findElement = document.querySelector('.js-file-finder'); - const projectFindFile = new ProjectFindFile($(".file-finder-holder"), { - url: findElement.dataset.fileFindUrl, - treeUrl: findElement.dataset.findTreeUrl, - blobUrlTemplate: findElement.dataset.blobUrlTemplate, - }); - new ShortcutsFindFile(projectFindFile); + import('./pages/projects/find_file/show') + .then(callDefault) + .catch(fail); shortcut_handler = true; break; case 'projects:blob:show': @@ -493,7 +495,7 @@ import Activities from './activities'; shortcut_handler = true; break; case 'projects:forks:new': - import(/* webpackChunkName: 'project_fork' */ './project_fork') + import('./pages/projects/forks/new') .then(callDefault) .catch(fail); break; diff --git a/app/assets/javascripts/pages/projects/edit/index.js b/app/assets/javascripts/pages/projects/edit/index.js new file mode 100644 index 00000000000..7f662ef6b6a --- /dev/null +++ b/app/assets/javascripts/pages/projects/edit/index.js @@ -0,0 +1,8 @@ +import initSettingsPanels from '~/settings_panels'; +import setupProjectEdit from '~/project_edit'; + +export default () => { + setupProjectEdit(); + // Initialize expandable settings panels + initSettingsPanels(); +}; diff --git a/app/assets/javascripts/pages/projects/find_file/show/index.js b/app/assets/javascripts/pages/projects/find_file/show/index.js new file mode 100644 index 00000000000..42bde0ff779 --- /dev/null +++ b/app/assets/javascripts/pages/projects/find_file/show/index.js @@ -0,0 +1,12 @@ +import ProjectFindFile from '~/project_find_file'; +import ShortcutsFindFile from '~/shortcuts_find_file'; + +export default () => { + const findElement = document.querySelector('.js-file-finder'); + const projectFindFile = new ProjectFindFile($('.file-finder-holder'), { + url: findElement.dataset.fileFindUrl, + treeUrl: findElement.dataset.findTreeUrl, + blobUrlTemplate: findElement.dataset.blobUrlTemplate, + }); + new ShortcutsFindFile(projectFindFile); // eslint-disable-line no-new +}; diff --git a/app/assets/javascripts/pages/projects/forks/new/index.js b/app/assets/javascripts/pages/projects/forks/new/index.js new file mode 100644 index 00000000000..4f68d1c0074 --- /dev/null +++ b/app/assets/javascripts/pages/projects/forks/new/index.js @@ -0,0 +1,3 @@ +import projectFork from '~/project_fork'; + +export default projectFork; diff --git a/app/assets/javascripts/pages/projects/imports/show/index.js b/app/assets/javascripts/pages/projects/imports/show/index.js new file mode 100644 index 00000000000..9fa50daa0c0 --- /dev/null +++ b/app/assets/javascripts/pages/projects/imports/show/index.js @@ -0,0 +1,3 @@ +import projectImport from '~/project_import'; + +export default projectImport; diff --git a/app/assets/javascripts/pages/projects/issues/edit/index.js b/app/assets/javascripts/pages/projects/issues/edit/index.js new file mode 100644 index 00000000000..5c7daf84738 --- /dev/null +++ b/app/assets/javascripts/pages/projects/issues/edit/index.js @@ -0,0 +1,16 @@ +/* eslint-disable no-new */ +import GLForm from '~/gl_form'; +import IssuableForm from '~/issuable_form'; +import LabelsSelect from '~/labels_select'; +import MilestoneSelect from '~/milestone_select'; +import ShortcutsNavigation from '~/shortcuts_navigation'; +import IssuableTemplateSelectors from '~/templates/issuable_template_selectors'; + +export default () => { + new ShortcutsNavigation(); + new GLForm($('.issue-form'), true); + new IssuableForm($('.issue-form')); + new LabelsSelect(); + new MilestoneSelect(); + new IssuableTemplateSelectors(); +}; diff --git a/app/assets/javascripts/pages/projects/issues/index/index.js b/app/assets/javascripts/pages/projects/issues/index/index.js new file mode 100644 index 00000000000..54802e11bd4 --- /dev/null +++ b/app/assets/javascripts/pages/projects/issues/index/index.js @@ -0,0 +1,18 @@ + +/* eslint-disable no-new */ + +import IssuableIndex from '~/issuable_index'; +import ShortcutsNavigation from '~/shortcuts_navigation'; +import UsersSelect from '~/users_select'; + +export default () => { + const filteredSearchEnabled = gl.FilteredSearchManager && document.querySelector('.filtered-search'); + if (filteredSearchEnabled) { + const filteredSearchManager = new gl.FilteredSearchManager('issues'); + filteredSearchManager.setup(); + } + new IssuableIndex('issue_'); // eslint-disable no-new + + new ShortcutsNavigation(); + new UsersSelect(); // eslint-disable no-new +}; diff --git a/app/assets/javascripts/pages/projects/issues/new/index.js b/app/assets/javascripts/pages/projects/issues/new/index.js new file mode 100644 index 00000000000..5c7daf84738 --- /dev/null +++ b/app/assets/javascripts/pages/projects/issues/new/index.js @@ -0,0 +1,16 @@ +/* eslint-disable no-new */ +import GLForm from '~/gl_form'; +import IssuableForm from '~/issuable_form'; +import LabelsSelect from '~/labels_select'; +import MilestoneSelect from '~/milestone_select'; +import ShortcutsNavigation from '~/shortcuts_navigation'; +import IssuableTemplateSelectors from '~/templates/issuable_template_selectors'; + +export default () => { + new ShortcutsNavigation(); + new GLForm($('.issue-form'), true); + new IssuableForm($('.issue-form')); + new LabelsSelect(); + new MilestoneSelect(); + new IssuableTemplateSelectors(); +}; diff --git a/app/assets/javascripts/pages/projects/issues/show/index.js b/app/assets/javascripts/pages/projects/issues/show/index.js new file mode 100644 index 00000000000..7245b803192 --- /dev/null +++ b/app/assets/javascripts/pages/projects/issues/show/index.js @@ -0,0 +1,13 @@ + +/* eslint-disable no-new */ +import initIssuableSidebar from '~/init_issuable_sidebar'; +import Issue from '~/issuable_index'; +import ShortcutsIssuable from '~/shortcuts_issuable'; +import ZenMode from '~/zen_mode'; + +export default () => { + new Issue(); + new ShortcutsIssuable(); + new ZenMode(); + initIssuableSidebar(); +}; -- cgit v1.2.1 From a25af3efbc4aa50d84448f23a0d686804c96102e Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Thu, 11 Jan 2018 19:32:10 -0600 Subject: convert notification subscription button into toggle --- .../components/subscriptions/subscriptions.vue | 25 ++++++++-------------- .../vue_shared/components/toggle_button.vue | 4 ++-- app/assets/stylesheets/pages/issuable.scss | 4 ---- 3 files changed, 11 insertions(+), 22 deletions(-) diff --git a/app/assets/javascripts/sidebar/components/subscriptions/subscriptions.vue b/app/assets/javascripts/sidebar/components/subscriptions/subscriptions.vue index 7226076a8fc..f4f9d04fcf2 100644 --- a/app/assets/javascripts/sidebar/components/subscriptions/subscriptions.vue +++ b/app/assets/javascripts/sidebar/components/subscriptions/subscriptions.vue @@ -2,11 +2,11 @@ /* eslint-disable vue/require-default-prop */ import { __ } from '../../../locale'; import eventHub from '../../event_hub'; - import loadingButton from '../../../vue_shared/components/loading_button.vue'; + import toggleButton from '../../../vue_shared/components/toggle_button.vue'; export default { components: { - loadingButton, + toggleButton, }, props: { loading: { @@ -24,15 +24,8 @@ }, }, computed: { - buttonLabel() { - let label; - if (this.subscribed === false) { - label = __('Subscribe'); - } else if (this.subscribed === true) { - label = __('Unsubscribe'); - } - - return label; + showLoadingState() { + return this.subscribed === null || this.loading; }, }, methods: { @@ -55,12 +48,12 @@ {{ __('Notifications') }} - diff --git a/app/assets/javascripts/vue_shared/components/toggle_button.vue b/app/assets/javascripts/vue_shared/components/toggle_button.vue index 2b12718ae96..274ea80c484 100644 --- a/app/assets/javascripts/vue_shared/components/toggle_button.vue +++ b/app/assets/javascripts/vue_shared/components/toggle_button.vue @@ -23,11 +23,10 @@ name: { type: String, required: false, - default: '', }, value: { type: Boolean, - required: true, + required: false, }, disabledInput: { type: Boolean, @@ -61,6 +60,7 @@