diff options
Diffstat (limited to 'app/assets/javascripts/projects')
12 files changed, 78 insertions, 48 deletions
diff --git a/app/assets/javascripts/projects/commit_box/info/components/commit_box_pipeline_mini_graph.vue b/app/assets/javascripts/projects/commit_box/info/components/commit_box_pipeline_mini_graph.vue index 9bd78b7c89e..1cdf26b76b7 100644 --- a/app/assets/javascripts/projects/commit_box/info/components/commit_box_pipeline_mini_graph.vue +++ b/app/assets/javascripts/projects/commit_box/info/components/commit_box_pipeline_mini_graph.vue @@ -43,7 +43,11 @@ export default { }, apollo: { pipeline: { + context() { + return getQueryHeaders(this.graphqlResourceEtag); + }, query: getLinkedPipelinesQuery, + pollInterval: COMMIT_BOX_POLL_INTERVAL, variables() { return { fullPath: this.fullPath, @@ -116,6 +120,7 @@ export default { }, mounted() { toggleQueryPollingByVisibility(this.$apollo.queries.pipelineStages); + toggleQueryPollingByVisibility(this.$apollo.queries.pipeline); }, }; </script> diff --git a/app/assets/javascripts/projects/commit_box/info/init_details_button.js b/app/assets/javascripts/projects/commit_box/info/init_details_button.js index 833e946af5c..bc2c16b9e83 100644 --- a/app/assets/javascripts/projects/commit_box/info/init_details_button.js +++ b/app/assets/javascripts/projects/commit_box/info/init_details_button.js @@ -1,9 +1,7 @@ -import $ from 'jquery'; - export const initDetailsButton = () => { - $('body').on('click', '.js-details-expand', function expand(e) { + document.querySelector('.commit-info').addEventListener('click', function expand(e) { e.preventDefault(); - $(this).next('.js-details-content').removeClass('hide'); - $(this).hide(); + this.querySelector('.js-details-content').classList.remove('hide'); + this.querySelector('.js-details-expand').classList.add('gl-display-none'); }); }; diff --git a/app/assets/javascripts/projects/commits/components/author_select.vue b/app/assets/javascripts/projects/commits/components/author_select.vue index 884ef732144..f85be67d4b3 100644 --- a/app/assets/javascripts/projects/commits/components/author_select.vue +++ b/app/assets/javascripts/projects/commits/components/author_select.vue @@ -110,7 +110,7 @@ export default { :text="dropdownText" :disabled="hasSearchParam" toggle-class="gl-py-3 gl-border-0" - class="w-100 mt-2 mt-sm-0" + class="w-100 gl-mt-3 mt-sm-0" > <gl-dropdown-section-header> {{ __('Search by author') }} diff --git a/app/assets/javascripts/projects/compare/components/app.vue b/app/assets/javascripts/projects/compare/components/app.vue index 3945bed9649..bda58091b97 100644 --- a/app/assets/javascripts/projects/compare/components/app.vue +++ b/app/assets/javascripts/projects/compare/components/app.vue @@ -121,27 +121,21 @@ export default { @selectRevision="onSelectRevision" /> </div> - <div class="gl-mt-6"> + <div class="gl-display-flex gl-mt-6 gl-gap-3"> <gl-button category="primary" variant="confirm" @click="onSubmit"> {{ s__('CompareRevisions|Compare') }} </gl-button> - <gl-button data-testid="swapRevisionsButton" class="btn btn-default" @click="onSwapRevision"> + <gl-button data-testid="swapRevisionsButton" @click="onSwapRevision"> {{ s__('CompareRevisions|Swap revisions') }} </gl-button> <gl-button v-if="projectMergeRequestPath" :href="projectMergeRequestPath" data-testid="projectMrButton" - class="btn btn-default gl-button" > {{ s__('CompareRevisions|View open merge request') }} </gl-button> - <gl-button - v-else-if="createMrPath" - :href="createMrPath" - data-testid="createMrButton" - class="btn btn-default gl-button" - > + <gl-button v-else-if="createMrPath" :href="createMrPath" data-testid="createMrButton"> {{ s__('CompareRevisions|Create merge request') }} </gl-button> </div> diff --git a/app/assets/javascripts/projects/new/components/app.vue b/app/assets/javascripts/projects/new/components/app.vue index 476d6466cbb..59ca393fe92 100644 --- a/app/assets/javascripts/projects/new/components/app.vue +++ b/app/assets/javascripts/projects/new/components/app.vue @@ -16,7 +16,7 @@ const PANELS = [ selector: '#blank-project-pane', title: s__('ProjectsNew|Create blank project'), description: s__( - 'ProjectsNew|Create a blank project to house your files, plan your work, and collaborate on code, among other things.', + 'ProjectsNew|Create a blank project to store your files, plan your work, and collaborate on code, among other things.', ), illustration: blankProjectIllustration, }, diff --git a/app/assets/javascripts/projects/new/components/new_project_url_select.vue b/app/assets/javascripts/projects/new/components/new_project_url_select.vue index 506f1ec5ffd..eccfb3d844c 100644 --- a/app/assets/javascripts/projects/new/components/new_project_url_select.vue +++ b/app/assets/javascripts/projects/new/components/new_project_url_select.vue @@ -7,6 +7,7 @@ import { GlDropdownText, GlDropdownSectionHeader, GlSearchBoxByType, + GlTruncate, } from '@gitlab/ui'; import { joinPaths, PATH_SEPARATOR } from '~/lib/utils/url_utility'; import { MINIMUM_SEARCH_LENGTH } from '~/graphql_shared/constants'; @@ -26,6 +27,7 @@ export default { GlDropdownText, GlDropdownSectionHeader, GlSearchBoxByType, + GlTruncate, }, mixins: [Tracking.mixin()], apollo: { @@ -55,10 +57,7 @@ export default { id: this.namespaceId, fullPath: this.namespaceFullPath, } - : { - id: undefined, - fullPath: s__('ProjectsNew|Pick a group or namespace'), - }, + : this.$options.emptyNameSpace, shouldSkipQuery: true, userNamespaceId: this.userNamespaceId, }; @@ -118,12 +117,18 @@ export default { this.setNamespace({ id, fullPath }); }, setNamespace({ id, fullPath }) { - this.selectedNamespace = { - id: getIdFromGraphQLId(id), - fullPath, - }; + this.selectedNamespace = id + ? { + id: getIdFromGraphQLId(id), + fullPath, + } + : this.$options.emptyNameSpace; }, }, + emptyNameSpace: { + id: undefined, + fullPath: s__('ProjectsNew|Pick a group or namespace'), + }, }; </script> @@ -137,13 +142,20 @@ export default { > <gl-dropdown - :text="selectedNamespace.fullPath" class="js-group-namespace-dropdown gl-flex-grow-1" :toggle-class="`gl-rounded-top-right-base! gl-rounded-bottom-right-base! gl-w-20 ${dropdownPlaceholderClass}`" data-qa-selector="select_namespace_dropdown" @show="track('activate_form_input', { label: trackLabel, property: 'project_path' })" @shown="handleDropdownShown" > + <template #button-text> + <gl-truncate + v-if="selectedNamespace.fullPath" + :text="selectedNamespace.fullPath" + position="start" + with-tooltip + /> + </template> <gl-search-box-by-type ref="search" v-model.trim="search" diff --git a/app/assets/javascripts/projects/pipelines/charts/components/app.vue b/app/assets/javascripts/projects/pipelines/charts/components/app.vue index 35e7554aee2..186fcf70838 100644 --- a/app/assets/javascripts/projects/pipelines/charts/components/app.vue +++ b/app/assets/javascripts/projects/pipelines/charts/components/app.vue @@ -14,12 +14,15 @@ export default { LeadTimeCharts: () => import('ee_component/dora/components/lead_time_charts.vue'), TimeToRestoreServiceCharts: () => import('ee_component/dora/components/time_to_restore_service_charts.vue'), + ChangeFailureRateCharts: () => + import('ee_component/dora/components/change_failure_rate_charts.vue'), ProjectQualitySummary: () => import('ee_component/project_quality_summary/app.vue'), }, piplelinesTabEvent: 'p_analytics_ci_cd_pipelines', deploymentFrequencyTabEvent: 'p_analytics_ci_cd_deployment_frequency', leadTimeTabEvent: 'p_analytics_ci_cd_lead_time', timeToRestoreServiceTabEvent: 'p_analytics_ci_cd_time_to_restore_service', + changeFailureRateTabEvent: 'p_analytics_ci_cd_change_failure_rate', inject: { shouldRenderDoraCharts: { type: Boolean, @@ -40,7 +43,12 @@ export default { const chartsToShow = ['pipelines']; if (this.shouldRenderDoraCharts) { - chartsToShow.push('deployment-frequency', 'lead-time', 'time-to-restore-service'); + chartsToShow.push( + 'deployment-frequency', + 'lead-time', + 'time-to-restore-service', + 'change-failure-rate', + ); } if (this.shouldRenderQualitySummary) { @@ -105,6 +113,13 @@ export default { > <time-to-restore-service-charts /> </gl-tab> + <gl-tab + :title="s__('DORA4Metrics|Change failure rate')" + data-testid="change-failure-rate-tab" + @click="trackTabClick($options.changeFailureRateTabEvent)" + > + <change-failure-rate-charts /> + </gl-tab> </template> <gl-tab v-if="shouldRenderQualitySummary" :title="s__('QualitySummary|Project quality')"> <project-quality-summary /> diff --git a/app/assets/javascripts/projects/project_new.js b/app/assets/javascripts/projects/project_new.js index 186946a83ad..fe84660422b 100644 --- a/app/assets/javascripts/projects/project_new.js +++ b/app/assets/javascripts/projects/project_new.js @@ -342,6 +342,7 @@ const bindEvents = () => { export default { bindEvents, + validateGroupNamespaceDropdown, deriveProjectPathFromUrl, onProjectNameChange, onProjectPathChange, diff --git a/app/assets/javascripts/projects/project_visibility.js b/app/assets/javascripts/projects/project_visibility.js index d299e106b14..b8ac17a01f2 100644 --- a/app/assets/javascripts/projects/project_visibility.js +++ b/app/assets/javascripts/projects/project_visibility.js @@ -10,7 +10,7 @@ const visibilityLevel = { }; function setVisibilityOptions({ name, visibility, showPath, editPath }) { - document.querySelectorAll('.visibility-level-setting .form-check').forEach((option) => { + document.querySelectorAll('.visibility-level-setting .gl-form-radio').forEach((option) => { // Don't change anything if the option is restricted by admin if (option.classList.contains('restricted')) { return; @@ -24,7 +24,7 @@ function setVisibilityOptions({ name, visibility, showPath, editPath }) { optionInput.disabled = true; const reason = option.querySelector('.option-disabled-reason'); if (reason) { - const optionTitle = option.querySelector('.option-title'); + const optionTitle = option.querySelector('.js-visibility-level-radio span'); const optionName = optionTitle ? optionTitle.innerText.toLowerCase() : ''; reason.innerHTML = sprintf( __( diff --git a/app/assets/javascripts/projects/settings/access_dropdown.js b/app/assets/javascripts/projects/settings/access_dropdown.js index 79dfa166b1a..060178a3cfb 100644 --- a/app/assets/javascripts/projects/settings/access_dropdown.js +++ b/app/assets/javascripts/projects/settings/access_dropdown.js @@ -441,11 +441,13 @@ export default class AccessDropdown { const { id, fingerprint, + fingerprint_sha256: fingerprintSha256, title, owner: { avatar_url, name, username }, } = response; - const shortFingerprint = `(${fingerprint.substring(0, 14)}...)`; + const availableFingerprint = fingerprintSha256 || fingerprint; + const shortFingerprint = `(${availableFingerprint.substring(0, 14)}...)`; return { id, diff --git a/app/assets/javascripts/projects/settings/components/access_dropdown.vue b/app/assets/javascripts/projects/settings/components/access_dropdown.vue index 9823b0229a0..fcf81c9d1f7 100644 --- a/app/assets/javascripts/projects/settings/components/access_dropdown.vue +++ b/app/assets/javascripts/projects/settings/components/access_dropdown.vue @@ -203,11 +203,13 @@ export default { const { id, fingerprint, + fingerprint_sha256: fingerprintSha256, title, owner: { avatar_url, name, username }, } = response; - const shortFingerprint = `(${fingerprint.substring(0, 14)}...)`; + const availableFingerprint = fingerprintSha256 || fingerprint; + const shortFingerprint = `(${availableFingerprint.substring(0, 14)}...)`; return { id, @@ -351,7 +353,6 @@ export default { <gl-dropdown-item v-for="group in groups" :key="`${group.id}${group.name}`" - fingerprint data-testid="group-dropdown-item" :avatar-url="group.avatar_url" is-check-item @@ -388,7 +389,7 @@ export default { }}</gl-dropdown-section-header> <gl-dropdown-item v-for="key in deployKeys" - :key="`${key.id}${key.fingerprint}`" + :key="`${key.id}-{key.title}`" data-testid="deploy_key-dropdown-item" is-check-item :is-checked="isSelected(key)" diff --git a/app/assets/javascripts/projects/star.js b/app/assets/javascripts/projects/star.js index 578e22ca25d..5bbace11b15 100644 --- a/app/assets/javascripts/projects/star.js +++ b/app/assets/javascripts/projects/star.js @@ -1,31 +1,33 @@ -import $ from 'jquery'; import createFlash from '~/flash'; import axios from '~/lib/utils/axios_utils'; import { spriteIcon } from '~/lib/utils/common_utils'; import { __, s__ } from '~/locale'; export default class Star { - constructor(container = '.project-home-panel') { - $(`${container} .toggle-star`).on('click', function toggleStarClickCallback() { - const $this = $(this); - const $starSpan = $this.find('span'); - const $starIcon = $this.find('svg'); - const iconClasses = $starIcon.attr('class').split(' '); + constructor(containerSelector = '.project-home-panel') { + const container = document.querySelector(containerSelector); + const starToggle = container.querySelector('.toggle-star'); + starToggle.addEventListener('click', function toggleStarClickCallback() { + const starSpan = starToggle.querySelector('span'); + const starIcon = starToggle.querySelector('svg'); + const iconClasses = Array.from(starIcon.classList.values()); axios - .post($this.data('endpoint')) + .post(starToggle.dataset.endpoint) .then(({ data }) => { - const isStarred = $starSpan.hasClass('starred'); - $this.parent().find('.count').text(data.star_count); + const isStarred = starSpan.classList.contains('starred'); + starToggle.parentNode.querySelector('.count').textContent = data.star_count; if (isStarred) { - $starSpan.removeClass('starred').text(s__('StarProject|Star')); - $starIcon.remove(); - $this.prepend(spriteIcon('star-o', iconClasses)); + starSpan.classList.remove('starred'); + starSpan.textContent = s__('StarProject|Star'); + starIcon.remove(); + starSpan.insertAdjacentHTML('beforebegin', spriteIcon('star-o', iconClasses)); } else { - $starSpan.addClass('starred').text(__('Unstar')); - $starIcon.remove(); - $this.prepend(spriteIcon('star', iconClasses)); + starSpan.classList.add('starred'); + starSpan.textContent = __('Unstar'); + starIcon.remove(); + starSpan.insertAdjacentHTML('beforebegin', spriteIcon('star', iconClasses)); } }) .catch(() => |