Skip to content
Snippets Groups Projects
Commit 67cdfd26 authored by GitLab Bot's avatar GitLab Bot
Browse files

Add latest changes from gitlab-org/gitlab@master

parent ca2a7ed5
No related branches found
No related tags found
No related merge requests found
Showing
with 201 additions and 45 deletions
Loading
Loading
@@ -479,24 +479,46 @@ export default class LabelsSelect {
// concatenation
// see: http://2ality.com/2016/05/template-literal-whitespace.html#joining-arrays
 
const linkOpenTag =
'<a href="<%- issueUpdateURL.slice(0, issueUpdateURL.lastIndexOf("/")) %>?label_name[]=<%- encodeURIComponent(label.title) %>" class="gl-link gl-label-link has-tooltip" <%= linkAttrs %> title="<%= tooltipTitleTemplate({ label, isScopedLabel, enableScopedLabels, escapeStr }) %>">';
const spanOpenTag =
'<span class="gl-label-text" style="background-color: <%= escapeStr(label.color) %>; color: <%= escapeStr(label.text_color) %>;">';
const labelTemplate = _.template(
[
'<a href="<%- issueUpdateURL.slice(0, issueUpdateURL.lastIndexOf("/")) %>?label_name[]=<%- encodeURIComponent(label.title) %>">',
'<span class="badge label has-tooltip color-label" <%= linkAttrs %> title="<%= tooltipTitleTemplate({ label, isScopedLabel, enableScopedLabels, escapeStr }) %>" style="background-color: <%= escapeStr(label.color) %>; color: <%= escapeStr(label.text_color) %>;">',
'<span class="gl-label">',
linkOpenTag,
spanOpenTag,
'<%- label.title %>',
'</span>',
'</a>',
'</span>',
].join(''),
);
 
const infoIconTemplate = _.template(
[
'<a href="<%= scopedLabelsDocumentationLink %>" class="label scoped-label" target="_blank" rel="noopener">',
'<i class="fa fa-question-circle" style="background-color: <%= escapeStr(label.color) %>; color: <%= escapeStr(label.text_color) %>;"></i>',
'<a href="<%= scopedLabelsDocumentationLink %>" class="gl-link gl-label-icon" target="_blank" rel="noopener">',
'<i class="fa fa-question-circle"></i>',
'</a>',
].join(''),
);
 
const scopedLabelTemplate = _.template(
[
'<span class="gl-label gl-label-scoped" style="color: <%= escapeStr(label.color) %>;">',
linkOpenTag,
spanOpenTag,
'<%- label.title.slice(0, label.title.lastIndexOf("::")) %>',
'</span>',
'<span class="gl-label-text" style="color: <%= escapeStr(label.color) %>;">',
'<%- label.title.slice(label.title.lastIndexOf("::") + 2) %>',
'</span>',
'</a>',
'<%= infoIconTemplate({ label, scopedLabelsDocumentationLink, escapeStr }) %>',
'</span>',
].join(''),
);
const tooltipTitleTemplate = _.template(
[
'<% if (isScopedLabel(label) && enableScopedLabels) { %>',
Loading
Loading
@@ -514,8 +536,7 @@ export default class LabelsSelect {
'<% _.each(labels, function(label){ %>',
'<% if (isScopedLabel(label) && enableScopedLabels) { %>',
'<span class="d-inline-block position-relative scoped-label-wrapper">',
'<%= labelTemplate({ label, issueUpdateURL, isScopedLabel, enableScopedLabels, tooltipTitleTemplate, escapeStr, linkAttrs: \'data-html="true"\' }) %>',
'<%= infoIconTemplate({ label, scopedLabelsDocumentationLink, escapeStr }) %>',
'<%= scopedLabelTemplate({ label, issueUpdateURL, isScopedLabel, enableScopedLabels, infoIconTemplate, scopedLabelsDocumentationLink, tooltipTitleTemplate, escapeStr, linkAttrs: \'data-html="true"\' }) %>',
'</span>',
'<% } else { %>',
'<%= labelTemplate({ label, issueUpdateURL, isScopedLabel, enableScopedLabels, tooltipTitleTemplate, escapeStr, linkAttrs: "" }) %>',
Loading
Loading
@@ -528,6 +549,7 @@ export default class LabelsSelect {
...tplData,
labelTemplate,
infoIconTemplate,
scopedLabelTemplate,
tooltipTitleTemplate,
isScopedLabel,
escapeStr: _.escape,
Loading
Loading
import $ from 'jquery';
import _ from 'underscore';
import { debounce } from 'lodash';
import axios from '~/lib/utils/axios_utils';
import flash from '~/flash';
import { __ } from '~/locale';
Loading
Loading
@@ -34,7 +34,7 @@ export default () => {
 
$broadcastMessage.on(
'input',
_.debounce(function onMessageInput() {
debounce(function onMessageInput() {
const message = $(this).val();
if (message === '') {
$jsBroadcastMessagePreview.text(__('Your message here'));
Loading
Loading
<script>
import _ from 'underscore';
import { escape as esc } from 'lodash';
import DeprecatedModal from '~/vue_shared/components/deprecated_modal.vue';
import { s__, sprintf } from '~/locale';
 
Loading
Loading
@@ -34,7 +34,7 @@ export default {
return sprintf(
s__('AdminProjects|Delete Project %{projectName}?'),
{
projectName: `'${_.escape(this.projectName)}'`,
projectName: `'${esc(this.projectName)}'`,
},
false,
);
Loading
Loading
@@ -46,7 +46,7 @@ export default {
and all related resources including issues, merge requests, etc.. Once you confirm and press
%{strong_start}Delete project%{strong_end}, it cannot be undone or recovered.`),
{
projectName: `<strong>${_.escape(this.projectName)}</strong>`,
projectName: `<strong>${esc(this.projectName)}</strong>`,
strong_start: '<strong>',
strong_end: '</strong>',
},
Loading
Loading
@@ -57,7 +57,7 @@ export default {
return sprintf(
s__('AdminUsers|To confirm, type %{projectName}'),
{
projectName: `<code>${_.escape(this.projectName)}</code>`,
projectName: `<code>${esc(this.projectName)}</code>`,
},
false,
);
Loading
Loading
<script>
import _ from 'underscore';
import { escape as esc } from 'lodash';
import { GlModal, GlButton, GlFormInput } from '@gitlab/ui';
import { s__, sprintf } from '~/locale';
 
Loading
Loading
@@ -56,7 +56,7 @@ export default {
return sprintf(
this.content,
{
username: `<strong>${_.escape(this.username)}</strong>`,
username: `<strong>${esc(this.username)}</strong>`,
strong_start: '<strong>',
strong_end: '</strong>',
},
Loading
Loading
@@ -67,7 +67,7 @@ export default {
return sprintf(
s__('AdminUsers|To confirm, type %{username}'),
{
username: `<code>${_.escape(this.username)}</code>`,
username: `<code>${esc(this.username)}</code>`,
},
false,
);
Loading
Loading
import _ from 'underscore';
import { debounce } from 'lodash';
import InputValidator from '~/validators/input_validator';
 
import fetchGroupPathAvailability from './fetch_group_path_availability';
Loading
Loading
@@ -20,7 +20,7 @@ export default class GroupPathValidator extends InputValidator {
const container = opts.container || '';
const validateElements = document.querySelectorAll(`${container} .js-validate-group-path`);
 
this.debounceValidateInput = _.debounce(inputDomElement => {
this.debounceValidateInput = debounce(inputDomElement => {
GroupPathValidator.validateGroupPathInput(inputDomElement);
}, debounceTimeoutDuration);
 
Loading
Loading
<script>
import _ from 'underscore';
import { escape as esc } from 'lodash';
import axios from '~/lib/utils/axios_utils';
import createFlash from '~/flash';
import DeprecatedModal2 from '~/vue_shared/components/deprecated_modal_2.vue';
Loading
Loading
@@ -48,7 +48,7 @@ export default {
const label = `<span
class="label color-label"
style="background-color: ${this.labelColor}; color: ${this.labelTextColor};"
>${_.escape(this.labelTitle)}</span>`;
>${esc(this.labelTitle)}</span>`;
 
return sprintf(
s__('Labels|<span>Promote label</span> %{labelTitle} <span>to Group Label?</span>'),
Loading
Loading
<script>
import _ from 'underscore';
export default {
props: {
initialCronInterval: {
Loading
Loading
@@ -24,7 +22,7 @@ export default {
},
computed: {
intervalIsPreset() {
return _.contains(this.cronIntervalPresets, this.cronInterval);
return Object.values(this.cronIntervalPresets).includes(this.cronInterval);
},
// The text input is editable when there's a custom interval, or when it's
// a preset interval and the user clicks the 'custom' radio button
Loading
Loading
<script>
import _ from 'underscore';
import { escape as esc } from 'lodash';
import { GlModal, GlModalDirective } from '@gitlab/ui';
import { s__, sprintf } from '~/locale';
 
Loading
Loading
@@ -38,7 +38,7 @@ export default {
return sprintf(
s__('WikiPageConfirmDelete|Delete page %{pageTitle}?'),
{
pageTitle: _.escape(this.pageTitle),
pageTitle: esc(this.pageTitle),
},
false,
);
Loading
Loading
import _ from 'underscore';
import { debounce } from 'lodash';
import InputValidator from '~/validators/input_validator';
 
import axios from '~/lib/utils/axios_utils';
Loading
Loading
@@ -20,7 +20,7 @@ export default class UsernameValidator extends InputValidator {
const container = opts.container || '';
const validateLengthElements = document.querySelectorAll(`${container} .js-validate-username`);
 
this.debounceValidateInput = _.debounce(inputDomElement => {
this.debounceValidateInput = debounce(inputDomElement => {
UsernameValidator.validateUsernameInput(inputDomElement);
}, debounceTimeoutDuration);
 
Loading
Loading
import $ from 'jquery';
import _ from 'underscore';
import { last } from 'lodash';
import { scaleLinear, scaleThreshold } from 'd3-scale';
import { select } from 'd3-selection';
import dateFormat from 'dateformat';
Loading
Loading
@@ -164,11 +164,11 @@ export default class ActivityCalendar {
.enter()
.append('g')
.attr('transform', (group, i) => {
_.each(group, (stamp, a) => {
group.forEach((stamp, a) => {
if (a === 0 && stamp.day === this.firstDayOfWeek) {
const month = stamp.date.getMonth();
const x = this.daySizeWithSpace * i + 1 + this.daySizeWithSpace;
const lastMonth = _.last(this.months);
const lastMonth = last(this.months);
if (
lastMonth == null ||
(month !== lastMonth.month && x - this.daySizeWithSpace !== lastMonth.x)
Loading
Loading
<script>
import { GlLoadingIcon } from '@gitlab/ui';
/* eslint-disable vue/require-default-prop */
/* This is a re-usable vue component for rendering a button
that will probably be sending off ajax requests and need
to show the loading status by setting the `loading` option.
This can also be used for initial page load when you don't
know the action of the button yet by setting
`loading: true, label: undefined`.
Sample configuration:
<loading-button
:loading="true"
:label="Hello"
@click="..."
/>
*/
/*
This component will be deprecated in favor of gl-button.
https://gitlab-org.gitlab.io/gitlab-ui/?path=/story/base-button--loading-button
https://gitlab.com/gitlab-org/gitlab/issues/207412
*/
 
export default {
components: {
Loading
Loading
---
title: Remove visibility check from epic descendant counts
merge_request: 25975
author:
type: changed
---
title: Migrate mentions for snippet and snippet notes to snippet_user_mentions DB
table
merge_request: 23783
author:
type: changed
---
title: Correctly style scoped labels in sidebar after updating
merge_request: 22071
author:
type: changed
---
title: Improve audit log header layout
merge_request: 25821
author:
type: changed
---
title: Schedule worker to migrate security job artifacts to security scans
merge_request: 24125
author:
type: other
# frozen_string_literal: true
class CleanupEmptySnippetUserMentions < ActiveRecord::Migration[5.2]
DOWNTIME = false
BATCH_SIZE = 10_000
class SnippetUserMention < ActiveRecord::Base
include EachBatch
self.table_name = 'snippet_user_mentions'
end
def up
# cleanup snippet user mentions with no actual mentions,
# re https://gitlab.com/gitlab-org/gitlab/-/merge_requests/24586#note_285982468
SnippetUserMention
.where(mentioned_users_ids: nil)
.where(mentioned_groups_ids: nil)
.where(mentioned_projects_ids: nil)
.each_batch(of: BATCH_SIZE) do |batch|
batch.delete_all
end
end
def down
# no-op
end
end
# frozen_string_literal: true
class MigrateSnippetMentionsToDb < ActiveRecord::Migration[5.2]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
DELAY = 2.minutes.to_i
BATCH_SIZE = 10_000
MIGRATION = 'UserMentions::CreateResourceUserMention'
JOIN = "LEFT JOIN snippet_user_mentions on snippets.id = snippet_user_mentions.snippet_id"
QUERY_CONDITIONS = "(description like '%@%' OR title like '%@%') AND snippet_user_mentions.snippet_id IS NULL"
disable_ddl_transaction!
class Snippet < ActiveRecord::Base
include EachBatch
self.table_name = 'snippets'
end
def up
Snippet
.joins(JOIN)
.where(QUERY_CONDITIONS)
.each_batch(of: BATCH_SIZE) do |batch, index|
range = batch.pluck(Arel.sql('MIN(snippets.id)'), Arel.sql('MAX(snippets.id)')).first
migrate_in(index * DELAY, MIGRATION, ['Snippet', JOIN, QUERY_CONDITIONS, false, *range])
end
end
def down
# no-op
end
end
# frozen_string_literal: true
class AddTemporarySnippetNotesWithMentionsIndex < ActiveRecord::Migration[5.2]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
INDEX_NAME = 'snippet_mentions_temp_index'
INDEX_CONDITION = "note LIKE '%@%'::text AND notes.noteable_type = 'Snippet'"
disable_ddl_transaction!
def up
# create temporary index for notes with mentions, may take well over 1h
add_concurrent_index(:notes, :id, where: INDEX_CONDITION, name: INDEX_NAME)
end
def down
remove_concurrent_index(:notes, :id, where: INDEX_CONDITION, name: INDEX_NAME)
end
end
# frozen_string_literal: true
class MigrateSnippetNotesMentionsToDb < ActiveRecord::Migration[5.2]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
DELAY = 2.minutes.to_i
BATCH_SIZE = 10_000
MIGRATION = 'UserMentions::CreateResourceUserMention'
INDEX_CONDITION = "note LIKE '%@%'::text AND notes.noteable_type = 'Snippet'"
QUERY_CONDITIONS = "#{INDEX_CONDITION} AND snippet_user_mentions.snippet_id IS NULL"
JOIN = 'INNER JOIN snippets ON snippets.id = notes.noteable_id LEFT JOIN snippet_user_mentions ON notes.id = snippet_user_mentions.note_id'
disable_ddl_transaction!
class Note < ActiveRecord::Base
include EachBatch
self.table_name = 'notes'
end
def up
Note
.joins(JOIN)
.where(QUERY_CONDITIONS)
.each_batch(of: BATCH_SIZE) do |batch, index|
range = batch.pluck(Arel.sql('MIN(notes.id)'), Arel.sql('MAX(notes.id)')).first
migrate_in(index * DELAY, MIGRATION, ['Snippet', JOIN, QUERY_CONDITIONS, true, *range])
end
end
def down
# no-op
# temporary index is to be dropped in a different migration in an upcoming release:
# https://gitlab.com/gitlab-org/gitlab/issues/196842
end
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment