diff options
Diffstat (limited to 'app/assets/javascripts/issuable_list/components/issuable_item.vue')
-rw-r--r-- | app/assets/javascripts/issuable_list/components/issuable_item.vue | 295 |
1 files changed, 0 insertions, 295 deletions
diff --git a/app/assets/javascripts/issuable_list/components/issuable_item.vue b/app/assets/javascripts/issuable_list/components/issuable_item.vue deleted file mode 100644 index ab04c6a38a5..00000000000 --- a/app/assets/javascripts/issuable_list/components/issuable_item.vue +++ /dev/null @@ -1,295 +0,0 @@ -<script> -import { GlLink, GlIcon, GlLabel, GlFormCheckbox, GlSprintf, GlTooltipDirective } from '@gitlab/ui'; - -import { getIdFromGraphQLId } from '~/graphql_shared/utils'; -import { isScopedLabel } from '~/lib/utils/common_utils'; -import { differenceInSeconds, getTimeago, SECONDS_IN_DAY } from '~/lib/utils/datetime_utility'; -import { isExternal, setUrlFragment } from '~/lib/utils/url_utility'; -import { __, n__, sprintf } from '~/locale'; -import IssuableAssignees from '~/vue_shared/components/issue/issue_assignees.vue'; -import timeagoMixin from '~/vue_shared/mixins/timeago'; - -export default { - components: { - GlLink, - GlIcon, - GlLabel, - GlFormCheckbox, - GlSprintf, - IssuableAssignees, - }, - directives: { - GlTooltip: GlTooltipDirective, - }, - mixins: [timeagoMixin], - props: { - issuableSymbol: { - type: String, - required: true, - }, - issuable: { - type: Object, - required: true, - }, - enableLabelPermalinks: { - type: Boolean, - required: true, - }, - labelFilterParam: { - type: String, - required: false, - default: 'label_name', - }, - showCheckbox: { - type: Boolean, - required: true, - }, - checked: { - type: Boolean, - required: false, - default: false, - }, - }, - computed: { - issuableId() { - return getIdFromGraphQLId(this.issuable.id); - }, - createdInPastDay() { - const createdSecondsAgo = differenceInSeconds(new Date(this.issuable.createdAt), new Date()); - return createdSecondsAgo < SECONDS_IN_DAY; - }, - author() { - return this.issuable.author; - }, - webUrl() { - return this.issuable.gitlabWebUrl || this.issuable.webUrl; - }, - authorId() { - return getIdFromGraphQLId(this.author.id); - }, - isIssuableUrlExternal() { - return isExternal(this.webUrl); - }, - reference() { - return this.issuable.reference || `${this.issuableSymbol}${this.issuable.iid}`; - }, - labels() { - return this.issuable.labels?.nodes || this.issuable.labels || []; - }, - labelIdsString() { - return JSON.stringify(this.labels.map((label) => getIdFromGraphQLId(label.id))); - }, - assignees() { - return this.issuable.assignees?.nodes || this.issuable.assignees || []; - }, - createdAt() { - return getTimeago().format(this.issuable.createdAt); - }, - updatedAt() { - return sprintf(__('updated %{timeAgo}'), { - timeAgo: getTimeago().format(this.issuable.updatedAt), - }); - }, - issuableTitleProps() { - if (this.isIssuableUrlExternal) { - return { - target: '_blank', - }; - } - return {}; - }, - taskStatus() { - const { completedCount, count } = this.issuable.taskCompletionStatus || {}; - if (!count) { - return undefined; - } - - return sprintf( - n__( - '%{completedCount} of %{count} task completed', - '%{completedCount} of %{count} tasks completed', - count, - ), - { completedCount, count }, - ); - }, - notesCount() { - return this.issuable.userDiscussionsCount ?? this.issuable.userNotesCount; - }, - showDiscussions() { - return typeof this.notesCount === 'number'; - }, - showIssuableMeta() { - return Boolean( - this.hasSlotContents('status') || this.showDiscussions || this.issuable.assignees, - ); - }, - issuableNotesLink() { - return setUrlFragment(this.webUrl, 'notes'); - }, - }, - methods: { - hasSlotContents(slotName) { - return Boolean(this.$slots[slotName]); - }, - scopedLabel(label) { - return isScopedLabel(label); - }, - labelTitle(label) { - return label.title || label.name; - }, - labelTarget(label) { - if (this.enableLabelPermalinks) { - const value = encodeURIComponent(this.labelTitle(label)); - return `?${this.labelFilterParam}[]=${value}`; - } - return '#'; - }, - /** - * This is needed as an independent method since - * when user changes current page, `$refs.authorLink` - * will be null until next page results are loaded & rendered. - */ - getAuthorPopoverTarget() { - if (this.$refs.authorLink) { - return this.$refs.authorLink.$el; - } - return ''; - }, - }, -}; -</script> - -<template> - <li - :id="`issuable_${issuableId}`" - class="issue gl-display-flex! gl-px-5!" - :class="{ closed: issuable.closedAt, today: createdInPastDay }" - :data-labels="labelIdsString" - > - <gl-form-checkbox - v-if="showCheckbox" - class="issue-check gl-mr-0" - :checked="checked" - :data-id="issuableId" - @input="$emit('checked-input', $event)" - > - <span class="gl-sr-only">{{ issuable.title }}</span> - </gl-form-checkbox> - <div class="issuable-main-info"> - <div data-testid="issuable-title" class="issue-title title"> - <gl-icon - v-if="issuable.confidential" - v-gl-tooltip - name="eye-slash" - :title="__('Confidential')" - :aria-label="__('Confidential')" - /> - <gl-link class="issue-title-text" dir="auto" :href="webUrl" v-bind="issuableTitleProps"> - {{ issuable.title }} - <gl-icon v-if="isIssuableUrlExternal" name="external-link" class="gl-ml-2" /> - </gl-link> - <span - v-if="taskStatus" - class="task-status gl-display-none gl-sm-display-inline-block! gl-ml-3" - data-testid="task-status" - > - {{ taskStatus }} - </span> - </div> - <div class="issuable-info"> - <slot v-if="hasSlotContents('reference')" name="reference"></slot> - <span v-else data-testid="issuable-reference" class="issuable-reference"> - {{ reference }} - </span> - <span class="gl-display-none gl-sm-display-inline-block"> - <span aria-hidden="true">·</span> - <span class="issuable-authored gl-mr-3"> - <gl-sprintf :message="__('created %{timeAgo} by %{author}')"> - <template #timeAgo> - <span - v-gl-tooltip.bottom - :title="tooltipTitle(issuable.createdAt)" - data-testid="issuable-created-at" - > - {{ createdAt }} - </span> - </template> - <template #author> - <slot v-if="hasSlotContents('author')" name="author"></slot> - <gl-link - v-else - :data-user-id="authorId" - :data-username="author.username" - :data-name="author.name" - :data-avatar-url="author.avatarUrl" - :href="author.webUrl" - data-testid="issuable-author" - class="author-link js-user-link" - > - <span class="author">{{ author.name }}</span> - </gl-link> - </template> - </gl-sprintf> - </span> - <slot name="timeframe"></slot> - </span> - - <span v-if="labels.length" role="group" :aria-label="__('Labels')"> - <gl-label - v-for="(label, index) in labels" - :key="index" - :background-color="label.color" - :title="labelTitle(label)" - :description="label.description" - :scoped="scopedLabel(label)" - :target="labelTarget(label)" - :class="{ 'gl-ml-2': index }" - size="sm" - /> - </span> - </div> - </div> - <div class="issuable-meta"> - <ul v-if="showIssuableMeta" class="controls"> - <li v-if="hasSlotContents('status')" class="issuable-status"> - <slot name="status"></slot> - </li> - <li v-if="assignees.length"> - <issuable-assignees - :assignees="assignees" - :icon-size="16" - :max-visible="4" - img-css-classes="gl-mr-2!" - class="gl-align-items-center gl-display-flex gl-ml-3" - /> - </li> - <slot name="statistics"></slot> - <li - v-if="showDiscussions" - data-testid="issuable-discussions" - class="issuable-comments gl-display-none gl-sm-display-block" - > - <gl-link - v-gl-tooltip.top - :title="__('Comments')" - :href="issuableNotesLink" - :class="{ 'no-comments': !notesCount }" - class="gl-reset-color!" - > - <gl-icon name="comments" /> - {{ notesCount }} - </gl-link> - </li> - </ul> - <div - v-gl-tooltip.bottom - class="gl-text-gray-500 gl-display-none gl-sm-display-inline-block" - :title="tooltipTitle(issuable.updatedAt)" - data-testid="issuable-updated-at" - > - {{ updatedAt }} - </div> - </div> - </li> -</template> |