diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-07-29 00:08:53 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-07-29 00:08:53 +0300 |
commit | 112fe349cb75b79a0075f5d3f89cf847b7beaf2d (patch) | |
tree | 9b1e1e9c61ab05e6725f7f961d02ddb57bf2d616 /app | |
parent | a66948df0c3fda7764965f8cf4c9c99226c0d44d (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
17 files changed, 167 insertions, 74 deletions
diff --git a/app/assets/javascripts/groups/components/group_item.vue b/app/assets/javascripts/groups/components/group_item.vue index ad0b27c9693..10c45abbfa2 100644 --- a/app/assets/javascripts/groups/components/group_item.vue +++ b/app/assets/javascripts/groups/components/group_item.vue @@ -28,6 +28,10 @@ export default { GlLoadingIcon, GlIcon, UserAccessRoleBadge, + ComplianceFrameworkLabel: () => + import( + 'ee_component/vue_shared/components/compliance_framework_label/compliance_framework_label.vue' + ), itemCaret, itemTypeIcon, itemStats, @@ -67,6 +71,9 @@ export default { hasAvatar() { return this.group.avatarUrl !== null; }, + hasComplianceFramework() { + return Boolean(this.group.complianceFramework?.name); + }, isGroup() { return this.group.type === 'group'; }, @@ -82,6 +89,9 @@ export default { microdata() { return this.group.microdata || {}; }, + complianceFramework() { + return this.group.complianceFramework; + }, }, methods: { onClickRowGroup(e) { @@ -167,6 +177,13 @@ export default { <user-access-role-badge v-if="group.permission" class="gl-mt-3"> {{ group.permission }} </user-access-role-badge> + <compliance-framework-label + v-if="hasComplianceFramework" + class="gl-mt-3" + :name="complianceFramework.name" + :color="complianceFramework.color" + :description="complianceFramework.description" + /> </div> <div v-if="group.description" class="description"> <span diff --git a/app/assets/javascripts/groups/store/groups_store.js b/app/assets/javascripts/groups/store/groups_store.js index 6cf70f4052e..93fbd8be47d 100644 --- a/app/assets/javascripts/groups/store/groups_store.js +++ b/app/assets/javascripts/groups/store/groups_store.js @@ -1,4 +1,5 @@ -import { normalizeHeaders, parseIntPagination } from '../../lib/utils/common_utils'; +import { isEmpty } from 'lodash'; +import { normalizeHeaders, parseIntPagination } from '~/lib/utils/common_utils'; import { getGroupItemMicrodata } from './utils'; export default class GroupsStore { @@ -70,7 +71,7 @@ export default class GroupsStore { ? rawGroupItem.subgroup_count : rawGroupItem.children_count; - return { + const groupItem = { id: rawGroupItem.id, name: rawGroupItem.name, fullName: rawGroupItem.full_name, @@ -98,6 +99,16 @@ export default class GroupsStore { pendingRemoval: rawGroupItem.marked_for_deletion, microdata: this.showSchemaMarkup ? getGroupItemMicrodata(rawGroupItem) : {}, }; + + if (!isEmpty(rawGroupItem.compliance_management_framework)) { + groupItem.complianceFramework = { + name: rawGroupItem.compliance_management_framework.name, + color: rawGroupItem.compliance_management_framework.color, + description: rawGroupItem.compliance_management_framework.description, + }; + } + + return groupItem; } removeGroup(group, parentGroup) { diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js index f63bf8f49cb..1aaefcaa13b 100644 --- a/app/assets/javascripts/main.js +++ b/app/assets/javascripts/main.js @@ -35,7 +35,6 @@ import GlFieldErrors from './gl_field_errors'; import initUserPopovers from './user_popovers'; import initBroadcastNotifications from './broadcast_notification'; import { initTopNav } from './nav'; -import navEventHub, { EVENT_RESPONSIVE_TOGGLE } from './nav/event_hub'; import 'ee_else_ce/main_ee'; @@ -203,11 +202,7 @@ $body.on('ajax:complete, ajax:beforeSend, submit', 'form', function ajaxComplete }); $('.navbar-toggler').on('click', () => { - // The order is important. The `menu-expanded` is used as a source of truth for now. - // This can be simplified when the :combined_menu feature flag is removed. - // https://gitlab.com/gitlab-org/gitlab/-/issues/333180 - $('.header-content').toggleClass('menu-expanded'); - navEventHub.$emit(EVENT_RESPONSIVE_TOGGLE); + document.body.classList.toggle('top-nav-responsive-open'); }); /** diff --git a/app/assets/javascripts/nav/components/responsive_app.vue b/app/assets/javascripts/nav/components/responsive_app.vue index d601586a3f8..68a39f862fc 100644 --- a/app/assets/javascripts/nav/components/responsive_app.vue +++ b/app/assets/javascripts/nav/components/responsive_app.vue @@ -2,8 +2,7 @@ import { FREQUENT_ITEMS_PROJECTS, FREQUENT_ITEMS_GROUPS } from '~/frequent_items/constants'; import { BV_DROPDOWN_SHOW, BV_DROPDOWN_HIDE } from '~/lib/utils/constants'; import KeepAliveSlots from '~/vue_shared/components/keep_alive_slots.vue'; -import eventHub, { EVENT_RESPONSIVE_TOGGLE } from '../event_hub'; -import { resetMenuItemsActive, hasMenuExpanded } from '../utils'; +import { resetMenuItemsActive } from '../utils'; import ResponsiveHeader from './responsive_header.vue'; import ResponsiveHome from './responsive_home.vue'; import TopNavContainerView from './top_nav_container_view.vue'; @@ -33,25 +32,14 @@ export default { }, }, created() { - eventHub.$on(EVENT_RESPONSIVE_TOGGLE, this.updateResponsiveOpen); this.$root.$on(BV_DROPDOWN_SHOW, this.showMobileOverlay); this.$root.$on(BV_DROPDOWN_HIDE, this.hideMobileOverlay); - - this.updateResponsiveOpen(); }, beforeDestroy() { - eventHub.$off(EVENT_RESPONSIVE_TOGGLE, this.onToggle); this.$root.$off(BV_DROPDOWN_SHOW, this.showMobileOverlay); this.$root.$off(BV_DROPDOWN_HIDE, this.hideMobileOverlay); }, methods: { - updateResponsiveOpen() { - if (hasMenuExpanded()) { - document.body.classList.add('top-nav-responsive-open'); - } else { - document.body.classList.remove('top-nav-responsive-open'); - } - }, onMenuItemClick({ view }) { if (view) { this.activeView = view; diff --git a/app/assets/javascripts/nav/event_hub.js b/app/assets/javascripts/nav/event_hub.js deleted file mode 100644 index 2c8b1371fe3..00000000000 --- a/app/assets/javascripts/nav/event_hub.js +++ /dev/null @@ -1,5 +0,0 @@ -import eventHubFactory from '~/helpers/event_hub_factory'; - -export const EVENT_RESPONSIVE_TOGGLE = 'top-nav-responsive-toggle'; - -export default eventHubFactory(); diff --git a/app/assets/javascripts/nav/utils/has_menu_expanded.js b/app/assets/javascripts/nav/utils/has_menu_expanded.js deleted file mode 100644 index 5f126bbdf76..00000000000 --- a/app/assets/javascripts/nav/utils/has_menu_expanded.js +++ /dev/null @@ -1,2 +0,0 @@ -export const hasMenuExpanded = () => - Boolean(document.querySelector('.header-content.menu-expanded')); diff --git a/app/assets/javascripts/nav/utils/index.js b/app/assets/javascripts/nav/utils/index.js index 4fa3d0910da..6d93818f0d3 100644 --- a/app/assets/javascripts/nav/utils/index.js +++ b/app/assets/javascripts/nav/utils/index.js @@ -1,2 +1 @@ -export * from './has_menu_expanded'; export * from './reset_menu_items_active'; diff --git a/app/assets/javascripts/registry/explorer/constants/details.js b/app/assets/javascripts/registry/explorer/constants/details.js index 1c4a28125e1..0836260b71e 100644 --- a/app/assets/javascripts/registry/explorer/constants/details.js +++ b/app/assets/javascripts/registry/explorer/constants/details.js @@ -162,6 +162,9 @@ export const IMAGE_STATUS_ALERT_TYPE = { [DELETE_FAILED]: 'warning', }; -export const PACKAGE_DELETE_HELP_PAGE_PATH = helpPagePath('user/packages/container_registry', { - anchor: 'delete-images', -}); +export const PACKAGE_DELETE_HELP_PAGE_PATH = helpPagePath( + 'user/packages/container_registry/index', + { + anchor: 'delete-images', + }, +); diff --git a/app/assets/javascripts/registry/explorer/pages/details.vue b/app/assets/javascripts/registry/explorer/pages/details.vue index 02d464e1eb0..feabc4f770b 100644 --- a/app/assets/javascripts/registry/explorer/pages/details.vue +++ b/app/assets/javascripts/registry/explorer/pages/details.vue @@ -188,7 +188,7 @@ export default { <partial-cleanup-alert v-if="showPartialCleanupWarning" :run-cleanup-policies-help-page-path="config.runCleanupPoliciesHelpPagePath" - :cleanup-policies-help-page-path="config.cleanupPoliciesHelpPagePath" + :cleanup-policies-help-page-path="config.expirationPolicyHelpPagePath" @dismiss="dismissPartialCleanupWarning" /> diff --git a/app/assets/javascripts/self_monitor/components/self_monitor_form.vue b/app/assets/javascripts/self_monitor/components/self_monitor_form.vue index 0cab90afb3c..2f31d8ef3fb 100644 --- a/app/assets/javascripts/self_monitor/components/self_monitor_form.vue +++ b/app/assets/javascripts/self_monitor/components/self_monitor_form.vue @@ -1,6 +1,13 @@ <script> -/* eslint-disable vue/no-v-html */ -import { GlFormGroup, GlButton, GlModal, GlToast, GlToggle, GlLink } from '@gitlab/ui'; +import { + GlFormGroup, + GlButton, + GlModal, + GlToast, + GlToggle, + GlLink, + GlSafeHtmlDirective, +} from '@gitlab/ui'; import Vue from 'vue'; import { mapState, mapActions } from 'vuex'; import { helpPagePath } from '~/helpers/help_page_helper'; @@ -18,6 +25,9 @@ export default { GlToggle, GlLink, }, + directives: { + SafeHtml: GlSafeHtmlDirective, + }, formLabels: { createProject: __('Self monitoring'), }, @@ -137,7 +147,7 @@ export default { </div> <div class="settings-content"> <form name="self-monitoring-form"> - <p ref="selfMonitoringFormText" v-html="selfMonitoringFormText"></p> + <p ref="selfMonitoringFormText" v-safe-html="selfMonitoringFormText"></p> <gl-form-group> <gl-toggle v-model="selfMonitorEnabled" diff --git a/app/assets/stylesheets/framework/header.scss b/app/assets/stylesheets/framework/header.scss index 65d914e47cf..ae46ff33ec0 100644 --- a/app/assets/stylesheets/framework/header.scss +++ b/app/assets/stylesheets/framework/header.scss @@ -27,17 +27,6 @@ $top-nav-hover-bg: var(--indigo-900-alpha-008, $indigo-900-alpha-008) !important display: none; } - .menu-expanded { - .more-icon { - display: none; - } - - .close-icon { - display: block; - margin: auto; - } - } - .header-content { width: 100%; display: flex; @@ -103,18 +92,6 @@ $top-nav-hover-bg: var(--indigo-900-alpha-008, $indigo-900-alpha-008) !important .navbar-collapse > ul.nav > li:not(.d-none) { margin: 0 2px; } - - &.menu-expanded { - @include media-breakpoint-down(xs) { - .hide-when-menu-expanded { - display: none; - } - - .navbar-collapse { - display: flex; - } - } - } } .navbar-collapse { @@ -673,19 +650,30 @@ $top-nav-hover-bg: var(--indigo-900-alpha-008, $indigo-900-alpha-008) !important } .top-nav-responsive-open { - .hide-when-top-nav-responsive-open { - @include media-breakpoint-down(xs) { + .more-icon { + display: none; + } + + .close-icon { + display: block; + margin: auto; + } + + @include media-breakpoint-down(xs) { + .navbar-collapse { + display: flex; + } + + .hide-when-top-nav-responsive-open { display: none !important; } - } - .top-nav-responsive { - @include media-breakpoint-down(xs) { + .top-nav-responsive { @include gl-display-block; } - } - .navbar-gitlab .header-content .title-container { - flex: 0; + .navbar-gitlab .header-content .title-container { + flex: 0; + } } } diff --git a/app/finders/lfs_pointers_finder.rb b/app/finders/lfs_pointers_finder.rb new file mode 100644 index 00000000000..7e621002f1e --- /dev/null +++ b/app/finders/lfs_pointers_finder.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +class LfsPointersFinder + def initialize(repository, path) + @repository = repository + @path = path + end + + def execute + return [] unless ref + + blob_ids = tree.blobs.map(&:id) + + # When current endpoint is a Blob then `tree.blobs` will be empty, it means we need to analyze + # the current Blob in order to determine if it's a LFS object + blob_ids = Array.wrap(current_blob&.id) if blob_ids.empty? + + Gitlab::Git::Blob.batch_lfs_pointers(repository, blob_ids).map(&:id) + end + + private + + attr_reader :repository, :path + + def ref + repository.root_ref + end + + def tree + repository.tree(ref, path) + end + + def current_blob + repository.blob_at(ref, path) + end +end diff --git a/app/finders/projects/members/effective_access_level_finder.rb b/app/finders/projects/members/effective_access_level_finder.rb index 2880d6667ce..c1e3842a9e4 100644 --- a/app/finders/projects/members/effective_access_level_finder.rb +++ b/app/finders/projects/members/effective_access_level_finder.rb @@ -59,8 +59,8 @@ module Projects # @return [Array<[user_id, access_level]>] def user_ids_and_access_levels_from_all_memberships strong_memoize(:user_ids_and_access_levels_from_all_memberships) do - all_possible_avenues_of_membership.flat_map do |relation| - relation.pluck(*USER_ID_AND_ACCESS_LEVEL) # rubocop: disable CodeReuse/ActiveRecord + all_possible_avenues_of_membership.flat_map do |members| + apply_scopes(members).pluck(*USER_ID_AND_ACCESS_LEVEL) # rubocop: disable CodeReuse/ActiveRecord end end end @@ -86,7 +86,7 @@ module Projects members << Member.from_union(members_per_batch) end - members.flatten + Member.from_union(members) end def project_owner_acting_as_maintainer @@ -120,6 +120,10 @@ module Projects Arel.sql(column_alias) ) end + + def apply_scopes(members) + members + end end end end diff --git a/app/finders/projects/members/effective_access_level_per_user_finder.rb b/app/finders/projects/members/effective_access_level_per_user_finder.rb new file mode 100644 index 00000000000..f367b4ca451 --- /dev/null +++ b/app/finders/projects/members/effective_access_level_per_user_finder.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +module Projects + module Members + class EffectiveAccessLevelPerUserFinder < EffectiveAccessLevelFinder + def initialize(project, user) + @project = project + @user = user + end + + private + + attr_reader :user + + def apply_scopes(members) + super.where(user_id: user.id) # rubocop: disable CodeReuse/ActiveRecord + end + end + end +end diff --git a/app/services/authorized_project_update/project_recalculate_per_user_service.rb b/app/services/authorized_project_update/project_recalculate_per_user_service.rb new file mode 100644 index 00000000000..6141bfc6498 --- /dev/null +++ b/app/services/authorized_project_update/project_recalculate_per_user_service.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +module AuthorizedProjectUpdate + class ProjectRecalculatePerUserService < ProjectRecalculateService + def initialize(project, user) + @project = project + @user = user + end + + private + + attr_reader :user + + def apply_scopes(project_authorizations) + super.where(user_id: user.id) # rubocop: disable CodeReuse/ActiveRecord + end + + def effective_access_levels + Projects::Members::EffectiveAccessLevelPerUserFinder.new(project, user).execute + end + end +end diff --git a/app/services/authorized_project_update/project_recalculate_service.rb b/app/services/authorized_project_update/project_recalculate_service.rb index cbb8efaf99f..d70d0efc2af 100644 --- a/app/services/authorized_project_update/project_recalculate_service.rb +++ b/app/services/authorized_project_update/project_recalculate_service.rb @@ -26,7 +26,7 @@ module AuthorizedProjectUpdate def current_authorizations strong_memoize(:current_authorizations) do - project.project_authorizations + apply_scopes(project.project_authorizations) .pluck(:user_id, :access_level) # rubocop: disable CodeReuse/ActiveRecord end end @@ -35,8 +35,7 @@ module AuthorizedProjectUpdate strong_memoize(:fresh_authorizations) do result = [] - Projects::Members::EffectiveAccessLevelFinder.new(project) - .execute + effective_access_levels .each_batch(of: BATCH_SIZE, column: :user_id) do |member_batch| result += member_batch.pluck(:user_id, 'MAX(access_level)') # rubocop: disable CodeReuse/ActiveRecord end @@ -76,5 +75,13 @@ module AuthorizedProjectUpdate end end end + + def apply_scopes(project_authorizations) + project_authorizations + end + + def effective_access_levels + Projects::Members::EffectiveAccessLevelFinder.new(project).execute + end end end diff --git a/app/views/layouts/header/_default.html.haml b/app/views/layouts/header/_default.html.haml index 4579eb59577..2f6287bdfb3 100644 --- a/app/views/layouts/header/_default.html.haml +++ b/app/views/layouts/header/_default.html.haml @@ -5,7 +5,7 @@ %a.gl-sr-only.gl-accessibility{ href: "#content-body" } Skip to content .container-fluid .header-content - .title-container.hide-when-menu-expanded + .title-container.hide-when-top-nav-responsive-open %h1.title %span.gl-sr-only GitLab = link_to root_path, title: _('Dashboard'), id: 'logo', **tracking_attrs('main_navigation', 'click_gitlab_logo_link', 'navigation') do |