diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-08-08 18:06:56 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-08-08 18:06:56 +0300 |
commit | bfb24e1685fb574d3144865da29a21b38cb52883 (patch) | |
tree | d694d329da73d9a312a6f819edaebebc3b081491 /app | |
parent | e44c3e4832e43c77e9c29fad6e49f8d6066d7f5c (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r-- | app/assets/javascripts/issues/index.js | 1 | ||||
-rw-r--r-- | app/assets/javascripts/issues/show/components/app.vue | 73 | ||||
-rw-r--r-- | app/assets/javascripts/issues/show/components/header_actions.vue | 4 | ||||
-rw-r--r-- | app/assets/javascripts/issues/show/components/issue_header.vue | 126 | ||||
-rw-r--r-- | app/assets/javascripts/issues/show/components/title.vue | 7 | ||||
-rw-r--r-- | app/assets/javascripts/issues/show/index.js | 37 | ||||
-rw-r--r-- | app/assets/javascripts/vue_shared/issuable/show/components/issuable_header.vue | 135 | ||||
-rw-r--r-- | app/helpers/issuables_helper.rb | 20 | ||||
-rw-r--r-- | app/models/ci/sources/pipeline.rb | 5 | ||||
-rw-r--r-- | app/views/admin/applications/index.html.haml | 2 | ||||
-rw-r--r-- | app/views/projects/issuable/_show.html.haml | 3 | ||||
-rw-r--r-- | app/views/shared/issue_type/_details_content.html.haml | 1 |
12 files changed, 357 insertions, 57 deletions
diff --git a/app/assets/javascripts/issues/index.js b/app/assets/javascripts/issues/index.js index 4d2df9e3602..e266966c665 100644 --- a/app/assets/javascripts/issues/index.js +++ b/app/assets/javascripts/issues/index.js @@ -63,7 +63,6 @@ export function initShow({ notesParams } = {}) { initRelatedIssues(TYPE_INCIDENT); } else { initIssueApp(issuableData, store); - initHeaderActions(store); } new Issue(); // eslint-disable-line no-new diff --git a/app/assets/javascripts/issues/show/components/app.vue b/app/assets/javascripts/issues/show/components/app.vue index fcdf1f7741b..633f336b0c0 100644 --- a/app/assets/javascripts/issues/show/components/app.vue +++ b/app/assets/javascripts/issues/show/components/app.vue @@ -15,6 +15,7 @@ import { visitUrl } from '~/lib/utils/url_utility'; import { __, sprintf } from '~/locale'; import ConfidentialityBadge from '~/vue_shared/components/confidentiality_badge.vue'; import { containsSensitiveToken, confirmSensitiveAction, i18n } from '~/lib/utils/secret_detection'; +import { WORK_ITEM_TYPE_VALUE_ISSUE } from '~/work_items/constants'; import { ISSUE_TYPE_PATH, INCIDENT_TYPE_PATH, POLLING_DELAY } from '../constants'; import eventHub from '../event_hub'; import getIssueStateQuery from '../queries/get_issue_state.query.graphql'; @@ -23,6 +24,8 @@ import Store from '../stores'; import DescriptionComponent from './description.vue'; import EditedComponent from './edited.vue'; import FormComponent from './form.vue'; +import HeaderActions from './header_actions.vue'; +import IssueHeader from './issue_header.vue'; import PinnedLinks from './pinned_links.vue'; import TitleComponent from './title.vue'; @@ -32,6 +35,8 @@ export default { GlIcon, GlBadge, GlIntersectionObserver, + HeaderActions, + IssueHeader, TitleComponent, EditedComponent, FormComponent, @@ -42,6 +47,11 @@ export default { GlTooltip: GlTooltipDirective, }, props: { + author: { + type: Object, + required: false, + default: () => ({}), + }, endpoint: { required: true, type: String, @@ -54,6 +64,11 @@ export default { required: true, type: Boolean, }, + createdAt: { + type: String, + required: false, + default: '', + }, enableAutocomplete: { type: Boolean, required: false, @@ -193,6 +208,36 @@ export default { required: false, default: null, }, + duplicatedToIssueUrl: { + type: String, + required: false, + default: '', + }, + movedToIssueUrl: { + type: String, + required: false, + default: '', + }, + promotedToEpicUrl: { + type: String, + required: false, + default: '', + }, + isFirstContribution: { + type: Boolean, + required: false, + default: false, + }, + serviceDeskReplyTo: { + type: String, + required: false, + default: '', + }, + workItemType: { + type: String, + required: false, + default: '', + }, }, data() { const store = new Store({ @@ -222,6 +267,9 @@ export default { }, }, computed: { + isIssue() { + return this.workItemType === WORK_ITEM_TYPE_VALUE_ISSUE; + }, issuableTemplates() { return this.store.formState.issuableTemplates; }, @@ -509,7 +557,13 @@ export default { :can-update="canUpdate" :title-html="state.titleHtml" :title-text="state.titleText" - /> + > + <template #actions> + <slot name="actions"> + <header-actions v-if="isIssue" /> + </slot> + </template> + </title-component> <gl-intersection-observer v-if="shouldShowStickyHeader" @@ -567,6 +621,23 @@ export default { </transition> </gl-intersection-observer> + <slot name="header"> + <issue-header + v-if="isIssue" + :author="author" + :confidential="isConfidential" + :created-at="createdAt" + :duplicated-to-issue-url="duplicatedToIssueUrl" + :is-first-contribution="isFirstContribution" + :is-hidden="isHidden" + :is-locked="isLocked" + :issuable-state="issuableStatus" + :moved-to-issue-url="movedToIssueUrl" + :promoted-to-epic-url="promotedToEpicUrl" + :service-desk-reply-to="serviceDeskReplyTo" + /> + </slot> + <pinned-links :zoom-meeting-url="zoomMeetingUrl" :published-incident-url="publishedIncidentUrl" diff --git a/app/assets/javascripts/issues/show/components/header_actions.vue b/app/assets/javascripts/issues/show/components/header_actions.vue index 321b12a0050..d05311cb1db 100644 --- a/app/assets/javascripts/issues/show/components/header_actions.vue +++ b/app/assets/javascripts/issues/show/components/header_actions.vue @@ -146,7 +146,7 @@ export default { variables() { return { fullPath: this.fullPath, - iid: this.iid, + iid: String(this.iid), }; }, update(data) { @@ -289,7 +289,7 @@ export default { mutation: promoteToEpicMutation, variables: { input: { - iid: this.iid, + iid: String(this.iid), projectPath: this.projectPath, }, }, diff --git a/app/assets/javascripts/issues/show/components/issue_header.vue b/app/assets/javascripts/issues/show/components/issue_header.vue new file mode 100644 index 00000000000..771b438f0da --- /dev/null +++ b/app/assets/javascripts/issues/show/components/issue_header.vue @@ -0,0 +1,126 @@ +<script> +import { GlLink, GlSprintf } from '@gitlab/ui'; +import { STATUS_OPEN, STATUS_REOPENED, TYPE_ISSUE, WORKSPACE_PROJECT } from '~/issues/constants'; +import { __, s__ } from '~/locale'; +import IssuableHeader from '~/vue_shared/issuable/show/components/issuable_header.vue'; + +export default { + TYPE_ISSUE, + WORKSPACE_PROJECT, + components: { + GlLink, + GlSprintf, + IssuableHeader, + }, + props: { + author: { + type: Object, + required: true, + }, + confidential: { + type: Boolean, + required: true, + }, + createdAt: { + type: String, + required: true, + }, + duplicatedToIssueUrl: { + type: String, + required: true, + }, + isFirstContribution: { + type: Boolean, + required: true, + }, + isHidden: { + type: Boolean, + required: true, + }, + isLocked: { + type: Boolean, + required: true, + }, + issuableState: { + type: String, + required: true, + }, + movedToIssueUrl: { + type: String, + required: true, + }, + promotedToEpicUrl: { + type: String, + required: true, + }, + serviceDeskReplyTo: { + type: String, + required: false, + default: '', + }, + }, + computed: { + closedStatusLink() { + return this.duplicatedToIssueUrl || this.movedToIssueUrl || this.promotedToEpicUrl; + }, + closedStatusText() { + if (this.duplicatedToIssueUrl) { + return s__('IssuableStatus|duplicated'); + } + if (this.movedToIssueUrl) { + return s__('IssuableStatus|moved'); + } + if (this.promotedToEpicUrl) { + return s__('IssuableStatus|promoted'); + } + return ''; + }, + isOpen() { + return this.issuableState === STATUS_OPEN || this.issuableState === STATUS_REOPENED; + }, + statusIcon() { + return this.isOpen ? 'issues' : 'issue-closed'; + }, + statusText() { + if (this.isOpen) { + return __('Open'); + } + if (this.closedStatusLink) { + return s__('IssuableStatus|Closed (%{link})'); + } + return s__('IssuableStatus|Closed'); + }, + }, +}; +</script> + +<template> + <issuable-header + class="gl-p-0 gl-mb-6 gl-mt-2 gl-sm-mt-0" + :author="author" + :blocked="isLocked" + :confidential="confidential" + :created-at="createdAt" + :is-first-contribution="isFirstContribution" + :is-hidden="isHidden" + :issuable-state="issuableState" + :issuable-type="$options.TYPE_ISSUE" + :service-desk-reply-to="serviceDeskReplyTo" + show-work-item-type-icon + :status-icon="statusIcon" + :workspace-type="$options.WORKSPACE_PROJECT" + > + <template #status-badge> + <gl-sprintf v-if="closedStatusLink" :message="statusText"> + <template #link> + <gl-link + class="gl-reset-color! gl-reset-font-size gl-text-decoration-underline" + :href="closedStatusLink" + >{{ closedStatusText }}</gl-link + > + </template> + </gl-sprintf> + <template v-else>{{ statusText }}</template> + </template> + </issuable-header> +</template> diff --git a/app/assets/javascripts/issues/show/components/title.vue b/app/assets/javascripts/issues/show/components/title.vue index 197a2594f4d..8c9e43b729b 100644 --- a/app/assets/javascripts/issues/show/components/title.vue +++ b/app/assets/javascripts/issues/show/components/title.vue @@ -53,16 +53,19 @@ export default { </script> <template> - <div class="title-container"> + <div + class="gl-display-flex gl-align-items-flex-start gl-flex-direction-column gl-sm-flex-direction-row gl-pt-3" + > <h1 v-safe-html="titleHtml" :class="{ 'issue-realtime-pre-pulse': preAnimation, 'issue-realtime-trigger-pulse': pulseAnimation, }" - class="title gl-font-size-h-display" + class="title gl-font-size-h-display gl-m-0!" data-testid="issue-title" dir="auto" ></h1> + <slot name="actions"></slot> </div> </template> diff --git a/app/assets/javascripts/issues/show/index.js b/app/assets/javascripts/issues/show/index.js index bc4284457f6..41e6daea4c1 100644 --- a/app/assets/javascripts/issues/show/index.js +++ b/app/assets/javascripts/issues/show/index.js @@ -2,8 +2,8 @@ import Vue from 'vue'; import { mapGetters } from 'vuex'; import errorTrackingStore from '~/error_tracking/store'; import { apolloProvider } from '~/graphql_shared/issuable_client'; -import { TYPE_INCIDENT } from '~/issues/constants'; -import { parseBoolean } from '~/lib/utils/common_utils'; +import { TYPE_INCIDENT, TYPE_ISSUE } from '~/issues/constants'; +import { convertObjectPropsToCamelCase, parseBoolean } from '~/lib/utils/common_utils'; import { scrollToTargetOnResize } from '~/lib/utils/resize_observer'; import IssueApp from './components/app.vue'; import HeaderActions from './components/header_actions.vue'; @@ -97,12 +97,17 @@ export function initIssueApp(issueData, store) { } const { fullPath, registerPath, signInPath } = el.dataset; + const headerActionsData = convertObjectPropsToCamelCase(JSON.parse(el.dataset.headerActionsData)); scrollToTargetOnResize(); - bootstrapApollo({ ...issueState, issueType: el.dataset.issueType }); + bootstrapApollo({ ...issueState, issueType: TYPE_ISSUE }); const { + authorId, + authorName, + authorUsername, + authorWebUrl, canCreateIncident, hasIssueWeightsFeature, hasIterationsFeature, @@ -121,6 +126,26 @@ export function initIssueApp(issueData, store) { signInPath, hasIssueWeightsFeature, hasIterationsFeature, + // for HeaderActions component + canCreateIssue: parseBoolean(headerActionsData.canCreateIssue), + canDestroyIssue: parseBoolean(headerActionsData.canDestroyIssue), + canPromoteToEpic: parseBoolean(headerActionsData.canPromoteToEpic), + canReopenIssue: parseBoolean(headerActionsData.canReopenIssue), + canReportSpam: parseBoolean(headerActionsData.canReportSpam), + canUpdateIssue: parseBoolean(headerActionsData.canUpdateIssue), + iid: headerActionsData.iid, + issuableId: headerActionsData.issuableId, + isIssueAuthor: parseBoolean(headerActionsData.isIssueAuthor), + issuePath: headerActionsData.issuePath, + issueType: headerActionsData.issueType, + newIssuePath: headerActionsData.newIssuePath, + projectPath: headerActionsData.projectPath, + projectId: headerActionsData.projectId, + reportAbusePath: headerActionsData.reportAbusePath, + reportedUserId: headerActionsData.reportedUserId, + reportedFromUrl: headerActionsData.reportedFromUrl, + submitAsSpamPath: headerActionsData.submitAsSpamPath, + issuableEmailAddress: headerActionsData.issuableEmailAddress, }, computed: { ...mapGetters(['getNoteableData']), @@ -129,6 +154,12 @@ export function initIssueApp(issueData, store) { return createElement(IssueApp, { props: { ...issueProps, + author: { + id: authorId, + name: authorName, + username: authorUsername, + webUrl: authorWebUrl, + }, isConfidential: this.getNoteableData?.confidential, isLocked: this.getNoteableData?.discussion_locked, issuableStatus: this.getNoteableData?.state, diff --git a/app/assets/javascripts/vue_shared/issuable/show/components/issuable_header.vue b/app/assets/javascripts/vue_shared/issuable/show/components/issuable_header.vue index 27276e55b13..29aef89a991 100644 --- a/app/assets/javascripts/vue_shared/issuable/show/components/issuable_header.vue +++ b/app/assets/javascripts/vue_shared/issuable/show/components/issuable_header.vue @@ -1,16 +1,7 @@ <script> -import { - GlIcon, - GlBadge, - GlButton, - GlSprintf, - GlTooltipDirective, - GlAvatarLink, - GlAvatarLabeled, -} from '@gitlab/ui'; - +import { GlIcon, GlBadge, GlButton, GlLink, GlSprintf, GlTooltipDirective } from '@gitlab/ui'; import { getIdFromGraphQLId } from '~/graphql_shared/utils'; -import { issuableStatusText, STATUS_OPEN } from '~/issues/constants'; +import { issuableStatusText, STATUS_OPEN, STATUS_REOPENED } from '~/issues/constants'; import { isExternal } from '~/lib/utils/url_utility'; import { __, n__, sprintf } from '~/locale'; import ConfidentialityBadge from '~/vue_shared/components/confidentiality_badge.vue'; @@ -23,8 +14,7 @@ export default { GlIcon, GlBadge, GlButton, - GlAvatarLink, - GlAvatarLabeled, + GlLink, GlSprintf, TimeAgoTooltip, WorkItemTypeIcon, @@ -66,21 +56,36 @@ export default { required: false, default: false, }, - taskCompletionStatus: { - type: Object, + isFirstContribution: { + type: Boolean, required: false, - default: null, + default: false, + }, + isHidden: { + type: Boolean, + required: false, + default: false, }, issuableType: { type: String, required: false, default: '', }, + serviceDeskReplyTo: { + type: String, + required: false, + default: '', + }, showWorkItemTypeIcon: { type: Boolean, required: false, default: false, }, + taskCompletionStatus: { + type: Object, + required: false, + default: null, + }, workspaceType: { type: String, required: false, @@ -92,10 +97,30 @@ export default { return issuableStatusText[this.issuableState]; }, badgeVariant() { - return this.issuableState === STATUS_OPEN ? 'success' : 'info'; + return this.issuableState === STATUS_OPEN || this.issuableState === STATUS_REOPENED + ? 'success' + : 'info'; + }, + blockedTooltip() { + return sprintf(__('This %{issuable} is locked. Only project members can comment.'), { + issuable: this.issuableType, + }); + }, + hiddenTooltip() { + return sprintf(__('This %{issuable} is hidden because its author has been banned'), { + issuable: this.issuableType, + }); + }, + shouldShowWorkItemTypeIcon() { + return this.showWorkItemTypeIcon && this.issuableType; }, createdMessage() { - return this.showWorkItemTypeIcon + if (this.serviceDeskReplyTo) { + return this.shouldShowWorkItemTypeIcon + ? __('created %{timeAgo} by %{email} via %{author}') + : __('Created %{timeAgo} by %{email} via %{author}'); + } + return this.shouldShowWorkItemTypeIcon ? __('created %{timeAgo} by %{author}') : __('Created %{timeAgo} by %{author}'); }, @@ -103,7 +128,7 @@ export default { return getIdFromGraphQLId(`${this.author.id}`); }, isAuthorExternal() { - return isExternal(this.author.webUrl); + return isExternal(this.author.webUrl ?? ''); }, taskStatusString() { const { count, completedCount } = this.taskCompletionStatus; @@ -144,60 +169,80 @@ export default { <slot name="status-badge">{{ badgeText }}</slot> </span> </gl-badge> - <span v-if="blocked" class="issuable-warning-icon" data-testid="blocked"> - <gl-icon name="lock" :aria-label="__('Blocked')" /> - </span> <confidentiality-badge v-if="confidential" :issuable-type="issuableType" :workspace-type="workspaceType" /> - <work-item-type-icon v-if="showWorkItemTypeIcon" :work-item-type="issuableType" show-text /> + <span v-if="blocked" class="issuable-warning-icon"> + <gl-icon + v-gl-tooltip.bottom + name="lock" + :title="blockedTooltip" + :aria-label="__('Blocked')" + /> + </span> + <span v-if="isHidden" class="issuable-warning-icon"> + <gl-icon + v-gl-tooltip.bottom + name="spam" + :title="hiddenTooltip" + :aria-label="__('Hidden')" + /> + </span> + <work-item-type-icon + v-if="shouldShowWorkItemTypeIcon" + show-text + :work-item-type="issuableType.toUpperCase()" + /> <gl-sprintf :message="createdMessage"> <template #timeAgo> <time-ago-tooltip class="gl-mx-2" :time="createdAt" /> </template> + <template #email> + {{ serviceDeskReplyTo }} + </template> <template #author> - <gl-avatar-link - :data-user-id="authorId" - :data-username="author.username" - :data-name="author.name" + <gl-link + class="gl-font-weight-bold gl-mx-2 js-user-link" :href="author.webUrl" - class="js-user-link gl-vertical-align-middle gl-mx-2" + :data-user-id="authorId" > - <gl-avatar-labeled - :size="24" - :src="author.avatarUrl" - :label="author.name" - :class="[ - { 'gl-display-none': !isAuthorExternal }, - 'gl-sm-display-inline-flex gl-mx-1', - ]" - > - <template #meta> - <gl-icon v-if="isAuthorExternal" name="external-link" class="gl-ml-1" /> - </template> - </gl-avatar-labeled> + <span :class="[{ 'gl-display-none': !isAuthorExternal }, 'gl-sm-display-inline']"> + {{ author.name }} + </span> + <gl-icon + v-if="isAuthorExternal" + name="external-link" + :aria-label="__('external link')" + /> <strong v-if="author.username" class="author gl-display-inline gl-sm-display-none!" >@{{ author.username }}</strong > - </gl-avatar-link> + </gl-link> </template> </gl-sprintf> + <gl-icon + v-if="isFirstContribution" + v-gl-tooltip + class="gl-mr-2" + name="first-contribution" + :title="__('1st contribution!')" + :aria-label="__('1st contribution!')" + /> <span v-if="taskCompletionStatus && hasTasks" - data-testid="task-status" class="gl-display-none gl-md-display-block gl-lg-display-inline-block" >{{ taskStatusString }}</span > <gl-button icon="chevron-double-lg-left" - class="gl-ml-auto gl-display-block gl-sm-display-none!" + class="gl-ml-auto gl-display-block gl-sm-display-none! js-sidebar-toggle" :aria-label="__('Expand sidebar')" @click="handleRightSidebarToggleClick" /> </div> - <div data-testid="header-actions" class="detail-page-header-actions gl-display-flex"> + <div class="detail-page-header-actions gl-display-flex"> <slot name="header-actions"></slot> </div> </div> diff --git a/app/helpers/issuables_helper.rb b/app/helpers/issuables_helper.rb index 910b9e31394..ef9cd98021d 100644 --- a/app/helpers/issuables_helper.rb +++ b/app/helpers/issuables_helper.rb @@ -251,9 +251,17 @@ module IssuablesHelper def issue_only_initial_data(issuable) return {} unless issuable.is_a?(Issue) - { + data = { + authorId: issuable.author.id, + authorName: issuable.author.name, + authorUsername: issuable.author.username, + authorWebUrl: url_for(user_path(issuable.author)), + createdAt: issuable.created_at.to_time.iso8601, hasClosingMergeRequest: issuable.merge_requests_count(current_user) != 0, + isFirstContribution: issuable.first_contribution?, issueType: issuable.issue_type, + serviceDeskReplyTo: issuable.present(current_user: current_user).service_desk_reply_to, + workItemType: issuable.work_item_type.name, zoomMeetingUrl: ZoomMeeting.canonical_meeting_url(issuable), sentryIssueIdentifier: SentryIssue.find_by(issue: issuable)&.sentry_issue_identifier, # rubocop:disable CodeReuse/ActiveRecord iid: issuable.iid.to_s, @@ -261,6 +269,16 @@ module IssuablesHelper canCreateIncident: create_issue_type_allowed?(issuable.project, :incident), **incident_only_initial_data(issuable) } + + data.tap do |d| + if issuable.duplicated? && can?(current_user, :read_issue, issuable.duplicated_to) + d[:duplicatedToIssueUrl] = url_for([issuable.duplicated_to.project, issuable.duplicated_to, { only_path: false }]) + end + + if issuable.moved? && can?(current_user, :read_issue, issuable.moved_to) + d[:movedToIssueUrl] = url_for([issuable.moved_to.project, issuable.moved_to, { only_path: false }]) + end + end end def incident_only_initial_data(issue) diff --git a/app/models/ci/sources/pipeline.rb b/app/models/ci/sources/pipeline.rb index 4853c57d41f..5b6946b04fd 100644 --- a/app/models/ci/sources/pipeline.rb +++ b/app/models/ci/sources/pipeline.rb @@ -6,6 +6,11 @@ module Ci include Ci::Partitionable include Ci::NamespacedModelName include SafelyChangeColumnDefault + include IgnorableColumns + + ignore_columns [ + :pipeline_id_convert_to_bigint, :source_pipeline_id_convert_to_bigint + ], remove_with: '16.6', remove_after: '2023-10-22' columns_changing_default :partition_id diff --git a/app/views/admin/applications/index.html.haml b/app/views/admin/applications/index.html.haml index 063045033b6..6846fe8f4aa 100644 --- a/app/views/admin/applications/index.html.haml +++ b/app/views/admin/applications/index.html.haml @@ -15,7 +15,7 @@ .gl-new-card-actions = render Pajamas::ButtonComponent.new(size: :small, href: new_admin_application_path, button_options: { data: { qa_selector: 'new_application_button' } }) do - = _('New application') + = _('Add new application') - c.with_body do - if @applications.empty? %section.empty-state.gl-my-5.gl-text-center.gl-display-flex.gl-flex-direction-column diff --git a/app/views/projects/issuable/_show.html.haml b/app/views/projects/issuable/_show.html.haml index ec233bc9aff..769847f3830 100644 --- a/app/views/projects/issuable/_show.html.haml +++ b/app/views/projects/issuable/_show.html.haml @@ -7,5 +7,6 @@ = render "projects/issues/service_desk/alert_moved_from_service_desk", issue: issuable -= render 'shared/issue_type/details_header', issuable: issuable +- if issuable.work_item_type&.incident? + = render 'shared/issue_type/details_header', issuable: issuable = render 'shared/issue_type/details_content', issuable: issuable, api_awards_path: api_awards_path diff --git a/app/views/shared/issue_type/_details_content.html.haml b/app/views/shared/issue_type/_details_content.html.haml index 40a02fddbf3..249e296b41a 100644 --- a/app/views/shared/issue_type/_details_content.html.haml +++ b/app/views/shared/issue_type/_details_content.html.haml @@ -4,6 +4,7 @@ .issue-details.issuable-details.js-issue-details .detail-page-description.content-block.js-detail-page-description.gl-pt-3.gl-pb-0.gl-border-none #js-issuable-app{ data: { initial: issuable_initial_data(issuable).to_json, + header_actions_data: issue_header_actions_data(@project, issuable, current_user, @issuable_sidebar).to_json, issuable_id: issuable.id, full_path: @project.full_path, register_path: new_user_registration_path(redirect_to_referer: 'yes'), |