diff options
Diffstat (limited to 'app')
30 files changed, 179 insertions, 57 deletions
diff --git a/app/assets/javascripts/graphql_shared/utils.js b/app/assets/javascripts/graphql_shared/utils.js new file mode 100644 index 00000000000..a262fbd9ac3 --- /dev/null +++ b/app/assets/javascripts/graphql_shared/utils.js @@ -0,0 +1,12 @@ +/** + * Ids generated by GraphQL endpoints are usually in the format + * gid://gitlab/Environments/123. This method extracts Id number + * from the Id path + * + * @param {String} gid GraphQL global ID + * @returns {Number} + */ +export const getIdFromGraphQLId = (gid = '') => + parseInt((gid || '').replace(/gid:\/\/gitlab\/.*\//g, ''), 10) || null; + +export default {}; diff --git a/app/assets/javascripts/groups/components/group_item.vue b/app/assets/javascripts/groups/components/group_item.vue index af9399a37bd..b192fb78631 100644 --- a/app/assets/javascripts/groups/components/group_item.vue +++ b/app/assets/javascripts/groups/components/group_item.vue @@ -1,5 +1,5 @@ <script> -import { GlLoadingIcon } from '@gitlab/ui'; +import { GlLoadingIcon, GlBadge } from '@gitlab/ui'; import { visitUrl } from '../../lib/utils/url_utility'; import tooltip from '../../vue_shared/directives/tooltip'; import identicon from '../../vue_shared/components/identicon.vue'; @@ -17,6 +17,7 @@ export default { tooltip, }, components: { + GlBadge, GlLoadingIcon, identicon, itemCaret, @@ -62,6 +63,9 @@ export default { isGroup() { return this.group.type === 'group'; }, + isGroupPendingRemoval() { + return this.group.type === 'group' && this.group.pendingRemoval; + }, visibilityIcon() { return VISIBILITY_TYPE_ICON[this.group.visibility]; }, @@ -139,6 +143,9 @@ export default { <span v-html="group.description"> </span> </div> </div> + <div v-if="isGroupPendingRemoval"> + <gl-badge variant="warning">{{ __('pending removal') }}</gl-badge> + </div> <div class="metadata align-items-md-center d-flex flex-grow-1 flex-shrink-0 flex-wrap justify-content-md-between" > diff --git a/app/assets/javascripts/groups/store/groups_store.js b/app/assets/javascripts/groups/store/groups_store.js index 214ac5e3db5..6a1197fa163 100644 --- a/app/assets/javascripts/groups/store/groups_store.js +++ b/app/assets/javascripts/groups/store/groups_store.js @@ -93,7 +93,7 @@ export default class GroupsStore { memberCount: rawGroupItem.number_users_with_delimiter, starCount: rawGroupItem.star_count, updatedAt: rawGroupItem.updated_at, - pendingRemoval: rawGroupItem.marked_for_deletion_at, + pendingRemoval: rawGroupItem.marked_for_deletion, }; } diff --git a/app/assets/javascripts/monitoring/queries/getEnvironments.query.graphql b/app/assets/javascripts/monitoring/queries/getEnvironments.query.graphql new file mode 100644 index 00000000000..fd3a4348509 --- /dev/null +++ b/app/assets/javascripts/monitoring/queries/getEnvironments.query.graphql @@ -0,0 +1,10 @@ +query getEnvironments($projectPath: ID!, $search: String) { + project(fullPath: $projectPath) { + data: environments(search: $search) { + environments: nodes { + name + id + } + } + } +} diff --git a/app/assets/javascripts/monitoring/stores/actions.js b/app/assets/javascripts/monitoring/stores/actions.js index 6303ed2b82f..e26e1457f55 100644 --- a/app/assets/javascripts/monitoring/stores/actions.js +++ b/app/assets/javascripts/monitoring/stores/actions.js @@ -1,7 +1,9 @@ import * as types from './mutation_types'; import axios from '~/lib/utils/axios_utils'; import createFlash from '~/flash'; +import { gqClient, parseEnvironmentsResponse, removeLeadingSlash } from './utils'; import trackDashboardLoad from '../monitoring_tracking_helper'; +import getEnvironments from '../queries/getEnvironments.query.graphql'; import statusCodes from '../../lib/utils/http_status'; import { backOff } from '../../lib/utils/common_utils'; import { s__, sprintf } from '../../locale'; @@ -187,26 +189,30 @@ export const fetchDeploymentsData = ({ state, dispatch }) => { }); }; -export const fetchEnvironmentsData = ({ state, dispatch }) => { - if (!state.environmentsEndpoint) { - return Promise.resolve([]); - } - return axios - .get(state.environmentsEndpoint) - .then(resp => resp.data) - .then(response => { - if (!response || !response.environments) { +export const fetchEnvironmentsData = ({ state, dispatch }) => + gqClient + .mutate({ + mutation: getEnvironments, + variables: { + projectPath: removeLeadingSlash(state.projectPath), + search: state.environmentsSearchTerm, + }, + }) + .then(resp => + parseEnvironmentsResponse(resp.data?.project?.data?.environments, state.projectPath), + ) + .then(environments => { + if (!environments) { createFlash( s__('Metrics|There was an error fetching the environments data, please try again'), ); } - dispatch('receiveEnvironmentsDataSuccess', response.environments); + dispatch('receiveEnvironmentsDataSuccess', environments); }) .catch(() => { dispatch('receiveEnvironmentsDataFailure'); createFlash(s__('Metrics|There was an error getting environments information.')); }); -}; /** * Set a new array of metrics to a panel group diff --git a/app/assets/javascripts/monitoring/stores/utils.js b/app/assets/javascripts/monitoring/stores/utils.js index 616d2e9bfd8..56244a4ca66 100644 --- a/app/assets/javascripts/monitoring/stores/utils.js +++ b/app/assets/javascripts/monitoring/stores/utils.js @@ -1,8 +1,41 @@ import { omit } from 'lodash'; +import createGqClient from '~/lib/graphql'; +import { getIdFromGraphQLId } from '~/graphql_shared/utils'; + +export const gqClient = createGqClient(); export const uniqMetricsId = metric => `${metric.metric_id}_${metric.id}`; /** + * Project path has a leading slash that doesn't work well + * with project full path resolver here + * https://gitlab.com/gitlab-org/gitlab/blob/5cad4bd721ab91305af4505b2abc92b36a56ad6b/app/graphql/resolvers/full_path_resolver.rb#L10 + * + * @param {String} str String with leading slash + * @returns {String} + */ +export const removeLeadingSlash = str => (str || '').replace(/^\/+/, ''); + +/** + * GraphQL environments API returns only id and name. + * For the environments dropdown we need metrics_path. + * This method parses the results and add neccessart attrs + * + * @param {Array} response Environments API result + * @param {String} projectPath Current project path + * @returns {Array} + */ +export const parseEnvironmentsResponse = (response = [], projectPath) => + (response || []).map(env => { + const id = getIdFromGraphQLId(env.id); + return { + ...env, + id, + metrics_path: `${projectPath}/environments/${id}/metrics`, + }; + }); + +/** * Metrics loaded from project-defined dashboards do not have a metric_id. * This method creates a unique ID combining metric_id and id, if either is present. * This is hopefully a temporary solution until BE processes metrics before passing to fE diff --git a/app/assets/javascripts/registry/settings/components/registry_settings_app.vue b/app/assets/javascripts/registry/settings/components/registry_settings_app.vue index 7530c1dfcaf..28f4ef62242 100644 --- a/app/assets/javascripts/registry/settings/components/registry_settings_app.vue +++ b/app/assets/javascripts/registry/settings/components/registry_settings_app.vue @@ -1,5 +1,8 @@ <script> -import { mapActions } from 'vuex'; +import { mapActions, mapState } from 'vuex'; +import { GlAlert } from '@gitlab/ui'; +import { sprintf, s__ } from '~/locale'; + import { FETCH_SETTINGS_ERROR_MESSAGE } from '../constants'; import SettingsForm from './settings_form.vue'; @@ -7,6 +10,23 @@ import SettingsForm from './settings_form.vue'; export default { components: { SettingsForm, + GlAlert, + }, + computed: { + ...mapState(['isDisabled']), + notAvailableMessage() { + return sprintf( + s__( + 'ContainerRegistry|Currently, the Container Registry tag expiration feature is not available for projects created before GitLab version 12.8. For updates and more information, visit Issue %{linkStart}#196124%{linkEnd}', + ), + { + linkStart: + '<a href="https://gitlab.com/gitlab-org/gitlab/issues/196124" target="_blank" rel="noopener noreferrer">', + linkEnd: '</a>', + }, + false, + ); + }, }, mounted() { this.fetchSettings().catch(() => @@ -34,6 +54,9 @@ export default { }} </li> </ul> - <settings-form ref="settings-form" /> + <settings-form v-if="!isDisabled" /> + <gl-alert v-else :dismissible="false"> + <p v-html="notAvailableMessage"></p> + </gl-alert> </div> </template> diff --git a/app/assets/javascripts/registry/settings/store/actions.js b/app/assets/javascripts/registry/settings/store/actions.js index 21a2008fef6..d0379d05164 100644 --- a/app/assets/javascripts/registry/settings/store/actions.js +++ b/app/assets/javascripts/registry/settings/store/actions.js @@ -4,7 +4,13 @@ import * as types from './mutation_types'; export const setInitialState = ({ commit }, data) => commit(types.SET_INITIAL_STATE, data); export const updateSettings = ({ commit }, data) => commit(types.UPDATE_SETTINGS, data); export const toggleLoading = ({ commit }) => commit(types.TOGGLE_LOADING); -export const receiveSettingsSuccess = ({ commit }, data = {}) => commit(types.SET_SETTINGS, data); +export const receiveSettingsSuccess = ({ commit }, data) => { + if (data) { + commit(types.SET_SETTINGS, data); + } else { + commit(types.SET_IS_DISABLED, true); + } +}; export const resetSettings = ({ commit }) => commit(types.RESET_SETTINGS); export const fetchSettings = ({ dispatch, state }) => { diff --git a/app/assets/javascripts/registry/settings/store/mutation_types.js b/app/assets/javascripts/registry/settings/store/mutation_types.js index db499ffa761..2d071567c1f 100644 --- a/app/assets/javascripts/registry/settings/store/mutation_types.js +++ b/app/assets/javascripts/registry/settings/store/mutation_types.js @@ -3,3 +3,4 @@ export const UPDATE_SETTINGS = 'UPDATE_SETTINGS'; export const TOGGLE_LOADING = 'TOGGLE_LOADING'; export const SET_SETTINGS = 'SET_SETTINGS'; export const RESET_SETTINGS = 'RESET_SETTINGS'; +export const SET_IS_DISABLED = 'SET_IS_DISABLED'; diff --git a/app/assets/javascripts/registry/settings/store/mutations.js b/app/assets/javascripts/registry/settings/store/mutations.js index 25a67cc6973..b773f2dd44c 100644 --- a/app/assets/javascripts/registry/settings/store/mutations.js +++ b/app/assets/javascripts/registry/settings/store/mutations.js @@ -16,6 +16,9 @@ export default { state.settings = settings; state.original = Object.freeze(settings); }, + [types.SET_IS_DISABLED](state, isDisabled) { + state.isDisabled = isDisabled; + }, [types.RESET_SETTINGS](state) { state.settings = { ...state.original }; }, diff --git a/app/assets/javascripts/registry/settings/store/state.js b/app/assets/javascripts/registry/settings/store/state.js index 50c882e1839..582e18e5465 100644 --- a/app/assets/javascripts/registry/settings/store/state.js +++ b/app/assets/javascripts/registry/settings/store/state.js @@ -8,6 +8,10 @@ export default () => ({ */ isLoading: false, /* + * Boolean to determine if the user is allowed to interact with the form + */ + isDisabled: false, + /* * This contains the data shown and manipulated in the UI * Has the following structure: * { diff --git a/app/assets/stylesheets/utilities.scss b/app/assets/stylesheets/utilities.scss index 1358b3aa6dd..9e99c92d3f2 100644 --- a/app/assets/stylesheets/utilities.scss +++ b/app/assets/stylesheets/utilities.scss @@ -56,6 +56,7 @@ .gl-bg-green-100 { @include gl-bg-green-100;} .gl-text-blue-500 { @include gl-text-blue-500; } +.gl-text-gray-700 { @include gl-text-gray-700; } .gl-text-gray-900 { @include gl-text-gray-900; } .gl-text-red-700 { @include gl-text-red-700; } .gl-text-orange-700 { @include gl-text-orange-700; } diff --git a/app/controllers/admin/groups_controller.rb b/app/controllers/admin/groups_controller.rb index 5455cefdc8e..0245c00aacb 100644 --- a/app/controllers/admin/groups_controller.rb +++ b/app/controllers/admin/groups_controller.rb @@ -6,8 +6,7 @@ class Admin::GroupsController < Admin::ApplicationController before_action :group, only: [:edit, :update, :destroy, :project_update, :members_update] def index - @groups = Group.with_statistics.with_route - @groups = @groups.sort_by_attribute(@sort = params[:sort]) + @groups = groups.sort_by_attribute(@sort = params[:sort]) @groups = @groups.search(params[:name]) if params[:name].present? @groups = @groups.page(params[:page]) end @@ -75,6 +74,10 @@ class Admin::GroupsController < Admin::ApplicationController private + def groups + Group.with_statistics.with_route + end + def group @group ||= Group.find_by_full_path(params[:id]) end diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index 3000cfb678e..b8d7685c2cf 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -709,4 +709,10 @@ module ProjectsHelper def show_visibility_confirm_modal?(project) project.unlink_forks_upon_visibility_decrease_enabled? && project.visibility_level > Gitlab::VisibilityLevel::PRIVATE && project.forks_count > 0 end + + def settings_container_registry_expiration_policy_available?(project) + Feature.enabled?(:registry_retention_policies_settings, project) && + Gitlab.config.registry.enabled && + can?(current_user, :read_container_image, project) + end end diff --git a/app/models/concerns/loaded_in_group_list.rb b/app/models/concerns/loaded_in_group_list.rb index fc15c6d55ed..79ff82d9f99 100644 --- a/app/models/concerns/loaded_in_group_list.rb +++ b/app/models/concerns/loaded_in_group_list.rb @@ -73,3 +73,5 @@ module LoadedInGroupList @member_count ||= try(:preloaded_member_count) || users.count end end + +LoadedInGroupList::ClassMethods.prepend_if_ee('EE::LoadedInGroupList::ClassMethods') diff --git a/app/models/group.rb b/app/models/group.rb index b642b177df1..ea5d46e23f4 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -467,6 +467,10 @@ class Group < Namespace import_export_upload&.export_file end + def adjourned_deletion? + false + end + private def update_two_factor_requirement diff --git a/app/views/admin/groups/_group.html.haml b/app/views/admin/groups/_group.html.haml index 3444e423235..855858ff929 100644 --- a/app/views/admin/groups/_group.html.haml +++ b/app/views/admin/groups/_group.html.haml @@ -10,6 +10,7 @@ = storage_counter(group.storage_size) = render_if_exists 'admin/namespace_plan_badge', namespace: group + = render_if_exists 'admin/groups/marked_for_deletion_badge', group: group %span = icon('bookmark') diff --git a/app/views/groups/settings/_advanced.html.haml b/app/views/groups/settings/_advanced.html.haml index 307309c6ca3..2734ab538a0 100644 --- a/app/views/groups/settings/_advanced.html.haml +++ b/app/views/groups/settings/_advanced.html.haml @@ -39,12 +39,5 @@ %li= s_("GroupSettings|If the parent group's visibility is lower than the group current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility.") = f.submit s_('GroupSettings|Transfer group'), class: 'btn btn-warning' -.sub-section - %h4.danger-title= _('Remove group') - = form_tag(@group, method: :delete) do - %p - = _('Removing group will cause all child projects and resources to be removed.') - %br - %strong= _('Removed group can not be restored!') - - = button_to _('Remove group'), '#', class: 'btn btn-remove js-confirm-danger', data: { 'confirm-danger-message' => remove_group_message(@group) } += render 'groups/settings/remove', group: @group += render_if_exists 'groups/settings/restore', group: @group diff --git a/app/views/groups/settings/_permanent_deletion.html.haml b/app/views/groups/settings/_permanent_deletion.html.haml new file mode 100644 index 00000000000..31e2bac70be --- /dev/null +++ b/app/views/groups/settings/_permanent_deletion.html.haml @@ -0,0 +1,9 @@ +.sub-section + %h4.danger-title= _('Remove group') + = form_tag(group, method: :delete) do + %p + = _('Removing group will cause all child projects and resources to be removed.') + %br + %strong= _('Removed group can not be restored!') + + = button_to _('Remove group'), '#', class: 'btn btn-remove js-confirm-danger', data: { 'confirm-danger-message' => remove_group_message(group) } diff --git a/app/views/groups/settings/_remove.html.haml b/app/views/groups/settings/_remove.html.haml new file mode 100644 index 00000000000..a617467019a --- /dev/null +++ b/app/views/groups/settings/_remove.html.haml @@ -0,0 +1,5 @@ +- if group.adjourned_deletion? + = render_if_exists 'groups/settings/adjourned_deletion', group: group +- else + = render 'groups/settings/permanent_deletion', group: group + diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml index 457d05b4a97..4916c4651dd 100644 --- a/app/views/groups/show.html.haml +++ b/app/views/groups/show.html.haml @@ -9,6 +9,8 @@ = render 'groups/home_panel' + = render_if_exists 'groups/self_or_ancestor_marked_for_deletion_notice', group: @group + .groups-listing{ data: { endpoints: { default: group_children_path(@group, format: :json), shared: group_shared_projects_path(@group, format: :json) } } } .top-area.group-nav-container.justify-content-between .scrolling-tabs-container.inner-page-scroll-tabs diff --git a/app/views/kaminari/gitlab/_first_page.html.haml b/app/views/kaminari/gitlab/_first_page.html.haml deleted file mode 100644 index 3b7d4a1c578..00000000000 --- a/app/views/kaminari/gitlab/_first_page.html.haml +++ /dev/null @@ -1,9 +0,0 @@ --# Link to the "First" page --# available local variables --# url: url to the first page --# current_page: a page object for the currently displayed page --# total_pages: total number of pages --# per_page: number of items to fetch per page --# remote: data-remote -%li.page-item.js-first-button - = link_to_unless current_page.first?, raw(t 'views.pagination.first'), url, remote: remote, class: 'page-link' diff --git a/app/views/kaminari/gitlab/_last_page.html.haml b/app/views/kaminari/gitlab/_last_page.html.haml deleted file mode 100644 index 7836e17f877..00000000000 --- a/app/views/kaminari/gitlab/_last_page.html.haml +++ /dev/null @@ -1,9 +0,0 @@ --# Link to the "Last" page --# available local variables --# url: url to the last page --# current_page: a page object for the currently displayed page --# total_pages: total number of pages --# per_page: number of items to fetch per page --# remote: data-remote -%li.page-item.js-last-button - = link_to_unless current_page.last?, raw(t 'views.pagination.last'), url, {remote: remote, class: 'page-link'} diff --git a/app/views/kaminari/gitlab/_next_page.html.haml b/app/views/kaminari/gitlab/_next_page.html.haml index a7fa1a21a6c..9572dd91330 100644 --- a/app/views/kaminari/gitlab/_next_page.html.haml +++ b/app/views/kaminari/gitlab/_next_page.html.haml @@ -9,4 +9,6 @@ - page_url = current_page.last? ? '#' : url %li.page-item.js-next-button{ class: ('disabled' if current_page.last?) } - = link_to raw(t 'views.pagination.next'), page_url, rel: 'next', remote: remote, class: 'page-link' + = link_to page_url, rel: 'next', remote: remote, class: 'page-link' do + = s_('Pagination|Next') + = sprite_icon('angle-right', size: 8) diff --git a/app/views/kaminari/gitlab/_page.html.haml b/app/views/kaminari/gitlab/_page.html.haml index d0dc1784540..33e00256100 100644 --- a/app/views/kaminari/gitlab/_page.html.haml +++ b/app/views/kaminari/gitlab/_page.html.haml @@ -6,5 +6,9 @@ -# total_pages: total number of pages -# per_page: number of items to fetch per page -# remote: data-remote -%li.page-item.js-pagination-page{ class: [active_when(page.current?), ('sibling' if page.next? || page.prev?), ('d-none d-md-block' if !page.current?) ] } +%li.page-item.js-pagination-page{ class: [active_when(page.current?), + ('sibling' if page.next? || page.prev?), + ('js-first-button' if page.first?), + ('js-last-button' if page.last?), + ('d-none d-md-block' if !page.current?) ] } = link_to page, url, { remote: remote, rel: page.next? ? 'next' : page.prev? ? 'prev' : nil, class: 'page-link' } diff --git a/app/views/kaminari/gitlab/_paginator.html.haml b/app/views/kaminari/gitlab/_paginator.html.haml index ac9e274dbc7..1b2edc0ad22 100644 --- a/app/views/kaminari/gitlab/_paginator.html.haml +++ b/app/views/kaminari/gitlab/_paginator.html.haml @@ -8,14 +8,10 @@ = paginator.render do .gl-pagination.prepend-top-default %ul.pagination.justify-content-center - - unless current_page.first? - = first_page_tag unless total_pages < 5 # As kaminari will always show the first 5 pages = prev_page_tag - each_page do |page| - - if page.left_outer? || page.right_outer? || page.inside_window? + - if page.left_outer? || page.right_outer? || page.inside_window? || page.first? || page.last? = page_tag page - elsif !page.was_truncated? = gap_tag = next_page_tag - - unless current_page.last? - = last_page_tag unless total_pages < 5 diff --git a/app/views/kaminari/gitlab/_prev_page.html.haml b/app/views/kaminari/gitlab/_prev_page.html.haml index 12b0e106a62..4ba7ab6488a 100644 --- a/app/views/kaminari/gitlab/_prev_page.html.haml +++ b/app/views/kaminari/gitlab/_prev_page.html.haml @@ -9,4 +9,6 @@ - page_url = current_page.first? ? '#' : url %li.page-item.js-previous-button{ class: ('disabled' if current_page.first?) } - = link_to raw(t 'views.pagination.previous'), page_url, rel: 'prev', remote: remote, class: 'page-link' + = link_to page_url, rel: 'prev', remote: remote, class: 'page-link' do + = sprite_icon('angle-left', size: 8) + = s_('Pagination|Prev') diff --git a/app/views/kaminari/gitlab/_without_count.html.haml b/app/views/kaminari/gitlab/_without_count.html.haml index f780400ebcb..d13f6ca5fa8 100644 --- a/app/views/kaminari/gitlab/_without_count.html.haml +++ b/app/views/kaminari/gitlab/_without_count.html.haml @@ -2,7 +2,11 @@ %ul.pagination.justify-content-center - if previous_path %li.page-item.prev - = link_to(t('views.pagination.previous'), previous_path, rel: 'prev', class: 'page-link') + = link_to previous_path, rel: 'prev', class: 'page-link' do + = sprite_icon('angle-left', size: 8) + = s_('Pagination|Prev') - if next_path %li.page-item.next - = link_to(t('views.pagination.next'), next_path, rel: 'next', class: 'page-link') + = link_to next_path, rel: 'next', class: 'page-link' do + = s_('Pagination|Next') + = sprite_icon('angle-right', size: 8) diff --git a/app/views/projects/settings/ci_cd/show.html.haml b/app/views/projects/settings/ci_cd/show.html.haml index a65afeecc17..1358077f2b2 100644 --- a/app/views/projects/settings/ci_cd/show.html.haml +++ b/app/views/projects/settings/ci_cd/show.html.haml @@ -62,12 +62,12 @@ .settings-content = render 'projects/triggers/index' -- if Feature.enabled?(:registry_retention_policies_settings, @project) +- if settings_container_registry_expiration_policy_available?(@project) %section.settings.no-animate#js-registry-policies{ class: ('expanded' if expanded) } .settings-header %h4 = _("Container Registry tag expiration policy") - = link_to icon('question-circle'), help_page_path('user/packages/container_registry/index', anchor: 'retention-and-expiration-policy'), target: '_blank', rel: 'noopener noreferrer' + = link_to icon('question-circle'), help_page_path('user/packages/container_registry/index', anchor: 'expiration-policy'), target: '_blank', rel: 'noopener noreferrer' %button.btn.js-settings-toggle{ type: 'button' } = expanded ? _('Collapse') : _('Expand') %p diff --git a/app/views/projects/show.html.haml b/app/views/projects/show.html.haml index 8f13806e8cd..17bc10af58a 100644 --- a/app/views/projects/show.html.haml +++ b/app/views/projects/show.html.haml @@ -20,6 +20,7 @@ = render "archived_notice", project: @project = render_if_exists "projects/marked_for_deletion_notice", project: @project + = render_if_exists "projects/ancestor_group_marked_for_deletion_notice", project: @project - view_path = @project.default_view |