diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-06-02 06:07:46 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-06-02 06:07:46 +0300 |
commit | 34beb8cec33a0ea1a296ecc9d1e5025d61624bcd (patch) | |
tree | 3633afa6fead0e18c927101a60e6176c2ced5fa4 /app | |
parent | 3ae3a2c23f5347493fc2842421941d56cb9545d6 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
15 files changed, 86 insertions, 56 deletions
diff --git a/app/assets/javascripts/ci/artifacts/utils.js b/app/assets/javascripts/ci/artifacts/utils.js index 2ed78261ade..74ade7d48aa 100644 --- a/app/assets/javascripts/ci/artifacts/utils.js +++ b/app/assets/javascripts/ci/artifacts/utils.js @@ -4,7 +4,7 @@ import { ARCHIVE_FILE_TYPE, METADATA_FILE_TYPE, JOB_STATUS_GROUP_SUCCESS } from export const totalArtifactsSizeForJob = (job) => numberToHumanSize( job.artifacts.nodes - .map((artifact) => artifact.size) + .map((artifact) => Number(artifact.size)) .reduce((total, artifact) => total + artifact, 0), ); diff --git a/app/assets/javascripts/usage_quotas/storage/components/project_storage_detail.vue b/app/assets/javascripts/usage_quotas/storage/components/project_storage_detail.vue index beff3b4c0c3..ce487beca07 100644 --- a/app/assets/javascripts/usage_quotas/storage/components/project_storage_detail.vue +++ b/app/assets/javascripts/usage_quotas/storage/components/project_storage_detail.vue @@ -82,7 +82,15 @@ export default { /> <div> <p class="gl-font-weight-bold gl-mb-0" :data-testid="`${item.storageType.id}-name`"> - {{ item.storageType.name }} + <gl-link + v-if="item.storageType.detailsPath && item.value" + :data-testid="`${item.storageType.id}-details-link`" + :href="item.storageType.detailsPath" + >{{ item.storageType.name }}</gl-link + > + <template v-else> + {{ item.storageType.name }} + </template> <gl-link v-if="item.storageType.helpPath" :href="item.storageType.helpPath" diff --git a/app/assets/javascripts/usage_quotas/storage/components/storage_type_icon.vue b/app/assets/javascripts/usage_quotas/storage/components/storage_type_icon.vue index 5142c2c0915..70dd1a841b2 100644 --- a/app/assets/javascripts/usage_quotas/storage/components/storage_type_icon.vue +++ b/app/assets/javascripts/usage_quotas/storage/components/storage_type_icon.vue @@ -14,10 +14,10 @@ export default { iconName(storageTypeName) { const defaultStorageTypeIcon = 'disk'; const storageTypeIconMap = { - lfsObjectsSize: 'doc-image', - snippetsSize: 'snippet', - repositorySize: 'infrastructure-registry', - packagesSize: 'package', + lfsObjects: 'doc-image', + snippets: 'snippet', + repository: 'infrastructure-registry', + packages: 'package', }; return storageTypeIconMap[`${storageTypeName}`] ?? defaultStorageTypeIcon; diff --git a/app/assets/javascripts/usage_quotas/storage/components/usage_graph.vue b/app/assets/javascripts/usage_quotas/storage/components/usage_graph.vue index e9683924ff8..cdaba2ad3f9 100644 --- a/app/assets/javascripts/usage_quotas/storage/components/usage_graph.vue +++ b/app/assets/javascripts/usage_quotas/storage/components/usage_graph.vue @@ -1,11 +1,10 @@ <script> import { numberToHumanSize } from '~/lib/utils/number_utils'; -import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import { PROJECT_STORAGE_TYPES } from '../constants'; import { descendingStorageUsageSort } from '../utils'; export default { - mixins: [glFeatureFlagMixin()], + name: 'UsageGraph', props: { rootStorageStatistics: { required: true, @@ -36,49 +35,49 @@ export default { return [ { - id: 'repositorySize', + id: 'repository', style: this.usageStyle(this.barRatio(repositorySize)), class: 'gl-bg-data-viz-blue-500', size: repositorySize, }, { - id: 'lfsObjectsSize', + id: 'lfsObjects', style: this.usageStyle(this.barRatio(lfsObjectsSize)), class: 'gl-bg-data-viz-orange-600', size: lfsObjectsSize, }, { - id: 'packagesSize', + id: 'packages', style: this.usageStyle(this.barRatio(packagesSize)), class: 'gl-bg-data-viz-aqua-500', size: packagesSize, }, { - id: 'containerRegistrySize', + id: 'containerRegistry', style: this.usageStyle(this.barRatio(containerRegistrySize)), class: 'gl-bg-data-viz-aqua-800', size: containerRegistrySize, }, { - id: 'buildArtifactsSize', + id: 'buildArtifacts', style: this.usageStyle(this.barRatio(buildArtifactsSize)), class: 'gl-bg-data-viz-green-500', size: buildArtifactsSize, }, { - id: 'pipelineArtifactsSize', + id: 'pipelineArtifacts', style: this.usageStyle(this.barRatio(pipelineArtifactsSize)), class: 'gl-bg-data-viz-green-800', size: pipelineArtifactsSize, }, { - id: 'wikiSize', + id: 'wiki', style: this.usageStyle(this.barRatio(wikiSize)), class: 'gl-bg-data-viz-magenta-500', size: wikiSize, }, { - id: 'snippetsSize', + id: 'snippets', style: this.usageStyle(this.barRatio(snippetsSize)), class: 'gl-bg-data-viz-orange-800', size: snippetsSize, diff --git a/app/assets/javascripts/usage_quotas/storage/constants.js b/app/assets/javascripts/usage_quotas/storage/constants.js index 8e3eaff4496..f08e8db26b9 100644 --- a/app/assets/javascripts/usage_quotas/storage/constants.js +++ b/app/assets/javascripts/usage_quotas/storage/constants.js @@ -26,44 +26,44 @@ export const PROJECT_TABLE_LABEL_USAGE = s__('UsageQuota|Usage'); export const PROJECT_STORAGE_TYPES = [ { - id: 'containerRegistrySize', + id: 'containerRegistry', name: __('Container Registry'), description: s__( 'UsageQuota|Gitlab-integrated Docker Container Registry for storing Docker Images.', ), }, { - id: 'buildArtifactsSize', + id: 'buildArtifacts', name: __('Job artifacts'), description: s__('UsageQuota|Job artifacts created by CI/CD.'), }, { - id: 'pipelineArtifactsSize', + id: 'pipelineArtifacts', name: __('Pipeline artifacts'), description: s__('UsageQuota|Pipeline artifacts created by CI/CD.'), }, { - id: 'lfsObjectsSize', + id: 'lfsObjects', name: __('LFS'), description: s__('UsageQuota|Audio samples, videos, datasets, and graphics.'), }, { - id: 'packagesSize', + id: 'packages', name: __('Packages'), description: s__('UsageQuota|Code packages and container images.'), }, { - id: 'repositorySize', + id: 'repository', name: __('Repository'), description: s__('UsageQuota|Git repository.'), }, { - id: 'snippetsSize', + id: 'snippets', name: __('Snippets'), description: s__('UsageQuota|Shared bits of code and text.'), }, { - id: 'wikiSize', + id: 'wiki', name: __('Wiki'), description: s__('UsageQuota|Wiki content.'), }, diff --git a/app/assets/javascripts/usage_quotas/storage/queries/project_storage.query.graphql b/app/assets/javascripts/usage_quotas/storage/queries/project_storage.query.graphql index d254f576219..85a181d3e01 100644 --- a/app/assets/javascripts/usage_quotas/storage/queries/project_storage.query.graphql +++ b/app/assets/javascripts/usage_quotas/storage/queries/project_storage.query.graphql @@ -1,6 +1,14 @@ query getProjectStorageStatistics($fullPath: ID!) { project(fullPath: $fullPath) { id + statisticsDetailsPaths { + containerRegistry + buildArtifacts + packages + repository + snippets + wiki + } statistics { containerRegistrySize buildArtifactsSize diff --git a/app/assets/javascripts/usage_quotas/storage/utils.js b/app/assets/javascripts/usage_quotas/storage/utils.js index 443788f650d..0460cd0a9b2 100644 --- a/app/assets/javascripts/usage_quotas/storage/utils.js +++ b/app/assets/javascripts/usage_quotas/storage/utils.js @@ -1,17 +1,23 @@ import { numberToHumanSize } from '~/lib/utils/number_utils'; import { PROJECT_STORAGE_TYPES } from './constants'; -export const getStorageTypesFromProjectStatistics = (projectStatistics, helpLinks = {}) => +export const getStorageTypesFromProjectStatistics = ( + projectStatistics, + helpLinks = {}, + statisticsDetailsPaths = {}, +) => PROJECT_STORAGE_TYPES.reduce((types, currentType) => { - const helpPathKey = currentType.id.replace(`Size`, ``); - const helpPath = helpLinks[helpPathKey]; + const helpPath = helpLinks[currentType.id]; + const value = projectStatistics[`${currentType.id}Size`]; + const detailsPath = statisticsDetailsPaths[currentType.id]; return types.concat({ storageType: { ...currentType, helpPath, + detailsPath, }, - value: projectStatistics[currentType.id], + value, }); }, []); @@ -27,7 +33,11 @@ export const parseGetProjectStorageResults = (data, helpLinks) => { return {}; } const { storageSize } = projectStatistics; - const storageTypes = getStorageTypesFromProjectStatistics(projectStatistics, helpLinks); + const storageTypes = getStorageTypesFromProjectStatistics( + projectStatistics, + helpLinks, + data?.project?.statisticsDetailsPaths, + ); return { storage: { diff --git a/app/models/personal_access_token.rb b/app/models/personal_access_token.rb index 40370359c01..80825c4bf08 100644 --- a/app/models/personal_access_token.rb +++ b/app/models/personal_access_token.rb @@ -79,10 +79,6 @@ class PersonalAccessToken < ApplicationRecord fuzzy_search(query, [:name]) end - def project_access_token? - user&.project_bot? - end - protected def validate_scopes diff --git a/app/services/resource_access_tokens/create_service.rb b/app/services/resource_access_tokens/create_service.rb index e6f6f63a116..b184c2f8f58 100644 --- a/app/services/resource_access_tokens/create_service.rb +++ b/app/services/resource_access_tokens/create_service.rb @@ -17,6 +17,8 @@ module ResourceAccessTokens access_level = params[:access_level] || Gitlab::Access::MAINTAINER return error("Could not provision owner access to project access token") if do_not_allow_owner_access_level_for_project_bot?(access_level) + return error(s_('AccessTokens|Access token limit reached')) if reached_access_token_limit? + user = create_user return error(user.errors.full_messages.to_sentence) unless user.persisted? @@ -45,6 +47,10 @@ module ResourceAccessTokens attr_reader :resource_type, :resource + def reached_access_token_limit? + false + end + def username_and_email_generator Gitlab::Utils::UsernameAndEmailGenerator.new( username_prefix: "#{resource_type}_#{resource.id}_bot", diff --git a/app/views/admin/sessions/new.html.haml b/app/views/admin/sessions/new.html.haml index 4fc30cbaecf..7301b0f6e04 100644 --- a/app/views/admin/sessions/new.html.haml +++ b/app/views/admin/sessions/new.html.haml @@ -8,7 +8,7 @@ - if any_form_based_providers_enabled? = render 'devise/shared/tabs_ldap', show_password_form: allow_admin_mode_password_authentication_for_web?, render_signup_link: false - else - = render 'devise/shared/tab_single', tab_title: page_title + = render 'devise/shared/tab_single', tab_title: page_title if Feature.disabled?(:restyle_login_page, @project) .tab-content - if allow_admin_mode_password_authentication_for_web? || ldap_sign_in_enabled? || crowd_enabled? = render 'admin/sessions/signin_box' diff --git a/app/views/admin/sessions/two_factor.html.haml b/app/views/admin/sessions/two_factor.html.haml index 69f8a8a3a97..bfe66e2477e 100644 --- a/app/views/admin/sessions/two_factor.html.haml +++ b/app/views/admin/sessions/two_factor.html.haml @@ -5,11 +5,10 @@ .col-md-5.new-session-forms-container .login-page #signin-container{ class: ('borderless' if Feature.enabled?(:restyle_login_page, @project)) } - = render 'devise/shared/tab_single', tab_title: _('Enter admin mode') - .tab-content - .login-box.tab-pane.gl-p-5.active{ id: 'login-pane', role: 'tabpanel' } - .login-body - - if current_user.two_factor_enabled? - = render 'admin/sessions/two_factor_otp' - - if current_user.two_factor_webauthn_enabled? - = render 'authentication/authenticate', render_remember_me: false, target_path: admin_session_path + = render 'devise/shared/tab_single', tab_title: _('Enter admin mode') if Feature.disabled?(:restyle_login_page, @project) + .login-box.gl-p-5 + .login-body + - if current_user.two_factor_enabled? + = render 'admin/sessions/two_factor_otp' + - if current_user.two_factor_webauthn_enabled? + = render 'authentication/authenticate', render_remember_me: false, target_path: admin_session_path diff --git a/app/views/dashboard/projects/_blank_state_admin_welcome.html.haml b/app/views/dashboard/projects/_blank_state_admin_welcome.html.haml index 855177fd836..94f956896d6 100644 --- a/app/views/dashboard/projects/_blank_state_admin_welcome.html.haml +++ b/app/views/dashboard/projects/_blank_state_admin_welcome.html.haml @@ -4,7 +4,7 @@ - if has_start_trial? = render_if_exists "dashboard/projects/blank_state_ee_trial" - = link_to new_project_path, class: link_classes do + = link_to new_project_path, class: link_classes, data: { qa_selector: 'new_project_button' } do .blank-state-icon = custom_icon("add_new_project", size: 50) .blank-state-body.gl-sm-pl-6 diff --git a/app/views/dashboard/projects/_blank_state_welcome.html.haml b/app/views/dashboard/projects/_blank_state_welcome.html.haml index 2b13e2ba9a5..08b914a218d 100644 --- a/app/views/dashboard/projects/_blank_state_welcome.html.haml +++ b/app/views/dashboard/projects/_blank_state_welcome.html.haml @@ -2,7 +2,7 @@ .gl-display-flex.gl-flex-wrap.gl-justify-content-space-between - if current_user.can_create_project? - = link_to new_project_path, class: link_classes do + = link_to new_project_path, class: link_classes, data: { qa_selector: 'new_project_button' } do .blank-state-icon = custom_icon("add_new_project", size: 50) .blank-state-body.gl-sm-pl-6 diff --git a/app/views/projects/settings/access_tokens/_form.html.haml b/app/views/projects/settings/access_tokens/_form.html.haml new file mode 100644 index 00000000000..919462a0f62 --- /dev/null +++ b/app/views/projects/settings/access_tokens/_form.html.haml @@ -0,0 +1,14 @@ +- type = local_assigns.fetch(:type) + += render 'shared/access_tokens/form', + ajax: true, + type: type, + path: project_settings_access_tokens_path(@project), + resource: @project, + token: @resource_access_token, + scopes: @scopes, + access_levels: ProjectMember.permissible_access_level_roles(current_user, @project), + default_access_level: Gitlab::Access::GUEST, + prefix: :resource_access_token, + description_prefix: :project_access_token, + help_path: help_page_path('user/project/settings/project_access_tokens', anchor: 'scopes-for-a-project-access-token') diff --git a/app/views/projects/settings/access_tokens/index.html.haml b/app/views/projects/settings/access_tokens/index.html.haml index 26c08fcdfe4..df517b5d642 100644 --- a/app/views/projects/settings/access_tokens/index.html.haml +++ b/app/views/projects/settings/access_tokens/index.html.haml @@ -27,18 +27,8 @@ #js-new-access-token-app{ data: { access_token_type: type } } - if current_user.can?(:create_resource_access_tokens, @project) - = render 'shared/access_tokens/form', - ajax: true, - type: type, - path: project_settings_access_tokens_path(@project), - resource: @project, - token: @resource_access_token, - scopes: @scopes, - access_levels: ProjectMember.permissible_access_level_roles(current_user, @project), - default_access_level: Gitlab::Access::GUEST, - prefix: :resource_access_token, - description_prefix: :project_access_token, - help_path: help_page_path('user/project/settings/project_access_tokens', anchor: 'scopes-for-a-project-access-token') + = render_if_exists 'projects/settings/access_tokens/form', + type: type #js-access-token-table-app{ data: { access_token_type: type, access_token_type_plural: type_plural, initial_active_access_tokens: @active_access_tokens.to_json, no_active_tokens_message: _('This project has no active access tokens.'), show_role: true } } |