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/design_management_legacy/components/design_notes')
-rw-r--r--app/assets/javascripts/design_management_legacy/components/design_notes/design_discussion.vue297
-rw-r--r--app/assets/javascripts/design_management_legacy/components/design_notes/design_note.vue156
-rw-r--r--app/assets/javascripts/design_management_legacy/components/design_notes/design_reply_form.vue141
-rw-r--r--app/assets/javascripts/design_management_legacy/components/design_notes/toggle_replies_widget.vue70
4 files changed, 0 insertions, 664 deletions
diff --git a/app/assets/javascripts/design_management_legacy/components/design_notes/design_discussion.vue b/app/assets/javascripts/design_management_legacy/components/design_notes/design_discussion.vue
deleted file mode 100644
index 6a20517eed7..00000000000
--- a/app/assets/javascripts/design_management_legacy/components/design_notes/design_discussion.vue
+++ /dev/null
@@ -1,297 +0,0 @@
-<script>
-import { ApolloMutation } from 'vue-apollo';
-import { GlTooltipDirective, GlIcon, GlLoadingIcon, GlLink } from '@gitlab/ui';
-import { s__ } from '~/locale';
-import ReplyPlaceholder from '~/notes/components/discussion_reply_placeholder.vue';
-import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
-import allVersionsMixin from '../../mixins/all_versions';
-import createNoteMutation from '../../graphql/mutations/create_note.mutation.graphql';
-import toggleResolveDiscussionMutation from '../../graphql/mutations/toggle_resolve_discussion.mutation.graphql';
-import getDesignQuery from '../../graphql/queries/get_design.query.graphql';
-import activeDiscussionQuery from '../../graphql/queries/active_discussion.query.graphql';
-import DesignNote from './design_note.vue';
-import DesignReplyForm from './design_reply_form.vue';
-import { updateStoreAfterAddDiscussionComment } from '../../utils/cache_update';
-import { ACTIVE_DISCUSSION_SOURCE_TYPES } from '../../constants';
-import ToggleRepliesWidget from './toggle_replies_widget.vue';
-
-export default {
- components: {
- ApolloMutation,
- DesignNote,
- ReplyPlaceholder,
- DesignReplyForm,
- GlIcon,
- GlLoadingIcon,
- GlLink,
- ToggleRepliesWidget,
- TimeAgoTooltip,
- },
- directives: {
- GlTooltip: GlTooltipDirective,
- },
- mixins: [allVersionsMixin],
- props: {
- discussion: {
- type: Object,
- required: true,
- },
- noteableId: {
- type: String,
- required: true,
- },
- designId: {
- type: String,
- required: true,
- },
- markdownPreviewPath: {
- type: String,
- required: false,
- default: '',
- },
- resolvedDiscussionsExpanded: {
- type: Boolean,
- required: true,
- },
- discussionWithOpenForm: {
- type: String,
- required: true,
- },
- },
- apollo: {
- activeDiscussion: {
- query: activeDiscussionQuery,
- result({ data }) {
- const discussionId = data.activeDiscussion.id;
- if (this.discussion.resolved && !this.resolvedDiscussionsExpanded) {
- return;
- }
- // We watch any changes to the active discussion from the design pins and scroll to this discussion if it exists
- // We don't want scrollIntoView to be triggered from the discussion click itself
- if (
- discussionId &&
- data.activeDiscussion.source === ACTIVE_DISCUSSION_SOURCE_TYPES.pin &&
- discussionId === this.discussion.notes[0].id
- ) {
- this.$el.scrollIntoView({
- behavior: 'smooth',
- inline: 'start',
- });
- }
- },
- },
- },
- data() {
- return {
- discussionComment: '',
- isFormRendered: false,
- activeDiscussion: {},
- isResolving: false,
- shouldChangeResolvedStatus: false,
- areRepliesCollapsed: this.discussion.resolved,
- };
- },
- computed: {
- mutationPayload() {
- return {
- noteableId: this.noteableId,
- body: this.discussionComment,
- discussionId: this.discussion.id,
- };
- },
- designVariables() {
- return {
- fullPath: this.projectPath,
- iid: this.issueIid,
- filenames: [this.$route.params.id],
- atVersion: this.designsVersion,
- };
- },
- isDiscussionHighlighted() {
- return this.discussion.notes[0].id === this.activeDiscussion.id;
- },
- resolveCheckboxText() {
- return this.discussion.resolved
- ? s__('DesignManagement|Unresolve thread')
- : s__('DesignManagement|Resolve thread');
- },
- firstNote() {
- return this.discussion.notes[0];
- },
- discussionReplies() {
- return this.discussion.notes.slice(1);
- },
- areRepliesShown() {
- return !this.discussion.resolved || !this.areRepliesCollapsed;
- },
- resolveIconName() {
- return this.discussion.resolved ? 'check-circle-filled' : 'check-circle';
- },
- isRepliesWidgetVisible() {
- return this.discussion.resolved && this.discussionReplies.length > 0;
- },
- isReplyPlaceholderVisible() {
- return this.areRepliesShown || !this.discussionReplies.length;
- },
- isFormVisible() {
- return this.isFormRendered && this.discussionWithOpenForm === this.discussion.id;
- },
- },
- methods: {
- addDiscussionComment(
- store,
- {
- data: { createNote },
- },
- ) {
- updateStoreAfterAddDiscussionComment(
- store,
- createNote,
- getDesignQuery,
- this.designVariables,
- this.discussion.id,
- );
- },
- onDone() {
- this.discussionComment = '';
- this.hideForm();
- if (this.shouldChangeResolvedStatus) {
- this.toggleResolvedStatus();
- }
- },
- onCreateNoteError(err) {
- this.$emit('createNoteError', err);
- },
- hideForm() {
- this.isFormRendered = false;
- this.discussionComment = '';
- },
- showForm() {
- this.$emit('openForm', this.discussion.id);
- this.isFormRendered = true;
- },
- toggleResolvedStatus() {
- this.isResolving = true;
- this.$apollo
- .mutate({
- mutation: toggleResolveDiscussionMutation,
- variables: { id: this.discussion.id, resolve: !this.discussion.resolved },
- })
- .then(({ data }) => {
- if (data.errors?.length > 0) {
- this.$emit('resolveDiscussionError', data.errors[0]);
- }
- })
- .catch(err => {
- this.$emit('resolveDiscussionError', err);
- })
- .finally(() => {
- this.isResolving = false;
- });
- },
- },
- createNoteMutation,
-};
-</script>
-
-<template>
- <div class="design-discussion-wrapper">
- <div
- class="badge badge-pill gl-display-flex gl-align-items-center gl-justify-content-center"
- :class="{ resolved: discussion.resolved }"
- type="button"
- >
- {{ discussion.index }}
- </div>
- <ul
- class="design-discussion bordered-box gl-relative gl-p-0 gl-list-style-none"
- data-qa-selector="design_discussion_content"
- >
- <design-note
- :note="firstNote"
- :markdown-preview-path="markdownPreviewPath"
- :is-resolving="isResolving"
- :class="{ 'gl-bg-blue-50': isDiscussionHighlighted }"
- @error="$emit('updateNoteError', $event)"
- >
- <template v-if="discussion.resolvable" #resolveDiscussion>
- <button
- v-gl-tooltip
- :class="{ 'is-active': discussion.resolved }"
- :title="resolveCheckboxText"
- :aria-label="resolveCheckboxText"
- type="button"
- class="line-resolve-btn note-action-button gl-mr-3"
- data-testid="resolve-button"
- @click.stop="toggleResolvedStatus"
- >
- <gl-icon v-if="!isResolving" :name="resolveIconName" data-testid="resolve-icon" />
- <gl-loading-icon v-else inline />
- </button>
- </template>
- <template v-if="discussion.resolved" #resolvedStatus>
- <p class="gl-text-gray-500 gl-font-sm gl-m-0 gl-mt-5" data-testid="resolved-message">
- {{ __('Resolved by') }}
- <gl-link
- class="gl-text-gray-500 gl-text-decoration-none gl-font-sm link-inherit-color"
- :href="discussion.resolvedBy.webUrl"
- target="_blank"
- >{{ discussion.resolvedBy.name }}</gl-link
- >
- <time-ago-tooltip :time="discussion.resolvedAt" tooltip-placement="bottom" />
- </p>
- </template>
- </design-note>
- <toggle-replies-widget
- v-if="isRepliesWidgetVisible"
- :collapsed="areRepliesCollapsed"
- :replies="discussionReplies"
- @toggle="areRepliesCollapsed = !areRepliesCollapsed"
- />
- <design-note
- v-for="note in discussionReplies"
- v-show="areRepliesShown"
- :key="note.id"
- :note="note"
- :markdown-preview-path="markdownPreviewPath"
- :is-resolving="isResolving"
- :class="{ 'gl-bg-blue-50': isDiscussionHighlighted }"
- @error="$emit('updateNoteError', $event)"
- />
- <li v-show="isReplyPlaceholderVisible" class="reply-wrapper">
- <reply-placeholder
- v-if="!isFormVisible"
- class="qa-discussion-reply"
- :button-text="__('Reply...')"
- @onClick="showForm"
- />
- <apollo-mutation
- v-else
- #default="{ mutate, loading }"
- :mutation="$options.createNoteMutation"
- :variables="{
- input: mutationPayload,
- }"
- :update="addDiscussionComment"
- @done="onDone"
- @error="onCreateNoteError"
- >
- <design-reply-form
- v-model="discussionComment"
- :is-saving="loading"
- :markdown-preview-path="markdownPreviewPath"
- @submitForm="mutate"
- @cancelForm="hideForm"
- >
- <template v-if="discussion.resolvable" #resolveCheckbox>
- <label data-testid="resolve-checkbox">
- <input v-model="shouldChangeResolvedStatus" type="checkbox" />
- {{ resolveCheckboxText }}
- </label>
- </template>
- </design-reply-form>
- </apollo-mutation>
- </li>
- </ul>
- </div>
-</template>
diff --git a/app/assets/javascripts/design_management_legacy/components/design_notes/design_note.vue b/app/assets/javascripts/design_management_legacy/components/design_notes/design_note.vue
deleted file mode 100644
index b1f3a43a66d..00000000000
--- a/app/assets/javascripts/design_management_legacy/components/design_notes/design_note.vue
+++ /dev/null
@@ -1,156 +0,0 @@
-<script>
-import { ApolloMutation } from 'vue-apollo';
-import { GlTooltipDirective, GlIcon } from '@gitlab/ui';
-import updateNoteMutation from '../../graphql/mutations/update_note.mutation.graphql';
-import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue';
-import TimelineEntryItem from '~/vue_shared/components/notes/timeline_entry_item.vue';
-import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
-import DesignReplyForm from './design_reply_form.vue';
-import { findNoteId } from '../../utils/design_management_utils';
-import { hasErrors } from '../../utils/cache_update';
-
-export default {
- components: {
- UserAvatarLink,
- TimelineEntryItem,
- TimeAgoTooltip,
- DesignReplyForm,
- ApolloMutation,
- GlIcon,
- },
- directives: {
- GlTooltip: GlTooltipDirective,
- },
- props: {
- note: {
- type: Object,
- required: true,
- },
- markdownPreviewPath: {
- type: String,
- required: false,
- default: '',
- },
- },
- data() {
- return {
- noteText: this.note.body,
- isEditing: false,
- };
- },
- computed: {
- author() {
- return this.note.author;
- },
- noteAnchorId() {
- return findNoteId(this.note.id);
- },
- isNoteLinked() {
- return this.$route.hash === `#note_${this.noteAnchorId}`;
- },
- mutationPayload() {
- return {
- id: this.note.id,
- body: this.noteText,
- };
- },
- isEditButtonVisible() {
- return !this.isEditing && this.note.userPermissions.adminNote;
- },
- },
- mounted() {
- if (this.isNoteLinked) {
- this.$refs.anchor.$el.scrollIntoView({ behavior: 'smooth', inline: 'start' });
- }
- },
- methods: {
- hideForm() {
- this.isEditing = false;
- this.noteText = this.note.body;
- },
- onDone({ data }) {
- this.hideForm();
- if (hasErrors(data.updateNote)) {
- this.$emit('error', data.errors[0]);
- }
- },
- },
- updateNoteMutation,
-};
-</script>
-
-<template>
- <timeline-entry-item :id="`note_${noteAnchorId}`" ref="anchor" class="design-note note-form">
- <user-avatar-link
- :link-href="author.webUrl"
- :img-src="author.avatarUrl"
- :img-alt="author.username"
- :img-size="40"
- />
- <div class="d-flex justify-content-between">
- <div>
- <a
- v-once
- :href="author.webUrl"
- class="js-user-link"
- :data-user-id="author.id"
- :data-username="author.username"
- >
- <span class="note-header-author-name bold">{{ author.name }}</span>
- <span v-if="author.status_tooltip_html" v-html="author.status_tooltip_html"></span>
- <span class="note-headline-light">@{{ author.username }}</span>
- </a>
- <span class="note-headline-light note-headline-meta">
- <span class="system-note-message"> <slot></slot> </span>
- <template v-if="note.createdAt">
- <span class="system-note-separator"></span>
- <a class="note-timestamp system-note-separator" :href="`#note_${noteAnchorId}`">
- <time-ago-tooltip :time="note.createdAt" tooltip-placement="bottom" />
- </a>
- </template>
- </span>
- </div>
- <div class="gl-display-flex">
- <slot name="resolveDiscussion"></slot>
- <button
- v-if="isEditButtonVisible"
- v-gl-tooltip
- type="button"
- :title="__('Edit comment')"
- class="note-action-button js-note-edit btn btn-transparent qa-note-edit-button"
- @click="isEditing = true"
- >
- <gl-icon name="pencil" class="link-highlight" />
- </button>
- </div>
- </div>
- <template v-if="!isEditing">
- <div
- class="note-text js-note-text md"
- data-qa-selector="note_content"
- v-html="note.bodyHtml"
- ></div>
- <slot name="resolvedStatus"></slot>
- </template>
- <apollo-mutation
- v-else
- #default="{ mutate, loading }"
- :mutation="$options.updateNoteMutation"
- :variables="{
- input: mutationPayload,
- }"
- @error="$emit('error', $event)"
- @done="onDone"
- >
- <design-reply-form
- v-model="noteText"
- :is-saving="loading"
- :markdown-preview-path="markdownPreviewPath"
- :is-new-comment="false"
- class="mt-5"
- @submitForm="mutate"
- @cancelForm="hideForm"
- />
- </apollo-mutation>
- </timeline-entry-item>
-</template>
diff --git a/app/assets/javascripts/design_management_legacy/components/design_notes/design_reply_form.vue b/app/assets/javascripts/design_management_legacy/components/design_notes/design_reply_form.vue
deleted file mode 100644
index 969034909f2..00000000000
--- a/app/assets/javascripts/design_management_legacy/components/design_notes/design_reply_form.vue
+++ /dev/null
@@ -1,141 +0,0 @@
-<script>
-import { GlDeprecatedButton, GlModal } from '@gitlab/ui';
-import MarkdownField from '~/vue_shared/components/markdown/field.vue';
-import { s__ } from '~/locale';
-
-export default {
- name: 'DesignReplyForm',
- components: {
- MarkdownField,
- GlDeprecatedButton,
- GlModal,
- },
- props: {
- markdownPreviewPath: {
- type: String,
- required: false,
- default: '',
- },
- value: {
- type: String,
- required: true,
- },
- isSaving: {
- type: Boolean,
- required: true,
- },
- isNewComment: {
- type: Boolean,
- required: false,
- default: true,
- },
- },
- data() {
- return {
- formText: this.value,
- };
- },
- computed: {
- hasValue() {
- return this.value.trim().length > 0;
- },
- modalSettings() {
- if (this.isNewComment) {
- return {
- title: s__('DesignManagement|Cancel comment confirmation'),
- okTitle: s__('DesignManagement|Discard comment'),
- cancelTitle: s__('DesignManagement|Keep comment'),
- content: s__('DesignManagement|Are you sure you want to cancel creating this comment?'),
- };
- }
- return {
- title: s__('DesignManagement|Cancel comment update confirmation'),
- okTitle: s__('DesignManagement|Cancel changes'),
- cancelTitle: s__('DesignManagement|Keep changes'),
- content: s__('DesignManagement|Are you sure you want to cancel changes to this comment?'),
- };
- },
- buttonText() {
- return this.isNewComment
- ? s__('DesignManagement|Comment')
- : s__('DesignManagement|Save comment');
- },
- },
- mounted() {
- this.focusInput();
- },
- methods: {
- submitForm() {
- if (this.hasValue) this.$emit('submitForm');
- },
- cancelComment() {
- if (this.hasValue && this.formText !== this.value) {
- this.$refs.cancelCommentModal.show();
- } else {
- this.$emit('cancelForm');
- }
- },
- focusInput() {
- this.$refs.textarea.focus();
- },
- },
-};
-</script>
-
-<template>
- <form class="new-note common-note-form" @submit.prevent>
- <markdown-field
- :markdown-preview-path="markdownPreviewPath"
- :can-attach-file="false"
- :enable-autocomplete="true"
- :textarea-value="value"
- markdown-docs-path="/help/user/markdown"
- class="bordered-box"
- >
- <template #textarea>
- <textarea
- ref="textarea"
- :value="value"
- class="note-textarea js-gfm-input js-autosize markdown-area"
- dir="auto"
- data-supports-quick-actions="false"
- data-qa-selector="note_textarea"
- :aria-label="__('Description')"
- :placeholder="__('Write a comment…')"
- @input="$emit('input', $event.target.value)"
- @keydown.meta.enter="submitForm"
- @keydown.ctrl.enter="submitForm"
- @keyup.esc.stop="cancelComment"
- >
- </textarea>
- </template>
- </markdown-field>
- <slot name="resolveCheckbox"></slot>
- <div class="note-form-actions gl-display-flex gl-justify-content-space-between">
- <gl-deprecated-button
- ref="submitButton"
- :disabled="!hasValue || isSaving"
- variant="success"
- type="submit"
- data-track-event="click_button"
- data-qa-selector="save_comment_button"
- @click="$emit('submitForm')"
- >
- {{ buttonText }}
- </gl-deprecated-button>
- <gl-deprecated-button ref="cancelButton" @click="cancelComment">{{
- __('Cancel')
- }}</gl-deprecated-button>
- </div>
- <gl-modal
- ref="cancelCommentModal"
- ok-variant="danger"
- :title="modalSettings.title"
- :ok-title="modalSettings.okTitle"
- :cancel-title="modalSettings.cancelTitle"
- modal-id="cancel-comment-modal"
- @ok="$emit('cancelForm')"
- >{{ modalSettings.content }}
- </gl-modal>
- </form>
-</template>
diff --git a/app/assets/javascripts/design_management_legacy/components/design_notes/toggle_replies_widget.vue b/app/assets/javascripts/design_management_legacy/components/design_notes/toggle_replies_widget.vue
deleted file mode 100644
index 2e366282de3..00000000000
--- a/app/assets/javascripts/design_management_legacy/components/design_notes/toggle_replies_widget.vue
+++ /dev/null
@@ -1,70 +0,0 @@
-<script>
-import { GlIcon, GlButton, GlLink } from '@gitlab/ui';
-import { __, n__ } from '~/locale';
-import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
-
-export default {
- name: 'ToggleNotesWidget',
- components: {
- GlIcon,
- GlButton,
- GlLink,
- TimeAgoTooltip,
- },
- props: {
- collapsed: {
- type: Boolean,
- required: true,
- },
- replies: {
- type: Array,
- required: true,
- },
- },
- computed: {
- lastReply() {
- return this.replies[this.replies.length - 1];
- },
- iconName() {
- return this.collapsed ? 'chevron-right' : 'chevron-down';
- },
- toggleText() {
- return this.collapsed
- ? `${this.replies.length} ${n__('reply', 'replies', this.replies.length)}`
- : __('Collapse replies');
- },
- },
-};
-</script>
-
-<template>
- <li
- class="toggle-comments gl-bg-gray-50 gl-display-flex gl-align-items-center gl-py-3"
- :class="{ expanded: !collapsed }"
- data-testid="toggle-comments-wrapper"
- >
- <gl-icon :name="iconName" class="gl-ml-3" @click.stop="$emit('toggle')" />
- <gl-button
- variant="link"
- class="toggle-comments-button gl-ml-2 gl-mr-2"
- @click.stop="$emit('toggle')"
- >
- {{ toggleText }}
- </gl-button>
- <template v-if="collapsed">
- <span class="gl-text-gray-500">{{ __('Last reply by') }}</span>
- <gl-link
- :href="lastReply.author.webUrl"
- target="_blank"
- class="link-inherit-color gl-text-body gl-text-decoration-none gl-font-weight-bold gl-ml-2 gl-mr-2"
- >
- {{ lastReply.author.name }}
- </gl-link>
- <time-ago-tooltip
- :time="lastReply.createdAt"
- tooltip-placement="bottom"
- class="gl-text-gray-500"
- />
- </template>
- </li>
-</template>