diff options
Diffstat (limited to 'app')
17 files changed, 145 insertions, 49 deletions
diff --git a/app/assets/javascripts/ci/pipeline_editor/components/job_assistant_drawer/accordion_items/artifacts_and_cache_item.vue b/app/assets/javascripts/ci/pipeline_editor/components/job_assistant_drawer/accordion_items/artifacts_and_cache_item.vue index 794763e0cd8..76db9613dc1 100644 --- a/app/assets/javascripts/ci/pipeline_editor/components/job_assistant_drawer/accordion_items/artifacts_and_cache_item.vue +++ b/app/assets/javascripts/ci/pipeline_editor/components/job_assistant_drawer/accordion_items/artifacts_and_cache_item.vue @@ -26,7 +26,7 @@ export default { return [ { key: 'artifacts.paths', - title: i18n.ARTIFACTS_AND_CACHE, + title: i18n.ARTIFACTS_PATHS, paths: this.job.artifacts.paths, generateInputDataTestId: (index) => `artifacts-paths-input-${index}`, generateDeleteButtonDataTestId: (index) => `delete-artifacts-paths-button-${index}`, diff --git a/app/assets/javascripts/error_tracking/components/timeline_chart.vue b/app/assets/javascripts/error_tracking/components/timeline_chart.vue index 51e0c900e4b..907a6c8557f 100644 --- a/app/assets/javascripts/error_tracking/components/timeline_chart.vue +++ b/app/assets/javascripts/error_tracking/components/timeline_chart.vue @@ -1,6 +1,6 @@ <script> import { GlChart } from '@gitlab/ui/dist/charts'; -import { dataVizBlue500 } from '@gitlab/ui/scss_to_js/scss_variables'; +import { DATA_VIZ_BLUE_500 } from '@gitlab/ui/dist/tokens/js/tokens'; import { hexToRgba } from '@gitlab/ui/dist/utils/utils'; import { isNumber } from 'lodash'; import { formatDate } from '~/lib/utils/datetime/date_format_utility'; @@ -109,7 +109,7 @@ export default { { data: yData, type: 'bar', - itemStyle: { color: hexToRgba(dataVizBlue500, 0.5) }, + itemStyle: { color: hexToRgba(DATA_VIZ_BLUE_500, 0.5) }, }, ], tooltip: { diff --git a/app/assets/javascripts/ide/components/ide_status_bar.vue b/app/assets/javascripts/ide/components/ide_status_bar.vue index 8962bb76926..edc6cc3dcdc 100644 --- a/app/assets/javascripts/ide/components/ide_status_bar.vue +++ b/app/assets/javascripts/ide/components/ide_status_bar.vue @@ -105,6 +105,7 @@ export default { :title="lastCommit.message" :href="getCommitPath(lastCommit.short_id)" class="commit-sha" + data-testid="commit-sha-content" data-qa-selector="commit_sha_content" >{{ lastCommit.short_id }}</a > diff --git a/app/assets/javascripts/jira_connect/subscriptions/components/app.vue b/app/assets/javascripts/jira_connect/subscriptions/components/app.vue index 7e79572f76d..c5f6f736626 100644 --- a/app/assets/javascripts/jira_connect/subscriptions/components/app.vue +++ b/app/assets/javascripts/jira_connect/subscriptions/components/app.vue @@ -10,6 +10,7 @@ import SignInPage from '../pages/sign_in/sign_in_page.vue'; import SubscriptionsPage from '../pages/subscriptions_page.vue'; import UserLink from './user_link.vue'; import BrowserSupportAlert from './browser_support_alert.vue'; +import FeedbackBanner from './feedback_banner.vue'; export default { name: 'JiraConnectApp', @@ -18,6 +19,7 @@ export default { GlLink, GlSprintf, BrowserSupportAlert, + FeedbackBanner, SignInPage, SubscriptionsPage, UserLink, @@ -103,39 +105,47 @@ export default { <user-link v-if="userSignedIn" :user="currentUser" class="gl-fixed gl-right-4" /> </header> - <main class="jira-connect-app gl-px-5 gl-pt-7 gl-mx-auto"> - <browser-support-alert v-if="!isBrowserSupported" class="gl-mb-7" /> - <div v-else data-testid="jira-connect-app"> - <gl-alert - v-if="shouldShowAlert" - :variant="alert.variant" - :title="alert.title" - class="gl-mb-5" - data-testid="jira-connect-persisted-alert" - @dismiss="setAlert" - > - <gl-sprintf v-if="alert.linkUrl" :message="alert.message"> - <template #link="{ content }"> - <gl-link :href="alert.linkUrl" target="_blank">{{ content }}</gl-link> - </template> - </gl-sprintf> + <main + class="jira-connect-app gl-px-5 gl-pt-7 gl-pb-7 gl-mx-auto gl-display-flex gl-flex-direction-column gl-gap-7" + > + <div class="gl-flex-grow-1"> + <browser-support-alert v-if="!isBrowserSupported" class="gl-mb-7" /> + <div v-else data-testid="jira-connect-app"> + <gl-alert + v-if="shouldShowAlert" + :variant="alert.variant" + :title="alert.title" + class="gl-mb-5" + data-testid="jira-connect-persisted-alert" + @dismiss="setAlert" + > + <gl-sprintf v-if="alert.linkUrl" :message="alert.message"> + <template #link="{ content }"> + <gl-link :href="alert.linkUrl" target="_blank">{{ content }}</gl-link> + </template> + </gl-sprintf> - <template v-else> - {{ alert.message }} - </template> - </gl-alert> + <template v-else> + {{ alert.message }} + </template> + </gl-alert> - <div class="gl-layout-w-limited gl-mx-auto gl-px-5 gl-mb-7"> - <sign-in-page - v-show="!userSignedIn" - :has-subscriptions="hasSubscriptions" - :public-key-storage-enabled="publicKeyStorageEnabled" - @sign-in-oauth="onSignInOauth" - @error="onSignInError" - /> - <subscriptions-page v-if="userSignedIn" :has-subscriptions="hasSubscriptions" /> + <div class="gl-layout-w-limited gl-mx-auto gl-px-5 gl-mb-7"> + <sign-in-page + v-show="!userSignedIn" + :has-subscriptions="hasSubscriptions" + :public-key-storage-enabled="publicKeyStorageEnabled" + @sign-in-oauth="onSignInOauth" + @error="onSignInError" + /> + <subscriptions-page v-if="userSignedIn" :has-subscriptions="hasSubscriptions" /> + </div> </div> </div> + + <div class="gl-flex-grow-2"> + <feedback-banner class="gl-max-w-80 gl-mx-auto" /> + </div> </main> </div> </template> diff --git a/app/assets/javascripts/jira_connect/subscriptions/components/feedback_banner.vue b/app/assets/javascripts/jira_connect/subscriptions/components/feedback_banner.vue new file mode 100644 index 00000000000..5d6117b836d --- /dev/null +++ b/app/assets/javascripts/jira_connect/subscriptions/components/feedback_banner.vue @@ -0,0 +1,57 @@ +<script> +import { GlBanner } from '@gitlab/ui'; +import ChatBubbleSvg from '@gitlab/svgs/dist/illustrations/chat-bubble-sm.svg?url'; +import { s__, __ } from '~/locale'; +import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue'; + +export default { + components: { + GlBanner, + LocalStorageSync, + }, + + data() { + return { + feedbackBannerDismissed: false, + }; + }, + + methods: { + handleBannerClose() { + this.feedbackBannerDismissed = true; + }, + }, + + i18n: { + title: s__('JiraConnect|Tell us what you think!'), + body: s__( + 'JiraConnect|We would love to learn more about your experience with the GitLab for Jira Cloud App.', + ), + dismissLabel: __('Dismiss'), + buttonText: __('Give feedback'), + }, + feedbackBannerKey: 'jira_connect_feedback_banner', + feedbackIssueUrl: 'https://gitlab.com/gitlab-org/gitlab/-/issues/413652', + buttonAttributes: { + target: '_blank', + }, + ChatBubbleSvg, +}; +</script> + +<template> + <local-storage-sync v-model="feedbackBannerDismissed" :storage-key="$options.feedbackBannerKey"> + <gl-banner + v-if="!feedbackBannerDismissed" + :title="$options.i18n.title" + :button-attributes="$options.buttonAttributes" + :button-text="$options.i18n.buttonText" + :button-link="$options.feedbackIssueUrl" + :dismiss-label="$options.i18n.dismissLabel" + :svg-path="$options.ChatBubbleSvg" + @close="handleBannerClose" + > + <p>{{ $options.i18n.body }}</p> + </gl-banner> + </local-storage-sync> +</template> diff --git a/app/assets/javascripts/mr_more_dropdown.js b/app/assets/javascripts/mr_more_dropdown.js index ca50028a93a..4a9e10be5ad 100644 --- a/app/assets/javascripts/mr_more_dropdown.js +++ b/app/assets/javascripts/mr_more_dropdown.js @@ -1,4 +1,5 @@ import Vue from 'vue'; +import { initReportAbuse } from '~/projects/report_abuse'; import MrMoreDropdown from '~/vue_shared/components/mr_more_dropdown.vue'; export const initMrMoreDropdown = () => { @@ -37,6 +38,9 @@ export const initMrMoreDropdown = () => { reportAbusePath: el.dataset.reportAbusePath, showSummaryNotesToggle: Boolean(document.querySelector('#js-summary-notes')), }, + beforeCreate() { + initReportAbuse(); + }, render: (createElement) => createElement(MrMoreDropdown, { props: { diff --git a/app/assets/javascripts/pages/projects/merge_requests/page.js b/app/assets/javascripts/pages/projects/merge_requests/page.js index 552e75da9b8..75e308e706f 100644 --- a/app/assets/javascripts/pages/projects/merge_requests/page.js +++ b/app/assets/javascripts/pages/projects/merge_requests/page.js @@ -9,6 +9,7 @@ import store from '~/mr_notes/stores'; import initSidebarBundle from '~/sidebar/sidebar_bundle'; import { apolloProvider } from '~/graphql_shared/issuable_client'; import { parseBoolean } from '~/lib/utils/common_utils'; +import { initMrMoreDropdown } from '~/mr_more_dropdown'; import initShow from './init_merge_request_show'; import getStateQuery from './queries/get_state.query.graphql'; @@ -17,6 +18,7 @@ Vue.use(VueApollo); export function initMrPage() { initMrNotes(); initShow(); + initMrMoreDropdown(); startCodeReviewMessaging({ signalBus: diffsEventHub }); } diff --git a/app/assets/javascripts/pages/projects/merge_requests/show/index.js b/app/assets/javascripts/pages/projects/merge_requests/show/index.js index 1cc7e892ca0..9eaf490abb2 100644 --- a/app/assets/javascripts/pages/projects/merge_requests/show/index.js +++ b/app/assets/javascripts/pages/projects/merge_requests/show/index.js @@ -1,9 +1,5 @@ import mountNotesApp from 'ee_else_ce/mr_notes/mount_app'; -import { initReportAbuse } from '~/projects/report_abuse'; -import { initMrMoreDropdown } from '~/mr_more_dropdown'; import { initMrPage } from 'ee_else_ce/pages/projects/merge_requests/page'; initMrPage(); mountNotesApp(); -initReportAbuse(); -initMrMoreDropdown(); diff --git a/app/assets/javascripts/super_sidebar/components/global_search/command_palette/command_palette_items.vue b/app/assets/javascripts/super_sidebar/components/global_search/command_palette/command_palette_items.vue index 1e31a1cbbee..a1d0e400b5f 100644 --- a/app/assets/javascripts/super_sidebar/components/global_search/command_palette/command_palette_items.vue +++ b/app/assets/javascripts/super_sidebar/components/global_search/command_palette/command_palette_items.vue @@ -59,6 +59,13 @@ export default { case COMMAND_HANDLE: this.getCommandsAndPages(); break; + /* TODO: Search for recent issues initiated by #(ISSUE_HANDLE) from the command palette scope + was removed as using the # in command palette conflicted + with the existing global search functionality to search for issue by its id. + The code that performs the Recent issues search was not removed from the code base + as it would be nice to bring it back when we decide how to combine both search by id and text. + In scope of https://gitlab.com/gitlab-org/gitlab/-/issues/417434 + we either bring back the search by #issue_text or remove the related code completely */ case USER_HANDLE: case PROJECT_HANDLE: case ISSUE_HANDLE: diff --git a/app/assets/javascripts/super_sidebar/components/global_search/command_palette/constants.js b/app/assets/javascripts/super_sidebar/components/global_search/command_palette/constants.js index 83b262cf0d7..a43e621da44 100644 --- a/app/assets/javascripts/super_sidebar/components/global_search/command_palette/constants.js +++ b/app/assets/javascripts/super_sidebar/components/global_search/command_palette/constants.js @@ -2,14 +2,14 @@ import { s__, sprintf } from '~/locale'; export const COMMAND_HANDLE = '>'; export const USER_HANDLE = '@'; -export const PROJECT_HANDLE = '&'; +export const PROJECT_HANDLE = ':'; export const ISSUE_HANDLE = '#'; export const PATH_HANDLE = '/'; -export const COMMON_HANDLES = [COMMAND_HANDLE, USER_HANDLE, PROJECT_HANDLE, ISSUE_HANDLE]; +export const COMMON_HANDLES = [COMMAND_HANDLE, USER_HANDLE, PROJECT_HANDLE]; export const SEARCH_OR_COMMAND_MODE_PLACEHOLDER = sprintf( s__( - 'CommandPalette|Type %{commandHandle} for command, %{userHandle} for user, %{projectHandle} for project, %{issueHandle} for issue, %{pathHandle} for project file or perform generic search...', + 'CommandPalette|Type %{commandHandle} for command, %{userHandle} for user, %{projectHandle} for project, %{pathHandle} for project file, or perform generic search...', ), { commandHandle: COMMAND_HANDLE, diff --git a/app/assets/javascripts/vue_shared/components/ci_icon.vue b/app/assets/javascripts/vue_shared/components/ci_icon.vue index 0d7547d88a1..6670b931416 100644 --- a/app/assets/javascripts/vue_shared/components/ci_icon.vue +++ b/app/assets/javascripts/vue_shared/components/ci_icon.vue @@ -36,6 +36,15 @@ export default { status: { type: Object, required: true, + validator(status) { + const { group, icon } = status; + return ( + typeof group === 'string' && + group.length && + typeof icon === 'string' && + icon.startsWith('status_') + ); + }, }, size: { type: Number, @@ -69,7 +78,7 @@ export default { computed: { wrapperStyleClasses() { const status = this.status.group; - return `ci-status-icon ci-status-icon-${status} js-ci-status-icon-${status} gl-rounded-full gl-justify-content-center gl-line-height-0`; + return `ci-status-icon ci-status-icon-${status} gl-rounded-full gl-justify-content-center gl-line-height-0`; }, icon() { return this.isBorderless ? `${this.status.icon}_borderless` : this.status.icon; @@ -84,7 +93,6 @@ export default { { interactive: isInteractive, active: isActive, borderless: isBorderless }, ]" :style="{ height: `${size}px`, width: `${size}px` }" - data-testid="ci-icon-wrapper" > <gl-icon :name="icon" :size="size" :class="cssClasses" :aria-label="status.icon" /> </span> diff --git a/app/assets/stylesheets/page_bundles/jira_connect.scss b/app/assets/stylesheets/page_bundles/jira_connect.scss index 2c54c819543..6972e98b0bf 100644 --- a/app/assets/stylesheets/page_bundles/jira_connect.scss +++ b/app/assets/stylesheets/page_bundles/jira_connect.scss @@ -9,6 +9,8 @@ @import '@gitlab/ui/src/components/base/alert/alert'; @import '@gitlab/ui/src/components/base/avatar/avatar'; @import '@gitlab/ui/src/components/base/button/button'; +@import '@gitlab/ui/src/components/base/banner/banner'; +@import '@gitlab/ui/src/components/base/card/card'; @import '@gitlab/ui/src/components/base/icon/icon'; @import '@gitlab/ui/src/components/base/link/link'; @import '@gitlab/ui/src/components/base/loading_icon/loading_icon'; @@ -23,7 +25,7 @@ @import '@gitlab/ui/src/components/base/form/form_group/form_group'; @import '@gitlab/ui/src/components/base/search_box_by_type/search_box_by_type'; -$header-height: 40px; +$header-height: $gl-spacing-scale-8; .jira-connect-header { min-height: $header-height; @@ -35,6 +37,6 @@ $header-height: 40px; .jira-connect-app { margin-top: $header-height; - height: calc(100% - #{$header-height}); - max-width: 1000px; + height: 100%; + max-height: calc(100% - #{$header-height + $gl-spacing-scale-7 * 2}); } diff --git a/app/graphql/types/ci/job_type.rb b/app/graphql/types/ci/job_type.rb index a779ceb2e2a..02b10f3e4bd 100644 --- a/app/graphql/types/ci/job_type.rb +++ b/app/graphql/types/ci/job_type.rb @@ -87,8 +87,10 @@ module Types description: 'Play path of the job.' field :playable, GraphQL::Types::Boolean, null: false, method: :playable?, description: 'Indicates the job can be played.' - field :previous_stage_jobs_or_needs, Types::Ci::JobNeedUnion.connection_type, null: true, - description: 'Jobs that must complete before the job runs. Returns `BuildNeed`, which is the needed jobs if the job uses the `needs` keyword, or the previous stage jobs otherwise.' + field :previous_stage_jobs_or_needs, Types::Ci::JobNeedUnion.connection_type, + null: true, + description: 'Jobs that must complete before the job runs. Returns `BuildNeed`, ' \ + 'which is the needed jobs if the job uses the `needs` keyword, or the previous stage jobs otherwise.' field :ref_name, GraphQL::Types::String, null: true, description: 'Ref name of the job.' field :ref_path, GraphQL::Types::String, null: true, @@ -179,7 +181,9 @@ module Types stages = pipeline.stages.by_position(positions) stages.each do |stage| - loader.call([pipeline, stage.position], stage.latest_statuses) + # Without `.to_a`, the memoization will only preserve the activerecord relation object. And when there is + # a call, the SQL query will be executed again. + loader.call([pipeline, stage.position], stage.latest_statuses.to_a) end end end diff --git a/app/graphql/types/ci/stage_type.rb b/app/graphql/types/ci/stage_type.rb index c0f3d1db57b..a9d8075329d 100644 --- a/app/graphql/types/ci/stage_type.rb +++ b/app/graphql/types/ci/stage_type.rb @@ -33,7 +33,7 @@ module Types by_pipeline = keys.group_by(&:pipeline) include_needs = keys.any? do |k| k.requires?(%i[nodes jobs nodes needs]) || - k.requires?(%i[nodes jobs nodes previousStageJobsAndNeeds]) + k.requires?(%i[nodes jobs nodes previousStageJobsOrNeeds]) end by_pipeline.each do |pl, key_group| diff --git a/app/models/user.rb b/app/models/user.rb index 7fd5d25d7e0..93c15229e03 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -317,6 +317,9 @@ class User < ApplicationRecord validates :color_scheme_id, allow_nil: true, inclusion: { in: Gitlab::ColorSchemes.valid_ids, message: ->(*) { _("%{placeholder} is not a valid color scheme") % { placeholder: '%{value}' } } } + validates :hide_no_ssh_key, allow_nil: false, inclusion: { in: [true, false] } + validates :hide_no_password, allow_nil: false, inclusion: { in: [true, false] } + validates :notified_of_own_activity, allow_nil: false, inclusion: { in: [true, false] } after_initialize :set_projects_limit before_validation :sanitize_attrs diff --git a/app/models/user_preference.rb b/app/models/user_preference.rb index e527542e357..78ccce2aaae 100644 --- a/app/models/user_preference.rb +++ b/app/models/user_preference.rb @@ -23,6 +23,8 @@ class UserPreference < ApplicationRecord format: { with: ColorsHelper::HEX_COLOR_PATTERN }, allow_blank: true + validates :time_display_relative, allow_nil: false, inclusion: { in: [true, false] } + validates :render_whitespace_in_code, allow_nil: false, inclusion: { in: [true, false] } validates :pass_user_identities_to_ci_jwt, allow_nil: false, inclusion: { in: [true, false] } validates :pinned_nav_items, json_schema: { filename: 'pinned_nav_items' } diff --git a/app/views/admin/application_settings/_help_page.html.haml b/app/views/admin/application_settings/_help_page.html.haml index e76a83662af..9509806fc41 100644 --- a/app/views/admin/application_settings/_help_page.html.haml +++ b/app/views/admin/application_settings/_help_page.html.haml @@ -18,7 +18,7 @@ .form-group = f.label :help_page_documentation_base_url, _('Documentation pages URL'), class: 'gl-font-weight-bold' = f.text_field :help_page_documentation_base_url, class: 'form-control gl-form-input', placeholder: 'https://docs.gitlab.com' - - docs_link_url = help_page_path('user/admin_area/settings/help_page', anchor: 'destination-requirements') + - docs_link_url = help_page_path('administration/settings/help_page', anchor: 'destination-requirements') - docs_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: docs_link_url } %span.form-text.text-muted#support_help_block= html_escape(_('Requests for pages at %{code_start}%{help_text_url}%{code_end} redirect to the URL. The destination must meet certain requirements. %{docs_link_start}Learn more.%{docs_link_end}')) % { code_start: '<code>'.html_safe, help_text_url: help_url, code_end: '</code>'.html_safe, docs_link_start: docs_link_start, docs_link_end: '</a>'.html_safe } = f.submit _('Save changes'), pajamas_button: true |