diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-02-22 21:07:43 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-02-22 21:07:43 +0000 |
commit | f19ffffacda2d7f415f682f6e50e3cf06182e15e (patch) | |
tree | b8a78ba727ab2ef38808c028401842e7370948b0 /app | |
parent | d0f16d56f3716d4a60027eb261f12080094f8db3 (diff) | |
download | gitlab-ce-f19ffffacda2d7f415f682f6e50e3cf06182e15e.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
14 files changed, 135 insertions, 70 deletions
diff --git a/app/assets/images/learn_gitlab/section_code.svg b/app/assets/images/learn_gitlab/section_code.svg new file mode 100644 index 00000000000..da170c93be6 --- /dev/null +++ b/app/assets/images/learn_gitlab/section_code.svg @@ -0,0 +1,4 @@ +<svg width="25" height="30" viewBox="0 0 20 23" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M15 8L15 9.5C15 10.3284 15.6716 11 16.5 11C17.3284 11 18 10.3284 18 9.5V7.74264C18 6.94699 17.6839 6.18393 17.1213 5.62132L12.8787 1.37868C12.3161 0.816071 11.553 0.5 10.7574 0.5H1.5C0.671573 0.5 0 1.17157 0 2V20C0 20.8284 0.671573 21.5 1.5 21.5H6C6.82843 21.5 7.5 20.8284 7.5 20C7.5 19.1716 6.82843 18.5 6 18.5H3V3.5H10.5V6.5C10.5 7.32843 11.1716 8 12 8H15Z" fill="#6E49CB"/> +<path d="M10.5 18.5C10.5 17.6716 11.1716 17 12 17H13.5V15.5C13.5 14.6716 14.1716 14 15 14C15.8284 14 16.5 14.6716 16.5 15.5V17H18C18.8284 17 19.5 17.6716 19.5 18.5C19.5 19.3284 18.8284 20 18 20H16.5V21.5C16.5 22.3284 15.8284 23 15 23C14.1716 23 13.5 22.3284 13.5 21.5V20H12C11.1716 20 10.5 19.3284 10.5 18.5Z" fill="#6E49CB"/> +</svg> diff --git a/app/assets/javascripts/ide/index.js b/app/assets/javascripts/ide/index.js index 29c44d2f596..967c83b320f 100644 --- a/app/assets/javascripts/ide/index.js +++ b/app/assets/javascripts/ide/index.js @@ -72,6 +72,7 @@ export const initLegacyWebIDE = (el, options = {}) => { environmentsGuidanceAlertDismissed: !parseBoolean(el.dataset.enableEnvironmentsGuidance), previewMarkdownPath: el.dataset.previewMarkdownPath, userPreferencesPath: el.dataset.userPreferencesPath, + learnGitlabSource: parseBoolean(el.dataset.learnGitlabSource), }); }, beforeDestroy() { diff --git a/app/assets/javascripts/ide/stores/modules/commit/actions.js b/app/assets/javascripts/ide/stores/modules/commit/actions.js index d490b8c5dad..7f8e253ed37 100644 --- a/app/assets/javascripts/ide/stores/modules/commit/actions.js +++ b/app/assets/javascripts/ide/stores/modules/commit/actions.js @@ -1,6 +1,7 @@ import { createAlert } from '~/flash'; import { addNumericSuffix } from '~/ide/utils'; import { sprintf, __ } from '~/locale'; +import Tracking from '~/tracking'; import { leftSidebarViews } from '../../../constants'; import eventHub from '../../../eventhub'; import { parseCommitError } from '../../../lib/errors'; @@ -162,6 +163,10 @@ export const commitChanges = ({ commit, state, getters, dispatch, rootState, roo ); } + if (rootState.learnGitlabSource) { + Tracking.event(undefined, 'commit', { label: 'web_ide_learn_gitlab_source' }); + } + dispatch('setLastCommitMessage', data); dispatch('updateCommitMessage', ''); return dispatch('updateFilesAfterCommit', { diff --git a/app/assets/javascripts/ide/stores/state.js b/app/assets/javascripts/ide/stores/state.js index 356bbf28a48..013a0c3ce8f 100644 --- a/app/assets/javascripts/ide/stores/state.js +++ b/app/assets/javascripts/ide/stores/state.js @@ -32,4 +32,5 @@ export default () => ({ environmentsGuidanceAlertDetected: false, previewMarkdownPath: '', userPreferencesPath: '', + learnGitlabSource: false, }); diff --git a/app/assets/javascripts/jobs/components/table/graphql/cache_config.js b/app/assets/javascripts/jobs/components/table/graphql/cache_config.js index 8bcd7ffd10f..5390c023da4 100644 --- a/app/assets/javascripts/jobs/components/table/graphql/cache_config.js +++ b/app/assets/javascripts/jobs/components/table/graphql/cache_config.js @@ -11,42 +11,48 @@ export default { }, CiJobConnection: { merge(existing = {}, incoming, { args = {} }) { - let nodes; + if (incoming.nodes) { + let nodes; - const areNodesEqual = isEqual(existing.nodes, incoming.nodes); - const statuses = Array.isArray(args.statuses) ? [...args.statuses] : args.statuses; - const { pageInfo } = incoming; + const areNodesEqual = isEqual(existing.nodes, incoming.nodes); + const statuses = Array.isArray(args.statuses) ? [...args.statuses] : args.statuses; + const { pageInfo } = incoming; - if (Object.keys(existing).length !== 0 && isEqual(existing?.statuses, args?.statuses)) { - if (areNodesEqual) { - if (incoming.pageInfo.hasNextPage) { - nodes = [...existing.nodes, ...incoming.nodes]; + if (Object.keys(existing).length !== 0 && isEqual(existing?.statuses, args?.statuses)) { + if (areNodesEqual) { + if (incoming.pageInfo.hasNextPage) { + nodes = [...existing.nodes, ...incoming.nodes]; + } else { + nodes = [...incoming.nodes]; + } } else { - nodes = [...incoming.nodes]; - } - } else { - if (!existing.pageInfo?.hasNextPage) { - nodes = [...incoming.nodes]; + if (!existing.pageInfo?.hasNextPage) { + nodes = [...incoming.nodes]; - return { - nodes, - statuses, - pageInfo, - count: incoming.count, - }; - } + return { + nodes, + statuses, + pageInfo, + }; + } - nodes = [...existing.nodes, ...incoming.nodes]; + nodes = [...existing.nodes, ...incoming.nodes]; + } + } else { + nodes = [...incoming.nodes]; } - } else { - nodes = [...incoming.nodes]; + + return { + nodes, + statuses, + pageInfo, + }; } return { - nodes, - statuses, - pageInfo, - count: incoming.count, + nodes: existing.nodes, + pageInfo: existing.pageInfo, + statuses: args.statuses, }; }, }, diff --git a/app/assets/javascripts/jobs/components/table/graphql/queries/get_jobs.query.graphql b/app/assets/javascripts/jobs/components/table/graphql/queries/get_jobs.query.graphql index 851be211b25..69719011079 100644 --- a/app/assets/javascripts/jobs/components/table/graphql/queries/get_jobs.query.graphql +++ b/app/assets/javascripts/jobs/components/table/graphql/queries/get_jobs.query.graphql @@ -2,7 +2,6 @@ query getJobs($fullPath: ID!, $after: String, $first: Int = 30, $statuses: [CiJo project(fullPath: $fullPath) { id jobs(after: $after, first: $first, statuses: $statuses) { - count pageInfo { endCursor hasNextPage diff --git a/app/assets/javascripts/jobs/components/table/graphql/queries/get_jobs_count.query.graphql b/app/assets/javascripts/jobs/components/table/graphql/queries/get_jobs_count.query.graphql new file mode 100644 index 00000000000..a4e02ae721a --- /dev/null +++ b/app/assets/javascripts/jobs/components/table/graphql/queries/get_jobs_count.query.graphql @@ -0,0 +1,8 @@ +query getJobsCount($fullPath: ID!, $statuses: [CiJobStatus!]) { + project(fullPath: $fullPath) { + id + jobs(statuses: $statuses) { + count + } + } +} diff --git a/app/assets/javascripts/jobs/components/table/jobs_table_app.vue b/app/assets/javascripts/jobs/components/table/jobs_table_app.vue index 3209fc4b90d..49960278208 100644 --- a/app/assets/javascripts/jobs/components/table/jobs_table_app.vue +++ b/app/assets/javascripts/jobs/components/table/jobs_table_app.vue @@ -6,6 +6,7 @@ import { setUrlParams, updateHistory, queryToObject } from '~/lib/utils/url_util import JobsFilteredSearch from '../filtered_search/jobs_filtered_search.vue'; import { validateQueryString } from '../filtered_search/utils'; import GetJobs from './graphql/queries/get_jobs.query.graphql'; +import GetJobsCount from './graphql/queries/get_jobs_count.query.graphql'; import JobsTable from './jobs_table.vue'; import JobsTableEmptyState from './jobs_table_empty_state.vue'; import JobsTableTabs from './jobs_table_tabs.vue'; @@ -13,7 +14,8 @@ import { RAW_TEXT_WARNING } from './constants'; export default { i18n: { - errorMsg: __('There was an error fetching the jobs for your project.'), + jobsFetchErrorMsg: __('There was an error fetching the jobs for your project.'), + jobsCountErrorMsg: __('There was an error fetching the number of jobs for your project.'), loadingAriaLabel: __('Loading'), }, filterSearchBoxStyles: @@ -43,15 +45,29 @@ export default { }; }, update(data) { - const { jobs: { nodes: list = [], pageInfo = {}, count } = {} } = data.project || {}; + const { jobs: { nodes: list = [], pageInfo = {} } = {} } = data.project || {}; return { list, pageInfo, - count, }; }, error() { - this.hasError = true; + this.error = this.$options.i18n.jobsFetchErrorMsg; + }, + }, + jobsCount: { + query: GetJobsCount, + variables() { + return { + fullPath: this.fullPath, + ...this.validatedQueryString, + }; + }, + update({ project }) { + return project?.jobs?.count || 0; + }, + error() { + this.error = this.$options.i18n.jobsCountErrorMsg; }, }, }, @@ -60,11 +76,11 @@ export default { jobs: { list: [], }, - hasError: false, - isAlertDismissed: false, + error: '', scope: null, infiniteScrollingTriggered: false, filterSearchTriggered: false, + jobsCount: null, count: 0, }; }, @@ -72,9 +88,6 @@ export default { loading() { return this.$apollo.queries.jobs.loading; }, - shouldShowAlert() { - return this.hasError && !this.isAlertDismissed; - }, // Show when on All tab with no jobs // Show only when not loading and filtered search has not been triggered // So we don't show empty state when results are empty on a filtered search @@ -95,9 +108,6 @@ export default { showFilteredSearch() { return !this.scope; }, - jobsCount() { - return this.jobs.count; - }, validatedQueryString() { const queryStringObject = queryToObject(window.location.search); @@ -146,6 +156,7 @@ export default { }); this.$apollo.queries.jobs.refetch({ statuses: filter.value.data }); + this.$apollo.queries.jobsCount.refetch({ statuses: filter.value.data }); } }); }, @@ -168,14 +179,14 @@ export default { <template> <div> <gl-alert - v-if="shouldShowAlert" + v-if="error" class="gl-mt-2" variant="danger" data-testid="jobs-table-error-alert" dismissible - @dismiss="isAlertDismissed = true" + @dismiss="error = ''" > - {{ $options.i18n.errorMsg }} + {{ error }} </gl-alert> <jobs-table-tabs diff --git a/app/controllers/ide_controller.rb b/app/controllers/ide_controller.rb index b61e2318cea..1b3d9223502 100644 --- a/app/controllers/ide_controller.rb +++ b/app/controllers/ide_controller.rb @@ -39,6 +39,7 @@ class IdeController < ApplicationController @branch = params[:branch] @path = params[:path] @merge_request = params[:merge_request_id] + @learn_gitlab_source = params[:learn_gitlab_source] @fork_info = fork_info(project, @branch) end diff --git a/app/helpers/broadcast_messages_helper.rb b/app/helpers/broadcast_messages_helper.rb index 01d28ed3221..1c5a601de25 100644 --- a/app/helpers/broadcast_messages_helper.rb +++ b/app/helpers/broadcast_messages_helper.rb @@ -62,6 +62,23 @@ module BroadcastMessagesHelper end.join(', ') end + def admin_broadcast_messages_data(broadcast_messages) + broadcast_messages.map do |message| + { + id: message.id, + status: broadcast_message_status(message), + preview: broadcast_message(message, preview: true), + starts_at: message.starts_at.iso8601, + ends_at: message.ends_at.iso8601, + target_roles: target_access_levels_display(message.target_access_levels), + target_path: message.target_path, + type: message.broadcast_type.capitalize, + edit_path: edit_admin_broadcast_message_path(message), + delete_path: "#{admin_broadcast_message_path(message)}.js" + } + end.to_json + end + private def current_user_access_level_for_project_or_group diff --git a/app/helpers/ide_helper.rb b/app/helpers/ide_helper.rb index c5be044a27b..296fe6856ac 100644 --- a/app/helpers/ide_helper.rb +++ b/app/helpers/ide_helper.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module IdeHelper - def ide_data(project:, branch:, path:, merge_request:, fork_info:) + def ide_data(project:, branch:, path:, merge_request:, fork_info:, learn_gitlab_source:) { 'can-use-new-web-ide' => can_use_new_web_ide?.to_s, 'use-new-web-ide' => use_new_web_ide?.to_s, @@ -13,7 +13,8 @@ module IdeHelper 'editor-font-src-url' => font_url('jetbrains-mono/JetBrainsMono.woff2'), 'editor-font-family' => 'JetBrains Mono', 'editor-font-format' => 'woff2', - 'merge-request' => merge_request + 'merge-request' => merge_request, + 'learn-gitlab-source' => (!!learn_gitlab_source).to_s }.merge(use_new_web_ide? ? new_ide_data(project: project) : legacy_ide_data(project: project)) end diff --git a/app/models/onboarding/completion.rb b/app/models/onboarding/completion.rb index 269283df826..2d1cfc4e876 100644 --- a/app/models/onboarding/completion.rb +++ b/app/models/onboarding/completion.rb @@ -19,35 +19,51 @@ module Onboarding :user_added ].freeze - def initialize(namespace, current_user = nil) - @namespace = namespace + def initialize(project, current_user = nil) + @project = project + @namespace = project.namespace @current_user = current_user end def percentage return 0 unless onboarding_progress - attributes = onboarding_progress.attributes.symbolize_keys - total_actions = action_columns.count - completed_actions = action_columns.count { |column| attributes[column].present? } + completed_actions = action_columns.count { |column| completed?(column) } (completed_actions.to_f / total_actions * 100).round end + def completed?(column) + if column == :code_added + repository.commit_count > 1 || repository.branch_count > 1 + else + attributes[column].present? + end + end + private + def repository + project.repository + end + strong_memoize_attr :repository + + def attributes + onboarding_progress.attributes.symbolize_keys + end + strong_memoize_attr :attributes + def onboarding_progress - strong_memoize(:onboarding_progress) do - ::Onboarding::Progress.find_by(namespace: namespace) - end + ::Onboarding::Progress.find_by(namespace: namespace) end + strong_memoize_attr :onboarding_progress def action_columns - strong_memoize(:action_columns) do + [:code_added] + tracked_actions.map { |action_key| ::Onboarding::Progress.column_name(action_key) } - end end + strong_memoize_attr :action_columns def tracked_actions ACTION_ISSUE_IDS.keys + ACTION_PATHS + deploy_section_tracked_actions @@ -65,6 +81,6 @@ module Onboarding end.run end - attr_reader :namespace, :current_user + attr_reader :project, :namespace, :current_user end end diff --git a/app/views/admin/broadcast_messages/index.html.haml b/app/views/admin/broadcast_messages/index.html.haml index 2fb59570231..010cc493ddf 100644 --- a/app/views/admin/broadcast_messages/index.html.haml +++ b/app/views/admin/broadcast_messages/index.html.haml @@ -10,16 +10,4 @@ page: params[:page] || 1, target_access_level_options: target_access_level_options.to_json, messages_count: @broadcast_messages.total_count, - messages: @broadcast_messages.map { |message| { - id: message.id, - status: broadcast_message_status(message), - preview: broadcast_message(message, preview: true), - starts_at: message.starts_at.to_s, - ends_at: message.ends_at.to_s, - target_roles: target_access_levels_display(message.target_access_levels), - target_path: message.target_path, - type: message.broadcast_type.capitalize, - edit_path: edit_admin_broadcast_message_path(message), - delete_path: admin_broadcast_message_path(message) + '.js' - } }.to_json -} } + messages: admin_broadcast_messages_data(@broadcast_messages) } } diff --git a/app/views/ide/_show.html.haml b/app/views/ide/_show.html.haml index 5a6e93c3573..091d7e7a4f1 100644 --- a/app/views/ide/_show.html.haml +++ b/app/views/ide/_show.html.haml @@ -7,4 +7,11 @@ - content_for :prefetch_asset_tags do - webpack_preload_asset_tag('monaco') -= render partial: 'shared/ide_root', locals: { data: ide_data(project: @project, branch: @branch, path: @path, merge_request: @merge_request, fork_info: @fork_info), loading_text: _('Loading the GitLab IDE...') } +- data = ide_data(project: @project, + branch: @branch, + path: @path, + merge_request: @merge_request, + fork_info: @fork_info, + learn_gitlab_source: @learn_gitlab_source) + += render partial: 'shared/ide_root', locals: { data: data, loading_text: _('Loading the GitLab IDE...') } |