Commit a5f7541a authored by Fatih Acet's avatar Fatih Acet

Merge branch '31910-add-vue-sidebar-container' into 'master'

[Part  1] Add Vue Issuable sidebar feature flag & app bundle

See merge request gitlab-org/gitlab!18199
parents d51c6208 44d332e0
<script>
export default {
props: {
signedIn: {
type: Boolean,
required: true,
},
sidebarStatusClass: {
type: String,
required: false,
default: '',
},
},
};
</script>
<template>
<aside
:class="sidebarStatusClass"
class="right-sidebar js-right-sidebar js-issuable-sidebar"
aria-live="polite"
></aside>
</template>
import Vue from 'vue';
import SidebarApp from './components/sidebar_app.vue';
export default () => {
const el = document.getElementById('js-vue-issuable-sidebar');
if (!el) {
return false;
}
const { sidebarStatusClass } = el.dataset;
// An empty string is present when user is signed in.
const signedIn = el.dataset.signedIn === '';
return new Vue({
el,
components: { SidebarApp },
render: createElement =>
createElement('sidebar-app', {
props: {
signedIn,
sidebarStatusClass,
},
}),
});
};
......@@ -5,6 +5,7 @@ import ZenMode from '~/zen_mode';
import '~/notes/index';
import initIssueableApp from '~/issue_show';
import initRelatedMergeRequestsApp from '~/related_merge_requests';
import initVueIssuableSidebarApp from '~/issuable_sidebar/sidebar_bundle';
export default function() {
initIssueableApp();
......@@ -12,5 +13,9 @@ export default function() {
new Issue(); // eslint-disable-line no-new
new ShortcutsIssuable(); // eslint-disable-line no-new
new ZenMode(); // eslint-disable-line no-new
initIssuableSidebar();
if (gon.features && gon.features.vueIssuableSidebar) {
initVueIssuableSidebarApp();
} else {
initIssuableSidebar();
}
}
......@@ -3,5 +3,7 @@ import initShow from '../show';
document.addEventListener('DOMContentLoaded', () => {
initShow();
initSidebarBundle();
if (gon.features && !gon.features.vueIssuableSidebar) {
initSidebarBundle();
}
});
......@@ -4,11 +4,16 @@ import ShortcutsIssuable from '~/behaviors/shortcuts/shortcuts_issuable';
import { handleLocationHash } from '~/lib/utils/common_utils';
import howToMerge from '~/how_to_merge';
import initPipelines from '~/commit/pipelines/pipelines_bundle';
import initVueIssuableSidebarApp from '~/issuable_sidebar/sidebar_bundle';
import initWidget from '../../../vue_merge_request_widget';
export default function() {
new ZenMode(); // eslint-disable-line no-new
initIssuableSidebar();
if (gon.features && gon.features.vueIssuableSidebar) {
initVueIssuableSidebarApp();
} else {
initIssuableSidebar();
}
initPipelines();
new ShortcutsIssuable(true); // eslint-disable-line no-new
handleLocationHash();
......
......@@ -4,6 +4,8 @@ import initShow from '../init_merge_request_show';
document.addEventListener('DOMContentLoaded', () => {
initShow();
initSidebarBundle();
if (gon.features && !gon.features.vueIssuableSidebar) {
initSidebarBundle();
}
initMrNotes();
});
......@@ -42,6 +42,10 @@ class Projects::IssuesController < Projects::ApplicationController
before_action :authorize_import_issues!, only: [:import_csv]
before_action :authorize_download_code!, only: [:related_branches]
before_action do
push_frontend_feature_flag(:vue_issuable_sidebar, project.group)
end
respond_to :html
alias_method :designs, :show
......
......@@ -21,6 +21,10 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
push_frontend_feature_flag(:diffs_batch_load, @project)
end
before_action do
push_frontend_feature_flag(:vue_issuable_sidebar, @project.group)
end
around_action :allow_gitaly_ref_name_caching, only: [:index, :show, :discussions]
def index
......
......@@ -5,174 +5,178 @@
- signed_in = !!issuable_sidebar.dig(:current_user, :id)
- can_edit_issuable = issuable_sidebar.dig(:current_user, :can_edit)
%aside.right-sidebar.js-right-sidebar.js-issuable-sidebar{ data: { signed: { in: signed_in } }, class: sidebar_gutter_collapsed_class, 'aria-live' => 'polite' }
.issuable-sidebar
.block.issuable-sidebar-header
- if signed_in
%span.issuable-header-text.hide-collapsed.float-left
= _('To Do')
%a.gutter-toggle.float-right.js-sidebar-toggle.has-tooltip{ role: "button", href: "#", "aria-label" => "Toggle sidebar", title: sidebar_gutter_tooltip_text, data: { container: 'body', placement: 'left', boundary: 'viewport' } }
= sidebar_gutter_toggle_icon
- if signed_in
= render "shared/issuable/sidebar_todo", issuable_sidebar: issuable_sidebar
= form_for issuable_type, url: issuable_sidebar[:issuable_json_path], remote: true, html: { class: 'issuable-context-form inline-update js-issuable-update' } do |f|
- if signed_in
.block.todo.hide-expanded
= render "shared/issuable/sidebar_todo", issuable_sidebar: issuable_sidebar, is_collapsed: true
.block.assignee.qa-assignee-block
= render "shared/issuable/sidebar_assignees", issuable_sidebar: issuable_sidebar, assignees: assignees
= render_if_exists 'shared/issuable/sidebar_item_epic', issuable_sidebar: issuable_sidebar
- milestone = issuable_sidebar[:milestone] || {}
.block.milestone
.sidebar-collapsed-icon.has-tooltip{ title: sidebar_milestone_tooltip_label(milestone), data: { container: 'body', html: 'true', placement: 'left', boundary: 'viewport' } }
= icon('clock-o', 'aria-hidden': 'true')
%span.milestone-title.collapse-truncated-title
- if milestone.present?
= milestone[:title]
- else
= _('None')
.title.hide-collapsed
= _('Milestone')
= icon('spinner spin', class: 'hidden block-loading', 'aria-hidden': 'true')
- if can_edit_issuable
= link_to _('Edit'), '#', class: 'js-sidebar-dropdown-toggle edit-link float-right', data: { track_label: "right_sidebar", track_property: "milestone", track_event: "click_edit_button", track_value: "" }
.value.hide-collapsed
- if milestone.present?
= link_to milestone[:title], milestone[:web_url], class: "bold has-tooltip", title: sidebar_milestone_remaining_days(milestone), data: { container: "body", html: 'true', boundary: 'viewport', qa_selector: 'milestone_link' }
- else
%span.no-value
= _('None')
.selectbox.hide-collapsed
= f.hidden_field 'milestone_id', value: milestone[:id], id: nil
= dropdown_tag('Milestone', options: { title: _('Assign milestone'), toggle_class: 'js-milestone-select js-extra-options', filter: true, dropdown_class: 'dropdown-menu-selectable', placeholder: _('Search milestones'), data: { show_no: true, field_name: "#{issuable_type}[milestone_id]", project_id: issuable_sidebar[:project_id], issuable_id: issuable_sidebar[:id], milestones: issuable_sidebar[:project_milestones_path], ability_name: issuable_type, issue_update: issuable_sidebar[:issuable_json_path], use_id: true, default_no: true, selected: milestone[:title], null_default: true, display: 'static' }})
#issuable-time-tracker.block
// Fallback while content is loading
.title.hide-collapsed
= _('Time tracking')
= icon('spinner spin', 'aria-hidden': 'true')
- if issuable_sidebar.has_key?(:due_date)
.block.due_date
.sidebar-collapsed-icon.has-tooltip{ data: { placement: 'left', container: 'body', html: 'true', boundary: 'viewport' }, title: sidebar_due_date_tooltip_label(issuable_sidebar[:due_date]) }
= icon('calendar', 'aria-hidden': 'true')
%span.js-due-date-sidebar-value
= issuable_sidebar[:due_date].try(:to_s, :medium) || 'None'
- if Feature.enabled?(:vue_issuable_sidebar, @project.group)
%aside#js-vue-issuable-sidebar{ data: { signed_in: signed_in,
sidebar_status_class: sidebar_gutter_collapsed_class } }
- else
%aside.right-sidebar.js-right-sidebar.js-issuable-sidebar{ data: { signed: { in: signed_in } }, class: sidebar_gutter_collapsed_class, 'aria-live' => 'polite' }
.issuable-sidebar
.block.issuable-sidebar-header
- if signed_in
%span.issuable-header-text.hide-collapsed.float-left
= _('To Do')
%a.gutter-toggle.float-right.js-sidebar-toggle.has-tooltip{ role: "button", href: "#", "aria-label" => "Toggle sidebar", title: sidebar_gutter_tooltip_text, data: { container: 'body', placement: 'left', boundary: 'viewport' } }
= sidebar_gutter_toggle_icon
- if signed_in
= render "shared/issuable/sidebar_todo", issuable_sidebar: issuable_sidebar
= form_for issuable_type, url: issuable_sidebar[:issuable_json_path], remote: true, html: { class: 'issuable-context-form inline-update js-issuable-update' } do |f|
- if signed_in
.block.todo.hide-expanded
= render "shared/issuable/sidebar_todo", issuable_sidebar: issuable_sidebar, is_collapsed: true
.block.assignee.qa-assignee-block
= render "shared/issuable/sidebar_assignees", issuable_sidebar: issuable_sidebar, assignees: assignees
= render_if_exists 'shared/issuable/sidebar_item_epic', issuable_sidebar: issuable_sidebar
- milestone = issuable_sidebar[:milestone] || {}
.block.milestone
.sidebar-collapsed-icon.has-tooltip{ title: sidebar_milestone_tooltip_label(milestone), data: { container: 'body', html: 'true', placement: 'left', boundary: 'viewport' } }
= icon('clock-o', 'aria-hidden': 'true')
%span.milestone-title.collapse-truncated-title
- if milestone.present?
= milestone[:title]
- else
= _('None')
.title.hide-collapsed
= _('Due date')
= _('Milestone')
= icon('spinner spin', class: 'hidden block-loading', 'aria-hidden': 'true')
- if can_edit_issuable
= link_to _('Edit'), '#', class: 'js-sidebar-dropdown-toggle edit-link float-right', data: { track_label: "right_sidebar", track_property: "due_date", track_event: "click_edit_button", track_value: "" }
= link_to _('Edit'), '#', class: 'js-sidebar-dropdown-toggle edit-link float-right', data: { track_label: "right_sidebar", track_property: "milestone", track_event: "click_edit_button", track_value: "" }
.value.hide-collapsed
%span.value-content
- if issuable_sidebar[:due_date]
%span.bold= issuable_sidebar[:due_date].to_s(:medium)
- else
%span.no-value
= _('None')
- if milestone.present?
= link_to milestone[:title], milestone[:web_url], class: "bold has-tooltip", title: sidebar_milestone_remaining_days(milestone), data: { container: "body", html: 'true', boundary: 'viewport', qa_selector: 'milestone_link' }
- else
%span.no-value
= _('None')
.selectbox.hide-collapsed
= f.hidden_field 'milestone_id', value: milestone[:id], id: nil
= dropdown_tag('Milestone', options: { title: _('Assign milestone'), toggle_class: 'js-milestone-select js-extra-options', filter: true, dropdown_class: 'dropdown-menu-selectable', placeholder: _('Search milestones'), data: { show_no: true, field_name: "#{issuable_type}[milestone_id]", project_id: issuable_sidebar[:project_id], issuable_id: issuable_sidebar[:id], milestones: issuable_sidebar[:project_milestones_path], ability_name: issuable_type, issue_update: issuable_sidebar[:issuable_json_path], use_id: true, default_no: true, selected: milestone[:title], null_default: true, display: 'static' }})
#issuable-time-tracker.block
// Fallback while content is loading
.title.hide-collapsed
= _('Time tracking')
= icon('spinner spin', 'aria-hidden': 'true')
- if issuable_sidebar.has_key?(:due_date)
.block.due_date
.sidebar-collapsed-icon.has-tooltip{ data: { placement: 'left', container: 'body', html: 'true', boundary: 'viewport' }, title: sidebar_due_date_tooltip_label(issuable_sidebar[:due_date]) }
= icon('calendar', 'aria-hidden': 'true')
%span.js-due-date-sidebar-value
= issuable_sidebar[:due_date].try(:to_s, :medium) || 'None'
.title.hide-collapsed
= _('Due date')
= icon('spinner spin', class: 'hidden block-loading', 'aria-hidden': 'true')
- if can_edit_issuable
= link_to _('Edit'), '#', class: 'js-sidebar-dropdown-toggle edit-link float-right', data: { track_label: "right_sidebar", track_property: "due_date", track_event: "click_edit_button", track_value: "" }
.value.hide-collapsed
%span.value-content
- if issuable_sidebar[:due_date]
%span.bold= issuable_sidebar[:due_date].to_s(:medium)
- else
%span.no-value
= _('None')
- if can_edit_issuable
%span.no-value.js-remove-due-date-holder{ class: ("hidden" if issuable_sidebar[:due_date].nil?) }
\-
%a.js-remove-due-date{ href: "#", role: "button" }
= _('remove due date')
- if can_edit_issuable
%span.no-value.js-remove-due-date-holder{ class: ("hidden" if issuable_sidebar[:due_date].nil?) }
\-
%a.js-remove-due-date{ href: "#", role: "button" }
= _('remove due date')
- if can_edit_issuable
.selectbox.hide-collapsed
= f.hidden_field :due_date, value: issuable_sidebar[:due_date].try(:strftime, 'yy-mm-dd')
.dropdown
%button.dropdown-menu-toggle.js-due-date-select{ type: 'button', data: { toggle: 'dropdown', field_name: "#{issuable_type}[due_date]", ability_name: issuable_type, issue_update: issuable_sidebar[:issuable_json_path], display: 'static' } }
%span.dropdown-toggle-text
= _('Due date')
= icon('chevron-down', 'aria-hidden': 'true')
.dropdown-menu.dropdown-menu-due-date
= dropdown_title(_('Due date'))
= dropdown_content do
.js-due-date-calendar
- selected_labels = issuable_sidebar[:labels]
.block.labels
.sidebar-collapsed-icon.js-sidebar-labels-tooltip{ title: issuable_labels_tooltip(selected_labels), data: { placement: "left", container: "body", boundary: 'viewport' } }
= icon('tags', 'aria-hidden': 'true')
%span
= selected_labels.size
.title.hide-collapsed
= _('Labels')
= icon('spinner spin', class: 'hidden block-loading', 'aria-hidden': 'true')
- if can_edit_issuable
= link_to _('Edit'), '#', class: 'js-sidebar-dropdown-toggle edit-link qa-edit-link-labels float-right', data: { track_label: "right_sidebar", track_property: "labels", track_event: "click_edit_button", track_value: "" }
.value.issuable-show-labels.dont-hide.hide-collapsed.qa-labels-block{ class: ("has-labels" if selected_labels.any?) }
- if selected_labels.any?
- selected_labels.each do |label_hash|
= render_label(label_from_hash(label_hash).present(issuable_subject: nil), link: sidebar_label_filter_path(issuable_sidebar[:project_issuables_path], label_hash[:title]))
- else
%span.no-value
= _('None')
.selectbox.hide-collapsed
- selected_labels.each do |label|
= hidden_field_tag "#{issuable_type}[label_names][]", label[:id], id: nil
.dropdown
%button.dropdown-menu-toggle.js-label-select.js-multiselect.js-label-sidebar-dropdown{ type: "button", data: sidebar_label_dropdown_data(issuable_type, issuable_sidebar) }
%span.dropdown-toggle-text{ class: ("is-default" if selected_labels.empty?) }
= multi_label_name(selected_labels, "Labels")
= icon('chevron-down', 'aria-hidden': 'true')
.dropdown-menu.dropdown-select.dropdown-menu-paging.qa-dropdown-menu-labels.dropdown-menu-labels.dropdown-menu-selectable.dropdown-extended-height
= render partial: "shared/issuable/label_page_default"
- if issuable_sidebar.dig(:current_user, :can_admin_label)
= render partial: "shared/issuable/label_page_create"
= render_if_exists 'shared/issuable/sidebar_weight', issuable_sidebar: issuable_sidebar
- if issuable_sidebar.has_key?(:confidential)
.selectbox.hide-collapsed
= f.hidden_field :due_date, value: issuable_sidebar[:due_date].try(:strftime, 'yy-mm-dd')
.dropdown
%button.dropdown-menu-toggle.js-due-date-select{ type: 'button', data: { toggle: 'dropdown', field_name: "#{issuable_type}[due_date]", ability_name: issuable_type, issue_update: issuable_sidebar[:issuable_json_path], display: 'static' } }
%span.dropdown-toggle-text
= _('Due date')
= icon('chevron-down', 'aria-hidden': 'true')
.dropdown-menu.dropdown-menu-due-date
= dropdown_title(_('Due date'))
= dropdown_content do
.js-due-date-calendar
- selected_labels = issuable_sidebar[:labels]
.block.labels
.sidebar-collapsed-icon.js-sidebar-labels-tooltip{ title: issuable_labels_tooltip(selected_labels), data: { placement: "left", container: "body", boundary: 'viewport' } }
= icon('tags', 'aria-hidden': 'true')
%span
= selected_labels.size
.title.hide-collapsed
= _('Labels')
= icon('spinner spin', class: 'hidden block-loading', 'aria-hidden': 'true')
- if can_edit_issuable
= link_to _('Edit'), '#', class: 'js-sidebar-dropdown-toggle edit-link qa-edit-link-labels float-right', data: { track_label: "right_sidebar", track_property: "labels", track_event: "click_edit_button", track_value: "" }
.value.issuable-show-labels.dont-hide.hide-collapsed.qa-labels-block{ class: ("has-labels" if selected_labels.any?) }
- if selected_labels.any?
- selected_labels.each do |label_hash|
= render_label(label_from_hash(label_hash).present(issuable_subject: nil), link: sidebar_label_filter_path(issuable_sidebar[:project_issuables_path], label_hash[:title]))
- else
%span.no-value
= _('None')
.selectbox.hide-collapsed
- selected_labels.each do |label|
= hidden_field_tag "#{issuable_type}[label_names][]", label[:id], id: nil
.dropdown
%button.dropdown-menu-toggle.js-label-select.js-multiselect.js-label-sidebar-dropdown{ type: "button", data: sidebar_label_dropdown_data(issuable_type, issuable_sidebar) }
%span.dropdown-toggle-text{ class: ("is-default" if selected_labels.empty?) }
= multi_label_name(selected_labels, "Labels")
= icon('chevron-down', 'aria-hidden': 'true')
.dropdown-menu.dropdown-select.dropdown-menu-paging.qa-dropdown-menu-labels.dropdown-menu-labels.dropdown-menu-selectable.dropdown-extended-height
= render partial: "shared/issuable/label_page_default"
- if issuable_sidebar.dig(:current_user, :can_admin_label)
= render partial: "shared/issuable/label_page_create"
= render_if_exists 'shared/issuable/sidebar_weight', issuable_sidebar: issuable_sidebar
- if issuable_sidebar.has_key?(:confidential)
-# haml-lint:disable InlineJavaScript
%script#js-confidential-issue-data{ type: "application/json" }= { is_confidential: issuable_sidebar[:confidential], is_editable: can_edit_issuable }.to_json.html_safe
#js-confidential-entry-point
-# haml-lint:disable InlineJavaScript
%script#js-confidential-issue-data{ type: "application/json" }= { is_confidential: issuable_sidebar[:confidential], is_editable: can_edit_issuable }.to_json.html_safe
#js-confidential-entry-point
%script#js-lock-issue-data{ type: "application/json" }= { is_locked: !!issuable_sidebar[:discussion_locked], is_editable: can_edit_issuable }.to_json.html_safe
#js-lock-entry-point
.js-sidebar-participants-entry-point
- if signed_in
- if issuable_sidebar[:project_emails_disabled]
.block.js-emails-disabled
.sidebar-collapsed-icon.has-tooltip{ title: notification_description(:owner_disabled), data: { placement: "left", container: "body", boundary: 'viewport' } }
= notification_setting_icon
.hide-collapsed= notification_description(:owner_disabled)
- else
.js-sidebar-subscriptions-entry-point
- project_ref = issuable_sidebar[:reference]
.block.project-reference
.sidebar-collapsed-icon.dont-change-state
= clipboard_button(text: project_ref, title: _('Copy reference'), placement: "left", boundary: 'viewport')
.cross-project-reference.hide-collapsed
%span
= _('Reference:')
%cite{ title: project_ref }
= project_ref
= clipboard_button(text: project_ref, title: _('Copy reference'), placement: "left", boundary: 'viewport')
- if issuable_sidebar.dig(:current_user, :can_move)
.block.js-sidebar-move-issue-block
.sidebar-collapsed-icon{ data: { toggle: 'tooltip', placement: 'left', container: 'body', boundary: 'viewport' }, title: _('Move issue') }
= custom_icon('icon_arrow_right')
.dropdown.sidebar-move-issue-dropdown.hide-collapsed
%button.btn.btn-default.btn-block.js-sidebar-dropdown-toggle.js-move-issue{ type: 'button',
data: { toggle: 'dropdown', display: 'static', track_label: "right_sidebar", track_property: "move_issue", track_event: "click_button", track_value: "" } }
= _('Move issue')
.dropdown-menu.dropdown-menu-selectable.dropdown-extended-height
= dropdown_title(_('Move issue'))
= dropdown_filter(_('Search project'), search_id: 'sidebar-move-issue-dropdown-search')
= dropdown_content
= dropdown_loading
= dropdown_footer add_content_class: true do
%button.btn.btn-success.sidebar-move-issue-confirmation-button.js-move-issue-confirmation-button{ type: 'button', disabled: true }
= _('Move')
= icon('spinner spin', class: 'sidebar-move-issue-confirmation-loading-icon')
-# haml-lint:disable InlineJavaScript
%script#js-lock-issue-data{ type: "application/json" }= { is_locked: !!issuable_sidebar[:discussion_locked], is_editable: can_edit_issuable }.to_json.html_safe
#js-lock-entry-point
.js-sidebar-participants-entry-point
- if signed_in
- if issuable_sidebar[:project_emails_disabled]
.block.js-emails-disabled
.sidebar-collapsed-icon.has-tooltip{ title: notification_description(:owner_disabled), data: { placement: "left", container: "body", boundary: 'viewport' } }
= notification_setting_icon
.hide-collapsed= notification_description(:owner_disabled)
- else
.js-sidebar-subscriptions-entry-point
- project_ref = issuable_sidebar[:reference]
.block.project-reference
.sidebar-collapsed-icon.dont-change-state
= clipboard_button(text: project_ref, title: _('Copy reference'), placement: "left", boundary: 'viewport')
.cross-project-reference.hide-collapsed
%span
= _('Reference:')
%cite{ title: project_ref }
= project_ref
= clipboard_button(text: project_ref, title: _('Copy reference'), placement: "left", boundary: 'viewport')
- if issuable_sidebar.dig(:current_user, :can_move)
.block.js-sidebar-move-issue-block
.sidebar-collapsed-icon{ data: { toggle: 'tooltip', placement: 'left', container: 'body', boundary: 'viewport' }, title: _('Move issue') }
= custom_icon('icon_arrow_right')
.dropdown.sidebar-move-issue-dropdown.hide-collapsed
%button.btn.btn-default.btn-block.js-sidebar-dropdown-toggle.js-move-issue{ type: 'button',
data: { toggle: 'dropdown', display: 'static', track_label: "right_sidebar", track_property: "move_issue", track_event: "click_button", track_value: "" } }
= _('Move issue')
.dropdown-menu.dropdown-menu-selectable.dropdown-extended-height
= dropdown_title(_('Move issue'))
= dropdown_filter(_('Search project'), search_id: 'sidebar-move-issue-dropdown-search')
= dropdown_content
= dropdown_loading
= dropdown_footer add_content_class: true do
%button.btn.btn-success.sidebar-move-issue-confirmation-button.js-move-issue-confirmation-button{ type: 'button', disabled: true }
= _('Move')
= icon('spinner spin', class: 'sidebar-move-issue-confirmation-loading-icon')
-# haml-lint:disable InlineJavaScript
%script.js-sidebar-options{ type: "application/json" }= issuable_sidebar_options(issuable_sidebar).to_json.html_safe
%script.js-sidebar-options{ type: "application/json" }= issuable_sidebar_options(issuable_sidebar).to_json.html_safe
<script>
import { mapState } from 'vuex';
import { mapState, mapGetters } from 'vuex';
import IssuableBody from '~/issue_show/components/app.vue';
import IssuableSidebar from '~/issuable_sidebar/components/sidebar_app.vue';
import RelatedItems from 'ee/related_issues/components/related_issues_root.vue';
import EpicSidebar from './epic_sidebar.vue';
......@@ -10,6 +11,7 @@ export default {
epicsPathIdSeparator: '&',
components: {
IssuableBody,
IssuableSidebar,
RelatedItems,
EpicSidebar,
},
......@@ -30,10 +32,18 @@ export default {
'initialDescriptionHtml',
'initialDescriptionText',
'lockVersion',
'sidebarCollapsed',
]),
...mapGetters(['isUserSignedIn']),
isEpicTreeEnabled() {
return gon.features && gon.features.epicTrees;
},
isVueIssuableEpicSidebarEnabled() {
return gon.features && gon.features.vueIssuableEpicSidebar;
},
sidebarStatusClass() {
return this.sidebarCollapsed ? 'right-sidebar-collapsed' : 'right-sidebar-expanded';
},
},
};
</script>
......@@ -84,6 +94,11 @@ export default {
css-class="js-related-issues-block"
path-id-separator="#"
/>
<epic-sidebar />
<issuable-sidebar
v-if="isVueIssuableEpicSidebarEnabled"
:signed-in="isUserSignedIn"
:sidebar-status-class="sidebarStatusClass"
/>
<epic-sidebar v-else />
</div>
</template>
......@@ -5,7 +5,9 @@ import UserCallout from '~/user_callout';
document.addEventListener('DOMContentLoaded', () => {
initShow();
initSidebarBundle();
if (gon.features && !gon.features.vueIssuableSidebar) {
initSidebarBundle();
}
initRelatedIssues();
if (document.getElementById('js-design-management')) {
......
......@@ -5,7 +5,9 @@ import { initReviewBar } from 'ee/batch_comments';
document.addEventListener('DOMContentLoaded', () => {
initShow();
initSidebarBundle();
if (gon.features && !gon.features.vueIssuableSidebar) {
initSidebarBundle();
}
initMrNotes();
initReviewBar();
});
......@@ -18,6 +18,7 @@ class Groups::EpicsController < Groups::ApplicationController
before_action do
push_frontend_feature_flag(:epic_trees, @group)
push_frontend_feature_flag(:roadmap_graphql, @group)
push_frontend_feature_flag(:vue_issuable_epic_sidebar, @group)
end
def index
......
......@@ -154,6 +154,17 @@ RSpec.configure do |config|
.with(:force_autodevops_on_by_default, anything)
.and_return(false)
# The following can be removed once Vue Issuable Sidebar
# is feature-complete and can be made default in place
# of older sidebar.
# See https://gitlab.com/groups/gitlab-org/-/epics/1863
allow(Feature).to receive(:enabled?)
.with(:vue_issuable_sidebar, anything)
.and_return(false)
allow(Feature).to receive(:enabled?)
.with(:vue_issuable_epic_sidebar, anything)
.and_return(false)
# Stub these calls due to being expensive operations
# It can be reenabled for specific tests via:
#
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment