diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-04-20 15:20:09 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-04-20 15:20:09 +0000 |
commit | da23c5d563d68bfa5271b216209a7715c7ce3073 (patch) | |
tree | ea829aa79f715b98c440d6bf3767328b4fc4f750 /app/assets | |
parent | 2366f969a4b3a95e052e551cc7283a2db8d5562e (diff) | |
download | gitlab-ce-da23c5d563d68bfa5271b216209a7715c7ce3073.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets')
17 files changed, 286 insertions, 72 deletions
diff --git a/app/assets/javascripts/batch_comments/components/submit_dropdown.vue b/app/assets/javascripts/batch_comments/components/submit_dropdown.vue index 107796a31e0..9005c1b1220 100644 --- a/app/assets/javascripts/batch_comments/components/submit_dropdown.vue +++ b/app/assets/javascripts/batch_comments/components/submit_dropdown.vue @@ -1,6 +1,6 @@ <script> import { GlDropdown, GlButton, GlIcon, GlForm, GlFormGroup, GlFormCheckbox } from '@gitlab/ui'; -import { mapGetters, mapActions } from 'vuex'; +import { mapGetters, mapActions, mapState } from 'vuex'; import { createAlert } from '~/alert'; import MarkdownField from '~/vue_shared/components/markdown/field.vue'; import { scrollToElement } from '~/lib/utils/common_utils'; @@ -31,6 +31,7 @@ export default { }, computed: { ...mapGetters(['getNotesData', 'getNoteableData', 'noteableType', 'getCurrentUserLastNote']), + ...mapState('batchComments', ['shouldAnimateReviewButton']), }, watch: { 'noteData.approve': function noteDataApproveWatch() { @@ -101,6 +102,7 @@ export default { right dropup class="submit-review-dropdown" + :class="{ 'submit-review-dropdown-animated': shouldAnimateReviewButton }" data-qa-selector="submit_review_dropdown" variant="info" category="primary" diff --git a/app/assets/javascripts/batch_comments/stores/modules/batch_comments/mutations.js b/app/assets/javascripts/batch_comments/stores/modules/batch_comments/mutations.js index 384d7904ac7..7961cf134be 100644 --- a/app/assets/javascripts/batch_comments/stores/modules/batch_comments/mutations.js +++ b/app/assets/javascripts/batch_comments/stores/modules/batch_comments/mutations.js @@ -8,6 +8,9 @@ const processDraft = (draft) => ({ export default { [types.ADD_NEW_DRAFT](state, draft) { state.drafts.push(processDraft(draft)); + if (state.drafts.length === 1) { + state.shouldAnimateReviewButton = true; + } }, [types.DELETE_DRAFT](state, draftId) { diff --git a/app/assets/javascripts/batch_comments/stores/modules/batch_comments/state.js b/app/assets/javascripts/batch_comments/stores/modules/batch_comments/state.js index 6b97fc242c8..10033ba17f9 100644 --- a/app/assets/javascripts/batch_comments/stores/modules/batch_comments/state.js +++ b/app/assets/javascripts/batch_comments/stores/modules/batch_comments/state.js @@ -4,4 +4,5 @@ export default () => ({ drafts: [], isPublishing: false, currentlyPublishingDrafts: [], + shouldAnimateReviewButton: false, }); diff --git a/app/assets/javascripts/ci/pipeline_new/components/pipeline_new_form.vue b/app/assets/javascripts/ci/pipeline_new/components/pipeline_new_form.vue index 5337d0da80c..4c4c0ce24f2 100644 --- a/app/assets/javascripts/ci/pipeline_new/components/pipeline_new_form.vue +++ b/app/assets/javascripts/ci/pipeline_new/components/pipeline_new_form.vue @@ -424,7 +424,11 @@ export default { </details> </gl-alert> <gl-form-group :label="s__('Pipeline|Run for branch name or tag')"> - <refs-dropdown v-model="refValue" @loadingError="onRefsLoadingError" /> + <refs-dropdown + v-model="refValue" + :project-id="projectId" + @loadingError="onRefsLoadingError" + /> </gl-form-group> <gl-loading-icon v-if="isLoading" class="gl-mb-5" size="lg" /> diff --git a/app/assets/javascripts/ci/pipeline_new/components/refs_dropdown.vue b/app/assets/javascripts/ci/pipeline_new/components/refs_dropdown.vue index 060527f2662..9b57f135a40 100644 --- a/app/assets/javascripts/ci/pipeline_new/components/refs_dropdown.vue +++ b/app/assets/javascripts/ci/pipeline_new/components/refs_dropdown.vue @@ -1,86 +1,59 @@ <script> -import { GlCollapsibleListbox } from '@gitlab/ui'; -import { debounce } from 'lodash'; -import axios from '~/lib/utils/axios_utils'; -import { DEBOUNCE_REFS_SEARCH_MS } from '../constants'; -import { formatListBoxItems, searchByFullNameInListboxOptions } from '../utils/format_refs'; +import { __ } from '~/locale'; +import RefSelector from '~/ref/components/ref_selector.vue'; +import { BRANCH_REF_TYPE, REF_TYPE_BRANCHES, REF_TYPE_TAGS } from '~/ref/constants'; +import { formatToShortName } from '../utils/format_refs'; export default { + BRANCH_REF_TYPE, + ENABLED_TYPE_REFS: [REF_TYPE_BRANCHES, REF_TYPE_TAGS], + i18n: { + /** + * In order to hide ListBox header + * we need to explicitly provide + * empty string for translations + */ + dropdownHeader: '', + searchPlaceholder: __('Search refs'), + }, components: { - GlCollapsibleListbox, + RefSelector, }, - inject: ['projectRefsEndpoint'], props: { + projectId: { + type: String, + required: true, + }, value: { type: Object, required: false, default: () => ({}), }, }, - data() { - return { - isLoading: false, - searchTerm: '', - listBoxItems: [], - }; - }, computed: { - lowerCasedSearchTerm() { - return this.searchTerm.toLowerCase(); - }, refShortName() { return this.value.shortName; }, }, methods: { - loadRefs() { - this.isLoading = true; - - axios - .get(this.projectRefsEndpoint, { - params: { - search: this.lowerCasedSearchTerm, - }, - }) - .then(({ data }) => { - // Note: These keys are uppercase in API - const { Branches = [], Tags = [] } = data; - - this.listBoxItems = formatListBoxItems(Branches, Tags); - }) - .catch((e) => { - this.$emit('loadingError', e); - }) - .finally(() => { - this.isLoading = false; - }); - }, - debouncedLoadRefs: debounce(function debouncedLoadRefs() { - this.loadRefs(); - }, DEBOUNCE_REFS_SEARCH_MS), - setRefSelected(refFullName) { - const ref = searchByFullNameInListboxOptions(refFullName, this.listBoxItems); - this.$emit('input', ref); - }, - setSearchTerm(searchQuery) { - this.searchTerm = searchQuery?.trim(); - this.debouncedLoadRefs(); + setRefSelected(fullName) { + this.$emit('input', { + shortName: formatToShortName(fullName), + fullName, + }); }, }, }; </script> <template> - <gl-collapsible-listbox - class="gl-w-full gl-font-monospace" - :items="listBoxItems" - :searchable="true" - :searching="isLoading" - :search-placeholder="__('Search refs')" - :selected="value.fullName" - toggle-class="gl-flex-direction-column gl-align-items-stretch!" - :toggle-text="refShortName" - @search="setSearchTerm" - @select="setRefSelected" - @shown.once="loadRefs" + <ref-selector + :value="refShortName" + :enabled-ref-types="$options.ENABLED_TYPE_REFS" + :ref-type="$options.BRANCH_REF_TYPE" + :project-id="projectId" + :translations="$options.i18n" + :use-symbolic-ref-names="true" + toggle-button-class="gl-w-auto! gl-mb-0!" + @input="setRefSelected" /> </template> diff --git a/app/assets/javascripts/ci/pipeline_new/utils/format_refs.js b/app/assets/javascripts/ci/pipeline_new/utils/format_refs.js index e6d26b32d47..228702fbc71 100644 --- a/app/assets/javascripts/ci/pipeline_new/utils/format_refs.js +++ b/app/assets/javascripts/ci/pipeline_new/utils/format_refs.js @@ -5,6 +5,10 @@ function convertToListBoxItems(items) { return items.map(({ shortName, fullName }) => ({ text: shortName, value: fullName })); } +export function formatToShortName(ref) { + return ref.replace(/^refs\/(tags|heads)\//, ''); +} + export function formatRefs(refs, type) { let fullName; diff --git a/app/assets/javascripts/ci/runner/components/runner_create_form.vue b/app/assets/javascripts/ci/runner/components/runner_create_form.vue index d3e02f5cd6e..6107b4dd3ea 100644 --- a/app/assets/javascripts/ci/runner/components/runner_create_form.vue +++ b/app/assets/javascripts/ci/runner/components/runner_create_form.vue @@ -4,7 +4,13 @@ import RunnerFormFields from '~/ci/runner/components/runner_form_fields.vue'; import runnerCreateMutation from '~/ci/runner/graphql/new/runner_create.mutation.graphql'; import { modelToUpdateMutationVariables } from 'ee_else_ce/ci/runner/runner_update_form_utils'; import { captureException } from '../sentry_utils'; -import { RUNNER_TYPES, DEFAULT_ACCESS_LEVEL, GROUP_TYPE, INSTANCE_TYPE } from '../constants'; +import { + RUNNER_TYPES, + DEFAULT_ACCESS_LEVEL, + PROJECT_TYPE, + GROUP_TYPE, + INSTANCE_TYPE, +} from '../constants'; export default { name: 'RunnerCreateForm', @@ -24,6 +30,11 @@ export default { required: false, default: null, }, + projectId: { + type: String, + required: false, + default: null, + }, }, data() { return { @@ -50,6 +61,13 @@ export default { groupId: this.groupId, }; } + if (this.runnerType === PROJECT_TYPE) { + return { + ...input, + runnerType: PROJECT_TYPE, + projectId: this.projectId, + }; + } return { ...input, runnerType: INSTANCE_TYPE, diff --git a/app/assets/javascripts/ci/runner/project_new_runner/index.js b/app/assets/javascripts/ci/runner/project_new_runner/index.js new file mode 100644 index 00000000000..5236f28752a --- /dev/null +++ b/app/assets/javascripts/ci/runner/project_new_runner/index.js @@ -0,0 +1,33 @@ +import Vue from 'vue'; +import VueApollo from 'vue-apollo'; +import createDefaultClient from '~/lib/graphql'; +import ProjectNewRunnerApp from './project_new_runner_app.vue'; + +Vue.use(VueApollo); + +export const initProjectNewRunner = (selector = '#js-project-new-runner') => { + const el = document.querySelector(selector); + + if (!el) { + return null; + } + + const { legacyRegistrationToken, projectId } = el.dataset; + + const apolloProvider = new VueApollo({ + defaultClient: createDefaultClient(), + }); + + return new Vue({ + el, + apolloProvider, + render(h) { + return h(ProjectNewRunnerApp, { + props: { + projectId, + legacyRegistrationToken, + }, + }); + }, + }); +}; diff --git a/app/assets/javascripts/ci/runner/project_new_runner/project_new_runner_app.vue b/app/assets/javascripts/ci/runner/project_new_runner/project_new_runner_app.vue new file mode 100644 index 00000000000..94d3e949e86 --- /dev/null +++ b/app/assets/javascripts/ci/runner/project_new_runner/project_new_runner_app.vue @@ -0,0 +1,92 @@ +<script> +import { GlSprintf, GlLink, GlModalDirective } from '@gitlab/ui'; +import { createAlert, VARIANT_SUCCESS } from '~/alert'; +import { s__ } from '~/locale'; +import RunnerInstructionsModal from '~/vue_shared/components/runner_instructions/runner_instructions_modal.vue'; +import RunnerPlatformsRadioGroup from '~/ci/runner/components/runner_platforms_radio_group.vue'; +import RunnerCreateForm from '~/ci/runner/components/runner_create_form.vue'; +import { DEFAULT_PLATFORM, PROJECT_TYPE } from '../constants'; + +export default { + name: 'ProjectNewRunnerApp', + components: { + GlLink, + GlSprintf, + RunnerInstructionsModal, + RunnerPlatformsRadioGroup, + RunnerCreateForm, + }, + directives: { + GlModal: GlModalDirective, + }, + props: { + projectId: { + type: String, + required: true, + }, + legacyRegistrationToken: { + type: String, + required: true, + }, + }, + data() { + return { + platform: DEFAULT_PLATFORM, + }; + }, + methods: { + onSaved() { + createAlert({ + message: s__('Runners|Runner created.'), + variant: VARIANT_SUCCESS, + }); + }, + onError(error) { + createAlert({ message: error.message }); + }, + }, + modalId: 'runners-legacy-registration-instructions-modal', + PROJECT_TYPE, +}; +</script> + +<template> + <div> + <h1 class="gl-font-size-h2">{{ s__('Runners|New project runner') }}</h1> + <p> + <gl-sprintf + :message=" + s__( + 'Runners|Create a project runner to generate a command that registers the runner with all its configurations. %{linkStart}Prefer to use a registration token to create a runner?%{linkEnd}', + ) + " + > + <template #link="{ content }"> + <gl-link v-gl-modal="$options.modalId" data-testid="legacy-instructions-link">{{ + content + }}</gl-link> + <runner-instructions-modal + :modal-id="$options.modalId" + :registration-token="legacyRegistrationToken" + /> + </template> + </gl-sprintf> + </p> + + <hr aria-hidden="true" /> + + <h2 class="gl-font-weight-normal gl-font-lg gl-my-5"> + {{ s__('Runners|Platform') }} + </h2> + <runner-platforms-radio-group v-model="platform" /> + + <hr aria-hidden="true" /> + + <runner-create-form + :runner-type="$options.PROJECT_TYPE" + :project-id="projectId" + @saved="onSaved" + @error="onError" + /> + </div> +</template> diff --git a/app/assets/javascripts/entrypoints/tracker.js b/app/assets/javascripts/entrypoints/tracker.js new file mode 100644 index 00000000000..91d19d249b3 --- /dev/null +++ b/app/assets/javascripts/entrypoints/tracker.js @@ -0,0 +1,50 @@ +import { + newTracker, + enableActivityTracking, + trackPageView, + setDocumentTitle, + trackStructEvent, + setCustomUrl, + setReferrerUrl, +} from '@snowplow/browser-tracker'; +import { + enableLinkClickTracking, + LinkClickTrackingPlugin, +} from '@snowplow/browser-plugin-link-click-tracking'; +import { enableFormTracking, FormTrackingPlugin } from '@snowplow/browser-plugin-form-tracking'; +import { TimezonePlugin } from '@snowplow/browser-plugin-timezone'; +import { GaCookiesPlugin } from '@snowplow/browser-plugin-ga-cookies'; +import { PerformanceTimingPlugin } from '@snowplow/browser-plugin-performance-timing'; +import { ClientHintsPlugin } from '@snowplow/browser-plugin-client-hints'; + +const SNOWPLOW_ACTIONS = { + newTracker, + enableActivityTracking, + trackPageView, + setDocumentTitle, + trackStructEvent, + enableLinkClickTracking, + enableFormTracking, + setCustomUrl, + setReferrerUrl, +}; + +window.snowplow = (action, ...config) => { + if (SNOWPLOW_ACTIONS[action]) { + SNOWPLOW_ACTIONS[action](...config); + } else { + // eslint-disable-next-line no-console, @gitlab/require-i18n-strings + console.warn('Unsupported snowplow action:', action); + } +}; + +window.snowplowPlugins = [ + LinkClickTrackingPlugin(), + FormTrackingPlugin(), + TimezonePlugin(), + GaCookiesPlugin(), + PerformanceTimingPlugin(), + ClientHintsPlugin(), +]; + +export default {}; diff --git a/app/assets/javascripts/pages/projects/runners/new/index.js b/app/assets/javascripts/pages/projects/runners/new/index.js new file mode 100644 index 00000000000..e67de424496 --- /dev/null +++ b/app/assets/javascripts/pages/projects/runners/new/index.js @@ -0,0 +1,3 @@ +import { initProjectNewRunner } from '~/ci/runner/project_new_runner'; + +initProjectNewRunner(); diff --git a/app/assets/javascripts/super_sidebar/components/context_switcher_toggle.vue b/app/assets/javascripts/super_sidebar/components/context_switcher_toggle.vue index e56ef9e410b..704b087c534 100644 --- a/app/assets/javascripts/super_sidebar/components/context_switcher_toggle.vue +++ b/app/assets/javascripts/super_sidebar/components/context_switcher_toggle.vue @@ -38,7 +38,7 @@ export default { <button v-collapse-toggle.context-switcher type="button" - class="context-switcher-toggle gl-p-0 gl-bg-transparent gl-hover-bg-t-gray-a-08 gl-focus-bg-t-gray-a-08 gl-border-0 border-top border-bottom gl-border-gray-a-08 gl-box-shadow-none gl-display-flex gl-align-items-center gl-font-weight-bold gl-w-full gl-h-8" + class="context-switcher-toggle gl-p-0 gl-bg-transparent gl-hover-bg-t-gray-a-08 gl-focus-bg-t-gray-a-08 gl-border-0 border-top border-bottom gl-border-gray-a-08 gl-box-shadow-none gl-display-flex gl-align-items-center gl-font-weight-bold gl-w-full gl-h-8 gl-flex-shrink-0" > <span v-if="context.icon" diff --git a/app/assets/javascripts/super_sidebar/components/super_sidebar.vue b/app/assets/javascripts/super_sidebar/components/super_sidebar.vue index 4b54e317639..64460fdcb68 100644 --- a/app/assets/javascripts/super_sidebar/components/super_sidebar.vue +++ b/app/assets/javascripts/super_sidebar/components/super_sidebar.vue @@ -112,12 +112,12 @@ export default { </gl-button> <user-bar :has-collapse-button="!isPeek" :sidebar-data="sidebarData" /> <div class="gl-display-flex gl-flex-direction-column gl-flex-grow-1 gl-overflow-hidden"> + <context-switcher-toggle + :context="sidebarData.current_context_header" + :expanded="contextSwitcherOpen" + data-qa-selector="context_switcher" + /> <div class="gl-flex-grow-1 gl-overflow-auto"> - <context-switcher-toggle - :context="sidebarData.current_context_header" - :expanded="contextSwitcherOpen" - data-qa-selector="context_switcher" - /> <gl-collapse id="context-switcher" v-model="contextSwitcherOpen" diff --git a/app/assets/javascripts/tracking/constants.js b/app/assets/javascripts/tracking/constants.js index 7f4c7a91b20..968e866eedd 100644 --- a/app/assets/javascripts/tracking/constants.js +++ b/app/assets/javascripts/tracking/constants.js @@ -10,6 +10,7 @@ export const DEFAULT_SNOWPLOW_OPTIONS = { contexts: { webPage: true, performanceTiming: true }, formTracking: false, linkClickTracking: false, + plugins: window.snowplowPlugins || [], formTrackingConfig: { forms: { allow: [] }, fields: { allow: [] }, diff --git a/app/assets/javascripts/vue_merge_request_widget/extensions/code_quality/index.js b/app/assets/javascripts/vue_merge_request_widget/extensions/code_quality/index.js index 4f9bba1e0cb..713c9e610b3 100644 --- a/app/assets/javascripts/vue_merge_request_widget/extensions/code_quality/index.js +++ b/app/assets/javascripts/vue_merge_request_widget/extensions/code_quality/index.js @@ -63,7 +63,9 @@ export default { this.collapsedData.newErrors.map((e) => { return fullData.push({ - text: `${capitalizeFirstCharacter(e.severity)} - ${e.description}`, + text: e.check_name + ? `${capitalizeFirstCharacter(e.severity)} - ${e.check_name} - ${e.description}` + : `${capitalizeFirstCharacter(e.severity)} - ${e.description}`, subtext: { prependText: i18n.prependText, text: `${e.file_path}:${e.line}`, @@ -77,7 +79,9 @@ export default { this.collapsedData.resolvedErrors.map((e) => { return fullData.push({ - text: `${capitalizeFirstCharacter(e.severity)} - ${e.description}`, + text: e.check_name + ? `${capitalizeFirstCharacter(e.severity)} - ${e.check_name} - ${e.description}` + : `${capitalizeFirstCharacter(e.severity)} - ${e.description}`, subtext: { prependText: i18n.prependText, text: `${e.file_path}:${e.line}`, diff --git a/app/assets/stylesheets/page_bundles/merge_requests.scss b/app/assets/stylesheets/page_bundles/merge_requests.scss index 97df87458ab..d62dc2b2c5c 100644 --- a/app/assets/stylesheets/page_bundles/merge_requests.scss +++ b/app/assets/stylesheets/page_bundles/merge_requests.scss @@ -1039,6 +1039,25 @@ $tabs-holder-z-index: 250; } } +.submit-review-dropdown-animated { + animation: review-btn-animate 300ms ease-in; +} + +@include keyframes(review-btn-animate) { + 0% { + transform: scale(1); + } + + 75% { + transform: scale(1.2); + } + + 100% { + transform: scale(1); + } +} + + .mr-widget-merge-details { *, & { diff --git a/app/assets/stylesheets/page_bundles/tree.scss b/app/assets/stylesheets/page_bundles/tree.scss index a13b8704095..9d13ccc676d 100644 --- a/app/assets/stylesheets/page_bundles/tree.scss +++ b/app/assets/stylesheets/page_bundles/tree.scss @@ -219,3 +219,10 @@ width: calc(100% + 24px); margin: -28px -12px 0; } + +.ai-genie-chat-message { + pre, + code { + @include gl-font-sm; + } +} |