summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/incidents_settings/components/incidents_settings_tabs.vue12
-rw-r--r--app/assets/javascripts/incidents_settings/constants.js1
-rw-r--r--app/assets/javascripts/monitoring/components/refresh_button.vue15
-rw-r--r--app/assets/javascripts/pages/projects/forks/new/components/fork_groups_list_item.vue16
-rw-r--r--app/assets/javascripts/pages/projects/forks/new/index.js24
-rw-r--r--app/assets/javascripts/project_fork.js9
-rw-r--r--app/assets/javascripts/vue_shared/components/rich_content_editor/services/build_html_to_markdown_renderer.js14
-rw-r--r--app/assets/stylesheets/pages/projects.scss21
-rw-r--r--app/controllers/explore/projects_controller.rb2
-rw-r--r--app/controllers/projects/environments_controller.rb1
-rw-r--r--app/controllers/projects/forks_controller.rb14
-rw-r--r--app/controllers/projects/merge_requests_controller.rb2
-rw-r--r--app/controllers/projects/metrics_dashboard_controller.rb1
-rw-r--r--app/controllers/projects/settings/operations_controller.rb4
-rw-r--r--app/helpers/application_settings_helper.rb3
-rw-r--r--app/models/application_setting.rb1
-rw-r--r--app/models/application_setting_implementation.rb3
-rw-r--r--app/models/release.rb10
-rw-r--r--app/models/wiki_page.rb16
-rw-r--r--app/services/incident_management/pager_duty/create_incident_issue_service.rb3
-rw-r--r--app/services/incident_management/pager_duty/process_webhook_service.rb3
-rw-r--r--app/services/projects/fork_service.rb4
-rw-r--r--app/views/profiles/preferences/show.html.haml2
-rw-r--r--app/views/projects/forks/_fork_button.html.haml40
-rw-r--r--app/views/projects/forks/new.html.haml11
25 files changed, 141 insertions, 91 deletions
diff --git a/app/assets/javascripts/incidents_settings/components/incidents_settings_tabs.vue b/app/assets/javascripts/incidents_settings/components/incidents_settings_tabs.vue
index 0623c275c5a..7411c0ffe0d 100644
--- a/app/assets/javascripts/incidents_settings/components/incidents_settings_tabs.vue
+++ b/app/assets/javascripts/incidents_settings/components/incidents_settings_tabs.vue
@@ -2,7 +2,6 @@
import { GlButton, GlTabs, GlTab } from '@gitlab/ui';
import AlertsSettingsForm from './alerts_form.vue';
import PagerDutySettingsForm from './pagerduty_form.vue';
-import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { INTEGRATION_TABS_CONFIG, I18N_INTEGRATION_TABS } from '../constants';
export default {
@@ -13,17 +12,8 @@ export default {
AlertsSettingsForm,
PagerDutySettingsForm,
},
- mixins: [glFeatureFlagMixin()],
tabs: INTEGRATION_TABS_CONFIG,
i18n: I18N_INTEGRATION_TABS,
- methods: {
- isFeatureFlagEnabled(tab) {
- if (tab.featureFlag) {
- return this.glFeatures[tab.featureFlag];
- }
- return true;
- },
- },
};
</script>
@@ -49,7 +39,7 @@ export default {
<gl-tabs>
<gl-tab
v-for="(tab, index) in $options.tabs"
- v-if="tab.active && isFeatureFlagEnabled(tab)"
+ v-if="tab.active"
:key="`${tab.title}_${index}`"
:title="tab.title"
>
diff --git a/app/assets/javascripts/incidents_settings/constants.js b/app/assets/javascripts/incidents_settings/constants.js
index b443c237f0f..e68198f84e0 100644
--- a/app/assets/javascripts/incidents_settings/constants.js
+++ b/app/assets/javascripts/incidents_settings/constants.js
@@ -11,7 +11,6 @@ export const INTEGRATION_TABS_CONFIG = [
title: s__('IncidentSettings|PagerDuty integration'),
component: 'PagerDutySettingsForm',
active: true,
- featureFlag: 'pagerdutyWebhook',
},
{
title: s__('IncidentSettings|Grafana integration'),
diff --git a/app/assets/javascripts/monitoring/components/refresh_button.vue b/app/assets/javascripts/monitoring/components/refresh_button.vue
index 5481806c3e0..31092a26048 100644
--- a/app/assets/javascripts/monitoring/components/refresh_button.vue
+++ b/app/assets/javascripts/monitoring/components/refresh_button.vue
@@ -10,6 +10,7 @@ import {
GlNewDropdownDivider,
GlTooltipDirective,
} from '@gitlab/ui';
+import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
const makeInterval = (length = 0, unit = 's') => {
const shortLabel = `${length}${unit}`;
@@ -53,6 +54,7 @@ export default {
directives: {
GlTooltip: GlTooltipDirective,
},
+ mixins: [glFeatureFlagsMixin()],
data() {
return {
refreshInterval: null,
@@ -60,6 +62,12 @@ export default {
};
},
computed: {
+ disableMetricDashboardRefreshRate() {
+ // Can refresh rates impact performance?
+ // Add "negative" feature flag called `disable_metric_dashboard_refresh_rate`
+ // See more at: https://gitlab.com/gitlab-org/gitlab/-/issues/229831
+ return this.glFeatures.disableMetricDashboardRefreshRate;
+ },
dropdownText() {
return this.refreshInterval?.shortLabel ?? __('Off');
},
@@ -142,7 +150,12 @@ export default {
icon="retry"
@click="refresh"
/>
- <gl-new-dropdown v-gl-tooltip :title="s__('Metrics|Set refresh rate')" :text="dropdownText">
+ <gl-new-dropdown
+ v-if="!disableMetricDashboardRefreshRate"
+ v-gl-tooltip
+ :title="s__('Metrics|Set refresh rate')"
+ :text="dropdownText"
+ >
<gl-new-dropdown-item
:is-check-item="true"
:is-checked="refreshInterval === null"
diff --git a/app/assets/javascripts/pages/projects/forks/new/components/fork_groups_list_item.vue b/app/assets/javascripts/pages/projects/forks/new/components/fork_groups_list_item.vue
index 792c2f3db34..b4816fa2cb3 100644
--- a/app/assets/javascripts/pages/projects/forks/new/components/fork_groups_list_item.vue
+++ b/app/assets/javascripts/pages/projects/forks/new/components/fork_groups_list_item.vue
@@ -35,7 +35,7 @@ export default {
},
},
data() {
- return { namespaces: null };
+ return { namespaces: null, isForking: false };
},
computed: {
@@ -67,6 +67,13 @@ export default {
},
},
+ methods: {
+ fork() {
+ this.isForking = true;
+ this.$refs.form.submit();
+ },
+ },
+
i18n: {
hasReachedProjectLimitMessage: __('You have reached your project limit'),
insufficientPermissionsMessage: __(
@@ -124,14 +131,17 @@ export default {
>
<template v-else>
<div ref="selectButtonWrapper">
- <form method="POST" :action="group.fork_path">
+ <form ref="form" method="POST" :action="group.fork_path">
<input type="hidden" name="authenticity_token" :value="$options.csrf.token" />
<gl-button
type="submit"
- class="gl-h-7 gl-text-decoration-none!"
+ class="gl-h-7"
:data-qa-name="group.full_name"
+ category="secondary"
variant="success"
:disabled="isSelectButtonDisabled"
+ :loading="isForking"
+ @click="fork"
>{{ __('Select') }}</gl-button
>
</form>
diff --git a/app/assets/javascripts/pages/projects/forks/new/index.js b/app/assets/javascripts/pages/projects/forks/new/index.js
index d80e27e9156..79485859738 100644
--- a/app/assets/javascripts/pages/projects/forks/new/index.js
+++ b/app/assets/javascripts/pages/projects/forks/new/index.js
@@ -1,3 +1,23 @@
-import ProjectFork from '~/project_fork';
+import Vue from 'vue';
+import { parseBoolean } from '~/lib/utils/common_utils';
+import ForkGroupsList from './components/fork_groups_list.vue';
-document.addEventListener('DOMContentLoaded', () => new ProjectFork());
+document.addEventListener('DOMContentLoaded', () => {
+ const mountElement = document.getElementById('fork-groups-mount-element');
+
+ const { endpoint, canCreateProject } = mountElement.dataset;
+
+ const hasReachedProjectLimit = !parseBoolean(canCreateProject);
+
+ return new Vue({
+ el: mountElement,
+ render(h) {
+ return h(ForkGroupsList, {
+ props: {
+ endpoint,
+ hasReachedProjectLimit,
+ },
+ });
+ },
+ });
+});
diff --git a/app/assets/javascripts/project_fork.js b/app/assets/javascripts/project_fork.js
deleted file mode 100644
index f5cd1c3cc3e..00000000000
--- a/app/assets/javascripts/project_fork.js
+++ /dev/null
@@ -1,9 +0,0 @@
-import $ from 'jquery';
-
-export default () => {
- $('.js-fork-thumbnail').on('click', function forkThumbnailClicked() {
- if ($(this).hasClass('disabled')) return false;
-
- return $('.js-fork-content').toggleClass('hidden');
- });
-};
diff --git a/app/assets/javascripts/vue_shared/components/rich_content_editor/services/build_html_to_markdown_renderer.js b/app/assets/javascripts/vue_shared/components/rich_content_editor/services/build_html_to_markdown_renderer.js
index ed04765c871..3331f4fb20d 100644
--- a/app/assets/javascripts/vue_shared/components/rich_content_editor/services/build_html_to_markdown_renderer.js
+++ b/app/assets/javascripts/vue_shared/components/rich_content_editor/services/build_html_to_markdown_renderer.js
@@ -1,7 +1,9 @@
+/* eslint-disable @gitlab/require-i18n-strings */
import { defaults, repeat } from 'lodash';
const DEFAULTS = {
subListIndentSpaces: 4,
+ unorderedListBulletChar: '-',
};
const countIndentSpaces = text => {
@@ -11,9 +13,12 @@ const countIndentSpaces = text => {
};
const buildHTMLToMarkdownRender = (baseRenderer, formattingPreferences = {}) => {
- const { subListIndentSpaces } = defaults(formattingPreferences, DEFAULTS);
- // eslint-disable-next-line @gitlab/require-i18n-strings
+ const { subListIndentSpaces, unorderedListBulletChar } = defaults(
+ formattingPreferences,
+ DEFAULTS,
+ );
const sublistNode = 'LI OL, LI UL';
+ const unorderedListItemNode = 'UL LI';
return {
TEXT_NODE(node) {
@@ -47,6 +52,11 @@ const buildHTMLToMarkdownRender = (baseRenderer, formattingPreferences = {}) =>
return reindentedList;
},
+ [unorderedListItemNode](node, subContent) {
+ const baseResult = baseRenderer.convert(node, subContent);
+
+ return baseResult.replace(/^(\s*)([*|-])/, `$1${unorderedListBulletChar}`);
+ },
};
};
diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss
index 438f6c2546e..a1a9489e659 100644
--- a/app/assets/stylesheets/pages/projects.scss
+++ b/app/assets/stylesheets/pages/projects.scss
@@ -472,17 +472,9 @@
margin-right: auto;
}
- a {
- display: block;
- width: 100%;
- height: 100%;
- padding-top: $gl-padding;
- text-decoration: none;
-
- &.disabled {
- opacity: 0.3;
- cursor: not-allowed;
- }
+ a.disabled {
+ opacity: 0.3;
+ cursor: not-allowed;
}
}
@@ -1538,3 +1530,10 @@ pre.light-well {
}
}
}
+
+@include media-breakpoint-down(xs) {
+ .fork-filtered-search {
+ width: 100%;
+ margin: $gl-spacing-scale-2 0;
+ }
+}
diff --git a/app/controllers/explore/projects_controller.rb b/app/controllers/explore/projects_controller.rb
index f1f41e67a4c..b3fa089a712 100644
--- a/app/controllers/explore/projects_controller.rb
+++ b/app/controllers/explore/projects_controller.rb
@@ -80,7 +80,7 @@ class Explore::ProjectsController < Explore::ApplicationController
# rubocop: disable CodeReuse/ActiveRecord
def preload_associations(projects)
- projects.includes(:route, :creator, :group, namespace: [:route, :owner])
+ projects.includes(:route, :creator, :group, :project_feature, namespace: [:route, :owner])
end
# rubocop: enable CodeReuse/ActiveRecord
diff --git a/app/controllers/projects/environments_controller.rb b/app/controllers/projects/environments_controller.rb
index d5da24a76de..99ec100e4c9 100644
--- a/app/controllers/projects/environments_controller.rb
+++ b/app/controllers/projects/environments_controller.rb
@@ -13,6 +13,7 @@ class Projects::EnvironmentsController < Projects::ApplicationController
authorize_metrics_dashboard!
push_frontend_feature_flag(:prometheus_computed_alerts)
+ push_frontend_feature_flag(:disable_metric_dashboard_refresh_rate)
end
before_action :authorize_read_environment!, except: [:metrics, :additional_metrics, :metrics_dashboard, :metrics_redirect]
before_action :authorize_create_environment!, only: [:new, :create]
diff --git a/app/controllers/projects/forks_controller.rb b/app/controllers/projects/forks_controller.rb
index b93f6384e0c..41631aea620 100644
--- a/app/controllers/projects/forks_controller.rb
+++ b/app/controllers/projects/forks_controller.rb
@@ -36,7 +36,19 @@ class Projects::ForksController < Projects::ApplicationController
end
def new
- @namespaces = fork_service.valid_fork_targets - [project.namespace]
+ respond_to do |format|
+ format.html do
+ @own_namespace = current_user.namespace if fork_service.valid_fork_targets.include?(current_user.namespace)
+ @project = project
+ end
+
+ format.json do
+ namespaces = fork_service.valid_fork_targets - [current_user.namespace, project.namespace]
+ render json: {
+ namespaces: ForkNamespaceSerializer.new.represent(namespaces, project: project, current_user: current_user)
+ }
+ end
+ end
end
# rubocop: disable CodeReuse/ActiveRecord
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index e65e5531b88..5d4514be838 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -84,7 +84,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
@issuable_sidebar = serializer.represent(@merge_request, serializer: 'sidebar')
@current_user_data = UserSerializer.new(project: @project).represent(current_user, {}, MergeRequestUserEntity).to_json
@show_whitespace_default = current_user.nil? || current_user.show_whitespace_in_diffs
- @file_by_file_default = Feature.enabled?(:view_diffs_file_by_file) && current_user&.view_diffs_file_by_file
+ @file_by_file_default = Feature.enabled?(:view_diffs_file_by_file, default_enabled: true) && current_user&.view_diffs_file_by_file
@coverage_path = coverage_reports_project_merge_request_path(@project, @merge_request, format: :json) if @merge_request.has_coverage_reports?
@endpoint_metadata_url = endpoint_metadata_url(@project, @merge_request)
diff --git a/app/controllers/projects/metrics_dashboard_controller.rb b/app/controllers/projects/metrics_dashboard_controller.rb
index 235ee1dfbf2..a7edfea5c09 100644
--- a/app/controllers/projects/metrics_dashboard_controller.rb
+++ b/app/controllers/projects/metrics_dashboard_controller.rb
@@ -9,6 +9,7 @@ module Projects
before_action :authorize_metrics_dashboard!
before_action do
push_frontend_feature_flag(:prometheus_computed_alerts)
+ push_frontend_feature_flag(:disable_metric_dashboard_refresh_rate)
end
def show
diff --git a/app/controllers/projects/settings/operations_controller.rb b/app/controllers/projects/settings/operations_controller.rb
index d7a6f1b0139..5b12bd000d8 100644
--- a/app/controllers/projects/settings/operations_controller.rb
+++ b/app/controllers/projects/settings/operations_controller.rb
@@ -6,10 +6,6 @@ module Projects
before_action :authorize_admin_operations!
before_action :authorize_read_prometheus_alerts!, only: [:reset_alerting_token]
- before_action do
- push_frontend_feature_flag(:pagerduty_webhook, project)
- end
-
respond_to :json, only: [:reset_alerting_token, :reset_pagerduty_token]
helper_method :error_tracking_setting
diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb
index aa118a9bc45..fdea17c2075 100644
--- a/app/helpers/application_settings_helper.rb
+++ b/app/helpers/application_settings_helper.rb
@@ -327,7 +327,8 @@ module ApplicationSettingsHelper
:project_download_export_limit,
:group_import_limit,
:group_export_limit,
- :group_download_export_limit
+ :group_download_export_limit,
+ :wiki_page_max_content_bytes
]
end
diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb
index 425a0e05c7d..4607f291a26 100644
--- a/app/models/application_setting.rb
+++ b/app/models/application_setting.rb
@@ -272,6 +272,7 @@ class ApplicationSetting < ApplicationRecord
numericality: { greater_than_or_equal_to: 0 }
validates :snippet_size_limit, numericality: { only_integer: true, greater_than: 0 }
+ validates :wiki_page_max_content_bytes, numericality: { only_integer: true, greater_than: 0 }
validates :email_restrictions, untrusted_regexp: true
diff --git a/app/models/application_setting_implementation.rb b/app/models/application_setting_implementation.rb
index c489d11d462..815a570f77a 100644
--- a/app/models/application_setting_implementation.rb
+++ b/app/models/application_setting_implementation.rb
@@ -164,7 +164,8 @@ module ApplicationSettingImplementation
project_download_export_limit: 1,
group_import_limit: 6,
group_export_limit: 6,
- group_download_export_limit: 1
+ group_download_export_limit: 1,
+ wiki_page_max_content_bytes: 50.megabytes
}
end
diff --git a/app/models/release.rb b/app/models/release.rb
index a0245105cd9..4c9d89105d7 100644
--- a/app/models/release.rb
+++ b/app/models/release.rb
@@ -18,12 +18,10 @@ class Release < ApplicationRecord
has_many :milestones, through: :milestone_releases
has_many :evidences, inverse_of: :release, class_name: 'Releases::Evidence'
- default_value_for :released_at, allows_nil: false do
- Time.zone.now
- end
-
accepts_nested_attributes_for :links, allow_destroy: true
+ before_create :set_released_at
+
validates :project, :tag, presence: true
validates_associated :milestone_releases, message: -> (_, obj) { obj[:value].map(&:errors).map(&:full_messages).join(",") }
@@ -90,6 +88,10 @@ class Release < ApplicationRecord
repository.find_tag(tag)
end
end
+
+ def set_released_at
+ self.released_at ||= created_at
+ end
end
Release.prepend_if_ee('EE::Release')
diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb
index 3dc90edb331..6a4b4472a03 100644
--- a/app/models/wiki_page.rb
+++ b/app/models/wiki_page.rb
@@ -65,6 +65,7 @@ class WikiPage
validates :title, presence: true
validates :content, presence: true
validate :validate_path_limits, if: :title_changed?
+ validate :validate_content_size_limit, if: :content_changed?
# The GitLab Wiki instance.
attr_reader :wiki
@@ -282,6 +283,10 @@ class WikiPage
end
end
+ def content_changed?
+ attributes[:content] != page&.text_data
+ end
+
# Updates the current @attributes hash by merging a hash of params
def update_attributes(attrs)
attrs[:title] = process_title(attrs[:title]) if attrs[:title].present?
@@ -391,4 +396,15 @@ class WikiPage
})
end
end
+
+ def validate_content_size_limit
+ current_value = raw_content.to_s.bytesize
+ max_size = Gitlab::CurrentSettings.wiki_page_max_content_bytes
+ return if current_value <= max_size
+
+ errors.add(:content, _('is too long (%{current_value}). The maximum size is %{max_size}.') % {
+ current_value: ActiveSupport::NumberHelper.number_to_human_size(current_value),
+ max_size: ActiveSupport::NumberHelper.number_to_human_size(max_size)
+ })
+ end
end
diff --git a/app/services/incident_management/pager_duty/create_incident_issue_service.rb b/app/services/incident_management/pager_duty/create_incident_issue_service.rb
index ee0feb49e0d..c0c07f39708 100644
--- a/app/services/incident_management/pager_duty/create_incident_issue_service.rb
+++ b/app/services/incident_management/pager_duty/create_incident_issue_service.rb
@@ -40,8 +40,7 @@ module IncidentManagement
end
def webhook_available?
- Feature.enabled?(:pagerduty_webhook, project) &&
- incident_management_setting.pagerduty_active?
+ incident_management_setting.pagerduty_active?
end
def forbidden
diff --git a/app/services/incident_management/pager_duty/process_webhook_service.rb b/app/services/incident_management/pager_duty/process_webhook_service.rb
index 5dd3186694a..fd8252f75fb 100644
--- a/app/services/incident_management/pager_duty/process_webhook_service.rb
+++ b/app/services/incident_management/pager_duty/process_webhook_service.rb
@@ -39,8 +39,7 @@ module IncidentManagement
end
def webhook_setting_active?
- Feature.enabled?(:pagerduty_webhook, project) &&
- incident_management_setting.pagerduty_active?
+ incident_management_setting.pagerduty_active?
end
def valid_token?(token)
diff --git a/app/services/projects/fork_service.rb b/app/services/projects/fork_service.rb
index 6ac53b15ef9..bb660d47887 100644
--- a/app/services/projects/fork_service.rb
+++ b/app/services/projects/fork_service.rb
@@ -14,10 +14,10 @@ module Projects
@valid_fork_targets ||= ForkTargetsFinder.new(@project, current_user).execute
end
- def valid_fork_target?
+ def valid_fork_target?(namespace = target_namespace)
return true if current_user.admin?
- valid_fork_targets.include?(target_namespace)
+ valid_fork_targets.include?(namespace)
end
private
diff --git a/app/views/profiles/preferences/show.html.haml b/app/views/profiles/preferences/show.html.haml
index 659b3066603..bc1f2cb3072 100644
--- a/app/views/profiles/preferences/show.html.haml
+++ b/app/views/profiles/preferences/show.html.haml
@@ -70,7 +70,7 @@
= f.check_box :show_whitespace_in_diffs, class: 'form-check-input'
= f.label :show_whitespace_in_diffs, class: 'form-check-label' do
= s_('Preferences|Show whitespace changes in diffs')
- - if Feature.enabled?(:view_diffs_file_by_file)
+ - if Feature.enabled?(:view_diffs_file_by_file, default_enabled: true)
.form-group.form-check
= f.check_box :view_diffs_file_by_file, class: 'form-check-input'
= f.label :view_diffs_file_by_file, class: 'form-check-label' do
diff --git a/app/views/projects/forks/_fork_button.html.haml b/app/views/projects/forks/_fork_button.html.haml
index eec02a50b85..dd49e8bdb4b 100644
--- a/app/views/projects/forks/_fork_button.html.haml
+++ b/app/views/projects/forks/_fork_button.html.haml
@@ -1,26 +1,20 @@
- avatar = namespace_icon(namespace, 100)
- can_create_project = current_user.can?(:create_projects, namespace)
-- if forked_project = namespace.find_fork_of(@project)
- .bordered-box.fork-thumbnail.text-center.gl-ml-3.gl-mr-3.gl-mt-3.gl-mb-3.forked
- = link_to project_path(forked_project) do
- - if /no_((\w*)_)*avatar/.match(avatar)
- = group_icon(namespace, class: "avatar rect-avatar s100 identicon mx-auto")
- - else
- .avatar-container.s100.mx-auto
- = image_tag(avatar, class: "avatar s100")
- %h5.gl-mt-3
- = namespace.human_name
-- else
- .bordered-box.fork-thumbnail.text-center.gl-ml-3.gl-mr-3.gl-mt-3.gl-mb-3{ class: ("disabled" unless can_create_project) }
- = link_to project_forks_path(@project, namespace_key: namespace.id),
- method: "POST",
- class: ("disabled has-tooltip" unless can_create_project),
- title: (_('You have reached your project limit') unless can_create_project) do
- - if /no_((\w*)_)*avatar/.match(avatar)
- = group_icon(namespace, class: "avatar rect-avatar s100 identicon mx-auto")
- - else
- .avatar-container.s100.mx-auto
- = image_tag(avatar, class: "avatar s100")
- %h5.gl-mt-3{ data: { qa_selector: 'fork_namespace_content', qa_name: namespace.human_name } }
- = namespace.human_name
+.bordered-box.fork-thumbnail.text-center.gl-m-3{ class: ("disabled" unless can_create_project) }
+ - if /no_((\w*)_)*avatar/.match(avatar)
+ = group_icon(namespace, class: "avatar rect-avatar s100 identicon mx-auto")
+ - else
+ .avatar-container.s100.mx-auto.gl-mt-5
+ = image_tag(avatar, class: "avatar s100")
+ %h5.gl-mt-3
+ = namespace.human_name
+ - if forked_project = namespace.find_fork_of(@project)
+ = link_to _("Go to project"), project_path(forked_project), class: "btn"
+ - else
+ %div{ class: ('has-tooltip' unless can_create_project),
+ title: (_('You have reached your project limit') unless can_create_project) }
+ = link_to _("Select"), project_forks_path(@project, namespace_key: namespace.id),
+ data: { qa_selector: 'fork_namespace_button', qa_name: namespace.human_name },
+ method: "POST",
+ class: ["btn btn-success", ("disabled" unless can_create_project)]
diff --git a/app/views/projects/forks/new.html.haml b/app/views/projects/forks/new.html.haml
index 887081d0f35..daac118d88e 100644
--- a/app/views/projects/forks/new.html.haml
+++ b/app/views/projects/forks/new.html.haml
@@ -7,15 +7,10 @@
%p
= _("A fork is a copy of a project.<br />Forking a repository allows you to make changes without affecting the original project.").html_safe
.col-lg-9
- - if @namespaces.present?
+ - if @own_namespace.present?
.fork-thumbnail-container.js-fork-content
%h5.gl-mt-0.gl-mb-0.gl-ml-3.gl-mr-3
= _("Select a namespace to fork the project")
- - @namespaces.each do |namespace|
- = render 'fork_button', namespace: namespace
- - else
- %strong
- = _("No available namespaces to fork the project.")
- %p.gl-mt-3
- = _("You must have permission to create a project in a namespace before forking.")
+ = render 'fork_button', namespace: @own_namespace
+ #fork-groups-mount-element{ data: { endpoint: new_project_fork_path(@project, format: :json), can_create_project: current_user.can_create_project?.to_s } }