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>2023-11-21 18:13:27 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-11-21 18:13:27 +0300
commitf1c788bb1836083e4f5ed91c1c7494244e6e13ee (patch)
tree2d591f05343513b6b3c9d5ce5839d3652c16f000 /app
parenteec96715e5dcbe934b4caecc6fcf9740a3fc8496 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/graphql_shared/issuable_client.js2
-rw-r--r--app/assets/javascripts/graphql_shared/possible_types.json1
-rw-r--r--app/assets/javascripts/lib/utils/datetime/locale_dateformat.js58
-rw-r--r--app/assets/javascripts/lib/utils/datetime/timeago_utility.js3
-rw-r--r--app/assets/javascripts/search/sidebar/components/archived_filter/index.vue4
-rw-r--r--app/assets/javascripts/search/sidebar/components/filters_template.vue6
-rw-r--r--app/assets/javascripts/search/sidebar/components/label_filter/index.vue6
-rw-r--r--app/assets/javascripts/search/sidebar/components/language_filter/index.vue4
-rw-r--r--app/assets/javascripts/search/sidebar/components/radio_filter.vue4
-rw-r--r--app/assets/javascripts/vue_shared/mixins/timeago.js4
-rw-r--r--app/graphql/mutations/projects/star.rb39
-rw-r--r--app/graphql/types/current_user_type.rb12
-rw-r--r--app/graphql/types/mutation_type.rb1
-rw-r--r--app/graphql/types/query_type.rb2
-rw-r--r--app/graphql/types/user_interface.rb2
-rw-r--r--app/graphql/types/user_type.rb2
-rw-r--r--app/models/merge_request.rb10
-rw-r--r--app/models/merge_request_diff.rb11
18 files changed, 134 insertions, 37 deletions
diff --git a/app/assets/javascripts/graphql_shared/issuable_client.js b/app/assets/javascripts/graphql_shared/issuable_client.js
index 9537c9ef8a6..d0ba34b6127 100644
--- a/app/assets/javascripts/graphql_shared/issuable_client.js
+++ b/app/assets/javascripts/graphql_shared/issuable_client.js
@@ -146,7 +146,7 @@ export const config = {
},
IssueConnection: {
merge(existing = { nodes: [] }, incoming, { args }) {
- if (!args.after) {
+ if (!args?.after) {
return incoming;
}
return {
diff --git a/app/assets/javascripts/graphql_shared/possible_types.json b/app/assets/javascripts/graphql_shared/possible_types.json
index ee5f8c2ac2f..4ef0d067030 100644
--- a/app/assets/javascripts/graphql_shared/possible_types.json
+++ b/app/assets/javascripts/graphql_shared/possible_types.json
@@ -150,6 +150,7 @@
"User": [
"AddOnUser",
"AutocompletedUser",
+ "CurrentUser",
"MergeRequestAssignee",
"MergeRequestAuthor",
"MergeRequestParticipant",
diff --git a/app/assets/javascripts/lib/utils/datetime/locale_dateformat.js b/app/assets/javascripts/lib/utils/datetime/locale_dateformat.js
index 81922c4da1d..f1446fa5ac4 100644
--- a/app/assets/javascripts/lib/utils/datetime/locale_dateformat.js
+++ b/app/assets/javascripts/lib/utils/datetime/locale_dateformat.js
@@ -3,25 +3,36 @@ import { createDateTimeFormat } from '~/locale';
/**
* Format a Date with the help of {@link DateTimeFormat.asDateTime}
*
- * Note: In case you can use localDateFormat.asDateTime directly, please do that.
+ * Note: In case you can use localeDateFormat.asDateTime directly, please do that.
*
* @example
- * localDateFormat[DATE_WITH_TIME_FORMAT].format(date) // returns 'Jul 6, 2020, 2:43 PM'
- * localDateFormat[DATE_WITH_TIME_FORMAT].formatRange(date, date) // returns 'Jul 6, 2020, 2:45PM – 8:43 PM'
+ * localeDateFormat[DATE_WITH_TIME_FORMAT].format(date) // returns 'Jul 6, 2020, 2:43 PM'
+ * localeDateFormat[DATE_WITH_TIME_FORMAT].formatRange(date, date) // returns 'Jul 6, 2020, 2:45PM – 8:43 PM'
*/
export const DATE_WITH_TIME_FORMAT = 'asDateTime';
+
+/**
+ * Format a Date with the help of {@link DateTimeFormat.asDateTimeFull}
+ *
+ * Note: In case you can use localeDateFormat.asDateTimeFull directly, please do that.
+ *
+ * @example
+ * localeDateFormat[DATE_TIME_FULL_FORMAT].format(date) // returns 'July 6, 2020 at 2:43:12 PM GMT'
+ */
+export const DATE_TIME_FULL_FORMAT = 'asDateTimeFull';
+
/**
* Format a Date with the help of {@link DateTimeFormat.asDate}
*
- * Note: In case you can use localDateFormat.asDate directly, please do that.
+ * Note: In case you can use localeDateFormat.asDate directly, please do that.
*
* @example
- * localDateFormat[DATE_ONLY_FORMAT].format(date) // returns 'Jul 05, 2023'
- * localDateFormat[DATE_ONLY_FORMAT].formatRange(date, date) // returns 'Jul 05 - Jul 07, 2023'
+ * localeDateFormat[DATE_ONLY_FORMAT].format(date) // returns 'Jul 05, 2023'
+ * localeDateFormat[DATE_ONLY_FORMAT].formatRange(date, date) // returns 'Jul 05 - Jul 07, 2023'
*/
export const DATE_ONLY_FORMAT = 'asDate';
export const DEFAULT_DATE_TIME_FORMAT = DATE_WITH_TIME_FORMAT;
-export const DATE_TIME_FORMATS = [DATE_WITH_TIME_FORMAT, DATE_ONLY_FORMAT];
+export const DATE_TIME_FORMATS = [DATE_WITH_TIME_FORMAT, DATE_TIME_FULL_FORMAT, DATE_ONLY_FORMAT];
/**
* The DateTimeFormat utilities support formatting a number of types,
@@ -54,7 +65,7 @@ class DateTimeFormat {
* @example
* // en-US: returns something like Jul 6, 2020, 2:43 PM
* // en-GB: returns something like 6 Jul 2020, 14:43
- * localDateFormat.asDateTime.format(date)
+ * localeDateFormat.asDateTime.format(date)
*
* @returns {DateTimeFormatter}
*/
@@ -68,6 +79,32 @@ class DateTimeFormat {
})
);
}
+ /**
+ * Locale aware formatter to a complete date time.
+ *
+ * This is needed if you need to convey a full timestamp including timezone and seconds.
+ *
+ * This is mainly used in tooltips. Use {@link DateTimeFormat.asDateTime}
+ * if you don't need to show all the information.
+ *
+ *
+ * @example
+ * // en-US: returns something like July 6, 2020 at 2:43:12 PM GMT
+ * // en-GB: returns something like 6 July 2020 at 14:43:12 GMT
+ * localeDateFormat.asDateTimeFull.format(date)
+ *
+ * @returns {DateTimeFormatter}
+ */
+ get asDateTimeFull() {
+ return (
+ this.#formatters[DATE_TIME_FULL_FORMAT] ||
+ this.#createFormatter(DATE_TIME_FULL_FORMAT, {
+ dateStyle: 'long',
+ timeStyle: 'long',
+ hourCycle: DateTimeFormat.#hourCycle,
+ })
+ );
+ }
/**
* Locale aware formatter to display a only the date.
@@ -77,12 +114,12 @@ class DateTimeFormat {
* @example
* // en-US: returns something like Jul 6, 2020
* // en-GB: returns something like 6 Jul 2020
- * localDateFormat.asDate.format(date)
+ * localeDateFormat.asDate.format(date)
*
* @example
* // en-US: returns something like Jul 6 – 7, 2020
* // en-GB: returns something like 6-7 Jul 2020
- * localDateFormat.asDate.formatRange(date, date2)
+ * localeDateFormat.asDate.formatRange(date, date2)
*
* @returns {DateTimeFormatter}
*/
@@ -177,6 +214,7 @@ class DateTimeFormat {
*
* DateTime (showing both date and times):
* - {@link DateTimeFormat.asDateTime localeDateFormat.asDateTime} - the default format for date times
+ * - {@link DateTimeFormat.asDateTimeFull localeDateFormat.asDateTimeFull} - full format, including timezone and seconds
*
* Date (showing date only):
* - {@link DateTimeFormat.asDate localeDateFormat.asDate} - the default format for a date
diff --git a/app/assets/javascripts/lib/utils/datetime/timeago_utility.js b/app/assets/javascripts/lib/utils/datetime/timeago_utility.js
index a25acd5c711..3a94b26ee35 100644
--- a/app/assets/javascripts/lib/utils/datetime/timeago_utility.js
+++ b/app/assets/javascripts/lib/utils/datetime/timeago_utility.js
@@ -1,7 +1,6 @@
import * as timeago from 'timeago.js';
import { languageCode, s__ } from '~/locale';
import { DEFAULT_DATE_TIME_FORMAT, localeDateFormat } from '~/lib/utils/datetime/locale_dateformat';
-import { formatDate } from './date_format_utility';
/**
* Timeago uses underscores instead of dashes to separate language from country code.
@@ -130,7 +129,7 @@ export const localTimeAgo = (elements, updateTooltip = true) => {
function addTimeAgoTooltip() {
elements.forEach((el) => {
// Recreate with custom template
- el.setAttribute('title', formatDate(el.dateTime));
+ el.setAttribute('title', localeDateFormat.asDateTimeFull.format(el.dateTime));
});
}
diff --git a/app/assets/javascripts/search/sidebar/components/archived_filter/index.vue b/app/assets/javascripts/search/sidebar/components/archived_filter/index.vue
index 914ff99075b..0308db17dc4 100644
--- a/app/assets/javascripts/search/sidebar/components/archived_filter/index.vue
+++ b/app/assets/javascripts/search/sidebar/components/archived_filter/index.vue
@@ -48,9 +48,9 @@ export default {
<template>
<gl-form-checkbox-group v-model="selectedFilter">
- <h5 class="gl-mt-0 gl-mb-5 gl-font-sm">
+ <div class="gl-mb-2 gl-font-weight-bold gl-font-sm" data-testid="archived-filter-title">
{{ $options.archivedFilterData.headerLabel }}
- </h5>
+ </div>
<gl-form-checkbox
class="gl-flex-grow-1 gl-display-inline-flex gl-justify-content-space-between gl-w-full"
:class="$options.LABEL_DEFAULT_CLASSES"
diff --git a/app/assets/javascripts/search/sidebar/components/filters_template.vue b/app/assets/javascripts/search/sidebar/components/filters_template.vue
index a3aa392d7fc..2f40a430bfa 100644
--- a/app/assets/javascripts/search/sidebar/components/filters_template.vue
+++ b/app/assets/javascripts/search/sidebar/components/filters_template.vue
@@ -40,7 +40,11 @@ export default {
</script>
<template>
- <gl-form class="issue-filters gl-px-5 gl-pt-0" @submit.prevent="applyQueryWithTracking">
+ <gl-form
+ class="issue-filters gl-px-5 gl-pt-0"
+ :aria-label="__('Search filters')"
+ @submit.prevent="applyQueryWithTracking"
+ >
<slot></slot>
<div class="gl-display-flex gl-align-items-center gl-mt-4">
<gl-button category="primary" variant="confirm" type="submit" :disabled="!sidebarDirty">
diff --git a/app/assets/javascripts/search/sidebar/components/label_filter/index.vue b/app/assets/javascripts/search/sidebar/components/label_filter/index.vue
index a53f519161b..106093b5ad1 100644
--- a/app/assets/javascripts/search/sidebar/components/label_filter/index.vue
+++ b/app/assets/javascripts/search/sidebar/components/label_filter/index.vue
@@ -179,10 +179,10 @@ export default {
<template>
<div class="gl-pb-0 gl-md-pt-0 label-filter gl-relative">
- <h5 class="gl-my-0 gl-font-sm" data-testid="label-filter-title">
+ <div class="gl-mb-2 gl-font-weight-bold gl-font-sm" data-testid="label-filter-title">
{{ $options.labelFilterData.header }}
- </h5>
- <div class="gl-my-5">
+ </div>
+ <div>
<gl-label
v-for="label in unappliedNewLabels"
:key="label.key"
diff --git a/app/assets/javascripts/search/sidebar/components/language_filter/index.vue b/app/assets/javascripts/search/sidebar/components/language_filter/index.vue
index 4a9975641c6..d0c895530cd 100644
--- a/app/assets/javascripts/search/sidebar/components/language_filter/index.vue
+++ b/app/assets/javascripts/search/sidebar/components/language_filter/index.vue
@@ -75,9 +75,9 @@ export default {
<template>
<div v-if="hasBuckets" class="language-filter-checkbox">
- <h5 class="gl-mt-0 gl-mb-5 gl-font-sm">
+ <div class="gl-mb-2 gl-font-weight-bold gl-font-sm">
{{ $options.languageFilterData.header }}
- </h5>
+ </div>
<div
v-if="!aggregations.error"
class="gl-overflow-x-hidden gl-overflow-y-auto"
diff --git a/app/assets/javascripts/search/sidebar/components/radio_filter.vue b/app/assets/javascripts/search/sidebar/components/radio_filter.vue
index d67844b93a7..f961bfea608 100644
--- a/app/assets/javascripts/search/sidebar/components/radio_filter.vue
+++ b/app/assets/javascripts/search/sidebar/components/radio_filter.vue
@@ -57,9 +57,9 @@ export default {
<template>
<div>
- <h5 class="gl-mt-0 gl-mb-5 gl-font-sm">
+ <div class="gl-mb-2 gl-font-weight-bold gl-font-sm">
{{ filterData.header }}
- </h5>
+ </div>
<gl-form-radio-group v-model="selectedFilter">
<gl-form-radio v-for="f in filtersArray" :key="f.value" :value="f.value">
{{ radioLabel(f) }}
diff --git a/app/assets/javascripts/vue_shared/mixins/timeago.js b/app/assets/javascripts/vue_shared/mixins/timeago.js
index 61e45fa5195..438da925937 100644
--- a/app/assets/javascripts/vue_shared/mixins/timeago.js
+++ b/app/assets/javascripts/vue_shared/mixins/timeago.js
@@ -1,4 +1,4 @@
-import { formatDate, getTimeago, timeagoLanguageCode } from '~/lib/utils/datetime_utility';
+import { getTimeago, localeDateFormat, timeagoLanguageCode } from '~/lib/utils/datetime_utility';
/**
* Mixin with time ago methods used in some vue components
@@ -12,7 +12,7 @@ export default {
},
tooltipTitle(time) {
- return formatDate(time);
+ return localeDateFormat.asDateTimeFull.format(time);
},
},
};
diff --git a/app/graphql/mutations/projects/star.rb b/app/graphql/mutations/projects/star.rb
new file mode 100644
index 00000000000..e4b64235c9a
--- /dev/null
+++ b/app/graphql/mutations/projects/star.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+
+module Mutations
+ module Projects
+ class Star < BaseMutation
+ graphql_name 'StarProject'
+
+ authorize :read_project
+
+ argument :project_id,
+ ::Types::GlobalIDType[::Project],
+ required: true,
+ description: 'Full path of the project to star or unstar.'
+
+ argument :starred,
+ GraphQL::Types::Boolean,
+ required: true,
+ description: 'Indicates whether to star or unstar the project.'
+
+ field :count,
+ GraphQL::Types::String,
+ null: false,
+ description: 'Number of stars for the project.'
+
+ def resolve(project_id:, starred:)
+ project = authorized_find!(id: project_id)
+
+ if current_user.starred?(project) != starred
+ current_user.toggle_star(project)
+ project.reset
+ end
+
+ {
+ count: project.star_count
+ }
+ end
+ end
+ end
+end
diff --git a/app/graphql/types/current_user_type.rb b/app/graphql/types/current_user_type.rb
new file mode 100644
index 00000000000..d5ecdeba9e2
--- /dev/null
+++ b/app/graphql/types/current_user_type.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+module Types
+ # rubocop:disable Graphql/AuthorizeTypes -- This is not necessary because the superclass declares the authorization
+ class CurrentUserType < ::Types::UserType
+ graphql_name 'CurrentUser'
+ description 'The currently authenticated GitLab user.'
+ end
+ # rubocop:enable Graphql/AuthorizeTypes
+end
+
+::Types::CurrentUserType.prepend_mod
diff --git a/app/graphql/types/mutation_type.rb b/app/graphql/types/mutation_type.rb
index d0a9ea11a27..3a2dea92cdc 100644
--- a/app/graphql/types/mutation_type.rb
+++ b/app/graphql/types/mutation_type.rb
@@ -108,6 +108,7 @@ module Types
mount_mutation Mutations::Notes::Destroy
mount_mutation Mutations::Organizations::Create, alpha: { milestone: '16.6' }
mount_mutation Mutations::Projects::SyncFork, calls_gitaly: true, alpha: { milestone: '15.9' }
+ mount_mutation Mutations::Projects::Star, alpha: { milestone: '16.7' }
mount_mutation Mutations::Releases::Create
mount_mutation Mutations::Releases::Update
mount_mutation Mutations::Releases::Delete
diff --git a/app/graphql/types/query_type.rb b/app/graphql/types/query_type.rb
index 6b7814754a4..9acff9eb2b1 100644
--- a/app/graphql/types/query_type.rb
+++ b/app/graphql/types/query_type.rb
@@ -48,7 +48,7 @@ module Types
required: true,
description: 'Global ID of the container repository.'
end
- field :current_user, Types::UserType,
+ field :current_user, Types::CurrentUserType,
null: true,
description: "Get information about current user."
field :design_management, Types::DesignManagementType,
diff --git a/app/graphql/types/user_interface.rb b/app/graphql/types/user_interface.rb
index 040711b5f58..2a628bb3ceb 100644
--- a/app/graphql/types/user_interface.rb
+++ b/app/graphql/types/user_interface.rb
@@ -229,5 +229,3 @@ module Types
end
end
end
-
-Types::UserInterface.prepend_mod
diff --git a/app/graphql/types/user_type.rb b/app/graphql/types/user_type.rb
index 87ca5fddf14..c5910236d51 100644
--- a/app/graphql/types/user_type.rb
+++ b/app/graphql/types/user_type.rb
@@ -14,3 +14,5 @@ module Types
present_using UserPresenter
end
end
+
+Types::UserType.prepend_mod
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index 051568a5674..c8fc10e6c94 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -2172,15 +2172,7 @@ class MergeRequest < ApplicationRecord
end
def current_patch_id_sha
- return merge_request_diff.patch_id_sha if merge_request_diff.patch_id_sha.present?
-
- base_sha = diff_refs&.base_sha
- head_sha = diff_refs&.head_sha
-
- return unless base_sha && head_sha
- return if base_sha == head_sha
-
- project.repository.get_patch_id(base_sha, head_sha)
+ merge_request_diff.get_patch_id_sha
end
private
diff --git a/app/models/merge_request_diff.rb b/app/models/merge_request_diff.rb
index 4c87b78d9f2..000fb9117af 100644
--- a/app/models/merge_request_diff.rb
+++ b/app/models/merge_request_diff.rb
@@ -237,6 +237,17 @@ class MergeRequestDiff < ApplicationRecord
)
end
+ def get_patch_id_sha
+ return patch_id_sha if patch_id_sha.present?
+
+ set_patch_id_sha
+
+ return unless patch_id_sha.present?
+
+ save
+ patch_id_sha
+ end
+
def set_as_latest_diff
# Don't set merge_head diff as latest so it won't get considered as the
# MergeRequest#merge_request_diff.