Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2019-10-11 03:06:24 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2019-10-11 03:06:24 +0300
commit133924c6cc443f5f69e1ab08d43b363d77677cb0 (patch)
treee893a7d36105fc4acec7038feae5f03bd34cfc2c /app
parentf607152a0802a68067343ad73f989033cb8e9a06 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r--[-rwxr-xr-x]app/assets/images/ci_favicons/favicon_status_preparing.pngbin11341 -> 11341 bytes
-rw-r--r--app/assets/javascripts/boards/components/issue_card_inner.vue10
-rw-r--r--app/assets/javascripts/lib/utils/url_utility.js8
-rw-r--r--app/assets/javascripts/notes/components/discussion_filter.vue8
-rw-r--r--app/assets/javascripts/notes/components/notes_app.vue27
-rw-r--r--app/assets/javascripts/notes/constants.js3
-rw-r--r--app/helpers/tags_helper.rb10
-rw-r--r--app/models/project_services/slash_commands_service.rb7
-rw-r--r--app/policies/global_policy.rb1
-rw-r--r--app/views/admin/users/_user_deactivation_effects.html.haml2
-rw-r--r--app/views/projects/tags/new.html.haml2
-rw-r--r--app/workers/prune_old_events_worker.rb4
12 files changed, 61 insertions, 21 deletions
diff --git a/app/assets/images/ci_favicons/favicon_status_preparing.png b/app/assets/images/ci_favicons/favicon_status_preparing.png
index f81baa0ece3..f81baa0ece3 100755..100644
--- a/app/assets/images/ci_favicons/favicon_status_preparing.png
+++ b/app/assets/images/ci_favicons/favicon_status_preparing.png
Binary files differ
diff --git a/app/assets/javascripts/boards/components/issue_card_inner.vue b/app/assets/javascripts/boards/components/issue_card_inner.vue
index 1d53a21c8ac..40d75d53f75 100644
--- a/app/assets/javascripts/boards/components/issue_card_inner.vue
+++ b/app/assets/javascripts/boards/components/issue_card_inner.vue
@@ -99,7 +99,10 @@ export default {
return !groupId ? referencePath.split('#')[0] : null;
},
orderedLabels() {
- return _.sortBy(this.issue.labels, 'title');
+ return _.chain(this.issue.labels)
+ .filter(this.isNonListLabel)
+ .sortBy('title')
+ .value();
},
helpLink() {
return boardsStore.scopedLabels.helpLink;
@@ -130,6 +133,9 @@ export default {
if (!label.id) return false;
return true;
},
+ isNonListLabel(label) {
+ return label.id && !(this.list.type === 'label' && this.list.title === label.title);
+ },
filterByLabel(label) {
if (!this.updateFilters) return;
const labelTitle = encodeURIComponent(label.title);
@@ -167,7 +173,7 @@ export default {
</h4>
</div>
<div v-if="showLabelFooter" class="board-card-labels prepend-top-4 d-flex flex-wrap">
- <template v-for="label in orderedLabels" v-if="showLabel(label)">
+ <template v-for="label in orderedLabels">
<issue-card-inner-scoped-label
v-if="showScopedLabel(label)"
:key="label.id"
diff --git a/app/assets/javascripts/lib/utils/url_utility.js b/app/assets/javascripts/lib/utils/url_utility.js
index 7ead9d46fbb..4be0d05a9b7 100644
--- a/app/assets/javascripts/lib/utils/url_utility.js
+++ b/app/assets/javascripts/lib/utils/url_utility.js
@@ -88,6 +88,14 @@ export function getLocationHash(url = window.location.href) {
}
/**
+ * Returns a boolean indicating whether the URL hash contains the given string value
+ */
+export function doesHashExistInUrl(hashName) {
+ const hash = getLocationHash();
+ return hash && hash.includes(hashName);
+}
+
+/**
* Apply the fragment to the given url by returning a new url string that includes
* the fragment. If the given url already contains a fragment, the original fragment
* will be removed.
diff --git a/app/assets/javascripts/notes/components/discussion_filter.vue b/app/assets/javascripts/notes/components/discussion_filter.vue
index 743684e7046..6b1e3298f9a 100644
--- a/app/assets/javascripts/notes/components/discussion_filter.vue
+++ b/app/assets/javascripts/notes/components/discussion_filter.vue
@@ -1,13 +1,14 @@
<script>
import $ from 'jquery';
import { mapGetters, mapActions } from 'vuex';
-import { getLocationHash } from '../../lib/utils/url_utility';
+import { getLocationHash, doesHashExistInUrl } from '../../lib/utils/url_utility';
import Icon from '~/vue_shared/components/icon.vue';
import {
DISCUSSION_FILTERS_DEFAULT_VALUE,
HISTORY_ONLY_FILTER_VALUE,
DISCUSSION_TAB_LABEL,
DISCUSSION_FILTER_TYPES,
+ NOTE_UNDERSCORE,
} from '../constants';
import notesEventHub from '../event_hub';
@@ -28,7 +29,9 @@ export default {
},
data() {
return {
- currentValue: this.selectedValue,
+ currentValue: doesHashExistInUrl(NOTE_UNDERSCORE)
+ ? DISCUSSION_FILTERS_DEFAULT_VALUE
+ : this.selectedValue,
defaultValue: DISCUSSION_FILTERS_DEFAULT_VALUE,
displayFilters: true,
};
@@ -50,7 +53,6 @@ export default {
notesEventHub.$on('dropdownSelect', this.selectFilter);
window.addEventListener('hashchange', this.handleLocationHash);
- this.handleLocationHash();
},
mounted() {
this.toggleCommentsForm();
diff --git a/app/assets/javascripts/notes/components/notes_app.vue b/app/assets/javascripts/notes/components/notes_app.vue
index fd592e965bf..c6c97489e5e 100644
--- a/app/assets/javascripts/notes/components/notes_app.vue
+++ b/app/assets/javascripts/notes/components/notes_app.vue
@@ -1,7 +1,7 @@
<script>
import { __ } from '~/locale';
import { mapGetters, mapActions } from 'vuex';
-import { getLocationHash } from '../../lib/utils/url_utility';
+import { getLocationHash, doesHashExistInUrl } from '../../lib/utils/url_utility';
import Flash from '../../flash';
import * as constants from '../constants';
import eventHub from '../event_hub';
@@ -156,19 +156,17 @@ export default {
this.isFetching = true;
- return this.fetchDiscussions({ path: this.getNotesDataByProp('discussionsPath') })
- .then(() => {
- this.initPolling();
- })
+ return this.fetchDiscussions(this.getFetchDiscussionsConfig())
+ .then(this.initPolling)
.then(() => {
this.setLoadingState(false);
this.setNotesFetchedState(true);
eventHub.$emit('fetchedNotesData');
this.isFetching = false;
})
- .then(() => this.$nextTick())
- .then(() => this.startTaskList())
- .then(() => this.checkLocationHash())
+ .then(this.$nextTick)
+ .then(this.startTaskList)
+ .then(this.checkLocationHash)
.catch(() => {
this.setLoadingState(false);
this.setNotesFetchedState(true);
@@ -199,9 +197,20 @@ export default {
},
startReplying(discussionId) {
return this.convertToDiscussion(discussionId)
- .then(() => this.$nextTick())
+ .then(this.$nextTick)
.then(() => eventHub.$emit('startReplying', discussionId));
},
+ getFetchDiscussionsConfig() {
+ const defaultConfig = { path: this.getNotesDataByProp('discussionsPath') };
+
+ if (doesHashExistInUrl(constants.NOTE_UNDERSCORE)) {
+ return Object.assign({}, defaultConfig, {
+ filter: constants.DISCUSSION_FILTERS_DEFAULT_VALUE,
+ persistFilter: false,
+ });
+ }
+ return defaultConfig;
+ },
},
systemNote: constants.SYSTEM_NOTE,
};
diff --git a/app/assets/javascripts/notes/constants.js b/app/assets/javascripts/notes/constants.js
index bdfb6b8f105..68c117183a1 100644
--- a/app/assets/javascripts/notes/constants.js
+++ b/app/assets/javascripts/notes/constants.js
@@ -8,8 +8,6 @@ export const OPENED = 'opened';
export const REOPENED = 'reopened';
export const CLOSED = 'closed';
export const MERGED = 'merged';
-export const EMOJI_THUMBSUP = 'thumbsup';
-export const EMOJI_THUMBSDOWN = 'thumbsdown';
export const ISSUE_NOTEABLE_TYPE = 'issue';
export const EPIC_NOTEABLE_TYPE = 'epic';
export const MERGE_REQUEST_NOTEABLE_TYPE = 'MergeRequest';
@@ -19,6 +17,7 @@ export const DESCRIPTION_TYPE = 'changed the description';
export const HISTORY_ONLY_FILTER_VALUE = 2;
export const DISCUSSION_FILTERS_DEFAULT_VALUE = 0;
export const DISCUSSION_TAB_LABEL = 'show';
+export const NOTE_UNDERSCORE = 'note_';
export const NOTEABLE_TYPE_MAPPING = {
Issue: ISSUE_NOTEABLE_TYPE,
diff --git a/app/helpers/tags_helper.rb b/app/helpers/tags_helper.rb
index de0b92b6fd7..4984b51555d 100644
--- a/app/helpers/tags_helper.rb
+++ b/app/helpers/tags_helper.rb
@@ -28,4 +28,14 @@ module TagsHelper
def protected_tag?(project, tag)
ProtectedTag.protected?(project, tag.name)
end
+
+ def tag_description_help_text
+ text = s_('TagsPage|Optionally, add a message to the tag. Leaving this blank creates '\
+ 'a %{link_start}lightweight tag.%{link_end}') % {
+ link_start: '<a href="https://git-scm.com/book/en/v2/Git-Basics-Tagging\" target="_blank" rel="noopener noreferrer">',
+ link_end: '</a>'
+ }
+
+ text.html_safe
+ end
end
diff --git a/app/models/project_services/slash_commands_service.rb b/app/models/project_services/slash_commands_service.rb
index 5bfd06476f0..d436176a52c 100644
--- a/app/models/project_services/slash_commands_service.rb
+++ b/app/models/project_services/slash_commands_service.rb
@@ -33,9 +33,12 @@ class SlashCommandsService < Service
return unless valid_token?(params[:token])
chat_user = find_chat_user(params)
+ user = chat_user&.user
+
+ if user
+ unless user.can?(:use_slash_commands)
+ return Gitlab::SlashCommands::Presenters::Access.new.deactivated if user.deactivated?
- if chat_user&.user
- unless chat_user.user.can?(:use_slash_commands)
return Gitlab::SlashCommands::Presenters::Access.new.access_denied(project)
end
diff --git a/app/policies/global_policy.rb b/app/policies/global_policy.rb
index 4d66a9e7d67..eca73f0a241 100644
--- a/app/policies/global_policy.rb
+++ b/app/policies/global_policy.rb
@@ -48,6 +48,7 @@ class GlobalPolicy < BasePolicy
prevent :access_git
prevent :access_api
prevent :receive_notifications
+ prevent :use_slash_commands
end
rule { required_terms_not_accepted }.policy do
diff --git a/app/views/admin/users/_user_deactivation_effects.html.haml b/app/views/admin/users/_user_deactivation_effects.html.haml
index 6cc47214d77..dc3896e18c0 100644
--- a/app/views/admin/users/_user_deactivation_effects.html.haml
+++ b/app/views/admin/users/_user_deactivation_effects.html.haml
@@ -10,6 +10,8 @@
%li
= s_('AdminUsers|The user will not receive any notifications')
%li
+ = s_('AdminUsers|The user will not be able to use slash commands')
+ %li
= s_('AdminUsers|When the user logs back in, their account will reactivate as a fully active account')
%li
= s_('AdminUsers|Personal projects, group and user history will be left intact')
diff --git a/app/views/projects/tags/new.html.haml b/app/views/projects/tags/new.html.haml
index 5e6d06d980e..a7f739ab13d 100644
--- a/app/views/projects/tags/new.html.haml
+++ b/app/views/projects/tags/new.html.haml
@@ -31,7 +31,7 @@
.col-sm-10
= text_area_tag :message, @message, required: false, class: 'form-control', rows: 5
.form-text.text-muted
- = s_('TagsPage|Optionally, add a message to the tag.')
+ = tag_description_help_text
%hr
.form-group.row
= label_tag :release_description, s_('TagsPage|Release notes'), class: 'col-form-label col-sm-2'
diff --git a/app/workers/prune_old_events_worker.rb b/app/workers/prune_old_events_worker.rb
index dc4b7670131..e2d1fb3ed35 100644
--- a/app/workers/prune_old_events_worker.rb
+++ b/app/workers/prune_old_events_worker.rb
@@ -6,13 +6,13 @@ class PruneOldEventsWorker
# rubocop: disable CodeReuse/ActiveRecord
def perform
- # Contribution calendar shows maximum 12 months of events, we retain 2 years for data integrity.
+ # Contribution calendar shows maximum 12 months of events, we retain 3 years for data integrity.
# Double nested query is used because MySQL doesn't allow DELETE subqueries on the same table.
Event.unscoped.where(
'(id IN (SELECT id FROM (?) ids_to_remove))',
Event.unscoped.where(
'created_at < ?',
- (2.years + 1.day).ago)
+ (3.years + 1.day).ago)
.select(:id)
.limit(10_000))
.delete_all