diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-10-04 18:12:14 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-10-04 18:12:14 +0300 |
commit | e9ab4187093f05b873b32045295eeb580c97cdce (patch) | |
tree | 74f41f843e6addc0e17d4da877366f90e7f2fc68 /app | |
parent | 0327ce54a7e315b3aa6f80cc4e540fbb6792f2e3 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
15 files changed, 337 insertions, 26 deletions
diff --git a/app/assets/javascripts/api/bulk_imports_api.js b/app/assets/javascripts/api/bulk_imports_api.js new file mode 100644 index 00000000000..d636cfdff0b --- /dev/null +++ b/app/assets/javascripts/api/bulk_imports_api.js @@ -0,0 +1,7 @@ +import { buildApiUrl } from '~/api/api_utils'; +import axios from '~/lib/utils/axios_utils'; + +const BULK_IMPORT_ENTITIES_PATH = '/api/:version/bulk_imports/entities'; + +export const getBulkImportsHistory = (params) => + axios.get(buildApiUrl(BULK_IMPORT_ENTITIES_PATH), { params }); diff --git a/app/assets/javascripts/import_entities/components/pagination_bar.vue b/app/assets/javascripts/import_entities/components/pagination_bar.vue new file mode 100644 index 00000000000..33bd3e08bb1 --- /dev/null +++ b/app/assets/javascripts/import_entities/components/pagination_bar.vue @@ -0,0 +1,90 @@ +<script> +import { GlDropdown, GlDropdownItem, GlIcon, GlSprintf } from '@gitlab/ui'; +import { __ } from '~/locale'; +import PaginationLinks from '~/vue_shared/components/pagination_links.vue'; + +const DEFAULT_PAGE_SIZES = [20, 50, 100]; + +export default { + components: { + PaginationLinks, + GlDropdown, + GlDropdownItem, + GlIcon, + GlSprintf, + }, + props: { + pageInfo: { + required: true, + type: Object, + }, + pageSizes: { + required: false, + type: Array, + default: () => DEFAULT_PAGE_SIZES, + }, + itemsCount: { + required: true, + type: Number, + }, + }, + + computed: { + humanizedTotal() { + return this.pageInfo.total >= 1000 ? __('1000+') : this.pageInfo.total; + }, + + paginationInfo() { + const { page, perPage } = this.pageInfo; + const start = (page - 1) * perPage + 1; + const end = start + this.itemsCount - 1; + + return { start, end }; + }, + }, + + methods: { + setPage(page) { + this.$emit('set-page', page); + }, + }, +}; +</script> + +<template> + <div class="gl-display-flex gl-align-items-center"> + <pagination-links :change="setPage" :page-info="pageInfo" class="gl-m-0" /> + <gl-dropdown category="tertiary" class="gl-ml-auto"> + <template #button-content> + <span class="gl-font-weight-bold"> + <gl-sprintf :message="__('%{count} items per page')"> + <template #count> + {{ pageInfo.perPage }} + </template> + </gl-sprintf> + </span> + <gl-icon class="gl-button-icon dropdown-chevron" name="chevron-down" /> + </template> + <gl-dropdown-item v-for="size in pageSizes" :key="size" @click="$emit('set-page-size', size)"> + <gl-sprintf :message="__('%{count} items per page')"> + <template #count> + {{ size }} + </template> + </gl-sprintf> + </gl-dropdown-item> + </gl-dropdown> + <div class="gl-ml-2" data-testid="information"> + <gl-sprintf :message="s__('BulkImport|Showing %{start}-%{end} of %{total}')"> + <template #start> + {{ paginationInfo.start }} + </template> + <template #end> + {{ paginationInfo.end }} + </template> + <template #total> + {{ humanizedTotal }} + </template> + </gl-sprintf> + </div> + </div> +</template> diff --git a/app/assets/javascripts/pages/admin/application_settings/metrics_and_profiling/usage_statistics.js b/app/assets/javascripts/pages/admin/application_settings/metrics_and_profiling/usage_statistics.js index 4c312a008cb..68849857d0f 100644 --- a/app/assets/javascripts/pages/admin/application_settings/metrics_and_profiling/usage_statistics.js +++ b/app/assets/javascripts/pages/admin/application_settings/metrics_and_profiling/usage_statistics.js @@ -1,7 +1,7 @@ import { __ } from '~/locale'; export const HELPER_TEXT_SERVICE_PING_DISABLED = __( - 'To enable Registration Features, make sure "Enable service ping" is checked.', + 'To enable Registration Features, first enable Service Ping.', ); export const HELPER_TEXT_SERVICE_PING_ENABLED = __( diff --git a/app/assets/javascripts/pages/import/bulk_imports/history/components/bulk_imports_history_app.vue b/app/assets/javascripts/pages/import/bulk_imports/history/components/bulk_imports_history_app.vue new file mode 100644 index 00000000000..ec3cf4a8a92 --- /dev/null +++ b/app/assets/javascripts/pages/import/bulk_imports/history/components/bulk_imports_history_app.vue @@ -0,0 +1,176 @@ +<script> +import { GlButton, GlEmptyState, GlLink, GlLoadingIcon, GlTable } from '@gitlab/ui'; + +import { s__, __ } from '~/locale'; +import createFlash from '~/flash'; +import { parseIntPagination, normalizeHeaders } from '~/lib/utils/common_utils'; +import { joinPaths } from '~/lib/utils/url_utility'; +import { getBulkImportsHistory } from '~/rest_api'; +import ImportStatus from '~/import_entities/components/import_status.vue'; +import PaginationBar from '~/import_entities/components/pagination_bar.vue'; +import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue'; + +import { DEFAULT_ERROR } from '../utils/error_messages'; + +const DEFAULT_PER_PAGE = 20; +const DEFAULT_TH_CLASSES = + 'gl-bg-transparent! gl-border-b-solid! gl-border-b-gray-200! gl-border-b-1! gl-p-5!'; + +const tableCell = (config) => ({ + thClass: `${DEFAULT_TH_CLASSES}`, + tdClass: (value, key, item) => { + return { + // eslint-disable-next-line no-underscore-dangle + 'gl-border-b-0!': item._showDetails, + }; + }, + ...config, +}); + +export default { + components: { + GlButton, + GlEmptyState, + GlLink, + GlLoadingIcon, + GlTable, + PaginationBar, + ImportStatus, + TimeAgo, + }, + + data() { + return { + loading: true, + historyItems: [], + paginationConfig: { + page: 1, + perPage: DEFAULT_PER_PAGE, + }, + pageInfo: {}, + }; + }, + + fields: [ + tableCell({ + key: 'source_full_path', + label: s__('BulkImport|Source group'), + thClass: `${DEFAULT_TH_CLASSES} gl-w-30p`, + }), + tableCell({ + key: 'destination_name', + label: s__('BulkImport|New group'), + thClass: `${DEFAULT_TH_CLASSES} gl-w-40p`, + }), + tableCell({ + key: 'created_at', + label: __('Date'), + }), + tableCell({ + key: 'status', + label: __('Status'), + tdAttr: { 'data-qa-selector': 'import_status_indicator' }, + }), + ], + + computed: { + hasHistoryItems() { + return this.historyItems.length > 0; + }, + }, + + watch: { + paginationConfig: { + handler() { + this.loadHistoryItems(); + }, + deep: true, + immediate: true, + }, + }, + + methods: { + async loadHistoryItems() { + try { + this.loading = true; + const { data: historyItems, headers } = await getBulkImportsHistory({ + page: this.paginationConfig.page, + per_page: this.paginationConfig.perPage, + }); + this.pageInfo = parseIntPagination(normalizeHeaders(headers)); + this.historyItems = historyItems; + } catch (e) { + createFlash({ message: DEFAULT_ERROR, captureError: true, error: e }); + } finally { + this.loading = false; + } + }, + + getDestinationUrl({ destination_name: name, destination_namespace: namespace }) { + return [namespace, name].filter(Boolean).join('/'); + }, + + getFullDestinationUrl(params) { + return joinPaths(gon.relative_url_root || '', this.getDestinationUrl(params)); + }, + }, + + gitlabLogo: window.gon.gitlab_logo, +}; +</script> + +<template> + <div> + <div + class="gl-border-solid gl-border-gray-200 gl-border-0 gl-border-b-1 gl-display-flex gl-align-items-center" + > + <h1 class="gl-my-0 gl-py-4 gl-font-size-h1"> + <img :src="$options.gitlabLogo" class="gl-w-6 gl-h-6 gl-mb-2 gl-display-inline gl-mr-2" /> + {{ s__('BulkImport|Group import history') }} + </h1> + </div> + <gl-loading-icon v-if="loading" size="md" class="gl-mt-5" /> + <gl-empty-state + v-else-if="!hasHistoryItems" + :title="s__('BulkImport|No history is available')" + :description="s__('BulkImport|Your imported groups will appear here.')" + /> + <template v-else> + <gl-table + :fields="$options.fields" + :items="historyItems" + data-qa-selector="import_history_table" + class="gl-w-full" + > + <template #cell(destination_name)="{ item }"> + <gl-link :href="getFullDestinationUrl(item)" target="_blank"> + {{ getDestinationUrl(item) }} + </gl-link> + </template> + <template #cell(created_at)="{ value }"> + <time-ago :time="value" /> + </template> + <template #cell(status)="{ value, item, toggleDetails, detailsShowing }"> + <import-status :status="value" class="gl-display-inline-block gl-w-13" /> + <gl-button + v-if="item.failures.length" + class="gl-ml-3" + :selected="detailsShowing" + @click="toggleDetails" + >{{ __('Details') }}</gl-button + > + </template> + <template #row-details="{ item }"> + <pre>{{ item.failures }}</pre> + </template> + </gl-table> + <pagination-bar + :page-info="pageInfo" + :items-count="historyItems.length" + class="gl-m-0 gl-mt-3" + @set-page="paginationConfig.page = $event" + @set-page-size="paginationConfig.perPage = $event" + /> + </template> + </div> +</template> diff --git a/app/assets/javascripts/pages/import/bulk_imports/history/index.js b/app/assets/javascripts/pages/import/bulk_imports/history/index.js new file mode 100644 index 00000000000..5a67aa99baa --- /dev/null +++ b/app/assets/javascripts/pages/import/bulk_imports/history/index.js @@ -0,0 +1,15 @@ +import Vue from 'vue'; +import BulkImportHistoryApp from './components/bulk_imports_history_app.vue'; + +function mountImportHistoryApp(mountElement) { + if (!mountElement) return undefined; + + return new Vue({ + el: mountElement, + render(createElement) { + return createElement(BulkImportHistoryApp); + }, + }); +} + +mountImportHistoryApp(document.querySelector('#import-history-mount-element')); diff --git a/app/assets/javascripts/pages/import/bulk_imports/history/utils/error_messages.js b/app/assets/javascripts/pages/import/bulk_imports/history/utils/error_messages.js new file mode 100644 index 00000000000..24669e22ade --- /dev/null +++ b/app/assets/javascripts/pages/import/bulk_imports/history/utils/error_messages.js @@ -0,0 +1,3 @@ +import { __ } from '~/locale'; + +export const DEFAULT_ERROR = __('Something went wrong on our end.'); diff --git a/app/assets/javascripts/performance_bar/components/performance_bar_app.vue b/app/assets/javascripts/performance_bar/components/performance_bar_app.vue index 7fd63acbede..ed30198244f 100644 --- a/app/assets/javascripts/performance_bar/components/performance_bar_app.vue +++ b/app/assets/javascripts/performance_bar/components/performance_bar_app.vue @@ -124,9 +124,6 @@ export default { const fileName = this.requests[0].truncatedUrl; return `${fileName}_perf_bar_${Date.now()}.json`; }, - flamegraphPath() { - return mergeUrlParams({ performance_bar: 'flamegraph' }, window.location.href); - }, }, mounted() { this.currentRequest = this.requestId; @@ -135,6 +132,12 @@ export default { changeCurrentRequest(newRequestId) { this.currentRequest = newRequestId; }, + flamegraphPath(mode) { + return mergeUrlParams( + { performance_bar: 'flamegraph', stackprof_mode: mode }, + window.location.href, + ); + }, }, safeHtmlConfig: { ADD_TAGS: ['gl-emoji'] }, }; @@ -180,8 +183,17 @@ export default { }}</a> </div> <div v-if="currentRequest.details" id="peek-flamegraph" class="view"> - <a class="gl-text-blue-200" :href="flamegraphPath">{{ - s__('PerformanceBar|Flamegraph') + <span class="gl-text-white-200">{{ s__('PerformanceBar|Flamegraph with mode:') }}</span> + <a class="gl-text-blue-200" :href="flamegraphPath('wall')">{{ + s__('PerformanceBar|wall') + }}</a> + / + <a class="gl-text-blue-200" :href="flamegraphPath('cpu')">{{ + s__('PerformanceBar|cpu') + }}</a> + / + <a class="gl-text-blue-200" :href="flamegraphPath('object')">{{ + s__('PerformanceBar|object') }}</a> </div> <a v-if="statsUrl" class="gl-text-blue-200 view" :href="statsUrl">{{ diff --git a/app/assets/javascripts/rest_api.js b/app/assets/javascripts/rest_api.js index 61fe89f4f7e..29642b6633f 100644 --- a/app/assets/javascripts/rest_api.js +++ b/app/assets/javascripts/rest_api.js @@ -2,6 +2,7 @@ export * from './api/groups_api'; export * from './api/projects_api'; export * from './api/user_api'; export * from './api/markdown_api'; +export * from './api/bulk_imports_api'; // Note: It's not possible to spy on methods imported from this file in // Jest tests. diff --git a/app/controllers/concerns/issuable_actions.rb b/app/controllers/concerns/issuable_actions.rb index 2462df77884..e1e662a1968 100644 --- a/app/controllers/concerns/issuable_actions.rb +++ b/app/controllers/concerns/issuable_actions.rb @@ -158,7 +158,7 @@ module IssuableActions discussions = Discussion.build_collection(notes, issuable) - if issuable.is_a?(MergeRequest) && Feature.enabled?(:merge_request_discussion_cache, issuable.target_project, default_enabled: :yaml) + if issuable.is_a?(MergeRequest) cache_context = [current_user&.cache_key, project.team.human_max_access(current_user&.id)].join(':') render_cached(discussions, with: discussion_serializer, cache_context: -> (_) { cache_context }, context: self) diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index d7f1cd505e9..b11541b46cc 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -351,7 +351,7 @@ module ProjectsHelper end def show_terraform_banner?(project) - project.repository_languages.with_programming_language('HCL').exists? && project.terraform_states.empty? + Feature.enabled?(:show_terraform_banner, type: :ops, default_enabled: true) && project.repository_languages.with_programming_language('HCL').exists? && project.terraform_states.empty? end def project_permissions_panel_data(project) diff --git a/app/models/ci/build_trace_metadata.rb b/app/models/ci/build_trace_metadata.rb index 901b84ceec6..4819029ea33 100644 --- a/app/models/ci/build_trace_metadata.rb +++ b/app/models/ci/build_trace_metadata.rb @@ -37,8 +37,10 @@ module Ci increment!(:archival_attempts, touch: :last_archival_attempt_at) end - def track_archival!(trace_artifact_id) - update!(trace_artifact_id: trace_artifact_id, archived_at: Time.current) + def track_archival!(trace_artifact_id, checksum) + update!(trace_artifact_id: trace_artifact_id, + checksum: checksum, + archived_at: Time.current) end def archival_attempts_message diff --git a/app/views/admin/application_settings/_usage.html.haml b/app/views/admin/application_settings/_usage.html.haml index 934c0643043..5bdad50c161 100644 --- a/app/views/admin/application_settings/_usage.html.haml +++ b/app/views/admin/application_settings/_usage.html.haml @@ -10,21 +10,21 @@ = f.label :version_check_enabled, class: 'form-check-label' do = _("Enable version check") .form-text.text-muted - = _("GitLab will inform you if a new version is available.") - = _("%{link_start}Learn more%{link_end} about what information is shared with GitLab Inc.").html_safe % { link_start: "<a href='#{help_page_path("user/admin_area/settings/usage_statistics", anchor: "version-check")}'>".html_safe, link_end: '</a>'.html_safe } + = _("GitLab informs you if a new version is available.") + = _("%{link_start}What information does GitLab Inc. collect?%{link_end}").html_safe % { link_start: "<a href='#{help_page_path("user/admin_area/settings/usage_statistics", anchor: "version-check")}'>".html_safe, link_end: '</a>'.html_safe } .form-group - can_be_configured = @application_setting.usage_ping_can_be_configured? .form-check = f.check_box :usage_ping_enabled, disabled: !can_be_configured, class: 'form-check-input' = f.label :usage_ping_enabled, class: 'form-check-label' do - = _('Enable service ping') + = _('Enable Service Ping') .form-text.text-muted - if can_be_configured - %p.mb-2= _('To help improve GitLab and its user experience, GitLab will periodically collect usage information.') + %p.mb-2= _('To help improve GitLab and its user experience, GitLab periodically collects usage information.') - - service_ping_path = help_page_path('user/admin_area/settings/usage_statistics', anchor: 'service-ping') + - service_ping_path = help_page_path('development/service_ping/index.md') - service_ping_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: service_ping_path } - %p.mb-2= s_('%{service_ping_link_start}Learn more%{service_ping_link_end} about what information is shared with GitLab Inc.').html_safe % { service_ping_link_start: service_ping_link_start, service_ping_link_end: '</a>'.html_safe } + %p.mb-2= s_('%{service_ping_link_start}What information is shared with GitLab Inc.?%{service_ping_link_end}').html_safe % { service_ping_link_start: service_ping_link_start, service_ping_link_end: '</a>'.html_safe } %button.gl-button.btn.btn-default.js-payload-preview-trigger{ type: 'button', data: { payload_selector: ".#{payload_class}" } } .gl-spinner.js-spinner.gl-display-none.gl-mr-2 @@ -46,7 +46,7 @@ - if usage_ping_enabled %p.gl-mb-3.text-muted{ id: 'service_ping_features_helper_text' }= _('You can enable Registration Features because Service Ping is enabled. To continue using Registration Features in the future, you will also need to register with GitLab via a new cloud licensing service.') - else - %p.gl-mb-3.text-muted{ id: 'service_ping_features_helper_text' }= _('To enable Registration Features, make sure "Enable service ping" is checked.') + %p.gl-mb-3.text-muted{ id: 'service_ping_features_helper_text' }= _('To enable Registration Features, first enable Service Ping.') %p.gl-mb-3.text-muted= _('Registration Features include:') .form-text @@ -61,7 +61,7 @@ %li = _('Email from GitLab - email users right from the Admin Area. %{link_start}Learn more%{link_end}.').html_safe % { link_start: email_from_gitlab_link, link_end: link_end } %li - = _('Limit project size at a global, group and project level. %{link_start}Learn more%{link_end}.').html_safe % { link_start: repo_size_limit_link, link_end: link_end } + = _('Limit project size at a global, group, and project level. %{link_start}Learn more%{link_end}.').html_safe % { link_start: repo_size_limit_link, link_end: link_end } %li = _('Restrict group access by IP address. %{link_start}Learn more%{link_end}.').html_safe % { link_start: restrict_ip_link, link_end: link_end } diff --git a/app/views/admin/application_settings/metrics_and_profiling.html.haml b/app/views/admin/application_settings/metrics_and_profiling.html.haml index f1e37c76130..6087551d7c7 100644 --- a/app/views/admin/application_settings/metrics_and_profiling.html.haml +++ b/app/views/admin/application_settings/metrics_and_profiling.html.haml @@ -49,7 +49,7 @@ %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } = expanded_by_default? ? _('Collapse') : _('Expand') %p - = _('Enable or disable version check and service ping.') + = _('Enable or disable version check and Service Ping.') .settings-content = render 'usage' diff --git a/app/views/groups/_import_group_from_another_instance_panel.html.haml b/app/views/groups/_import_group_from_another_instance_panel.html.haml index 2b9277c67e9..06a86c2465f 100644 --- a/app/views/groups/_import_group_from_another_instance_panel.html.haml +++ b/app/views/groups/_import_group_from_another_instance_panel.html.haml @@ -1,16 +1,15 @@ = form_with url: configure_import_bulk_imports_path, class: 'group-form gl-show-field-errors' do |f| .gl-border-l-solid.gl-border-r-solid.gl-border-gray-100.gl-border-1.gl-p-5 - %h4.gl-display-flex - = s_('GroupsNew|Import groups from another instance of GitLab') - %span.badge.badge-info.badge-pill.gl-badge.md.gl-ml-3 - = _('Beta') + .gl-display-flex.gl-align-items-center + %h4.gl-display-flex + = s_('GroupsNew|Import groups from another instance of GitLab') + = link_to _('History'), history_import_bulk_imports_path, class: 'gl-link gl-ml-auto' .gl-alert.gl-alert-warning{ role: 'alert' } = sprite_icon('warning', css_class: 'gl-icon s16 gl-alert-icon gl-alert-icon-no-title') .gl-alert-body - docs_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('user/group/import/index.md') } - - feedback_link_start = '<a href="https://gitlab.com/gitlab-org/gitlab/-/issues/284495" target="_blank" rel="noopener noreferrer">'.html_safe - - link_end = '</a>'.html_safe - = s_('GroupsNew|Not all related objects are migrated, as %{docs_link_start}described here%{docs_link_end}. Please %{feedback_link_start}leave feedback%{feedback_link_end} on this feature.').html_safe % { docs_link_start: docs_link_start, docs_link_end: link_end, feedback_link_start: feedback_link_start, feedback_link_end: link_end } + - docs_link_end = '</a>'.html_safe + = s_('GroupsNew|Not all related objects are migrated. %{docs_link_start}More info%{docs_link_end}.').html_safe % { docs_link_start: docs_link_start, docs_link_end: docs_link_end } %p.gl-mt-3 = s_('GroupsNew|Provide credentials for another instance of GitLab to import your groups directly.') .form-group.gl-display-flex.gl-flex-direction-column diff --git a/app/views/import/bulk_imports/history.html.haml b/app/views/import/bulk_imports/history.html.haml new file mode 100644 index 00000000000..80eb0c7a764 --- /dev/null +++ b/app/views/import/bulk_imports/history.html.haml @@ -0,0 +1,6 @@ +- add_to_breadcrumbs _('New group'), new_group_path +- add_to_breadcrumbs _('Import group'), new_group_path(anchor: 'import-group-pane') +- add_page_specific_style 'page_bundles/import' +- page_title _('Import history') + +#import-history-mount-element |