summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/repository/components/last_commit.vue2
-rw-r--r--app/assets/javascripts/repository/components/preview/index.vue2
-rw-r--r--app/assets/javascripts/repository/components/table/index.vue13
-rw-r--r--app/assets/javascripts/repository/components/table/parent_row.vue25
-rw-r--r--app/assets/javascripts/repository/components/table/row.vue16
-rw-r--r--app/assets/javascripts/repository/components/tree_content.vue12
-rw-r--r--app/assets/javascripts/repository/mixins/preload.js36
-rw-r--r--app/assets/javascripts/repository/pages/tree.vue4
-rw-r--r--app/controllers/projects/wikis_controller.rb4
-rw-r--r--app/helpers/markup_helper.rb1
-rw-r--r--app/models/ci/pipeline.rb2
-rw-r--r--app/models/concerns/atomic_internal_id.rb6
-rw-r--r--app/models/deployment.rb3
-rw-r--r--app/models/issue.rb6
-rw-r--r--app/models/merge_request.rb6
-rw-r--r--app/models/merge_request_diff.rb2
-rw-r--r--app/models/milestone.rb5
-rw-r--r--app/models/release.rb5
-rw-r--r--app/models/user.rb1
-rw-r--r--app/services/users/destroy_service.rb7
20 files changed, 132 insertions, 26 deletions
diff --git a/app/assets/javascripts/repository/components/last_commit.vue b/app/assets/javascripts/repository/components/last_commit.vue
index 70678b0db37..8e7529899c0 100644
--- a/app/assets/javascripts/repository/components/last_commit.vue
+++ b/app/assets/javascripts/repository/components/last_commit.vue
@@ -90,7 +90,7 @@ export default {
<template>
<div class="info-well d-none d-sm-flex project-last-commit commit p-3">
- <gl-loading-icon v-if="isLoading" size="md" class="m-auto" />
+ <gl-loading-icon v-if="isLoading" size="md" color="dark" class="m-auto" />
<template v-else>
<user-avatar-link
v-if="commit.author"
diff --git a/app/assets/javascripts/repository/components/preview/index.vue b/app/assets/javascripts/repository/components/preview/index.vue
index 6b3822151ff..2bc93c3f1c1 100644
--- a/app/assets/javascripts/repository/components/preview/index.vue
+++ b/app/assets/javascripts/repository/components/preview/index.vue
@@ -44,7 +44,7 @@ export default {
</div>
</div>
<div class="blob-viewer">
- <gl-loading-icon v-if="loading > 0" size="md" class="my-4 mx-auto" />
+ <gl-loading-icon v-if="loading > 0" size="md" color="dark" class="my-4 mx-auto" />
<div v-else-if="readme" v-html="readme.html"></div>
</div>
</article>
diff --git a/app/assets/javascripts/repository/components/table/index.vue b/app/assets/javascripts/repository/components/table/index.vue
index 8f2e9264bca..29a3340b83d 100644
--- a/app/assets/javascripts/repository/components/table/index.vue
+++ b/app/assets/javascripts/repository/components/table/index.vue
@@ -34,6 +34,11 @@ export default {
type: Boolean,
required: true,
},
+ loadingPath: {
+ type: String,
+ required: false,
+ default: '',
+ },
},
data() {
return {
@@ -69,7 +74,12 @@ export default {
<table :aria-label="tableCaption" class="table tree-table qa-file-tree" aria-live="polite">
<table-header v-once />
<tbody>
- <parent-row v-show="showParentRow" :commit-ref="ref" :path="path" />
+ <parent-row
+ v-show="showParentRow"
+ :commit-ref="ref"
+ :path="path"
+ :loading-path="loadingPath"
+ />
<template v-for="val in entries">
<table-row
v-for="entry in val"
@@ -84,6 +94,7 @@ export default {
:url="entry.webUrl"
:submodule-tree-url="entry.treeUrl"
:lfs-oid="entry.lfsOid"
+ :loading-path="loadingPath"
/>
</template>
<template v-if="isLoading">
diff --git a/app/assets/javascripts/repository/components/table/parent_row.vue b/app/assets/javascripts/repository/components/table/parent_row.vue
index 3c39f404226..70a188f98cc 100644
--- a/app/assets/javascripts/repository/components/table/parent_row.vue
+++ b/app/assets/javascripts/repository/components/table/parent_row.vue
@@ -1,5 +1,10 @@
<script>
+import { GlLoadingIcon } from '@gitlab/ui';
+
export default {
+ components: {
+ GlLoadingIcon,
+ },
props: {
commitRef: {
type: String,
@@ -9,13 +14,21 @@ export default {
type: String,
required: true,
},
+ loadingPath: {
+ type: String,
+ required: false,
+ default: null,
+ },
},
computed: {
- parentRoute() {
+ parentPath() {
const splitArray = this.path.split('/');
splitArray.pop();
- return { path: `/tree/${this.commitRef}/${splitArray.join('/')}` };
+ return splitArray.join('/');
+ },
+ parentRoute() {
+ return { path: `/tree/${this.commitRef}/${this.parentPath}` };
},
},
methods: {
@@ -29,7 +42,13 @@ export default {
<template>
<tr class="tree-item">
<td colspan="3" class="tree-item-file-name" @click.self="clickRow">
- <router-link :to="parentRoute" :aria-label="__('Go to parent')">
+ <gl-loading-icon
+ v-if="parentPath === loadingPath"
+ size="sm"
+ inline
+ class="d-inline-block align-text-bottom"
+ />
+ <router-link v-else :to="parentRoute" :aria-label="__('Go to parent')">
..
</router-link>
</td>
diff --git a/app/assets/javascripts/repository/components/table/row.vue b/app/assets/javascripts/repository/components/table/row.vue
index cf0457a2abf..a8e13241c37 100644
--- a/app/assets/javascripts/repository/components/table/row.vue
+++ b/app/assets/javascripts/repository/components/table/row.vue
@@ -1,5 +1,5 @@
<script>
-import { GlBadge, GlLink, GlSkeletonLoading, GlTooltipDirective } from '@gitlab/ui';
+import { GlBadge, GlLink, GlSkeletonLoading, GlTooltipDirective, GlLoadingIcon } from '@gitlab/ui';
import { visitUrl } from '~/lib/utils/url_utility';
import TimeagoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import Icon from '~/vue_shared/components/icon.vue';
@@ -12,6 +12,7 @@ export default {
GlBadge,
GlLink,
GlSkeletonLoading,
+ GlLoadingIcon,
TimeagoTooltip,
Icon,
},
@@ -76,6 +77,11 @@ export default {
required: false,
default: null,
},
+ loadingPath: {
+ type: String,
+ required: false,
+ default: '',
+ },
},
data() {
return {
@@ -125,7 +131,13 @@ export default {
<template>
<tr :class="`file_${id}`" class="tree-item" @click="openRow">
<td class="tree-item-file-name">
- <i :aria-label="type" role="img" :class="iconName" class="fa fa-fw"></i>
+ <gl-loading-icon
+ v-if="path === loadingPath"
+ size="sm"
+ inline
+ class="d-inline-block align-text-bottom fa-fw"
+ />
+ <i v-else :aria-label="type" role="img" :class="iconName" class="fa fa-fw"></i>
<component :is="linkComponent" :to="routerLinkTo" :href="url" class="str-truncated">
{{ fullPath }}
</component>
diff --git a/app/assets/javascripts/repository/components/tree_content.vue b/app/assets/javascripts/repository/components/tree_content.vue
index 949e653fc8f..c30d6f05c6a 100644
--- a/app/assets/javascripts/repository/components/tree_content.vue
+++ b/app/assets/javascripts/repository/components/tree_content.vue
@@ -27,6 +27,11 @@ export default {
required: false,
default: '/',
},
+ loadingPath: {
+ type: String,
+ required: false,
+ default: '',
+ },
},
data() {
return {
@@ -109,7 +114,12 @@ export default {
<template>
<div>
- <file-table :path="path" :entries="entries" :is-loading="isLoadingFiles" />
+ <file-table
+ :path="path"
+ :entries="entries"
+ :is-loading="isLoadingFiles"
+ :loading-path="loadingPath"
+ />
<file-preview v-if="readme" :blob="readme" />
</div>
</template>
diff --git a/app/assets/javascripts/repository/mixins/preload.js b/app/assets/javascripts/repository/mixins/preload.js
new file mode 100644
index 00000000000..e68996245a8
--- /dev/null
+++ b/app/assets/javascripts/repository/mixins/preload.js
@@ -0,0 +1,36 @@
+import getFiles from '../queries/getFiles.query.graphql';
+import getRefMixin from './get_ref';
+import getProjectPath from '../queries/getProjectPath.query.graphql';
+
+export default {
+ mixins: [getRefMixin],
+ apollo: {
+ projectPath: {
+ query: getProjectPath,
+ },
+ },
+ data() {
+ return { projectPath: '', loadingPath: null };
+ },
+ beforeRouteUpdate(to, from, next) {
+ this.preload(to.params.pathMatch, next);
+ },
+ methods: {
+ preload(path, next) {
+ this.loadingPath = path.replace(/^\//, '');
+
+ return this.$apollo
+ .query({
+ query: getFiles,
+ variables: {
+ projectPath: this.projectPath,
+ ref: this.ref,
+ path: this.loadingPath,
+ nextPageCursor: '',
+ pageSize: 100,
+ },
+ })
+ .then(() => next());
+ },
+ },
+};
diff --git a/app/assets/javascripts/repository/pages/tree.vue b/app/assets/javascripts/repository/pages/tree.vue
index dd4d437f4dd..adc332fa370 100644
--- a/app/assets/javascripts/repository/pages/tree.vue
+++ b/app/assets/javascripts/repository/pages/tree.vue
@@ -1,11 +1,13 @@
<script>
import TreeContent from '../components/tree_content.vue';
import { updateElementsVisibility } from '../utils/dom';
+import preloadMixin from '../mixins/preload';
export default {
components: {
TreeContent,
},
+ mixins: [preloadMixin],
props: {
path: {
type: String,
@@ -34,5 +36,5 @@ export default {
</script>
<template>
- <tree-content :path="path" />
+ <tree-content :path="path" :loading-path="loadingPath" />
</template>
diff --git a/app/controllers/projects/wikis_controller.rb b/app/controllers/projects/wikis_controller.rb
index fb06299676c..cfc0925d9e1 100644
--- a/app/controllers/projects/wikis_controller.rb
+++ b/app/controllers/projects/wikis_controller.rb
@@ -39,6 +39,10 @@ class Projects::WikisController < Projects::ApplicationController
if @page
set_encoding_error unless valid_encoding?
+ # Assign vars expected by MarkupHelper
+ @ref = params[:version_id]
+ @path = @page.path
+
render 'show'
elsif file_blob
send_blob(@project_wiki.repository, file_blob)
diff --git a/app/helpers/markup_helper.rb b/app/helpers/markup_helper.rb
index e1e756c2f4c..657e5accdab 100644
--- a/app/helpers/markup_helper.rb
+++ b/app/helpers/markup_helper.rb
@@ -132,6 +132,7 @@ module MarkupHelper
pipeline: :wiki,
project: @project,
project_wiki: @project_wiki,
+ repository: @project_wiki.repository,
page_slug: wiki_page.slug,
issuable_state_filter_enabled: true
)
diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb
index 5ad3a9b4431..663389050d1 100644
--- a/app/models/ci/pipeline.rb
+++ b/app/models/ci/pipeline.rb
@@ -26,7 +26,7 @@ module Ci
belongs_to :merge_request, class_name: 'MergeRequest'
belongs_to :external_pull_request
- has_internal_id :iid, scope: :project, presence: false, ensure_if: -> { !importing? }, init: ->(s) do
+ has_internal_id :iid, scope: :project, presence: false, track_if: -> { !importing? }, ensure_if: -> { !importing? }, init: ->(s) do
s&.project&.all_pipelines&.maximum(:iid) || s&.project&.all_pipelines&.count
end
diff --git a/app/models/concerns/atomic_internal_id.rb b/app/models/concerns/atomic_internal_id.rb
index 64df265dc25..3e9b084e784 100644
--- a/app/models/concerns/atomic_internal_id.rb
+++ b/app/models/concerns/atomic_internal_id.rb
@@ -27,13 +27,13 @@ module AtomicInternalId
extend ActiveSupport::Concern
class_methods do
- def has_internal_id(column, scope:, init:, ensure_if: nil, presence: true) # rubocop:disable Naming/PredicateName
+ def has_internal_id(column, scope:, init:, ensure_if: nil, track_if: nil, presence: true) # rubocop:disable Naming/PredicateName
# We require init here to retain the ability to recalculate in the absence of a
- # InternaLId record (we may delete records in `internal_ids` for example).
+ # InternalId record (we may delete records in `internal_ids` for example).
raise "has_internal_id requires a init block, none given." unless init
raise "has_internal_id needs to be defined on association." unless self.reflect_on_association(scope)
- before_validation :"track_#{scope}_#{column}!", on: :create
+ before_validation :"track_#{scope}_#{column}!", on: :create, if: track_if
before_validation :"ensure_#{scope}_#{column}!", on: :create, if: ensure_if
validates column, presence: presence
diff --git a/app/models/deployment.rb b/app/models/deployment.rb
index 5a22a6ada9d..74cc7f93580 100644
--- a/app/models/deployment.rb
+++ b/app/models/deployment.rb
@@ -5,6 +5,7 @@ class Deployment < ApplicationRecord
include IidRoutes
include AfterCommitQueue
include UpdatedAtFilterable
+ include Importable
include Gitlab::Utils::StrongMemoize
belongs_to :project, required: true
@@ -17,7 +18,7 @@ class Deployment < ApplicationRecord
has_many :merge_requests,
through: :deployment_merge_requests
- has_internal_id :iid, scope: :project, init: ->(s) do
+ has_internal_id :iid, scope: :project, track_if: -> { !importing? }, init: ->(s) do
Deployment.where(project: s.project).maximum(:iid) if s&.project
end
diff --git a/app/models/issue.rb b/app/models/issue.rb
index da6450c6092..bf600278162 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -31,7 +31,7 @@ class Issue < ApplicationRecord
belongs_to :duplicated_to, class_name: 'Issue'
belongs_to :closed_by, class_name: 'User'
- has_internal_id :iid, scope: :project, init: ->(s) { s&.project&.issues&.maximum(:iid) }
+ has_internal_id :iid, scope: :project, track_if: -> { !importing? }, init: ->(s) { s&.project&.issues&.maximum(:iid) }
has_many :issue_milestones
has_many :milestones, through: :issue_milestones
@@ -78,8 +78,8 @@ class Issue < ApplicationRecord
ignore_column :state, remove_with: '12.7', remove_after: '2019-12-22'
- after_commit :expire_etag_cache
- after_save :ensure_metrics, unless: :imported?
+ after_commit :expire_etag_cache, unless: :importing?
+ after_save :ensure_metrics, unless: :importing?
attr_spammable :title, spam_title: true
attr_spammable :description, spam_description: true
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index 61f10620e39..6be14abe744 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -31,7 +31,7 @@ class MergeRequest < ApplicationRecord
belongs_to :source_project, class_name: "Project"
belongs_to :merge_user, class_name: "User"
- has_internal_id :iid, scope: :target_project, init: ->(s) { s&.target_project&.merge_requests&.maximum(:iid) }
+ has_internal_id :iid, scope: :target_project, track_if: -> { !importing? }, init: ->(s) { s&.target_project&.merge_requests&.maximum(:iid) }
has_many :merge_request_diffs
@@ -97,8 +97,8 @@ class MergeRequest < ApplicationRecord
after_create :ensure_merge_request_diff
after_update :clear_memoized_shas
after_update :reload_diff_if_branch_changed
- after_save :ensure_metrics
- after_commit :expire_etag_cache
+ after_save :ensure_metrics, unless: :importing?
+ after_commit :expire_etag_cache, unless: :importing?
# When this attribute is true some MR validation is ignored
# It allows us to close or modify broken merge requests
diff --git a/app/models/merge_request_diff.rb b/app/models/merge_request_diff.rb
index 71a344e69e3..fa633a1a725 100644
--- a/app/models/merge_request_diff.rb
+++ b/app/models/merge_request_diff.rb
@@ -138,7 +138,7 @@ class MergeRequestDiff < ApplicationRecord
# All diff information is collected from repository after object is created.
# It allows you to override variables like head_commit_sha before getting diff.
after_create :save_git_content, unless: :importing?
- after_create_commit :set_as_latest_diff
+ after_create_commit :set_as_latest_diff, unless: :importing?
after_save :update_external_diff_store, if: -> { !importing? && saved_change_to_external_diff? }
diff --git a/app/models/milestone.rb b/app/models/milestone.rb
index 920c28aeceb..5da92fc4bc5 100644
--- a/app/models/milestone.rb
+++ b/app/models/milestone.rb
@@ -17,6 +17,7 @@ class Milestone < ApplicationRecord
include StripAttribute
include Milestoneish
include FromUnion
+ include Importable
include Gitlab::SQL::Pattern
prepend_if_ee('::EE::Milestone') # rubocop: disable Cop/InjectEnterpriseEditionModule
@@ -30,8 +31,8 @@ class Milestone < ApplicationRecord
has_many :milestone_releases
has_many :releases, through: :milestone_releases
- has_internal_id :iid, scope: :project, init: ->(s) { s&.project&.milestones&.maximum(:iid) }
- has_internal_id :iid, scope: :group, init: ->(s) { s&.group&.milestones&.maximum(:iid) }
+ has_internal_id :iid, scope: :project, track_if: -> { !importing? }, init: ->(s) { s&.project&.milestones&.maximum(:iid) }
+ has_internal_id :iid, scope: :group, track_if: -> { !importing? }, init: ->(s) { s&.group&.milestones&.maximum(:iid) }
has_many :issues
has_many :labels, -> { distinct.reorder('labels.title') }, through: :issues
diff --git a/app/models/release.rb b/app/models/release.rb
index 823fd61eebd..ecfae554fe0 100644
--- a/app/models/release.rb
+++ b/app/models/release.rb
@@ -3,6 +3,7 @@
class Release < ApplicationRecord
include Presentable
include CacheMarkdownField
+ include Importable
include Gitlab::Utils::StrongMemoize
cache_markdown_field :description
@@ -33,8 +34,8 @@ class Release < ApplicationRecord
delegate :repository, to: :project
- after_commit :create_evidence!, on: :create
- after_commit :notify_new_release, on: :create
+ after_commit :create_evidence!, on: :create, unless: :importing?
+ after_commit :notify_new_release, on: :create, unless: :importing?
MAX_NUMBER_TO_DISPLAY = 3
diff --git a/app/models/user.rb b/app/models/user.rb
index b9efbcdf502..6442e74bbe3 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -20,6 +20,7 @@ class User < ApplicationRecord
include WithUploads
include OptionallySearch
include FromUnion
+ include BatchDestroyDependentAssociations
DEFAULT_NOTIFICATION_LEVEL = :participating
diff --git a/app/services/users/destroy_service.rb b/app/services/users/destroy_service.rb
index e341c7f0537..643ebdc6839 100644
--- a/app/services/users/destroy_service.rb
+++ b/app/services/users/destroy_service.rb
@@ -56,6 +56,13 @@ module Users
MigrateToGhostUserService.new(user).execute unless options[:hard_delete]
+ if Feature.enabled?(:destroy_user_associations_in_batches)
+ # Rails attempts to load all related records into memory before
+ # destroying: https://github.com/rails/rails/issues/22510
+ # This ensures we delete records in batches.
+ user.destroy_dependent_associations_in_batches
+ end
+
# Destroy the namespace after destroying the user since certain methods may depend on the namespace existing
user_data = user.destroy
namespace.destroy