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
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/admin/abuse_report/components')
-rw-r--r--app/assets/javascripts/admin/abuse_report/components/abuse_report_app.vue7
-rw-r--r--app/assets/javascripts/admin/abuse_report/components/abuse_report_notes.vue92
-rw-r--r--app/assets/javascripts/admin/abuse_report/components/activity_events_list.vue2
-rw-r--r--app/assets/javascripts/admin/abuse_report/components/graphql/abuse_report.query.graphql13
-rw-r--r--app/assets/javascripts/admin/abuse_report/components/graphql/abuse_report_labels.query.graphql11
-rw-r--r--app/assets/javascripts/admin/abuse_report/components/graphql/create_abuse_report_label.mutation.graphql10
-rw-r--r--app/assets/javascripts/admin/abuse_report/components/labels_select.vue2
-rw-r--r--app/assets/javascripts/admin/abuse_report/components/notes/abuse_report_discussion.vue104
-rw-r--r--app/assets/javascripts/admin/abuse_report/components/notes/abuse_report_note.vue81
-rw-r--r--app/assets/javascripts/admin/abuse_report/components/notes/abuse_report_note_body.vue48
-rw-r--r--app/assets/javascripts/admin/abuse_report/components/report_details.vue2
-rw-r--r--app/assets/javascripts/admin/abuse_report/components/reported_content.vue4
12 files changed, 337 insertions, 39 deletions
diff --git a/app/assets/javascripts/admin/abuse_report/components/abuse_report_app.vue b/app/assets/javascripts/admin/abuse_report/components/abuse_report_app.vue
index 3c46de7c2be..f0540ffa71e 100644
--- a/app/assets/javascripts/admin/abuse_report/components/abuse_report_app.vue
+++ b/app/assets/javascripts/admin/abuse_report/components/abuse_report_app.vue
@@ -7,6 +7,7 @@ import ReportDetails from './report_details.vue';
import ReportedContent from './reported_content.vue';
import ActivityEventsList from './activity_events_list.vue';
import ActivityHistoryItem from './activity_history_item.vue';
+import AbuseReportNotes from './abuse_report_notes.vue';
const alertDefaults = {
visible: false,
@@ -24,6 +25,7 @@ export default {
ReportedContent,
ActivityEventsList,
ActivityHistoryItem,
+ AbuseReportNotes,
},
mixins: [glFeatureFlagsMixin()],
props: {
@@ -96,5 +98,10 @@ export default {
/>
</template>
</activity-events-list>
+
+ <abuse-report-notes
+ v-if="glFeatures.abuseReportNotes"
+ :abuse-report-id="abuseReport.report.globalId"
+ />
</section>
</template>
diff --git a/app/assets/javascripts/admin/abuse_report/components/abuse_report_notes.vue b/app/assets/javascripts/admin/abuse_report/components/abuse_report_notes.vue
new file mode 100644
index 00000000000..80af7d7400a
--- /dev/null
+++ b/app/assets/javascripts/admin/abuse_report/components/abuse_report_notes.vue
@@ -0,0 +1,92 @@
+<script>
+import { uniqueId } from 'lodash';
+import { __ } from '~/locale';
+import { createAlert } from '~/alert';
+import SkeletonLoadingContainer from '~/vue_shared/components/notes/skeleton_note.vue';
+import { SKELETON_NOTES_COUNT } from '~/admin/abuse_report/constants';
+import abuseReportNotesQuery from '../graphql/notes/abuse_report_notes.query.graphql';
+import AbuseReportDiscussion from './notes/abuse_report_discussion.vue';
+
+export default {
+ name: 'AbuseReportNotes',
+ SKELETON_NOTES_COUNT,
+ i18n: {
+ fetchError: __('An error occurred while fetching comments, please try again.'),
+ },
+ components: {
+ SkeletonLoadingContainer,
+ AbuseReportDiscussion,
+ },
+ props: {
+ abuseReportId: {
+ type: String,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ addNoteKey: uniqueId(`abuse-report-add-note-${this.abuseReportId}`),
+ };
+ },
+ apollo: {
+ abuseReportNotes: {
+ query: abuseReportNotesQuery,
+ variables() {
+ return {
+ id: this.abuseReportId,
+ };
+ },
+ update(data) {
+ return data.abuseReport?.discussions || [];
+ },
+ skip() {
+ return !this.abuseReportId;
+ },
+ error() {
+ createAlert({ message: this.$options.i18n.fetchError });
+ },
+ },
+ },
+ computed: {
+ initialLoading() {
+ return this.$apollo.queries.abuseReportNotes.loading;
+ },
+ notesArray() {
+ return this.abuseReportNotes?.nodes || [];
+ },
+ },
+ methods: {
+ getDiscussionKey(discussion) {
+ const discussionId = discussion.notes.nodes[0].id;
+ return discussionId.split('/')[discussionId.split('/').length - 1];
+ },
+ },
+};
+</script>
+
+<template>
+ <div>
+ <div class="issuable-discussion gl-mb-5 gl-clearfix!">
+ <template v-if="initialLoading">
+ <ul class="notes main-notes-list timeline">
+ <skeleton-loading-container
+ v-for="index in $options.SKELETON_NOTES_COUNT"
+ :key="index"
+ class="note-skeleton"
+ />
+ </ul>
+ </template>
+
+ <template v-else>
+ <ul class="notes main-notes-list timeline">
+ <abuse-report-discussion
+ v-for="discussion in notesArray"
+ :key="getDiscussionKey(discussion)"
+ :discussion="discussion.notes.nodes"
+ :abuse-report-id="abuseReportId"
+ />
+ </ul>
+ </template>
+ </div>
+ </div>
+</template>
diff --git a/app/assets/javascripts/admin/abuse_report/components/activity_events_list.vue b/app/assets/javascripts/admin/abuse_report/components/activity_events_list.vue
index 8c4c1da28b8..2206e600543 100644
--- a/app/assets/javascripts/admin/abuse_report/components/activity_events_list.vue
+++ b/app/assets/javascripts/admin/abuse_report/components/activity_events_list.vue
@@ -11,7 +11,7 @@ export default {
<!-- The styles `issuable-discussion`, `timeline`, `main-notes-list` and `notes` used below
are declared in app/assets/stylesheets/pages/notes.scss -->
<section class="gl-pt-6 issuable-discussion">
- <h2 class="gl-font-lg gl-mt-0 gl-mb-2">{{ $options.i18n.activity }}</h2>
+ <h2 class="gl-font-size-h1 gl-mt-0 gl-mb-4">{{ $options.i18n.activity }}</h2>
<ul class="timeline main-notes-list notes">
<slot name="history-items"></slot>
</ul>
diff --git a/app/assets/javascripts/admin/abuse_report/components/graphql/abuse_report.query.graphql b/app/assets/javascripts/admin/abuse_report/components/graphql/abuse_report.query.graphql
deleted file mode 100644
index f5b075cb9af..00000000000
--- a/app/assets/javascripts/admin/abuse_report/components/graphql/abuse_report.query.graphql
+++ /dev/null
@@ -1,13 +0,0 @@
-query abuseReportQuery($id: AbuseReportID!) {
- abuseReport(id: $id) {
- labels {
- nodes {
- id
- title
- description
- color
- textColor
- }
- }
- }
-}
diff --git a/app/assets/javascripts/admin/abuse_report/components/graphql/abuse_report_labels.query.graphql b/app/assets/javascripts/admin/abuse_report/components/graphql/abuse_report_labels.query.graphql
deleted file mode 100644
index 4e724b4db2c..00000000000
--- a/app/assets/javascripts/admin/abuse_report/components/graphql/abuse_report_labels.query.graphql
+++ /dev/null
@@ -1,11 +0,0 @@
-query abuseReportLabelsQuery($searchTerm: String) {
- labels: abuseReportLabels(searchTerm: $searchTerm) {
- nodes {
- id
- title
- description
- color
- textColor
- }
- }
-}
diff --git a/app/assets/javascripts/admin/abuse_report/components/graphql/create_abuse_report_label.mutation.graphql b/app/assets/javascripts/admin/abuse_report/components/graphql/create_abuse_report_label.mutation.graphql
deleted file mode 100644
index 0781b8e634b..00000000000
--- a/app/assets/javascripts/admin/abuse_report/components/graphql/create_abuse_report_label.mutation.graphql
+++ /dev/null
@@ -1,10 +0,0 @@
-#import "~/graphql_shared/fragments/label.fragment.graphql"
-
-mutation createAbuseReportLabel($title: String!, $color: String) {
- labelCreate: abuseReportLabelCreate(input: { title: $title, color: $color }) {
- label {
- ...Label
- }
- errors
- }
-}
diff --git a/app/assets/javascripts/admin/abuse_report/components/labels_select.vue b/app/assets/javascripts/admin/abuse_report/components/labels_select.vue
index 747c9a1a947..d2d143f0460 100644
--- a/app/assets/javascripts/admin/abuse_report/components/labels_select.vue
+++ b/app/assets/javascripts/admin/abuse_report/components/labels_select.vue
@@ -11,7 +11,7 @@ import DropdownContentsCreateView from '~/sidebar/components/labels/labels_selec
import DropdownHeader from '~/sidebar/components/labels/labels_select_widget/dropdown_header.vue';
import DropdownFooter from '~/sidebar/components/labels/labels_select_widget/dropdown_footer.vue';
import DropdownWidget from '~/vue_shared/components/dropdown/dropdown_widget/dropdown_widget.vue';
-import abuseReportLabelsQuery from './graphql/abuse_report_labels.query.graphql';
+import abuseReportLabelsQuery from '../graphql/abuse_report_labels.query.graphql';
export default {
components: {
diff --git a/app/assets/javascripts/admin/abuse_report/components/notes/abuse_report_discussion.vue b/app/assets/javascripts/admin/abuse_report/components/notes/abuse_report_discussion.vue
new file mode 100644
index 00000000000..4d24471fa43
--- /dev/null
+++ b/app/assets/javascripts/admin/abuse_report/components/notes/abuse_report_discussion.vue
@@ -0,0 +1,104 @@
+<script>
+import { getIdFromGraphQLId } from '~/graphql_shared/utils';
+import TimelineEntryItem from '~/vue_shared/components/notes/timeline_entry_item.vue';
+import DiscussionNotesRepliesWrapper from '~/notes/components/discussion_notes_replies_wrapper.vue';
+import ToggleRepliesWidget from '~/notes/components/toggle_replies_widget.vue';
+import AbuseReportNote from './abuse_report_note.vue';
+
+export default {
+ name: 'AbuseReportDiscussion',
+ components: {
+ TimelineEntryItem,
+ DiscussionNotesRepliesWrapper,
+ ToggleRepliesWidget,
+ AbuseReportNote,
+ },
+ props: {
+ abuseReportId: {
+ type: String,
+ required: true,
+ },
+ discussion: {
+ type: Array,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ isExpanded: true,
+ };
+ },
+ computed: {
+ note() {
+ return this.discussion[0];
+ },
+ noteId() {
+ return getIdFromGraphQLId(this.note.id);
+ },
+ replies() {
+ if (this.discussion?.length > 1) {
+ return this.discussion.slice(1);
+ }
+ return null;
+ },
+ hasReplies() {
+ return Boolean(this.replies?.length);
+ },
+ discussionId() {
+ return this.discussion[0]?.discussion?.id || '';
+ },
+ },
+ methods: {
+ toggleDiscussion() {
+ this.isExpanded = !this.isExpanded;
+ },
+ },
+};
+</script>
+
+<template>
+ <abuse-report-note
+ v-if="!hasReplies"
+ :note="note"
+ :abuse-report-id="abuseReportId"
+ class="gl-mb-4"
+ />
+ <timeline-entry-item v-else :data-note-id="noteId" class="note note-discussion gl-px-0">
+ <div class="timeline-content">
+ <div class="discussion">
+ <div class="discussion-body">
+ <div class="discussion-wrapper">
+ <div class="discussion-notes">
+ <ul class="notes">
+ <abuse-report-note
+ :note="note"
+ :discussion-id="discussionId"
+ :abuse-report-id="abuseReportId"
+ class="gl-mb-4"
+ />
+ <discussion-notes-replies-wrapper>
+ <toggle-replies-widget
+ v-if="hasReplies"
+ :collapsed="!isExpanded"
+ :replies="replies"
+ @toggle="toggleDiscussion({ discussionId })"
+ />
+ <template v-if="isExpanded">
+ <template v-for="reply in replies">
+ <abuse-report-note
+ :key="reply.id"
+ :discussion-id="discussionId"
+ :note="reply"
+ :abuse-report-id="abuseReportId"
+ />
+ </template>
+ </template>
+ </discussion-notes-replies-wrapper>
+ </ul>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </timeline-entry-item>
+</template>
diff --git a/app/assets/javascripts/admin/abuse_report/components/notes/abuse_report_note.vue b/app/assets/javascripts/admin/abuse_report/components/notes/abuse_report_note.vue
new file mode 100644
index 00000000000..6da3017e11e
--- /dev/null
+++ b/app/assets/javascripts/admin/abuse_report/components/notes/abuse_report_note.vue
@@ -0,0 +1,81 @@
+<script>
+import { GlAvatarLink, GlAvatar } from '@gitlab/ui';
+import SafeHtml from '~/vue_shared/directives/safe_html';
+import { getIdFromGraphQLId } from '~/graphql_shared/utils';
+import TimelineEntryItem from '~/vue_shared/components/notes/timeline_entry_item.vue';
+import NoteHeader from '~/notes/components/note_header.vue';
+import NoteBody from './abuse_report_note_body.vue';
+
+export default {
+ name: 'AbuseReportNote',
+ directives: {
+ SafeHtml,
+ },
+ components: {
+ GlAvatarLink,
+ GlAvatar,
+ TimelineEntryItem,
+ NoteHeader,
+ NoteBody,
+ },
+ props: {
+ abuseReportId: {
+ type: String,
+ required: true,
+ },
+ note: {
+ type: Object,
+ required: true,
+ },
+ },
+ computed: {
+ noteAnchorId() {
+ return `note_${getIdFromGraphQLId(this.note.id)}`;
+ },
+ author() {
+ return this.note.author;
+ },
+ authorId() {
+ return getIdFromGraphQLId(this.author.id);
+ },
+ },
+};
+</script>
+
+<template>
+ <timeline-entry-item :id="noteAnchorId" class="note note-wrapper note-comment">
+ <div :key="note.id" class="timeline-avatar gl-float-left">
+ <gl-avatar-link
+ :href="author.webUrl"
+ :data-user-id="authorId"
+ :data-username="author.username"
+ class="js-user-link"
+ >
+ <gl-avatar
+ :src="author.avatarUrl"
+ :entity-name="author.username"
+ :alt="author.name"
+ :size="32"
+ />
+ </gl-avatar-link>
+ </div>
+ <div class="timeline-content">
+ <div data-testid="note-wrapper">
+ <div class="note-header">
+ <note-header
+ :author="author"
+ :created-at="note.createdAt"
+ :note-id="note.id"
+ :note-url="note.url"
+ >
+ <span v-if="note.createdAt" class="d-none d-sm-inline">&middot;</span>
+ </note-header>
+ </div>
+
+ <div class="timeline-discussion-body">
+ <note-body ref="noteBody" :note="note" />
+ </div>
+ </div>
+ </div>
+ </timeline-entry-item>
+</template>
diff --git a/app/assets/javascripts/admin/abuse_report/components/notes/abuse_report_note_body.vue b/app/assets/javascripts/admin/abuse_report/components/notes/abuse_report_note_body.vue
new file mode 100644
index 00000000000..ab3d7f5fa6c
--- /dev/null
+++ b/app/assets/javascripts/admin/abuse_report/components/notes/abuse_report_note_body.vue
@@ -0,0 +1,48 @@
+<script>
+import SafeHtml from '~/vue_shared/directives/safe_html';
+import { renderGFM } from '~/behaviors/markdown/render_gfm';
+
+export default {
+ name: 'AbuseReportNoteBody',
+ directives: {
+ SafeHtml,
+ },
+ props: {
+ note: {
+ type: Object,
+ required: true,
+ },
+ },
+ watch: {
+ 'note.bodyHtml': {
+ immediate: true,
+ async handler(newVal, oldVal) {
+ if (newVal === oldVal) {
+ return;
+ }
+ await this.$nextTick();
+ this.renderGFM();
+ },
+ },
+ },
+ methods: {
+ renderGFM() {
+ renderGFM(this.$refs['note-body']);
+ gl?.lazyLoader?.searchLazyImages();
+ },
+ },
+ safeHtmlConfig: {
+ ADD_TAGS: ['use', 'gl-emoji', 'copy-code'],
+ },
+};
+</script>
+
+<template>
+ <div ref="note-body" class="note-body">
+ <div
+ v-safe-html:[$options.safeHtmlConfig]="note.bodyHtml"
+ class="note-text md"
+ data-testid="abuse-report-note-body"
+ ></div>
+ </div>
+</template>
diff --git a/app/assets/javascripts/admin/abuse_report/components/report_details.vue b/app/assets/javascripts/admin/abuse_report/components/report_details.vue
index 10e1dca7f91..89017e6cbd4 100644
--- a/app/assets/javascripts/admin/abuse_report/components/report_details.vue
+++ b/app/assets/javascripts/admin/abuse_report/components/report_details.vue
@@ -1,8 +1,8 @@
<script>
import { __ } from '~/locale';
import { createAlert } from '~/alert';
+import abuseReportQuery from '../graphql/abuse_report.query.graphql';
import LabelsSelect from './labels_select.vue';
-import abuseReportQuery from './graphql/abuse_report.query.graphql';
export default {
name: 'ReportDetails',
diff --git a/app/assets/javascripts/admin/abuse_report/components/reported_content.vue b/app/assets/javascripts/admin/abuse_report/components/reported_content.vue
index 84d6f25ac05..99c8b3ece10 100644
--- a/app/assets/javascripts/admin/abuse_report/components/reported_content.vue
+++ b/app/assets/javascripts/admin/abuse_report/components/reported_content.vue
@@ -67,7 +67,7 @@ export default {
<div
class="gl-pb-3 gl-display-flex gl-justify-content-space-between gl-xs-flex-direction-column gl-align-items-center"
>
- <h2 class="gl-font-lg gl-mt-2 gl-mb-2">
+ <h2 class="gl-font-size-h1 gl-mt-2 gl-mb-2">
{{ $options.i18n.reportTypes[reportType] }}
</h2>
@@ -128,7 +128,7 @@ export default {
</gl-link>
<time-ago-tooltip
:time="report.reportedAt"
- class="gl-ml-3 gl-text-secondary gl-xs-w-full"
+ class="gl-ml-3 gl-text-secondary gl-w-full gl-sm-w-auto"
/>
</div>
</div>