diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-08-11 06:08:51 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-08-11 06:08:51 +0300 |
commit | cf127374b5f72c00426acad9f2432064eeb1f1e3 (patch) | |
tree | 710922928ab9888128a6c9f9dbc0edbf6ef2f8af /app | |
parent | 7303dddd09bf28d28e36666f0cc2775e9fa27872 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r-- | app/assets/javascripts/notes/components/note_form.vue | 71 | ||||
-rw-r--r-- | app/assets/javascripts/notes/mixins/resolvable.js | 8 | ||||
-rw-r--r-- | app/assets/javascripts/vue_shared/components/color_picker/color_picker.vue | 2 | ||||
-rw-r--r-- | app/assets/javascripts/vue_shared/components/listbox_input/init_listbox_inputs.js | 3 | ||||
-rw-r--r-- | app/assets/javascripts/vue_shared/components/listbox_input/listbox_input.vue | 6 | ||||
-rw-r--r-- | app/controllers/projects/discussions_controller.rb | 23 | ||||
-rw-r--r-- | app/models/concerns/noteable.rb | 4 | ||||
-rw-r--r-- | app/models/discussion.rb | 4 | ||||
-rw-r--r-- | app/presenters/merge_request_presenter.rb | 11 | ||||
-rw-r--r-- | app/serializers/base_discussion_entity.rb | 6 | ||||
-rw-r--r-- | app/serializers/note_entity.rb | 4 | ||||
-rw-r--r-- | app/serializers/project_note_entity.rb | 8 | ||||
-rw-r--r-- | app/views/discussions/_diff_with_notes.html.haml | 2 | ||||
-rw-r--r-- | app/views/profiles/preferences/show.html.haml | 11 |
14 files changed, 81 insertions, 82 deletions
diff --git a/app/assets/javascripts/notes/components/note_form.vue b/app/assets/javascripts/notes/components/note_form.vue index 4e816038539..4a6b6d5233f 100644 --- a/app/assets/javascripts/notes/components/note_form.vue +++ b/app/assets/javascripts/notes/components/note_form.vue @@ -245,15 +245,16 @@ export default { }, methods: { ...mapActions(['toggleResolveNote']), - shouldToggleResolved(shouldResolve, beforeSubmitDiscussionState) { - const newResolvedStateAfterUpdate = - this.shouldBeResolved && this.shouldBeResolved(shouldResolve); - - const shouldToggleState = - newResolvedStateAfterUpdate !== undefined && - beforeSubmitDiscussionState !== newResolvedStateAfterUpdate; - - return shouldResolve || shouldToggleState; + shouldToggleResolved(beforeSubmitDiscussionState) { + return ( + this.showResolveDiscussionToggle && beforeSubmitDiscussionState !== this.newResolvedState() + ); + }, + newResolvedState() { + return ( + (this.discussionResolved && !this.isUnresolving) || + (!this.discussionResolved && this.isResolving) + ); }, editMyLastNote() { if (this.updatedNoteBody === '') { @@ -293,7 +294,7 @@ export default { } this.updatedNoteBody = ''; }, - handleUpdate(shouldResolve) { + handleUpdate() { const beforeSubmitDiscussionState = this.discussionResolved; this.isSubmitting = true; @@ -309,23 +310,13 @@ export default { () => { this.isSubmitting = false; - if (this.shouldToggleResolved(shouldResolve, beforeSubmitDiscussionState)) { + if (this.shouldToggleResolved(beforeSubmitDiscussionState)) { this.resolveHandler(beforeSubmitDiscussionState); } }, this.discussionResolved ? !this.isUnresolving : this.isResolving, ); }, - shouldBeResolved(resolveStatus) { - if (this.withBatchComments) { - return ( - (this.discussionResolved && !this.isUnresolving) || - (!this.discussionResolved && this.isResolving) - ); - } - - return resolveStatus; - }, handleAddToReview() { // check if draft should resolve thread const shouldResolve = @@ -390,21 +381,22 @@ export default { /> </comment-field-layout> <div class="note-form-actions"> + <p v-if="showResolveDiscussionToggle"> + <label> + <template v-if="discussionResolved"> + <gl-form-checkbox v-model="isUnresolving" class="js-unresolve-checkbox"> + {{ __('Unresolve thread') }} + </gl-form-checkbox> + </template> + <template v-else> + <gl-form-checkbox v-model="isResolving" class="js-resolve-checkbox"> + {{ __('Resolve thread') }} + </gl-form-checkbox> + </template> + </label> + </p> + <template v-if="showBatchCommentsActions"> - <p v-if="showResolveDiscussionToggle"> - <label> - <template v-if="discussionResolved"> - <gl-form-checkbox v-model="isUnresolving" class="js-unresolve-checkbox"> - {{ __('Unresolve thread') }} - </gl-form-checkbox> - </template> - <template v-else> - <gl-form-checkbox v-model="isResolving" class="js-resolve-checkbox"> - {{ __('Resolve thread') }} - </gl-form-checkbox> - </template> - </label> - </p> <div class="gl-display-flex gl-flex-wrap gl-mb-n3"> <gl-button :disabled="isDisabled" @@ -451,15 +443,6 @@ export default { {{ saveButtonTitle }} </gl-button> <gl-button - v-if="discussion.resolvable" - category="secondary" - variant="default" - class="gl-sm-mr-3 gl-xs-mb-3 js-comment-resolve-button" - @click.prevent="handleUpdate(true)" - > - {{ resolveButtonTitle }} - </gl-button> - <gl-button class="note-edit-cancel js-close-discussion-note-form" category="secondary" variant="default" diff --git a/app/assets/javascripts/notes/mixins/resolvable.js b/app/assets/javascripts/notes/mixins/resolvable.js index 63822a31cd1..814702b724d 100644 --- a/app/assets/javascripts/notes/mixins/resolvable.js +++ b/app/assets/javascripts/notes/mixins/resolvable.js @@ -11,14 +11,6 @@ export default { return this.note.resolved; }, resolveButtonTitle() { - if (this.updatedNoteBody) { - if (this.discussionResolved) { - return __('Comment & unresolve thread'); - } - - return __('Comment & resolve thread'); - } - return this.discussionResolved ? __('Unresolve thread') : __('Resolve thread'); }, }, diff --git a/app/assets/javascripts/vue_shared/components/color_picker/color_picker.vue b/app/assets/javascripts/vue_shared/components/color_picker/color_picker.vue index 78db2bf15b0..149082d036a 100644 --- a/app/assets/javascripts/vue_shared/components/color_picker/color_picker.vue +++ b/app/assets/javascripts/vue_shared/components/color_picker/color_picker.vue @@ -110,7 +110,7 @@ export default { <gl-form-input-group max-length="7" type="text" - class="gl-align-center gl-rounded-0 gl-rounded-top-right-base gl-rounded-bottom-right-base" + class="gl-align-center gl-rounded-0 gl-rounded-top-right-base gl-rounded-bottom-right-base gl-max-w-26" :value="value" :state="state" @input="handleColorChange" diff --git a/app/assets/javascripts/vue_shared/components/listbox_input/init_listbox_inputs.js b/app/assets/javascripts/vue_shared/components/listbox_input/init_listbox_inputs.js index b447822b1e0..e098103adde 100644 --- a/app/assets/javascripts/vue_shared/components/listbox_input/init_listbox_inputs.js +++ b/app/assets/javascripts/vue_shared/components/listbox_input/init_listbox_inputs.js @@ -6,7 +6,7 @@ export const initListboxInputs = () => { const els = [...document.querySelectorAll('.js-listbox-input')]; els.forEach((el, index) => { - const { label, description, name, defaultToggleText, value = null } = el.dataset; + const { label, description, name, defaultToggleText, value = null, toggleClass } = el.dataset; const { id } = el; const items = JSON.parse(el.dataset.items); @@ -34,6 +34,7 @@ export const initListboxInputs = () => { block: parseBoolean(el.dataset.block), fluidWidth: parseBoolean(el.dataset.fluidWidth), items, + toggleClass, }, attrs: { id, diff --git a/app/assets/javascripts/vue_shared/components/listbox_input/listbox_input.vue b/app/assets/javascripts/vue_shared/components/listbox_input/listbox_input.vue index 09ecad0713a..d20593d104e 100644 --- a/app/assets/javascripts/vue_shared/components/listbox_input/listbox_input.vue +++ b/app/assets/javascripts/vue_shared/components/listbox_input/listbox_input.vue @@ -62,6 +62,11 @@ export default { required: false, default: GlCollapsibleListbox.props.block.default, }, + toggleClass: { + type: [Array, String, Object], + required: false, + default: null, + }, }, data() { return { @@ -134,6 +139,7 @@ export default { <gl-collapsible-listbox :selected="selected" :toggle-text="toggleText" + :toggle-class="toggleClass" :items="filteredItems" :searchable="isSearchable" :no-results-text="$options.i18n.noResultsText" diff --git a/app/controllers/projects/discussions_controller.rb b/app/controllers/projects/discussions_controller.rb index 59de4fbb698..34b283b87f5 100644 --- a/app/controllers/projects/discussions_controller.rb +++ b/app/controllers/projects/discussions_controller.rb @@ -4,8 +4,8 @@ class Projects::DiscussionsController < Projects::ApplicationController include NotesHelper include RendersNotes - before_action :check_merge_requests_available! - before_action :merge_request + before_action :check_noteable_supports_resolvable_notes! + before_action :noteable before_action :discussion, only: [:resolve, :unresolve] before_action :authorize_resolve_discussion!, only: [:resolve, :unresolve] @@ -56,13 +56,26 @@ class Projects::DiscussionsController < Projects::ApplicationController end # rubocop: disable CodeReuse/ActiveRecord - def merge_request - @merge_request ||= MergeRequestsFinder.new(current_user, project_id: @project.id).find_by!(iid: params[:merge_request_id]) + def noteable + @noteable ||= noteable_finder_class.new(current_user, project_id: @project.id).find_by!(iid: params[:noteable_id]) end # rubocop: enable CodeReuse/ActiveRecord + def noteable_finder_class + case params[:noteable_type] + when 'issues' + IssuesFinder + when 'merge_requests' + MergeRequestsFinder + end + end + + def check_noteable_supports_resolvable_notes! + render_404 unless noteable_finder_class && noteable&.supports_resolvable_notes? + end + def discussion - @discussion ||= @merge_request.find_discussion(params[:id]) || render_404 + @discussion ||= @noteable.find_discussion(params[:id]) || render_404 end def authorize_resolve_discussion! diff --git a/app/models/concerns/noteable.rb b/app/models/concerns/noteable.rb index b30d60652c2..40a91c8ac94 100644 --- a/app/models/concerns/noteable.rb +++ b/app/models/concerns/noteable.rb @@ -17,7 +17,7 @@ module Noteable # `Noteable` class names that support resolvable notes. def resolvable_types - %w(MergeRequest DesignManagement::Design) + %w(Issue MergeRequest DesignManagement::Design) end # `Noteable` class names that support creating/forwarding individual notes. @@ -49,6 +49,8 @@ module Noteable end def supports_resolvable_notes? + return false if is_a?(Issue) && Feature.disabled?(:resolvable_issue_threads, project) + self.class.resolvable_types.include?(base_class_name) end diff --git a/app/models/discussion.rb b/app/models/discussion.rb index dc4794ed3cd..2d2519dc995 100644 --- a/app/models/discussion.rb +++ b/app/models/discussion.rb @@ -191,4 +191,8 @@ class Discussion def to_global_id(options = {}) GlobalID.new(::Gitlab::GlobalId.build(model_name: Discussion.to_s, id: id)) end + + def noteable_collection_name + noteable.class.underscore.pluralize + end end diff --git a/app/presenters/merge_request_presenter.rb b/app/presenters/merge_request_presenter.rb index 8d2baa6ee99..5c23af6e821 100644 --- a/app/presenters/merge_request_presenter.rb +++ b/app/presenters/merge_request_presenter.rb @@ -266,10 +266,15 @@ class MergeRequestPresenter < Gitlab::View::Presenter::Delegated def issues_sentence(project, issues) # Sorting based on the `#123` or `group/project#123` reference will sort - # local issues first. - issues.map do |issue| + # local issues numerically first. + issue_refs = issues.map do |issue| issue.to_reference(project) - end.sort.to_sentence + end + + issue_refs.sort_by do |issue_ref| + path_section = issue_ref.split('#') + [path_section.first, path_section.last.to_i] + end.to_sentence end def user_can_fork_project? diff --git a/app/serializers/base_discussion_entity.rb b/app/serializers/base_discussion_entity.rb index d1aef60a09e..0b006078343 100644 --- a/app/serializers/base_discussion_entity.rb +++ b/app/serializers/base_discussion_entity.rb @@ -40,16 +40,16 @@ class BaseDiscussionEntity < Grape::Entity expose :resolved_at expose :resolve_path do |discussion| - resolve_project_merge_request_discussion_path(discussion.project, discussion.noteable, discussion.id) + resolve_project_discussion_path(discussion.project, discussion.noteable_collection_name, discussion.noteable, discussion.id) end - expose :resolve_with_issue_path do |discussion| + expose :resolve_with_issue_path, if: -> (d, _) { d.noteable.is_a?(MergeRequest) } do |discussion| new_project_issue_path(discussion.project, merge_request_to_resolve_discussions_of: discussion.noteable.iid, discussion_to_resolve: discussion.id) if discussion&.project&.issues_enabled? end end expose :truncated_diff_lines_path, if: -> (d, _) { !d.expanded? && !render_truncated_diff_lines? } do |discussion| - project_merge_request_discussion_path(discussion.project, discussion.noteable, discussion) + project_discussion_path(discussion.project, discussion.noteable_collection_name, discussion.noteable, discussion) end private diff --git a/app/serializers/note_entity.rb b/app/serializers/note_entity.rb index 2155a1b4601..a50d893d244 100644 --- a/app/serializers/note_entity.rb +++ b/app/serializers/note_entity.rb @@ -78,10 +78,10 @@ class NoteEntity < API::Entities::Note end expose :resolve_path, if: -> (note, _) { note.part_of_discussion? && note.resolvable? } do |note| - resolve_project_merge_request_discussion_path(note.project, note.noteable, note.discussion_id) + resolve_project_discussion_path(discussion.project, discussion.noteable_collection_name, discussion.noteable, discussion.id) end - expose :resolve_with_issue_path, if: -> (note, _) { note.part_of_discussion? && note.resolvable? } do |note| + expose :resolve_with_issue_path, if: -> (note, _) { note.part_of_discussion? && note.resolvable? && note.noteable.is_a?(MergeRequest) } do |note| new_project_issue_path(note.project, merge_request_to_resolve_discussions_of: note.noteable.iid, discussion_to_resolve: note.discussion_id) end diff --git a/app/serializers/project_note_entity.rb b/app/serializers/project_note_entity.rb index 3cd34f6af0d..3e004fb5d32 100644 --- a/app/serializers/project_note_entity.rb +++ b/app/serializers/project_note_entity.rb @@ -21,14 +21,6 @@ class ProjectNoteEntity < NoteEntity project_note_path(note.project, note) end - expose :resolve_path, if: -> (note, _) { note.part_of_discussion? && note.resolvable? } do |note| - resolve_project_merge_request_discussion_path(note.project, note.noteable, note.discussion_id) - end - - expose :resolve_with_issue_path, if: -> (note, _) { note.part_of_discussion? && note.resolvable? } do |note| - new_project_issue_path(note.project, merge_request_to_resolve_discussions_of: note.noteable.iid, discussion_to_resolve: note.discussion_id) - end - expose :delete_attachment_path, if: -> (note, _) { note.attachment? } do |note| delete_attachment_project_note_path(note.project, note) end diff --git a/app/views/discussions/_diff_with_notes.html.haml b/app/views/discussions/_diff_with_notes.html.haml index a6904495f7c..db122fe82b1 100644 --- a/app/views/discussions/_diff_with_notes.html.haml +++ b/app/views/discussions/_diff_with_notes.html.haml @@ -3,7 +3,7 @@ - diff_data = {} - expanded = discussion.expanded? || local_assigns.fetch(:expanded, nil) - unless expanded - - diff_data = { lines_path: project_merge_request_discussion_path(discussion.project, discussion.noteable, discussion) } + - diff_data = { lines_path: project_discussion_path(discussion.project, discussion.noteable_collection_name, discussion.noteable, discussion) } .diff-file.file-holder.js-lazy-load-discussion{ class: diff_file_class, data: diff_data } .js-file-title.file-title.file-title-flex-parent diff --git a/app/views/profiles/preferences/show.html.haml b/app/views/profiles/preferences/show.html.haml index 05a8f64efe1..e7ea139eb71 100644 --- a/app/views/profiles/preferences/show.html.haml +++ b/app/views/profiles/preferences/show.html.haml @@ -74,14 +74,14 @@ = f.gitlab_ui_radio_component :layout, layout_choices[0][1], layout_choices[0][0], help_text: fixed_help_text = f.gitlab_ui_radio_component :layout, layout_choices[1][1], layout_choices[1][0], help_text: fluid_help_text - .js-listbox-input{ data: { label: s_('Preferences|Homepage'), description: s_('Preferences|Choose what content you want to see by default on your homepage.'), name: 'user[dashboard]', items: dashboard_choices.to_json, value: current_user.dashboard, block: true.to_s, fluid_width: true.to_s } } + .js-listbox-input{ data: { label: s_('Preferences|Homepage'), description: s_('Preferences|Choose what content you want to see by default on your homepage.'), name: 'user[dashboard]', items: dashboard_choices.to_json, value: current_user.dashboard, block: true.to_s, toggle_class: 'gl-form-input-xl' } } = render_if_exists 'profiles/preferences/group_overview_selector', f: f # EE-specific .form-group = f.label :project_view, class: 'label-bold' do = s_('Preferences|Project overview content') - = f.select :project_view, project_view_choices, {}, class: 'gl-form-select custom-select' + = f.select :project_view, project_view_choices, {}, class: 'gl-form-select custom-select gl-form-input-xl gl-display-block' .form-text.text-muted = s_('Preferences|Choose what content you want to see on a project’s overview page.') .form-group @@ -107,7 +107,7 @@ .form-group = f.label :tab_width, s_('Preferences|Tab width'), class: 'label-bold' = f.number_field :tab_width, - class: 'form-control gl-form-input', + class: 'form-control gl-form-input gl-max-w-15', min: Gitlab::TabWidth::MIN, max: Gitlab::TabWidth::MAX, required: true @@ -123,7 +123,8 @@ = _('Customize language and region related settings.') = succeed '.' do = link_to _('Learn more'), help_page_path('user/profile/preferences', anchor: 'localization'), target: '_blank', rel: 'noopener noreferrer' - .js-listbox-input{ data: { label: _('Language'), description: s_('Preferences|This feature is experimental and translations are not yet complete.'), name: 'user[preferred_language]', items: language_choices.to_json, value: current_user.preferred_language, block: true.to_s, fluid_width: true.to_s } } + + .js-listbox-input{ data: { label: _('Language'), description: s_('Preferences|This feature is experimental and translations are not yet complete.'), name: 'user[preferred_language]', items: language_choices.to_json, value: current_user.preferred_language, block: true.to_s, toggle_class: 'gl-form-input-xl' } } %p.gl-mt-n5 = link_to help_page_url('development/i18n/translation'), class: 'text-nowrap', target: '_blank', rel: 'noopener noreferrer' do = _("Help translate GitLab into your language") @@ -132,7 +133,7 @@ .form-group = f.label :first_day_of_week, class: 'label-bold' do = _('First day of the week') - = f.select :first_day_of_week, first_day_of_week_choices_with_default, {}, class: 'gl-form-select custom-select' + = f.select :first_day_of_week, first_day_of_week_choices_with_default, {}, class: 'gl-form-select custom-select gl-display-block gl-form-input-xl' .settings-section.js-preferences-form.js-search-settings-section#time-preferences .settings-sticky-header |