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

Add latest changes from gitlab-org/gitlab@master

parent 80e51340
No related branches found
No related tags found
No related merge requests found
Showing
with 159 additions and 74 deletions
/* eslint-disable no-param-reassign, no-void, consistent-return */
/* eslint-disable no-param-reassign, consistent-return */
 
import AccessorUtilities from './lib/utils/accessor';
 
export default class Autosave {
constructor(field, key) {
constructor(field, key, fallbackKey) {
this.field = field;
 
this.isLocalStorageAvailable = AccessorUtilities.isLocalStorageAccessSafe();
Loading
Loading
@@ -11,6 +11,7 @@ export default class Autosave {
key = key.join('/');
}
this.key = `autosave/${key}`;
this.fallbackKey = fallbackKey;
this.field.data('autosave', this);
this.restore();
this.field.on('input', () => this.save());
Loading
Loading
@@ -21,9 +22,12 @@ export default class Autosave {
if (!this.field.length) return;
 
const text = window.localStorage.getItem(this.key);
const fallbackText = window.localStorage.getItem(this.fallbackKey);
 
if ((text != null ? text.length : void 0) > 0) {
if (text) {
this.field.val(text);
} else if (fallbackText) {
this.field.val(fallbackText);
}
 
this.field.trigger('input');
Loading
Loading
@@ -41,7 +45,10 @@ export default class Autosave {
 
const text = this.field.val();
 
if (this.isLocalStorageAvailable && (text != null ? text.length : void 0) > 0) {
if (this.isLocalStorageAvailable && text) {
if (this.fallbackKey) {
window.localStorage.setItem(this.fallbackKey, text);
}
return window.localStorage.setItem(this.key, text);
}
 
Loading
Loading
@@ -51,6 +58,7 @@ export default class Autosave {
reset() {
if (!this.isLocalStorageAvailable) return;
 
window.localStorage.removeItem(this.fallbackKey);
return window.localStorage.removeItem(this.key);
}
 
Loading
Loading
<script>
import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
import Icon from '~/vue_shared/components/icon.vue';
import { GlDropdown, GlDropdownItem, GlIcon } from '@gitlab/ui';
import { s__ } from '../../locale';
 
export default {
Loading
Loading
@@ -8,7 +7,7 @@ export default {
components: {
GlDropdown,
GlDropdownItem,
Icon,
GlIcon,
},
props: {
stacks: {
Loading
Loading
@@ -86,8 +85,9 @@ export default {
href="https://crossplane.io/docs/master/stacks-guide.html"
target="_blank"
rel="noopener noreferrer"
>{{ __('Crossplane') }}</a
>
>{{ __('Crossplane') }}
<gl-icon name="external-link" class="vertical-align-middle" />
</a>
</p>
</div>
</template>
Loading
Loading
@@ -6,6 +6,36 @@ import UsersSelect from './users_select';
import ZenMode from './zen_mode';
import AutoWidthDropdownSelect from './issuable/auto_width_dropdown_select';
import { parsePikadayDate, pikadayToString } from './lib/utils/datetime_utility';
import { queryToObject, objectToQuery } from './lib/utils/url_utility';
function organizeQuery(obj, isFallbackKey = false) {
const sourceBranch = 'merge_request[source_branch]';
const targetBranch = 'merge_request[target_branch]';
if (isFallbackKey) {
return {
[sourceBranch]: obj[sourceBranch],
};
}
return {
[sourceBranch]: obj[sourceBranch],
[targetBranch]: obj[targetBranch],
};
}
function format(searchTerm, isFallbackKey = false) {
const queryObject = queryToObject(searchTerm);
const organizeQueryObject = organizeQuery(queryObject, isFallbackKey);
const formattedQuery = objectToQuery(organizeQueryObject);
return formattedQuery;
}
function getFallbackKey() {
const searchTerm = format(document.location.search, true);
return ['autosave', document.location.pathname, searchTerm].join('/');
}
 
export default class IssuableForm {
constructor(form) {
Loading
Loading
@@ -57,16 +87,20 @@ export default class IssuableForm {
}
 
initAutosave() {
this.autosave = new Autosave(this.titleField, [
document.location.pathname,
document.location.search,
'title',
]);
return new Autosave(this.descriptionField, [
document.location.pathname,
document.location.search,
'description',
]);
const searchTerm = format(document.location.search);
const fallbackKey = getFallbackKey();
this.autosave = new Autosave(
this.titleField,
[document.location.pathname, searchTerm, 'title'],
`${fallbackKey}=title`,
);
return new Autosave(
this.descriptionField,
[document.location.pathname, searchTerm, 'description'],
`${fallbackKey}=description`,
);
}
 
handleSubmit() {
Loading
Loading
Loading
Loading
@@ -181,4 +181,36 @@ export function getWebSocketUrl(path) {
return `${getWebSocketProtocol()}//${joinPaths(window.location.host, path)}`;
}
 
/**
* Convert search query into an object
*
* @param {String} query from "document.location.search"
* @returns {Object}
*
* ex: "?one=1&two=2" into {one: 1, two: 2}
*/
export function queryToObject(query) {
const removeQuestionMarkFromQuery = String(query).startsWith('?') ? query.slice(1) : query;
return removeQuestionMarkFromQuery.split('&').reduce((accumulator, curr) => {
const p = curr.split('=');
accumulator[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
return accumulator;
}, {});
}
/**
* Convert search query object back into a search query
*
* @param {Object} obj that needs to be converted
* @returns {String}
*
* ex: {one: 1, two: 2} into "one=1&two=2"
*
*/
export function objectToQuery(obj) {
return Object.keys(obj)
.map(k => `${encodeURIComponent(k)}=${encodeURIComponent(obj[k])}`)
.join('&');
}
export { joinPaths };
Loading
Loading
@@ -30,9 +30,6 @@ export default {
return this.collapseGroup && this.showGroup ? 'angle-down' : 'angle-right';
},
},
created() {
this.showGroup = this.collapseGroup;
},
methods: {
collapse() {
this.showGroup = !this.showGroup;
Loading
Loading
/* eslint-disable func-names, no-var, no-return-assign */
/* eslint-disable func-names, no-return-assign */
 
import $ from 'jquery';
import Cookies from 'js-cookie';
Loading
Loading
@@ -90,19 +90,19 @@ export default class Project {
}
 
static initRefSwitcher() {
var refListItem = document.createElement('li');
var refLink = document.createElement('a');
const refListItem = document.createElement('li');
const refLink = document.createElement('a');
 
refLink.href = '#';
 
return $('.js-project-refs-dropdown').each(function() {
var $dropdown = $(this);
var selected = $dropdown.data('selected');
var fieldName = $dropdown.data('fieldName');
var shouldVisit = Boolean($dropdown.data('visit'));
var $form = $dropdown.closest('form');
var action = $form.attr('action');
var linkTarget = mergeUrlParams(serializeForm($form[0]), action);
const $dropdown = $(this);
const selected = $dropdown.data('selected');
const fieldName = $dropdown.data('fieldName');
const shouldVisit = Boolean($dropdown.data('visit'));
const $form = $dropdown.closest('form');
const action = $form.attr('action');
const linkTarget = mergeUrlParams(serializeForm($form[0]), action);
 
return $dropdown.glDropdown({
data(term, callback) {
Loading
Loading
@@ -123,9 +123,9 @@ export default class Project {
inputFieldName: $dropdown.data('inputFieldName'),
fieldName,
renderRow(ref) {
var li = refListItem.cloneNode(false);
const li = refListItem.cloneNode(false);
 
var link = refLink.cloneNode(false);
const link = refLink.cloneNode(false);
 
if (ref === selected) {
link.className = 'is-active';
Loading
Loading
Loading
Loading
@@ -88,10 +88,6 @@ class DiffNote < Note
line&.suggestible?
end
 
def discussion_first_note?
self == discussion.first_note
end
def banzai_render_context(field)
super.merge(suggestions_filter_enabled: true)
end
Loading
Loading
@@ -108,7 +104,7 @@ class DiffNote < Note
end
 
def should_create_diff_file?
on_text? && note_diff_file.nil? && discussion_first_note?
on_text? && note_diff_file.nil? && start_of_discussion?
end
 
def fetch_diff_file
Loading
Loading
Loading
Loading
@@ -139,10 +139,6 @@ class Discussion
false
end
 
def new_discussion?
notes.length == 1
end
def last_note
@last_note ||= notes.last
end
Loading
Loading
Loading
Loading
@@ -409,6 +409,10 @@ class Note < ApplicationRecord
full_discussion || to_discussion
end
 
def start_of_discussion?
discussion.first_note == self
end
def part_of_discussion?
!to_discussion.individual_note?
end
Loading
Loading
Loading
Loading
@@ -7,20 +7,24 @@ module Issuable
def execute(issuable, old_labels: [], is_update: true)
@issuable = issuable
 
if is_update
if issuable.previous_changes.include?('title')
create_title_change_note(issuable.previous_changes['title'].first)
# We disable touch so that created system notes do not update
# the noteable's updated_at field
ActiveRecord::Base.no_touching do
if is_update
if issuable.previous_changes.include?('title')
create_title_change_note(issuable.previous_changes['title'].first)
end
handle_description_change_note
handle_time_tracking_note if issuable.is_a?(TimeTrackable)
create_discussion_lock_note if issuable.previous_changes.include?('discussion_locked')
end
 
handle_description_change_note
handle_time_tracking_note if issuable.is_a?(TimeTrackable)
create_discussion_lock_note if issuable.previous_changes.include?('discussion_locked')
create_due_date_note if issuable.previous_changes.include?('due_date')
create_milestone_note if issuable.previous_changes.include?('milestone_id')
create_labels_note(old_labels) if old_labels && issuable.labels != old_labels
end
create_due_date_note if issuable.previous_changes.include?('due_date')
create_milestone_note if issuable.previous_changes.include?('milestone_id')
create_labels_note(old_labels) if old_labels && issuable.labels != old_labels
end
 
private
Loading
Loading
Loading
Loading
@@ -164,9 +164,7 @@ class IssuableBaseService < BaseService
before_create(issuable)
 
if issuable.save
ActiveRecord::Base.no_touching do
Issuable::CommonSystemNotesService.new(project, current_user).execute(issuable, is_update: false)
end
Issuable::CommonSystemNotesService.new(project, current_user).execute(issuable, is_update: false)
 
after_create(issuable)
execute_hooks(issuable)
Loading
Loading
@@ -227,10 +225,7 @@ class IssuableBaseService < BaseService
ensure_milestone_available(issuable)
 
if issuable.with_transaction_returning_status { issuable.save(touch: should_touch) }
# We do not touch as it will affect a update on updated_at field
ActiveRecord::Base.no_touching do
Issuable::CommonSystemNotesService.new(project, current_user).execute(issuable, old_labels: old_associations[:labels])
end
Issuable::CommonSystemNotesService.new(project, current_user).execute(issuable, old_labels: old_associations[:labels])
 
handle_changes(issuable, old_associations: old_associations)
 
Loading
Loading
@@ -264,10 +259,7 @@ class IssuableBaseService < BaseService
before_update(issuable, skip_spam_check: true)
 
if issuable.with_transaction_returning_status { issuable.save }
# We do not touch as it will affect a update on updated_at field
ActiveRecord::Base.no_touching do
Issuable::CommonSystemNotesService.new(project, current_user).execute(issuable, old_labels: nil)
end
Issuable::CommonSystemNotesService.new(project, current_user).execute(issuable, old_labels: nil)
 
handle_task_changes(issuable)
invalidate_cache_counts(issuable, users: issuable.assignees.to_a)
Loading
Loading
Loading
Loading
@@ -4,7 +4,7 @@ module Notes
class BaseService < ::BaseService
def clear_noteable_diffs_cache(note)
if note.is_a?(DiffNote) &&
note.discussion_first_note? &&
note.start_of_discussion? &&
note.position.unfolded_diff?(project.repository)
note.noteable.diffs.clear_cache
end
Loading
Loading
Loading
Loading
@@ -11,7 +11,7 @@
- if discussion.nil?
commented
- else
- if discussion.new_discussion?
- if note.start_of_discussion?
started a new
- else
commented on a
Loading
Loading
Loading
Loading
@@ -7,7 +7,7 @@
<% if discussion.nil? -%>
<%= 'commented' -%>:
<% else -%>
<% if discussion.new_discussion? -%>
<% if note.start_of_discussion? -%>
<%= 'started a new discussion' -%>
<% else -%>
<%= 'commented on a discussion' -%>
Loading
Loading
---
title: Keep details in MR when changing target branch
merge_request: 19138
author:
type: changed
---
title: Fix graph groups in monitor dashboard that are hidden on load
merge_request: 20312
author:
type: fixed
---
title: SaaS trial copy shows plan
merge_request: 20207
author:
type: changed
---
title: Add missing external-link icon for Crossplane managed app
merge_request: 20283
author:
type: fixed
---
title: View closed issues in epic
merge_request: 19741
author:
type: added
Loading
Loading
@@ -2515,10 +2515,10 @@ msgstr ""
msgid "BillingPlans|To manage the plan for this group, visit the billing section of %{parent_billing_page_link}."
msgstr ""
 
msgid "BillingPlans|Your GitLab.com Gold trial expired on %{expiration_date}. You can restore access to the Gold features at any time by upgrading below."
msgid "BillingPlans|Your GitLab.com %{plan} trial will <strong>expire after %{expiration_date}</strong>. You can retain access to the %{plan} features by upgrading below."
msgstr ""
 
msgid "BillingPlans|Your GitLab.com Gold trial will <strong>expire after %{expiration_date}</strong>. You can retain access to the Gold features by upgrading below."
msgid "BillingPlans|Your GitLab.com trial expired on %{expiration_date}. You can restore access to the features at any time by upgrading below."
msgstr ""
 
msgid "BillingPlans|billed annually at %{price_per_year}"
Loading
Loading
@@ -5770,7 +5770,7 @@ msgstr ""
msgid "DesignManagement|Could not add a new comment. Please try again"
msgstr ""
 
msgid "DesignManagement|Could not create new discussion, please try again."
msgid "DesignManagement|Could not create new discussion. Please try again."
msgstr ""
 
msgid "DesignManagement|Could not find design, please try again."
Loading
Loading
@@ -5821,9 +5821,6 @@ msgstr ""
msgid "DesignManagement|We could not delete %{design}. Please try again."
msgstr ""
 
msgid "DesignManagement|We could not delete design(s). Please try again."
msgstr ""
msgid "Designs"
msgstr ""
 
Loading
Loading
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