summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/notes
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-02-20 13:49:51 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2023-02-20 13:49:51 +0000
commit71786ddc8e28fbd3cb3fcc4b3ff15e5962a1c82e (patch)
tree6a2d93ef3fb2d353bb7739e4b57e6541f51cdd71 /app/assets/javascripts/notes
parenta7253423e3403b8c08f8a161e5937e1488f5f407 (diff)
downloadgitlab-ce-71786ddc8e28fbd3cb3fcc4b3ff15e5962a1c82e.tar.gz
Add latest changes from gitlab-org/gitlab@15-9-stable-eev15.9.0-rc42
Diffstat (limited to 'app/assets/javascripts/notes')
-rw-r--r--app/assets/javascripts/notes/components/attachments_warning.vue18
-rw-r--r--app/assets/javascripts/notes/components/comment_field_layout.vue17
-rw-r--r--app/assets/javascripts/notes/components/comment_form.vue5
-rw-r--r--app/assets/javascripts/notes/components/note_actions.vue52
-rw-r--r--app/assets/javascripts/notes/components/note_header.vue2
-rw-r--r--app/assets/javascripts/notes/components/noteable_note.vue8
-rw-r--r--app/assets/javascripts/notes/components/sidebar_subscription.vue4
-rw-r--r--app/assets/javascripts/notes/components/toggle_replies_widget.vue7
-rw-r--r--app/assets/javascripts/notes/i18n.js3
-rw-r--r--app/assets/javascripts/notes/index.js1
-rw-r--r--app/assets/javascripts/notes/stores/actions.js10
11 files changed, 104 insertions, 23 deletions
diff --git a/app/assets/javascripts/notes/components/attachments_warning.vue b/app/assets/javascripts/notes/components/attachments_warning.vue
new file mode 100644
index 00000000000..aaa4b0d92b9
--- /dev/null
+++ b/app/assets/javascripts/notes/components/attachments_warning.vue
@@ -0,0 +1,18 @@
+<script>
+import { COMMENT_FORM } from '../i18n';
+
+export default {
+ i18n: COMMENT_FORM.attachmentMsg,
+ data() {
+ return {
+ message: this.$options.i18n,
+ };
+ },
+};
+</script>
+
+<template>
+ <div class="issuable-note-warning" data-testid="attachment-warning">
+ {{ message }}
+ </div>
+</template>
diff --git a/app/assets/javascripts/notes/components/comment_field_layout.vue b/app/assets/javascripts/notes/components/comment_field_layout.vue
index 84bda1b0b5c..cc372520c70 100644
--- a/app/assets/javascripts/notes/components/comment_field_layout.vue
+++ b/app/assets/javascripts/notes/components/comment_field_layout.vue
@@ -1,14 +1,18 @@
<script>
+import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import NoteableWarning from '~/vue_shared/components/notes/noteable_warning.vue';
import EmailParticipantsWarning from './email_participants_warning.vue';
+import AttachmentsWarning from './attachments_warning.vue';
const DEFAULT_NOTEABLE_TYPE = 'Issue';
export default {
components: {
+ AttachmentsWarning,
EmailParticipantsWarning,
NoteableWarning,
},
+ mixins: [glFeatureFlagsMixin()],
props: {
noteableData: {
type: Object,
@@ -29,6 +33,11 @@ export default {
required: false,
default: false,
},
+ containsLink: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
},
computed: {
isLocked() {
@@ -46,6 +55,13 @@ export default {
showEmailParticipantsWarning() {
return this.emailParticipants.length && !this.isInternalNote;
},
+ showAttachmentWarning() {
+ return (
+ this.glFeatures.serviceDeskNewNoteEmailNativeAttachments &&
+ this.showEmailParticipantsWarning &&
+ this.containsLink
+ );
+ },
},
};
</script>
@@ -68,6 +84,7 @@ export default {
:confidential-noteable-docs-path="noteableData.confidential_issues_docs_path"
/>
<slot></slot>
+ <attachments-warning v-if="showAttachmentWarning" />
<email-participants-warning
v-if="showEmailParticipantsWarning"
class="gl-border-t-1 gl-border-t-solid gl-border-t-gray-100 gl-rounded-base gl-rounded-top-left-none! gl-rounded-top-right-none!"
diff --git a/app/assets/javascripts/notes/components/comment_form.vue b/app/assets/javascripts/notes/components/comment_form.vue
index c6e7117cf2e..4f7256d0b0e 100644
--- a/app/assets/javascripts/notes/components/comment_form.vue
+++ b/app/assets/javascripts/notes/components/comment_form.vue
@@ -28,6 +28,7 @@ import CommentTypeDropdown from './comment_type_dropdown.vue';
import DiscussionLockedWidget from './discussion_locked_widget.vue';
import NoteSignedOutWidget from './note_signed_out_widget.vue';
+const ATTACHMENT_REGEXP = /!?\[.*?\]\(\/uploads\/[0-9a-f]{32}\/.*?\)/;
export default {
name: 'CommentForm',
i18n: COMMENT_FORM,
@@ -176,6 +177,9 @@ export default {
disableSubmitButton() {
return this.note.length === 0 || this.isSubmitting;
},
+ containsLink() {
+ return ATTACHMENT_REGEXP.test(this.note);
+ },
},
mounted() {
// jQuery is needed here because it is a custom event being dispatched with jQuery.
@@ -356,6 +360,7 @@ export default {
:noteable-data="getNoteableData"
:is-internal-note="noteIsInternal"
:noteable-type="noteableType"
+ :contains-link="containsLink"
>
<markdown-field
ref="markdownField"
diff --git a/app/assets/javascripts/notes/components/note_actions.vue b/app/assets/javascripts/notes/components/note_actions.vue
index c15c11ed9db..abed95a9706 100644
--- a/app/assets/javascripts/notes/components/note_actions.vue
+++ b/app/assets/javascripts/notes/components/note_actions.vue
@@ -4,12 +4,14 @@ import { mapActions, mapGetters, mapState } from 'vuex';
import Api from '~/api';
import resolvedStatusMixin from '~/batch_comments/mixins/resolved_status';
import { createAlert } from '~/flash';
+import { TYPE_ISSUE } from '~/issues/constants';
import { BV_HIDE_TOOLTIP } from '~/lib/utils/constants';
import { __, sprintf } from '~/locale';
import eventHub from '~/sidebar/event_hub';
import UserAccessRoleBadge from '~/vue_shared/components/user_access_role_badge.vue';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { splitCamelCase } from '~/lib/utils/text_utility';
+import AbuseCategorySelector from '~/abuse_reports/components/abuse_category_selector.vue';
import ReplyButton from './note_actions/reply_button.vue';
import TimelineEventButton from './note_actions/timeline_event_button.vue';
@@ -30,6 +32,7 @@ export default {
GlDropdownItem,
UserAccessRoleBadge,
EmojiPicker: () => import('~/emoji/components/picker.vue'),
+ AbuseCategorySelector,
},
directives: {
GlTooltip: GlTooltipDirective,
@@ -58,11 +61,6 @@ export default {
required: false,
default: '',
},
- reportAbusePath: {
- type: String,
- required: false,
- default: null,
- },
isAuthor: {
type: Boolean,
required: false,
@@ -135,11 +133,16 @@ export default {
default: '',
},
},
+ data() {
+ return {
+ isReportAbuseDrawerOpen: false,
+ };
+ },
computed: {
...mapState(['isPromoteCommentToTimelineEventInProgress']),
...mapGetters(['getUserDataByProp', 'getNoteableData', 'canUserAddIncidentTimelineEvents']),
shouldShowActionsDropdown() {
- return this.currentUserId && (this.canEdit || this.canReportAsAbuse);
+ return this.currentUserId;
},
showDeleteAction() {
return this.canDelete && !this.canReportAsAbuse && !this.noteUrl;
@@ -171,7 +174,7 @@ export default {
return this.getNoteableData.assignees || [];
},
isIssue() {
- return this.targetType === 'issue';
+ return this.targetType === TYPE_ISSUE;
},
canAssign() {
return this.getNoteableData.current_user?.can_set_issue_metadata && this.isIssue;
@@ -233,7 +236,7 @@ export default {
assignees.push({ id: this.author.id });
}
- if (this.targetType === 'issue') {
+ if (this.targetType === TYPE_ISSUE) {
Api.updateIssue(project_id, iid, {
assignee_ids: assignees.map((assignee) => assignee.id),
})
@@ -252,6 +255,9 @@ export default {
awardName,
});
},
+ toggleReportAbuseDrawer(isOpen) {
+ this.isReportAbuseDrawerOpen = isOpen;
+ },
},
};
</script>
@@ -261,7 +267,7 @@ export default {
<user-access-role-badge
v-if="isAuthor"
v-gl-tooltip
- class="gl-mr-3 d-none d-md-inline-block"
+ class="gl-mr-3 gl-display-none gl-sm-display-block"
:title="displayAuthorBadgeText"
>
{{ __('Author') }}
@@ -269,7 +275,7 @@ export default {
<user-access-role-badge
v-if="accessLevel"
v-gl-tooltip
- class="gl-mr-3"
+ class="gl-mr-3 gl-display-none gl-sm-display-block"
:title="displayMemberBadgeText"
>
{{ accessLevel }}
@@ -277,7 +283,7 @@ export default {
<user-access-role-badge
v-else-if="isContributor"
v-gl-tooltip
- class="gl-mr-3"
+ class="gl-mr-3 gl-display-none gl-sm-display-block"
:title="displayContributorBadgeText"
>
{{ __('Contributor') }}
@@ -334,7 +340,7 @@ export default {
:aria-label="$options.i18n.editCommentLabel"
icon="pencil"
category="tertiary"
- class="note-action-button js-note-edit"
+ class="note-action-button js-note-edit gl-display-none gl-sm-display-block"
data-qa-selector="note_edit_button"
@click="onEdit"
/>
@@ -362,7 +368,18 @@ export default {
/>
<!-- eslint-enable @gitlab/vue-no-data-toggle -->
<ul class="dropdown-menu more-actions-dropdown dropdown-open-left">
- <gl-dropdown-item v-if="canReportAsAbuse" :href="reportAbusePath">
+ <gl-dropdown-item
+ v-if="canEdit"
+ class="js-note-edit gl-sm-display-none!"
+ @click.prevent="onEdit"
+ >
+ {{ __('Edit comment') }}
+ </gl-dropdown-item>
+ <gl-dropdown-item
+ v-if="canReportAsAbuse"
+ data-testid="report-abuse-button"
+ @click="toggleReportAbuseDrawer(true)"
+ >
{{ $options.i18n.reportAbuse }}
</gl-dropdown-item>
<gl-dropdown-item
@@ -380,5 +397,14 @@ export default {
</gl-dropdown-item>
</ul>
</div>
+ <!-- IMPORTANT: show this component lazily because it causes layout thrashing -->
+ <!-- https://gitlab.com/gitlab-org/gitlab/-/issues/331172#note_1269378396 -->
+ <abuse-category-selector
+ v-if="canReportAsAbuse && isReportAbuseDrawerOpen"
+ :reported-user-id="authorId"
+ :reported-from-url="noteUrl"
+ :show-drawer="isReportAbuseDrawerOpen"
+ @close-drawer="toggleReportAbuseDrawer(false)"
+ />
</div>
</template>
diff --git a/app/assets/javascripts/notes/components/note_header.vue b/app/assets/javascripts/notes/components/note_header.vue
index 79b6139d4b1..c83b3d870d7 100644
--- a/app/assets/javascripts/notes/components/note_header.vue
+++ b/app/assets/javascripts/notes/components/note_header.vue
@@ -96,6 +96,8 @@ export default {
'text-underline': this.isUsernameLinkHovered,
'author-name-link': true,
'js-user-link': true,
+ 'gl-overflow-hidden': true,
+ 'gl-overflow-wrap-break': true,
};
},
authorName() {
diff --git a/app/assets/javascripts/notes/components/noteable_note.vue b/app/assets/javascripts/notes/components/noteable_note.vue
index 826e7e5a3d0..93575ad57ff 100644
--- a/app/assets/javascripts/notes/components/noteable_note.vue
+++ b/app/assets/javascripts/notes/components/noteable_note.vue
@@ -43,6 +43,11 @@ export default {
SafeHtml,
},
mixins: [noteable, resolvable],
+ inject: {
+ reportAbusePath: {
+ default: '',
+ },
+ },
props: {
note: {
type: Object,
@@ -129,7 +134,7 @@ export default {
};
},
canReportAsAbuse() {
- return Boolean(this.note.report_abuse_path) && this.author.id !== this.getUserData.id;
+ return Boolean(this.reportAbusePath) && this.author.id !== this.getUserData.id;
},
noteAnchorId() {
return `note_${this.note.id}`;
@@ -488,7 +493,6 @@ export default {
:can-delete="note.current_user.can_edit"
:can-report-as-abuse="canReportAsAbuse"
:can-resolve="canResolve"
- :report-abuse-path="note.report_abuse_path"
:resolvable="note.resolvable || note.isDraft"
:is-resolved="note.resolved || note.resolve_discussion"
:is-resolving="isResolving"
diff --git a/app/assets/javascripts/notes/components/sidebar_subscription.vue b/app/assets/javascripts/notes/components/sidebar_subscription.vue
index 9fc11ff65d5..2a0a3d5414f 100644
--- a/app/assets/javascripts/notes/components/sidebar_subscription.vue
+++ b/app/assets/javascripts/notes/components/sidebar_subscription.vue
@@ -1,6 +1,6 @@
<script>
import { mapActions } from 'vuex';
-import { IssuableType } from '~/issues/constants';
+import { TYPE_EPIC, TYPE_ISSUE } from '~/issues/constants';
import { fetchPolicies } from '~/lib/graphql';
import { confidentialityQueries } from '~/sidebar/constants';
import { defaultClient as gqlClient } from '~/graphql_shared/issuable_client';
@@ -28,7 +28,7 @@ export default {
},
},
created() {
- if (this.issuableType !== IssuableType.Issue && this.issuableType !== IssuableType.Epic) {
+ if (this.issuableType !== TYPE_ISSUE && this.issuableType !== TYPE_EPIC) {
return;
}
diff --git a/app/assets/javascripts/notes/components/toggle_replies_widget.vue b/app/assets/javascripts/notes/components/toggle_replies_widget.vue
index 734e08dd586..4437d461308 100644
--- a/app/assets/javascripts/notes/components/toggle_replies_widget.vue
+++ b/app/assets/javascripts/notes/components/toggle_replies_widget.vue
@@ -79,7 +79,7 @@ export default {
:link-href="author.path"
:img-alt="author.name"
img-css-classes="gl-mr-0!"
- :img-src="author.avatar_url"
+ :img-src="author.avatar_url || author.avatarUrl"
:img-size="24"
:tooltip-text="author.name"
tooltip-placement="bottom"
@@ -102,7 +102,10 @@ export default {
</gl-link>
</template>
</gl-sprintf>
- <time-ago-tooltip :time="lastReply.created_at" tooltip-placement="bottom" />
+ <time-ago-tooltip
+ :time="lastReply.created_at || lastReply.createdAt"
+ tooltip-placement="bottom"
+ />
</template>
<gl-button
v-else
diff --git a/app/assets/javascripts/notes/i18n.js b/app/assets/javascripts/notes/i18n.js
index 9b5fd69f816..a758a55014a 100644
--- a/app/assets/javascripts/notes/i18n.js
+++ b/app/assets/javascripts/notes/i18n.js
@@ -45,4 +45,7 @@ export const COMMENT_FORM = {
commentHelp: __('Add a general comment to this %{noteableDisplayName}.'),
internalCommentHelp: __('Add a confidential internal note to this %{noteableDisplayName}.'),
},
+ attachmentMsg: s__(
+ 'Notes|Attachments are sent by email. Attachments over 10 MB are sent as links to your GitLab instance, and only accessible to project members.',
+ ),
};
diff --git a/app/assets/javascripts/notes/index.js b/app/assets/javascripts/notes/index.js
index 95263e666b2..2e09c9f2288 100644
--- a/app/assets/javascripts/notes/index.js
+++ b/app/assets/javascripts/notes/index.js
@@ -52,6 +52,7 @@ export default () => {
store,
provide: {
showTimelineViewToggle,
+ reportAbusePath: notesDataset.reportAbusePath,
},
data() {
return {
diff --git a/app/assets/javascripts/notes/stores/actions.js b/app/assets/javascripts/notes/stores/actions.js
index 5cad091ce2c..f6b9be6ee9b 100644
--- a/app/assets/javascripts/notes/stores/actions.js
+++ b/app/assets/javascripts/notes/stores/actions.js
@@ -4,6 +4,7 @@ import Vue from 'vue';
import Api from '~/api';
import { createAlert, VARIANT_INFO } from '~/flash';
import { EVENT_ISSUABLE_VUE_APP_CHANGE } from '~/issuable/constants';
+import { TYPE_ISSUE } from '~/issues/constants';
import axios from '~/lib/utils/axios_utils';
import { __, sprintf } from '~/locale';
import toast from '~/vue_shared/plugins/global_toast';
@@ -20,7 +21,7 @@ import TaskList from '~/task_list';
import mrWidgetEventHub from '~/vue_merge_request_widget/event_hub';
import SidebarStore from '~/sidebar/stores/sidebar_store';
import { convertToGraphQLId } from '~/graphql_shared/utils';
-import { TYPE_NOTE } from '~/graphql_shared/constants';
+import { TYPENAME_NOTE } from '~/graphql_shared/constants';
import notesEventHub from '../event_hub';
import promoteTimelineEvent from '../graphql/promote_timeline_event.mutation.graphql';
@@ -37,7 +38,8 @@ export const updateLockedAttribute = ({ commit, getters }, { locked, fullPath })
return utils.gqClient
.mutate({
- mutation: targetType === 'issue' ? updateIssueLockMutation : updateMergeRequestLockMutation,
+ mutation:
+ targetType === TYPE_ISSUE ? updateIssueLockMutation : updateMergeRequestLockMutation,
variables: {
input: {
projectPath: fullPath,
@@ -48,7 +50,7 @@ export const updateLockedAttribute = ({ commit, getters }, { locked, fullPath })
})
.then(({ data }) => {
const discussionLocked =
- targetType === 'issue'
+ targetType === TYPE_ISSUE
? data.issueSetLocked.issue.discussionLocked
: data.mergeRequestSetLocked.mergeRequest.discussionLocked;
@@ -276,7 +278,7 @@ export const promoteCommentToTimelineEvent = (
mutation: promoteTimelineEvent,
variables: {
input: {
- noteId: convertToGraphQLId(TYPE_NOTE, noteId),
+ noteId: convertToGraphQLId(TYPENAME_NOTE, noteId),
},
},
})