Skip to content
Snippets Groups Projects
Commit ec1eb8d0 authored by Simon Knox's avatar Simon Knox
Browse files

Remove board_new_list feature flag

Changelog: other
parent c410054e
No related branches found
No related tags found
No related merge requests found
Showing
with 42 additions and 438 deletions
Loading
Loading
@@ -2548,8 +2548,6 @@ Gitlab/FeatureAvailableUsage:
- 'ee/app/views/projects/settings/operations/_status_page.html.haml'
- 'ee/app/views/projects/settings/repository/_protected_branches.html.haml'
- 'ee/app/views/projects/sidebar/_repository_locked_files.html.haml'
- 'ee/app/views/shared/issuable/_board_create_list_dropdown.html.haml'
- 'ee/app/views/shared/issuable/_board_create_list_dropdown.html.haml'
- 'ee/app/views/shared/issuable/_group_bulk_update_sidebar.html.haml'
- 'ee/app/views/shared/issuable/form/_default_templates.html.haml'
- 'ee/app/views/shared/labels/_create_label_help_text.html.haml'
Loading
Loading
/* eslint-disable func-names, no-new */
import $ from 'jquery';
import store from '~/boards/stores';
import initDeprecatedJQueryDropdown from '~/deprecated_jquery_dropdown';
import createFlash from '~/flash';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import axios from '~/lib/utils/axios_utils';
import { __ } from '~/locale';
import CreateLabelDropdown from '../../create_label';
import { fullLabelId } from '../boards_util';
import boardsStore from '../stores/boards_store';
function shouldCreateListGraphQL(label) {
return store.getters.shouldUseGraphQL && !store.getters.getListByLabelId(fullLabelId(label));
}
// eslint-disable-next-line @gitlab/no-global-event-off
$(document)
.off('created.label')
.on('created.label', (e, label, addNewList) => {
if (!addNewList) {
return;
}
if (shouldCreateListGraphQL(label)) {
store.dispatch('createList', { labelId: fullLabelId(label) });
} else {
boardsStore.new({
title: label.title,
position: boardsStore.state.lists.length - 2,
list_type: 'label',
label: {
id: label.id,
title: label.title,
color: label.color,
},
});
}
});
export default function initNewListDropdown() {
$('.js-new-board-list').each(function () {
const $dropdownToggle = $(this);
const $dropdown = $dropdownToggle.closest('.dropdown');
new CreateLabelDropdown(
$dropdown.find('.dropdown-new-label'),
$dropdownToggle.data('namespacePath'),
$dropdownToggle.data('projectPath'),
);
initDeprecatedJQueryDropdown($dropdownToggle, {
data(term, callback) {
const reqFailed = () => {
$dropdownToggle.data('bs.dropdown').hide();
createFlash({
message: __('Error fetching labels.'),
});
};
if (store.getters.shouldUseGraphQL) {
store
.dispatch('fetchLabels')
.then((data) => callback(data))
.catch(reqFailed);
} else {
axios
.get($dropdownToggle.attr('data-list-labels-path'))
.then(({ data }) => callback(data))
.catch(reqFailed);
}
},
renderRow(label) {
const active = store.getters.shouldUseGraphQL
? store.getters.getListByLabelId(label.id)
: boardsStore.findListByLabelId(label.id);
const $li = $('<li />');
const $a = $('<a />', {
class: active ? `is-active js-board-list-${getIdFromGraphQLId(active.id)}` : '',
text: label.title,
href: '#',
});
const $labelColor = $('<span />', {
class: 'dropdown-label-box',
style: `background-color: ${label.color}`,
});
return $li.append($a.prepend($labelColor));
},
search: {
fields: ['title'],
},
filterable: true,
selectable: true,
multiSelect: true,
containerSelector: '.js-tab-container-labels .dropdown-page-one .dropdown-content',
clicked(options) {
const { e } = options;
const label = options.selectedObj;
e.preventDefault();
if (shouldCreateListGraphQL(label)) {
store.dispatch('createList', { labelId: label.id });
} else if (!boardsStore.findListByLabelId(label.id)) {
boardsStore.new({
title: label.title,
position: boardsStore.state.lists.length - 2,
list_type: 'label',
label: {
id: label.id,
title: label.title,
color: label.color,
},
});
}
},
});
});
}
Loading
Loading
@@ -7,12 +7,7 @@ import { mapActions, mapGetters } from 'vuex';
import 'ee_else_ce/boards/models/issue';
import 'ee_else_ce/boards/models/list';
import BoardSidebar from 'ee_else_ce/boards/components/board_sidebar';
import initNewListDropdown from 'ee_else_ce/boards/components/new_list_dropdown';
import {
setWeightFetchingState,
setEpicFetchingState,
getMilestoneTitle,
} from 'ee_else_ce/boards/ee_functions';
import { setWeightFetchingState, setEpicFetchingState } from 'ee_else_ce/boards/ee_functions';
import toggleEpicsSwimlanes from 'ee_else_ce/boards/toggle_epics_swimlanes';
import toggleLabels from 'ee_else_ce/boards/toggle_labels';
import BoardAddNewColumnTrigger from '~/boards/components/board_add_new_column_trigger.vue';
Loading
Loading
@@ -313,20 +308,6 @@ export default () => {
},
});
 
// eslint-disable-next-line no-new, @gitlab/no-runtime-template-compiler
new Vue({
el: document.getElementById('js-add-list'),
data() {
return {
filters: boardsStore.state.filters,
...getMilestoneTitle($boardApp),
};
},
mounted() {
initNewListDropdown();
},
});
const createColumnTriggerEl = document.querySelector('.js-create-column-trigger');
if (createColumnTriggerEl) {
// eslint-disable-next-line no-new
Loading
Loading
Loading
Loading
@@ -386,15 +386,6 @@
}
}
}
.boards-add-list > .btn {
text-align: left;
> svg {
position: absolute;
right: 6px;
}
}
}
 
.droplab-dropdown .dropdown-menu .filter-dropdown-item {
Loading
Loading
Loading
Loading
@@ -15,14 +15,6 @@
}
}
 
.dropdown-menu-issues-board-new {
width: 320px;
.dropdown-content {
max-height: 140px;
}
}
.issue-board-dropdown-content {
margin: 0;
padding: $gl-padding-4 $gl-padding $gl-padding;
Loading
Loading
.dropdown.gl-display-flex.gl-align-items-center.gl-ml-3#js-add-list
%button.gl-button.btn.btn-confirm.js-new-board-list{ type: "button", data: board_list_data }
Add list
.dropdown-menu.dropdown-extended-height.dropdown-menu-paging.dropdown-menu-right.dropdown-menu-issues-board-new.dropdown-menu-selectable.js-tab-container-labels
= render partial: "shared/issuable/label_page_default", locals: { show_footer: true, show_create: true, show_boards_content: true, title: "Add list" }
- if can?(current_user, :admin_label, board.resource_parent)
= render partial: "shared/issuable/label_page_create", locals: { show_add_list: true, add_list: true, add_list_class: 'd-none' }
= dropdown_loading
Loading
Loading
@@ -207,10 +207,7 @@
#js-board-epics-swimlanes-toggle
.js-board-config{ data: { can_admin_list: user_can_admin_list.to_s, has_scope: board.scoped?.to_s } }
- if user_can_admin_list
- if Feature.enabled?(:board_new_list, board.resource_parent, default_enabled: :yaml) || board.to_type == "EpicBoard"
.js-create-column-trigger{ data: board_list_data }
- else
= render 'shared/issuable/board_create_list_dropdown', board: board
.js-create-column-trigger{ data: board_list_data }
#js-toggle-focus-btn
- elsif type != :productivity_analytics && show_sorting_dropdown
= render 'shared/issuable/sort_dropdown'
---
name: board_new_list
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/52061
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/299366
milestone: '13.8'
type: development
group: group::project management
default_enabled: true
Loading
Loading
@@ -339,14 +339,14 @@ As in other list types, click the trash icon to remove a list.
### Iteration lists **(PREMIUM)**
 
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/250479) in GitLab 13.11.
> - [Deployed behind the `board_new_list` and `iteration_board_lists` feature flags](../feature_flags.md), enabled by default.
> - Enabled on GitLab.com.
> - Recommended for production use.
> - For GitLab self-managed instances, GitLab administrators can opt to disable the feature flags: [`board_new_list`](#enable-or-disable-new-add-list-form) and [`iteration_board_lists`](#enable-or-disable-iteration-lists-in-boards). **(PREMIUM SELF)**
> - Enabled on GitLab.com and is ready for production use.
> - Enabled with `iteration_board_lists` flag for self-managed GitLab and is ready for production use.
> GitLab administrators can opt to [disable the feature flag](#enable-or-disable-iteration-lists-in-boards).
 
There can be
[risks when disabling released features](../../administration/feature_flags.md#risks-when-disabling-released-features).
Refer to this feature's version history for more details.
FLAG:
On self-managed GitLab, by default this feature is available. To hide the feature, ask an
administrator to [disable the `iteration_board_lists` flag](../../administration/feature_flags.md).
On GitLab.com, this feature is available.
 
You're also able to create lists of an iteration.
These are lists that filter issues by the assigned
Loading
Loading
@@ -675,10 +675,6 @@ A few things to remember:
 
### Enable or disable GraphQL-based issue boards **(FREE SELF)**
 
NOTE:
When enabling GraphQL-based issue boards, you must also enable the
[new add list form](#enable-or-disable-new-add-list-form).
It is deployed behind a feature flag that is **enabled by default** as of GitLab 14.1.
[GitLab administrators with access to the GitLab Rails console](../../administration/feature_flags.md)
can disable it.
Loading
Loading
@@ -695,30 +691,8 @@ To disable it:
Feature.disable(:graphql_board_lists)
```
 
### Enable or disable new add list form **(FREE SELF)**
The new form for adding lists is under development but ready for production use. It is
deployed behind a feature flag that is **enabled by default**.
[GitLab administrators with access to the GitLab Rails console](../../administration/feature_flags.md)
can disable it.
To enable it:
```ruby
Feature.enable(:board_new_list)
```
To disable it:
```ruby
Feature.disable(:board_new_list)
```
### Enable or disable iteration lists in boards **(PREMIUM SELF)**
 
NOTE:
When disabling iteration lists in boards, you also need to disable the [new add list form](#enable-or-disable-new-add-list-form).
The iteration list is under development but ready for production use. It is
deployed behind a feature flag that is **enabled by default**.
[GitLab administrators with access to the GitLab Rails console](../../administration/feature_flags.md)
Loading
Loading
import BoardsListSelector from './boards_list_selector/index';
export default function initAssigneesListSelector() {
const $addListEl = document.querySelector('#js-add-list');
return new BoardsListSelector({
propsData: {
listPath: $addListEl.querySelector('.js-new-board-list').dataset.listAssigneesPath,
listType: 'assignees',
},
}).$mount('.js-assignees-list');
}
import BoardsListSelector from './boards_list_selector';
export default function initMilestoneListSelector() {
const $addListEl = document.querySelector('#js-add-list');
return new BoardsListSelector({
propsData: {
listPath: $addListEl.querySelector('.js-new-board-list').dataset.listMilestonePath,
listType: 'milestones',
},
}).$mount('.js-milestone-list');
}
import $ from 'jquery';
import initNewListDropdown from '~/boards/components/new_list_dropdown';
import AssigneeList from './assignees_list_selector';
import MilestoneList from './milestone_list_selector';
const handleDropdownHide = (e) => {
const $currTarget = $(e.currentTarget);
if ($currTarget.data('preventClose')) {
e.preventDefault();
}
$currTarget.removeData('preventClose');
};
let assigneeList;
let milestoneList;
const handleDropdownTabClick = (e) => {
const $addListEl = $('#js-add-list');
$addListEl.data('preventClose', true);
if (e.target.dataset.action === 'tab-assignees' && !assigneeList) {
assigneeList = AssigneeList();
}
if (e.target.dataset.action === 'tab-milestones' && !milestoneList) {
milestoneList = MilestoneList();
}
};
export default () => {
initNewListDropdown();
$('#js-add-list').on('hide.bs.dropdown', handleDropdownHide);
$('.js-new-board-list-tabs').on('click', handleDropdownTabClick);
};
@import '../../../../../app/assets/stylesheets/page_bundles/boards';
 
.boards-add-list {
&.show {
.dropdown-menu-tabs {
max-height: 400px;
min-width: 240px;
overflow-y: hidden;
}
}
.dropdown-tabs-list {
box-shadow: 0 0 0 1px var(--border-color, $border-color);
}
.dropdown-tab-item {
border-left: 1px solid var(--border-color, $border-color);
a {
border-bottom: 2px solid transparent;
background-color: var(--gray-50, $gray-50);
&:focus,
&.active {
background-color: var(--white, $white);
}
&.active {
font-weight: bold;
border-bottom-color: var(--indigo-500, $indigo-500);
}
}
}
.issue-board-dropdown-content {
padding: $gl-padding;
}
}
.board-add-new-list .gl-new-dropdown-inner {
max-height: 12rem !important;
 
Loading
Loading
.dropdown-page-one
.issue-board-dropdown-content
%p
= _('Assignee lists show all issues assigned to the selected user.')
.js-assignees-list
- assignee_lists_available = board.resource_parent.feature_available?(:board_assignee_lists)
- milestone_lists_available = board.resource_parent.feature_available?(:board_milestone_lists)
- if assignee_lists_available || milestone_lists_available
.dropdown.boards-add-list.gl-ml-3.gl-display-flex.gl-align-items-center#js-add-list
%button.btn.gl-button.btn-confirm.gl-display-flex.js-new-board-list{ type: "button", data: board_list_data }
%span Add list
= sprite_icon('chevron-down', css_class: 'gl-ml-2 btn-success-board-list-chevron')
.dropdown-menu.dropdown-menu-paging.dropdown-menu-right.dropdown-menu-issues-board-new.dropdown-menu-selectable.dropdown-menu-tabs.pt-0
%ul.nav.nav-tabs.dropdown-tabs-list.d-flex.js-new-board-list-tabs{ role: 'tablist' }
%li.nav-item.dropdown-tab-item.flex-grow-1.flex-shrink-1.w-0.border-left-0.js-tab-button-labels
%a.w-100.text-center.py-3.px-2.active{ href: '#', role: 'tab', data: { is_link: 'true', toggle: 'tab', action: 'tab-labels', target: '#tab-labels' } }
Label
- if assignee_lists_available
%li.nav-item.dropdown-tab-item.flex-grow-1.flex-shrink-1.w-0.js-tab-button-assignees
%a.w-100.text-center.py-3.px-2{ href: '#', role: 'tab', data: { is_link: 'true', toggle: 'tab', action: 'tab-assignees', target: '#tab-assignees' } }
Assignee
- if milestone_lists_available
%li.nav-item.dropdown-tab-item.flex-grow-1.flex-shrink-1.w-0.js-tab-button-milestones
%a.w-100.text-center.py-3.px-2{ href: '#', role: 'tab', data: { is_link: 'true', toggle: 'tab', action: 'tab-milestones', target: '#tab-milestones' } }
Milestone
.tab-content
#tab-labels.tab-pane.tab-pane-labels.active.js-tab-container-labels{ role: 'tabpanel' }
= render partial: "shared/issuable/label_page_default", locals: { show_title: false, show_footer: true, show_create: true, show_boards_content: true, content_title: _('Label lists show all issues with the selected label.') }
- if can?(current_user, :admin_label, board.resource_parent)
= render partial: "shared/issuable/label_page_create", locals: { show_close: false }
- if assignee_lists_available
#tab-assignees.tab-pane.tab-pane-assignees.js-tab-container-assignees{ role: 'tabpanel' }
= render partial: "shared/issuable/assignee_page_default"
- if milestone_lists_available
#tab-milestones.tab-pane.tab-pane-milestones.js-tab-container-milestones{ role: 'tabpanel' }
= render partial: "shared/issuable/milestone_page_default"
= dropdown_loading
- else
= render_ce 'shared/issuable/board_create_list_dropdown', board: board
.dropdown-page-one
.issue-board-dropdown-content
%p
= _('Milestone lists show all issues from the selected milestone.')
.js-milestone-list
Loading
Loading
@@ -35,46 +35,6 @@
end
end
 
context 'add list dropdown' do
let(:group) { create(:group) }
let(:project) { create(:project, :public, namespace: group) }
before do
stub_feature_flags(board_new_list: false)
project.add_maintainer(user)
group.add_reporter(user)
login_as(user)
end
it 'shows tabbed dropdown with labels list and assignees list' do
stub_licensed_features(board_assignee_lists: true)
visit_board_page
page.within('#js-add-list') do
page.find('.js-new-board-list').click
wait_for_requests
expect(page).to have_css('.dropdown-menu.dropdown-menu-tabs')
expect(page).to have_css('.js-tab-button-labels')
expect(page).to have_css('.js-tab-button-assignees')
end
end
it 'shows simple dropdown with only labels list' do
stub_licensed_features(board_assignee_lists: false)
visit_board_page
page.within('#js-add-list') do
page.find('.js-new-board-list').click
wait_for_requests
expect(page).to have_css('.dropdown-menu.js-tab-container-labels')
expect(page).to have_content('Create lists from labels. Issues with that label appear in that list.')
expect(page).not_to have_css('.js-tab-button-assignees')
end
end
end
context 'swimlanes dropdown' do
context 'license feature on' do
before do
Loading
Loading
Loading
Loading
@@ -44,8 +44,7 @@
set_cookie('sidebar_collapsed', 'true')
 
stub_feature_flags(
graphql_board_lists: graphql_board_lists_enabled,
board_new_list: true
graphql_board_lists: graphql_board_lists_enabled
)
 
if board_type == :project
Loading
Loading
@@ -89,10 +88,6 @@
 
sign_in(user)
 
stub_feature_flags(
board_new_list: true
)
visit project_board_path(project, project_board)
 
wait_for_all_requests
Loading
Loading
Loading
Loading
@@ -4650,9 +4650,6 @@ msgstr ""
msgid "Assignee lists not available with your current license"
msgstr ""
 
msgid "Assignee lists show all issues assigned to the selected user."
msgstr ""
msgid "Assignee(s)"
msgstr ""
 
Loading
Loading
@@ -19448,9 +19445,6 @@ msgstr ""
msgid "Label actions dropdown"
msgstr ""
 
msgid "Label lists show all issues with the selected label."
msgstr ""
msgid "Label priority"
msgstr ""
 
Loading
Loading
@@ -21526,9 +21520,6 @@ msgstr ""
msgid "Milestone lists not available with your current license"
msgstr ""
 
msgid "Milestone lists show all issues from the selected milestone."
msgstr ""
msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
 
Loading
Loading
Loading
Loading
@@ -17,6 +17,8 @@
let_it_be(:project_label) { create(:label, project: project) }
let_it_be(:group_backlog_list) { create(:backlog_list, board: group_board) }
let_it_be(:project_backlog_list) { create(:backlog_list, board: project_board) }
let_it_be(:backlog) { create(:group_label, group: group, name: 'Backlog') }
let_it_be(:closed) { create(:group_label, group: group, name: 'Closed') }
 
let_it_be(:issue) { create(:labeled_issue, project: project, labels: [group_label, project_label]) }
 
Loading
Loading
@@ -25,15 +27,11 @@
group.add_owner(user)
end
 
where(:board_type, :graphql_board_lists_enabled, :board_new_list_enabled) do
:project | true | true
:project | false | true
:project | true | false
:project | false | false
:group | true | true
:group | false | true
:group | true | false
:group | false | false
where(:board_type, :graphql_board_lists_enabled) do
:project | true
:project | false
:group | true
:group | false
end
 
with_them do
Loading
Loading
@@ -43,8 +41,7 @@
set_cookie('sidebar_collapsed', 'true')
 
stub_feature_flags(
graphql_board_lists: graphql_board_lists_enabled,
board_new_list: board_new_list_enabled
graphql_board_lists: graphql_board_lists_enabled
)
 
if board_type == :project
Loading
Loading
@@ -57,39 +54,44 @@
end
 
it 'creates new column for label containing labeled issue' do
click_button button_text(board_new_list_enabled)
click_button 'Create list'
wait_for_all_requests
 
select_label(board_new_list_enabled, group_label)
select_label(group_label)
 
wait_for_all_requests
 
expect(page).to have_selector('.board', text: group_label.title)
expect(find('.board:nth-child(2) .board-card')).to have_content(issue.title)
end
end
 
def select_label(board_new_list_enabled, label)
if board_new_list_enabled
click_button 'Select a label'
it 'creates new list for Backlog and closed labels' do
click_button 'Create list'
wait_for_requests
 
find('label', text: label.title).click
select_label(backlog)
 
click_button 'Add to board'
click_button 'Create list'
wait_for_requests
 
wait_for_all_requests
else
page.within('.dropdown-menu-issues-board-new') do
click_link label.title
end
select_label(closed)
wait_for_requests
expect(page).to have_selector('.board', text: closed.title)
expect(find('.board:nth-child(2) .board-header')).to have_content(backlog.title)
expect(find('.board:nth-child(3) .board-header')).to have_content(closed.title)
expect(find('.board:nth-child(4) .board-header')).to have_content('Closed')
end
end
 
def button_text(board_new_list_enabled)
if board_new_list_enabled
'Create list'
else
'Add list'
end
def select_label(label)
click_button 'Select a label'
find('label', text: label.title).click
click_button 'Add to board'
wait_for_all_requests
end
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment