Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
731d58455c
commit
93e4425400
39 changed files with 246 additions and 127 deletions
|
@ -30,6 +30,7 @@ const Api = {
|
|||
projectProtectedBranchesPath: '/api/:version/projects/:id/protected_branches',
|
||||
projectSearchPath: '/api/:version/projects/:id/search',
|
||||
projectMilestonesPath: '/api/:version/projects/:id/milestones',
|
||||
projectIssuePath: '/api/:version/projects/:id/issues/:issue_iid',
|
||||
mergeRequestsPath: '/api/:version/merge_requests',
|
||||
groupLabelsPath: '/groups/:namespace_path/-/labels',
|
||||
issuableTemplatePath: '/:namespace_path/:project_path/templates/:type/:key',
|
||||
|
@ -328,6 +329,14 @@ const Api = {
|
|||
});
|
||||
},
|
||||
|
||||
addProjectIssueAsTodo(projectId, issueIid) {
|
||||
const url = Api.buildUrl(Api.projectIssuePath)
|
||||
.replace(':id', encodeURIComponent(projectId))
|
||||
.replace(':issue_iid', encodeURIComponent(issueIid));
|
||||
|
||||
return axios.post(`${url}/todo`);
|
||||
},
|
||||
|
||||
mergeRequests(params = {}) {
|
||||
const url = Api.buildUrl(Api.mergeRequestsPath);
|
||||
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
<script>
|
||||
import { GlModal, GlSprintf, GlLink, GlButton } from '@gitlab/ui';
|
||||
import Cookies from 'js-cookie';
|
||||
import { sprintf, s__, __ } from '~/locale';
|
||||
import { glEmojiTag } from '~/emoji';
|
||||
import { s__ } from '~/locale';
|
||||
import Tracking from '~/tracking';
|
||||
|
||||
const trackingMixin = Tracking.mixin();
|
||||
|
@ -12,21 +11,6 @@ export default {
|
|||
'https://about.gitlab.com/blog/2018/01/22/a-beginners-guide-to-continuous-integration/',
|
||||
exampleLink: 'https://docs.gitlab.com/ee/ci/examples/',
|
||||
codeQualityLink: 'https://docs.gitlab.com/ee/user/project/merge_requests/code_quality.html',
|
||||
bodyMessage: s__(
|
||||
`MR widget|The pipeline will test your code on every commit. A %{codeQualityLinkStart}code quality report%{codeQualityLinkEnd} will appear in your merge requests to warn you about potential code degradations.`,
|
||||
),
|
||||
helpMessage: s__(
|
||||
`MR widget|Take a look at our %{beginnerLinkStart}Beginner's Guide to Continuous Integration%{beginnerLinkEnd} and our %{exampleLinkStart}examples of GitLab CI/CD%{exampleLinkEnd} to learn more.`,
|
||||
),
|
||||
pipelinesButton: s__('MR widget|See your pipeline in action'),
|
||||
mergeRequestButton: s__('MR widget|Back to the Merge request'),
|
||||
modalTitle: sprintf(
|
||||
__("That's it, well done!%{celebrate}"),
|
||||
{
|
||||
celebrate: glEmojiTag('tada'),
|
||||
},
|
||||
false,
|
||||
),
|
||||
goToTrackValuePipelines: 10,
|
||||
goToTrackValueMergeRequest: 20,
|
||||
trackEvent: 'click_button',
|
||||
|
@ -78,6 +62,17 @@ export default {
|
|||
return '';
|
||||
},
|
||||
},
|
||||
i18n: {
|
||||
modalTitle: s__("That's it, well done!"),
|
||||
pipelinesButton: s__('MR widget|See your pipeline in action'),
|
||||
mergeRequestButton: s__('MR widget|Back to the Merge request'),
|
||||
bodyMessage: s__(
|
||||
`MR widget|The pipeline will test your code on every commit. A %{codeQualityLinkStart}code quality report%{codeQualityLinkEnd} will appear in your merge requests to warn you about potential code degradations.`,
|
||||
),
|
||||
helpMessage: s__(
|
||||
`MR widget|Take a look at our %{beginnerLinkStart}Beginner's Guide to Continuous Integration%{beginnerLinkEnd} and our %{exampleLinkStart}examples of GitLab CI/CD%{exampleLinkEnd} to learn more.`,
|
||||
),
|
||||
},
|
||||
mounted() {
|
||||
this.track();
|
||||
this.disableModalFromRenderingAgain();
|
||||
|
@ -90,14 +85,13 @@ export default {
|
|||
};
|
||||
</script>
|
||||
<template>
|
||||
<gl-modal
|
||||
visible
|
||||
size="sm"
|
||||
:title="$options.modalTitle"
|
||||
modal-id="success-pipeline-modal-id-not-used"
|
||||
>
|
||||
<gl-modal visible size="sm" modal-id="success-pipeline-modal-id-not-used">
|
||||
<template #modal-title>
|
||||
{{ $options.i18n.modalTitle }}
|
||||
<gl-emoji class="gl-vertical-align-baseline font-size-inherit gl-mr-1" data-name="tada" />
|
||||
</template>
|
||||
<p>
|
||||
<gl-sprintf :message="$options.bodyMessage">
|
||||
<gl-sprintf :message="$options.i18n.bodyMessage">
|
||||
<template #codeQualityLink="{content}">
|
||||
<gl-link :href="$options.codeQualityLink" target="_blank" class="font-size-inherit">{{
|
||||
content
|
||||
|
@ -105,7 +99,7 @@ export default {
|
|||
</template>
|
||||
</gl-sprintf>
|
||||
</p>
|
||||
<gl-sprintf :message="$options.helpMessage">
|
||||
<gl-sprintf :message="$options.i18n.helpMessage">
|
||||
<template #beginnerLink="{content}">
|
||||
<gl-link :href="$options.beginnerLink" target="_blank">
|
||||
{{ content }}
|
||||
|
@ -127,7 +121,7 @@ export default {
|
|||
:data-track-event="$options.trackEvent"
|
||||
:data-track-label="trackLabel"
|
||||
>
|
||||
{{ $options.mergeRequestButton }}
|
||||
{{ $options.i18n.mergeRequestButton }}
|
||||
</gl-button>
|
||||
<gl-button
|
||||
ref="goToPipelines"
|
||||
|
@ -138,7 +132,7 @@ export default {
|
|||
:data-track-event="$options.trackEvent"
|
||||
:data-track-label="trackLabel"
|
||||
>
|
||||
{{ $options.pipelinesButton }}
|
||||
{{ $options.i18n.pipelinesButton }}
|
||||
</gl-button>
|
||||
</template>
|
||||
</gl-modal>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import $ from 'jquery';
|
||||
import Vue from 'vue';
|
||||
import { mapActions, mapState } from 'vuex';
|
||||
import { GlTooltip, GlButton } from '@gitlab/ui';
|
||||
|
||||
import 'ee_else_ce/boards/models/issue';
|
||||
import 'ee_else_ce/boards/models/list';
|
||||
|
@ -299,6 +299,10 @@ export default () => {
|
|||
// eslint-disable-next-line no-new
|
||||
new Vue({
|
||||
el: issueBoardsModal,
|
||||
components: {
|
||||
GlTooltip,
|
||||
GlButton,
|
||||
},
|
||||
mixins: [modalMixin],
|
||||
data() {
|
||||
return {
|
||||
|
@ -323,26 +327,7 @@ export default () => {
|
|||
return '';
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
disabled() {
|
||||
this.updateTooltip();
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.updateTooltip();
|
||||
},
|
||||
methods: {
|
||||
updateTooltip() {
|
||||
const $tooltip = $(this.$refs.addIssuesButton);
|
||||
|
||||
this.$nextTick(() => {
|
||||
if (this.disabled) {
|
||||
$tooltip.tooltip();
|
||||
} else {
|
||||
$tooltip.tooltip('dispose');
|
||||
}
|
||||
});
|
||||
},
|
||||
openModal() {
|
||||
if (!this.disabled) {
|
||||
this.toggleModal(true);
|
||||
|
@ -351,20 +336,25 @@ export default () => {
|
|||
},
|
||||
template: `
|
||||
<div class="board-extra-actions">
|
||||
<button
|
||||
class="btn btn-success gl-ml-3"
|
||||
type="button"
|
||||
data-placement="bottom"
|
||||
data-track-event="click_button"
|
||||
data-track-label="board_add_issues"
|
||||
ref="addIssuesButton"
|
||||
:class="{ 'disabled': disabled }"
|
||||
:title="tooltipTitle"
|
||||
:aria-disabled="disabled"
|
||||
v-if="canAdminList"
|
||||
@click="openModal">
|
||||
Add issues
|
||||
</button>
|
||||
<span ref="addIssuesButtonTooltip" class="gl-ml-3">
|
||||
<gl-button
|
||||
type="button"
|
||||
data-placement="bottom"
|
||||
data-track-event="click_button"
|
||||
data-track-label="board_add_issues"
|
||||
:disabled="disabled"
|
||||
:aria-disabled="disabled"
|
||||
v-if="canAdminList"
|
||||
@click="openModal">
|
||||
Add issues
|
||||
</button>
|
||||
</span>
|
||||
<gl-tooltip
|
||||
v-if="disabled"
|
||||
:target="() => $refs.addIssuesButtonTooltip"
|
||||
placement="bottom">
|
||||
{{tooltipTitle}}
|
||||
</gl-tooltip>
|
||||
</div>
|
||||
`,
|
||||
});
|
||||
|
|
|
@ -26,10 +26,10 @@ export default {
|
|||
},
|
||||
inject: {
|
||||
strategyTypeDocsPagePath: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
environmentsScopeDocsPath: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
props: {
|
||||
|
|
5
app/assets/javascripts/issuable_show/constants.js
Normal file
5
app/assets/javascripts/issuable_show/constants.js
Normal file
|
@ -0,0 +1,5 @@
|
|||
export const IssuableType = {
|
||||
Issue: 'issue',
|
||||
Incident: 'incident',
|
||||
TestCase: 'test_case',
|
||||
};
|
|
@ -744,6 +744,21 @@ export const differenceInSeconds = (startDate, endDate) => {
|
|||
return (endDate.getTime() - startDate.getTime()) / 1000;
|
||||
};
|
||||
|
||||
/**
|
||||
* A utility function which computes the difference in months
|
||||
* between 2 dates.
|
||||
*
|
||||
* @param {Date} startDate the start date
|
||||
* @param {Date} endDate the end date
|
||||
*
|
||||
* @return {Int} the difference in months
|
||||
*/
|
||||
export const differenceInMonths = (startDate, endDate) => {
|
||||
const yearDiff = endDate.getYear() - startDate.getYear();
|
||||
const monthDiff = endDate.getMonth() - startDate.getMonth();
|
||||
return monthDiff + 12 * yearDiff;
|
||||
};
|
||||
|
||||
/**
|
||||
* A utility function which computes the difference in milliseconds
|
||||
* between 2 dates.
|
||||
|
|
|
@ -14,13 +14,20 @@ import { parseIssuableData } from '~/issue_show/utils/parse_data';
|
|||
import initInviteMemberTrigger from '~/invite_member/init_invite_member_trigger';
|
||||
import initInviteMemberModal from '~/invite_member/init_invite_member_modal';
|
||||
|
||||
import { IssuableType } from '~/issuable_show/constants';
|
||||
|
||||
export default function() {
|
||||
const { issueType, ...issuableData } = parseIssuableData();
|
||||
|
||||
if (issueType === 'incident') {
|
||||
initIncidentApp(issuableData);
|
||||
} else if (issueType === 'issue') {
|
||||
initIssueApp(issuableData);
|
||||
switch (issueType) {
|
||||
case IssuableType.Incident:
|
||||
initIncidentApp(issuableData);
|
||||
break;
|
||||
case IssuableType.Issue:
|
||||
initIssueApp(issuableData);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
initIssuableHeaderWarning(store);
|
||||
|
@ -31,12 +38,14 @@ export default function() {
|
|||
.then(module => module.default())
|
||||
.catch(() => {});
|
||||
|
||||
new Issue(); // eslint-disable-line no-new
|
||||
new ShortcutsIssuable(); // eslint-disable-line no-new
|
||||
new ZenMode(); // eslint-disable-line no-new
|
||||
initIssuableSidebar();
|
||||
|
||||
loadAwardsHandler();
|
||||
initInviteMemberModal();
|
||||
initInviteMemberTrigger();
|
||||
if (issueType !== IssuableType.TestCase) {
|
||||
new Issue(); // eslint-disable-line no-new
|
||||
new ShortcutsIssuable(); // eslint-disable-line no-new
|
||||
initIssuableSidebar();
|
||||
loadAwardsHandler();
|
||||
initInviteMemberModal();
|
||||
initInviteMemberTrigger();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
<script>
|
||||
import { GlIcon, GlSprintf } from '@gitlab/ui';
|
||||
import tooltip from '../../vue_shared/directives/tooltip';
|
||||
import { GlIcon, GlSprintf, GlTooltipDirective } from '@gitlab/ui';
|
||||
import { __ } from '../../locale';
|
||||
|
||||
export default {
|
||||
|
@ -13,7 +12,7 @@ export default {
|
|||
GlSprintf,
|
||||
},
|
||||
directives: {
|
||||
tooltip,
|
||||
GlTooltip: GlTooltipDirective,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
@ -28,7 +27,7 @@ export default {
|
|||
</gl-sprintf>
|
||||
</span>
|
||||
<gl-icon
|
||||
v-tooltip
|
||||
v-gl-tooltip.hover
|
||||
:title="$options.i18n.tooltipTitle"
|
||||
:aria-label="$options.i18n.tooltipTitle"
|
||||
name="question-o"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<script>
|
||||
/* eslint-disable vue/no-v-html */
|
||||
import { groupBy } from 'lodash';
|
||||
import { GlIcon } from '@gitlab/ui';
|
||||
import { GlIcon, GlLoadingIcon } from '@gitlab/ui';
|
||||
import tooltip from '~/vue_shared/directives/tooltip';
|
||||
import { glEmojiTag } from '../../emoji';
|
||||
import { __, sprintf } from '~/locale';
|
||||
|
@ -12,6 +12,7 @@ const NO_USER_ID = -1;
|
|||
export default {
|
||||
components: {
|
||||
GlIcon,
|
||||
GlLoadingIcon,
|
||||
},
|
||||
directives: {
|
||||
tooltip,
|
||||
|
@ -184,10 +185,7 @@ export default {
|
|||
<span class="award-control-icon award-control-icon-super-positive">
|
||||
<gl-icon aria-hidden="true" name="smiley" />
|
||||
</span>
|
||||
<i
|
||||
aria-hidden="true"
|
||||
class="fa fa-spinner fa-spin award-control-icon award-control-icon-loading"
|
||||
></i>
|
||||
<gl-loading-icon size="md" color="dark" class="award-control-icon-loading" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -125,10 +125,6 @@
|
|||
content: '\f077';
|
||||
}
|
||||
|
||||
.fa-file-text-o::before {
|
||||
content: '\f0f6';
|
||||
}
|
||||
|
||||
.fa-github::before {
|
||||
content: '\f09b';
|
||||
}
|
||||
|
@ -153,10 +149,6 @@
|
|||
content: '\f0f3';
|
||||
}
|
||||
|
||||
.fa-bitbucket-square::before {
|
||||
content: '\f172';
|
||||
}
|
||||
|
||||
.fa-file-o::before {
|
||||
content: '\f016';
|
||||
}
|
||||
|
@ -169,10 +161,6 @@
|
|||
content: '\f111';
|
||||
}
|
||||
|
||||
.fa-bitbucket::before {
|
||||
content: '\f171';
|
||||
}
|
||||
|
||||
.fa-git::before {
|
||||
content: '\f1d3';
|
||||
}
|
||||
|
|
|
@ -41,15 +41,11 @@ module ChatMessage
|
|||
private
|
||||
|
||||
def message
|
||||
if opened_issue?
|
||||
"[#{project_link}] Issue #{state} by #{user_combined_name}"
|
||||
else
|
||||
"[#{project_link}] Issue #{issue_link} #{state} by #{user_combined_name}"
|
||||
end
|
||||
"[#{project_link}] Issue #{issue_link} #{state} by #{user_combined_name}"
|
||||
end
|
||||
|
||||
def opened_issue?
|
||||
action == "open"
|
||||
action == 'open'
|
||||
end
|
||||
|
||||
def description_message
|
||||
|
@ -57,7 +53,7 @@ module ChatMessage
|
|||
title: issue_title,
|
||||
title_link: issue_url,
|
||||
text: format(description),
|
||||
color: "#C95823"
|
||||
color: '#C95823'
|
||||
}]
|
||||
end
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ module Spam
|
|||
attr_reader :user, :context
|
||||
|
||||
def allowlisted?(user)
|
||||
user.try(:gitlab_employee?) || user.try(:gitlab_bot?)
|
||||
user.try(:gitlab_employee?) || user.try(:gitlab_bot?) || user.try(:gitlab_service_user?)
|
||||
end
|
||||
|
||||
def perform_spam_service_check(api)
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
- page_title _('Bitbucket import')
|
||||
- header_title _('Projects'), root_path
|
||||
|
||||
%h3.page-title
|
||||
%i.fa.fa-bitbucket
|
||||
%h3.page-title.d-flex
|
||||
.gl-display-flex.gl-align-items-center.gl-justify-content-center
|
||||
= sprite_icon('bitbucket', css_class: 'gl-mr-2')
|
||||
= _('Import projects from Bitbucket')
|
||||
|
||||
= render 'import/githubish_status', provider: 'bitbucket'
|
||||
|
|
|
@ -3,8 +3,10 @@
|
|||
- breadcrumb_title title
|
||||
- header_title _("Projects"), root_path
|
||||
|
||||
%h3.page-title
|
||||
= icon 'bitbucket-square', text: _('Import repositories from Bitbucket Server')
|
||||
%h3.page-title.d-flex
|
||||
.gl-display-flex.gl-align-items-center.gl-justify-content-center
|
||||
= sprite_icon('bitbucket', css_class: 'gl-mr-2')
|
||||
= _('Import repositories from Bitbucket Server')
|
||||
|
||||
%p
|
||||
= _('Enter in your Bitbucket Server URL and personal access token below')
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
- page_title _('Bitbucket Server import')
|
||||
- header_title _('Projects'), root_path
|
||||
|
||||
%h3.page-title
|
||||
%i.fa.fa-bitbucket-square
|
||||
%h3.page-title.d-flex
|
||||
.gl-display-flex.gl-align-items-center.gl-justify-content-center
|
||||
= sprite_icon('bitbucket', css_class: 'gl-mr-2')
|
||||
= _('Import projects from Bitbucket Server')
|
||||
|
||||
= render 'import/githubish_status', provider: 'bitbucket_server', paginatable: true, extra_data: { reconfigure_path: configure_import_bitbucket_server_path }
|
||||
|
|
|
@ -21,13 +21,15 @@
|
|||
%div
|
||||
= link_to status_import_bitbucket_path, class: "btn import_bitbucket #{'how_to_import_link' unless bitbucket_import_configured?}",
|
||||
**tracking_attrs(track_label, 'click_button', 'bitbucket_cloud') do
|
||||
= icon('bitbucket', text: 'Bitbucket Cloud')
|
||||
= sprite_icon('bitbucket')
|
||||
Bitbucket Cloud
|
||||
- unless bitbucket_import_configured?
|
||||
= render 'projects/bitbucket_import_modal'
|
||||
- if bitbucket_server_import_enabled?
|
||||
%div
|
||||
= link_to status_import_bitbucket_server_path, class: "btn import_bitbucket", **tracking_attrs(track_label, 'click_button', 'bitbucket_server') do
|
||||
= icon('bitbucket-square', text: 'Bitbucket Server')
|
||||
= sprite_icon('bitbucket')
|
||||
Bitbucket Server
|
||||
%div
|
||||
- if gitlab_import_enabled?
|
||||
%div
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
.file-holder
|
||||
.js-file-title.file-title{ data: { qa_selector: 'file_title_content' } }
|
||||
= link_to blob_link, data: {track_event: 'click_text', track_label: 'blob_path', track_property: 'search_result'} do
|
||||
%i.fa.fa-file
|
||||
= sprite_icon('document')
|
||||
%strong
|
||||
= search_blob_title(project, path)
|
||||
- if blob.data
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Migrate '.fa-spinner' to '.spinner' for 'awards_list.vue'
|
||||
merge_request: 45393
|
||||
author:
|
||||
type: changed
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Replace fa-file icons with GitLab SVG document icon
|
||||
merge_request: 45380
|
||||
author:
|
||||
type: changed
|
5
changelogs/unreleased/Add-Issue-Link-to-Open-Message.yml
Normal file
5
changelogs/unreleased/Add-Issue-Link-to-Open-Message.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Add Issue Link to "Issue opened by" Integration Chat Message
|
||||
merge_request: 42785
|
||||
author: Kev @KevSlashNull
|
||||
type: changed
|
5
changelogs/unreleased/mw-replace-fa-bitbucket-icons.yml
Normal file
5
changelogs/unreleased/mw-replace-fa-bitbucket-icons.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Replace fa-bitbucket-* icons with GitLab SVG
|
||||
merge_request: 45437
|
||||
author:
|
||||
type: changed
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Remove duplicate index from the Vulnerabilities table
|
||||
merge_request: 44422
|
||||
author: Borivoje Tasovac @borivojetasovac
|
||||
type: performance
|
|
@ -189,6 +189,7 @@ module Gitlab
|
|||
config.assets.precompile << "page_bundles/milestone.css"
|
||||
config.assets.precompile << "page_bundles/pipeline.css"
|
||||
config.assets.precompile << "page_bundles/pipelines.css"
|
||||
config.assets.precompile << "page_bundles/productivity_analytics.css"
|
||||
config.assets.precompile << "page_bundles/todos.css"
|
||||
config.assets.precompile << "page_bundles/reports.css"
|
||||
config.assets.precompile << "page_bundles/xterm.css"
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
class RemoveProjectIdAndIdIndexFromVulnerabilitiesTable < ActiveRecord::Migration[6.0]
|
||||
include Gitlab::Database::MigrationHelpers
|
||||
|
||||
DOWNTIME = false
|
||||
INDEX_NAME = 'index_vulnerabilities_on_project_id_and_id'
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
Gitlab::BackgroundMigration.steal('PopulateResolvedOnDefaultBranchColumn')
|
||||
remove_concurrent_index_by_name :vulnerabilities, INDEX_NAME
|
||||
end
|
||||
|
||||
def down
|
||||
add_concurrent_index :vulnerabilities, [:project_id, :id], name: INDEX_NAME
|
||||
end
|
||||
end
|
1
db/schema_migrations/20201004163918
Normal file
1
db/schema_migrations/20201004163918
Normal file
|
@ -0,0 +1 @@
|
|||
e25da3da50ed2396afe3bcb1ff441b5f1f0a43c0e23d66140a160d42f1b66a1a
|
|
@ -21764,8 +21764,6 @@ CREATE INDEX index_vulnerabilities_on_milestone_id ON vulnerabilities USING btre
|
|||
|
||||
CREATE INDEX index_vulnerabilities_on_project_id ON vulnerabilities USING btree (project_id);
|
||||
|
||||
CREATE INDEX index_vulnerabilities_on_project_id_and_id ON vulnerabilities USING btree (project_id, id);
|
||||
|
||||
CREATE INDEX index_vulnerabilities_on_resolved_by_id ON vulnerabilities USING btree (resolved_by_id);
|
||||
|
||||
CREATE INDEX index_vulnerabilities_on_start_date_sourcing_milestone_id ON vulnerabilities USING btree (start_date_sourcing_milestone_id);
|
||||
|
|
|
@ -116,7 +116,6 @@ gitlab_rails['ldap_servers'] = {
|
|||
'verify_certificates' => true,
|
||||
'bind_dn' => '_the_full_dn_of_the_user_you_will_bind_with',
|
||||
'password' => '_the_password_of_the_bind_user',
|
||||
'encryption' => 'plain',
|
||||
'verify_certificates' => true,
|
||||
'tls_options' => {
|
||||
'ca_file' => '',
|
||||
|
|
|
@ -3425,6 +3425,9 @@ msgstr ""
|
|||
msgid "Archive project"
|
||||
msgstr ""
|
||||
|
||||
msgid "Archive test case"
|
||||
msgstr ""
|
||||
|
||||
msgid "Archived"
|
||||
msgstr ""
|
||||
|
||||
|
@ -22070,6 +22073,9 @@ msgstr ""
|
|||
msgid "Reopen milestone"
|
||||
msgstr ""
|
||||
|
||||
msgid "Reopen test case"
|
||||
msgstr ""
|
||||
|
||||
msgid "Reopen this %{quick_action_target}"
|
||||
msgstr ""
|
||||
|
||||
|
@ -25897,15 +25903,30 @@ msgstr ""
|
|||
msgid "TestCases|Search test cases"
|
||||
msgstr ""
|
||||
|
||||
msgid "TestCases|Something went wrong while adding test case to Todo."
|
||||
msgstr ""
|
||||
|
||||
msgid "TestCases|Something went wrong while creating a test case."
|
||||
msgstr ""
|
||||
|
||||
msgid "TestCases|Something went wrong while fetching count of test cases."
|
||||
msgstr ""
|
||||
|
||||
msgid "TestCases|Something went wrong while fetching test case."
|
||||
msgstr ""
|
||||
|
||||
msgid "TestCases|Something went wrong while fetching test cases list."
|
||||
msgstr ""
|
||||
|
||||
msgid "TestCases|Something went wrong while marking test case todo as done."
|
||||
msgstr ""
|
||||
|
||||
msgid "TestCases|Something went wrong while updating the test case labels."
|
||||
msgstr ""
|
||||
|
||||
msgid "TestCases|Something went wrong while updating the test case."
|
||||
msgstr ""
|
||||
|
||||
msgid "TestCases|Submit test case"
|
||||
msgstr ""
|
||||
|
||||
|
@ -25990,7 +26011,7 @@ msgstr ""
|
|||
msgid "Thanks! Don't show me this again"
|
||||
msgstr ""
|
||||
|
||||
msgid "That's it, well done!%{celebrate}"
|
||||
msgid "That's it, well done!"
|
||||
msgstr ""
|
||||
|
||||
msgid "The \"%{group_path}\" group allows you to sign in with your Single Sign-On Account"
|
||||
|
|
|
@ -421,6 +421,25 @@ describe('Api', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('addProjectIssueAsTodo', () => {
|
||||
it('adds issue ID as a todo', () => {
|
||||
const projectId = 1;
|
||||
const issueIid = 11;
|
||||
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects/1/issues/11/todo`;
|
||||
mock.onPost(expectedUrl).reply(200, {
|
||||
id: 112,
|
||||
project: {
|
||||
id: 1,
|
||||
},
|
||||
});
|
||||
|
||||
return Api.addProjectIssueAsTodo(projectId, issueIid).then(({ data }) => {
|
||||
expect(data.id).toBe(112);
|
||||
expect(data.project.id).toBe(projectId);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('newLabel', () => {
|
||||
it('creates a new label', done => {
|
||||
const namespace = 'some namespace';
|
||||
|
|
|
@ -16,6 +16,7 @@ describe('PipelineTourSuccessModal', () => {
|
|||
stubs: {
|
||||
GlModal,
|
||||
GlSprintf,
|
||||
'gl-emoji': '<img/>',
|
||||
},
|
||||
});
|
||||
};
|
||||
|
@ -66,9 +67,11 @@ describe('PipelineTourSuccessModal', () => {
|
|||
it('has expected structure', () => {
|
||||
const modal = wrapper.find(GlModal);
|
||||
const sprintf = modal.find(GlSprintf);
|
||||
const emoji = modal.find('img');
|
||||
|
||||
expect(modal.attributes('title')).toContain("That's it, well done!");
|
||||
expect(wrapper.text()).toContain("That's it, well done!");
|
||||
expect(sprintf.exists()).toBe(true);
|
||||
expect(emoji.exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('renders the link for codeQualityLink', () => {
|
||||
|
|
|
@ -20,7 +20,7 @@ const diffFile = Object.freeze(
|
|||
name: 'base.js',
|
||||
mode: '100644',
|
||||
readable_text: true,
|
||||
icon: 'file-text-o',
|
||||
icon: 'doc-text',
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
|
|
@ -260,7 +260,7 @@ export default {
|
|||
name: 'CHANGELOG',
|
||||
mode: '100644',
|
||||
readable_text: true,
|
||||
icon: 'file-text-o',
|
||||
icon: 'doc-text',
|
||||
},
|
||||
blob_path: 'CHANGELOG',
|
||||
blob_name: 'CHANGELOG',
|
||||
|
|
|
@ -7,7 +7,7 @@ export default {
|
|||
name: 'CHANGELOG',
|
||||
mode: '100644',
|
||||
readable_text: true,
|
||||
icon: 'file-text-o',
|
||||
icon: 'doc-text',
|
||||
},
|
||||
blob_path: 'CHANGELOG',
|
||||
blob_name: 'CHANGELOG',
|
||||
|
|
|
@ -7,7 +7,7 @@ export default {
|
|||
name: 'CHANGELOG',
|
||||
mode: '100644',
|
||||
readable_text: false,
|
||||
icon: 'file-text-o',
|
||||
icon: 'doc-text',
|
||||
},
|
||||
blob_path: 'CHANGELOG',
|
||||
blob_name: 'CHANGELOG',
|
||||
|
|
|
@ -30,13 +30,23 @@ export const mockScopedLabel = {
|
|||
|
||||
export const mockLabels = [mockRegularLabel, mockScopedLabel];
|
||||
|
||||
export const mockCurrentUserTodo = {
|
||||
id: 'gid://gitlab/Todo/489',
|
||||
state: 'done',
|
||||
};
|
||||
|
||||
export const mockIssuable = {
|
||||
iid: '30',
|
||||
title: 'Dismiss Cipher with no integrity',
|
||||
description: null,
|
||||
titleHtml: 'Dismiss Cipher with no integrity',
|
||||
description: 'fortitudinis _fomentis_ dolor mitigari solet.',
|
||||
descriptionHtml: 'fortitudinis <i>fomentis</i> dolor mitigari solet.',
|
||||
state: 'opened',
|
||||
createdAt: '2020-06-29T13:52:56Z',
|
||||
updatedAt: '2020-09-10T11:41:13Z',
|
||||
webUrl: 'http://0.0.0.0:3000/gitlab-org/gitlab-shell/-/issues/30',
|
||||
blocked: false,
|
||||
confidential: false,
|
||||
author: mockAuthor,
|
||||
labels: {
|
||||
nodes: mockLabels,
|
||||
|
|
|
@ -682,6 +682,20 @@ describe('differenceInSeconds', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('differenceInMonths', () => {
|
||||
const startDateTime = new Date('2019-07-17T00:00:00.000Z');
|
||||
|
||||
it.each`
|
||||
startDate | endDate | expected
|
||||
${startDateTime} | ${startDateTime} | ${0}
|
||||
${startDateTime} | ${new Date('2019-12-17T12:00:00.000Z')} | ${5}
|
||||
${startDateTime} | ${new Date('2021-02-18T00:00:00.000Z')} | ${19}
|
||||
${new Date('2021-02-18T00:00:00.000Z')} | ${startDateTime} | ${-19}
|
||||
`('returns $expected for $endDate - $startDate', ({ startDate, endDate, expected }) => {
|
||||
expect(datetimeUtility.differenceInMonths(startDate, endDate)).toBe(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('differenceInMilliseconds', () => {
|
||||
const startDateTime = new Date('2019-07-17T00:00:00.000Z');
|
||||
|
||||
|
|
|
@ -536,7 +536,7 @@ describe('mrWidgetOptions', () => {
|
|||
const tooltip = vm.$el.querySelector('[data-testid="question-o-icon"]');
|
||||
|
||||
expect(vm.$el.textContent).toContain('Deletes source branch');
|
||||
expect(tooltip.getAttribute('data-original-title')).toBe(
|
||||
expect(tooltip.getAttribute('title')).toBe(
|
||||
'A user with write access to the source branch selected this option',
|
||||
);
|
||||
|
||||
|
|
|
@ -228,9 +228,11 @@ exports[`vue_shared/components/awards_list default matches snapshot 1`] = `
|
|||
/>
|
||||
</span>
|
||||
|
||||
<i
|
||||
aria-hidden="true"
|
||||
class="fa fa-spinner fa-spin award-control-icon award-control-icon-loading"
|
||||
<gl-loading-icon-stub
|
||||
class="award-control-icon-loading"
|
||||
color="dark"
|
||||
label="Loading"
|
||||
size="md"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
@ -44,7 +44,7 @@ RSpec.describe ChatMessage::IssueMessage do
|
|||
context 'open' do
|
||||
it 'returns a message regarding opening of issues' do
|
||||
expect(subject.pretext).to eq(
|
||||
'[<http://somewhere.com|project_name>] Issue opened by Test User (test.user)')
|
||||
'[<http://somewhere.com|project_name>] Issue <http://url.com|#100 Issue title> opened by Test User (test.user)')
|
||||
expect(subject.attachments).to eq([
|
||||
{
|
||||
title: "#100 Issue title",
|
||||
|
@ -91,7 +91,7 @@ RSpec.describe ChatMessage::IssueMessage do
|
|||
context 'open' do
|
||||
it 'returns a message regarding opening of issues' do
|
||||
expect(subject.pretext).to eq(
|
||||
'[[project_name](http://somewhere.com)] Issue opened by Test User (test.user)')
|
||||
'[[project_name](http://somewhere.com)] Issue [#100 Issue title](http://url.com) opened by Test User (test.user)')
|
||||
expect(subject.attachments).to eq('issue description')
|
||||
expect(subject.activity).to eq({
|
||||
title: 'Issue opened by Test User (test.user)',
|
||||
|
|
Loading…
Reference in a new issue