Commit ea6ecacd authored by Simon Knox's avatar Simon Knox

Merge branch '260439-remove-boards-upsell-list' into 'master'

Removed boards promotion [RUN AS-IF-FOSS]

See merge request gitlab-org/gitlab!47972
parents 465e5f66 084f9e9a
......@@ -2,15 +2,12 @@
// This component is being replaced in favor of './board_column_new.vue' for GraphQL boards
import Sortable from 'sortablejs';
import BoardListHeader from 'ee_else_ce/boards/components/board_list_header.vue';
import EmptyComponent from '~/vue_shared/components/empty_component';
import BoardList from './board_list.vue';
import boardsStore from '../stores/boards_store';
import { getBoardSortableDefaultOptions, sortableEnd } from '../mixins/sortable_default_options';
import { ListType } from '../constants';
export default {
components: {
BoardPromotionState: EmptyComponent,
BoardListHeader,
BoardList,
},
......@@ -42,9 +39,6 @@ export default {
};
},
computed: {
showBoardListAndBoardInfo() {
return this.list.type !== ListType.promotion;
},
listIssues() {
return this.list.issues;
},
......@@ -105,16 +99,7 @@ export default {
class="board-inner gl-display-flex gl-flex-direction-column gl-relative gl-h-full gl-rounded-base"
>
<board-list-header :can-admin-list="canAdminList" :list="list" :disabled="disabled" />
<board-list
v-if="showBoardListAndBoardInfo"
ref="board-list"
:disabled="disabled"
:issues="listIssues"
:list="list"
/>
<!-- Will be only available in EE -->
<board-promotion-state v-if="list.id === 'promotion'" />
<board-list ref="board-list" :disabled="disabled" :issues="listIssues" :list="list" />
</div>
</div>
</template>
<script>
import { mapGetters, mapActions, mapState } from 'vuex';
import BoardListHeader from 'ee_else_ce/boards/components/board_list_header_new.vue';
import BoardPromotionState from 'ee_else_ce/boards/components/board_promotion_state';
import BoardList from './board_list_new.vue';
import { ListType } from '../constants';
export default {
components: {
BoardPromotionState,
BoardListHeader,
BoardList,
},
......@@ -35,9 +33,6 @@ export default {
computed: {
...mapState(['filterParams']),
...mapGetters(['getIssuesByList']),
showBoardListAndBoardInfo() {
return this.list.type !== ListType.promotion;
},
listIssues() {
return this.getIssuesByList(this.list.id);
},
......@@ -80,16 +75,12 @@ export default {
>
<board-list-header :can-admin-list="canAdminList" :list="list" :disabled="disabled" />
<board-list
v-if="showBoardListAndBoardInfo"
ref="board-list"
:disabled="disabled"
:issues="listIssues"
:list="list"
:can-admin-list="canAdminList"
/>
<!-- Will be only available in EE -->
<board-promotion-state v-if="list.id === 'promotion'" />
</div>
</div>
</template>
......@@ -3,7 +3,7 @@ import Draggable from 'vuedraggable';
import { mapState, mapGetters, mapActions } from 'vuex';
import { sortBy } from 'lodash';
import { GlAlert } from '@gitlab/ui';
import BoardColumn from 'ee_else_ce/boards/components/board_column.vue';
import BoardColumn from './board_column.vue';
import BoardColumnNew from './board_column_new.vue';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import defaultSortableConfig from '~/sortable/sortable_config';
......@@ -59,13 +59,8 @@ export default {
return this.canDragColumns ? options : {};
},
},
mounted() {
if (this.glFeatures.graphqlBoardLists) {
this.showPromotionList();
}
},
methods: {
...mapActions(['moveList', 'showPromotionList']),
...mapActions(['moveList']),
handleDragOnStart() {
sortableStart();
},
......
......@@ -73,10 +73,7 @@ export default {
},
showListHeaderButton() {
return (
!this.disabled &&
this.listType !== ListType.closed &&
this.listType !== ListType.blank &&
this.listType !== ListType.promotion
!this.disabled && this.listType !== ListType.closed && this.listType !== ListType.blank
);
},
showMilestoneListDetails() {
......@@ -110,7 +107,7 @@ export default {
);
},
showBoardListAndBoardInfo() {
return this.listType !== ListType.blank && this.listType !== ListType.promotion;
return this.listType !== ListType.blank;
},
uniqueKey() {
// eslint-disable-next-line @gitlab/require-i18n-strings
......
......@@ -76,10 +76,7 @@ export default {
},
showListHeaderButton() {
return (
!this.disabled &&
this.listType !== ListType.closed &&
this.listType !== ListType.blank &&
this.listType !== ListType.promotion
!this.disabled && this.listType !== ListType.closed && this.listType !== ListType.blank
);
},
showMilestoneListDetails() {
......@@ -115,7 +112,7 @@ export default {
);
},
showBoardListAndBoardInfo() {
return this.listType !== ListType.blank && this.listType !== ListType.promotion;
return this.listType !== ListType.blank;
},
uniqueKey() {
// eslint-disable-next-line @gitlab/require-i18n-strings
......
......@@ -9,7 +9,6 @@ export const ListType = {
backlog: 'backlog',
closed: 'closed',
label: 'label',
promotion: 'promotion',
blank: 'blank',
};
......
export const setPromotionState = () => {};
export const setWeightFetchingState = () => {};
export const setEpicFetchingState = () => {};
......
......@@ -9,7 +9,6 @@ import boardConfigToggle from 'ee_else_ce/boards/config_toggle';
import toggleLabels from 'ee_else_ce/boards/toggle_labels';
import toggleEpicsSwimlanes from 'ee_else_ce/boards/toggle_epics_swimlanes';
import {
setPromotionState,
setWeightFetchingState,
setEpicFetchingState,
getMilestoneTitle,
......@@ -131,7 +130,6 @@ export default () => {
...endpoints,
boardType: this.parent,
disabled: this.disabled,
showPromotion: parseBoolean($boardApp.getAttribute('data-show-promotion')),
});
boardsStore.setEndpoints(endpoints);
boardsStore.rootPath = this.boardsEndpoint;
......@@ -184,7 +182,6 @@ export default () => {
.then(lists => {
lists.forEach(list => boardsStore.addList(list));
boardsStore.addBlankState();
setPromotionState(boardsStore);
this.loading = false;
})
.catch(() => {
......
......@@ -126,8 +126,6 @@ export default {
);
},
showPromotionList: () => {},
fetchLabels: ({ state, commit }, searchTerm) => {
const { endpoints, boardType } = state;
const { fullPath } = endpoints;
......
......@@ -172,13 +172,6 @@
}
}
.board-promotion-state {
background-color: var(--white, $white);
flex: 1;
overflow-y: auto;
overflow-x: hidden;
}
.board-list-component {
min-height: 0; // firefox fix
}
......
......@@ -13,7 +13,6 @@
- content_for :page_specific_javascripts do
%script#js-board-modal-filter{ type: "text/x-template" }= render "shared/issuable/search_bar", type: :boards_modal, show_sorting_dropdown: false
%script#js-board-promotion{ type: "text/x-template" }= render_if_exists "shared/promotions/promote_issue_board"
= render 'shared/issuable/search_bar', type: :boards, board: board
#board-app.boards-app.position-relative{ "v-cloak" => "true", data: board_data, ":class" => "{ 'is-compact': detailIssueVisible }" }
......
---
title: Removed boards promotion
merge_request: 47972
author:
type: changed
<script>
import BoardPromotionState from 'ee/boards/components/board_promotion_state';
import BoardColumnFoss from '~/boards/components/board_column.vue';
export default {
components: {
BoardPromotionState,
},
extends: BoardColumnFoss,
};
</script>
import boardsStore from '~/boards/stores/boards_store';
export default {
template: '#js-board-promotion',
methods: {
clearPromotionState: boardsStore.removePromotionState.bind(boardsStore),
},
};
export const setPromotionState = store => {
store.addPromotionState();
};
export const setWeightFetchingState = (issue, value) => {
issue.setFetchingState('weight', value);
};
......
......@@ -3,24 +3,12 @@ import List from '~/boards/models/list';
import ListAssignee from '~/boards/models/assignee';
import ListMilestone from '~/boards/models/milestone';
const EE_TYPES = {
promotion: {
isPreset: true,
isExpandable: false,
isBlank: true,
},
};
class ListEE extends List {
constructor(...args) {
super(...args);
this.totalWeight = args[0]?.totalWeight || 0;
}
getTypeInfo(type) {
return EE_TYPES[type] || super.getTypeInfo(type);
}
getIssues(...args) {
return super.getIssues(...args).then(data => {
this.totalWeight = data.total_weight;
......
import { pick } from 'lodash';
import Cookies from 'js-cookie';
import axios from '~/lib/utils/axios_utils';
import boardsStore from '~/boards/stores/boards_store';
import { __ } from '~/locale';
import { historyPushState, parseBoolean } from '~/lib/utils/common_utils';
import { historyPushState } from '~/lib/utils/common_utils';
import { mergeUrlParams, removeParams } from '~/lib/utils/url_utility';
import actionsCE from '~/boards/stores/actions';
import { BoardType, ListType } from '~/boards/constants';
import { BoardType } from '~/boards/constants';
import { EpicFilterType, IterationFilterType, GroupByParamType } from '../constants';
import boardsStoreEE from './boards_store_ee';
import * as types from './mutation_types';
......@@ -228,22 +226,6 @@ export default {
});
},
showPromotionList: ({ state, dispatch }) => {
if (
!state.showPromotion ||
parseBoolean(Cookies.get('promotion_issue_board_hidden')) ||
state.disabled
) {
return;
}
dispatch('addList', {
id: 'promotion',
listType: ListType.promotion,
title: __('Improve Issue Boards'),
position: 0,
});
},
fetchAllBoards: () => {
notImplemented();
},
......@@ -264,10 +246,6 @@ export default {
notImplemented();
},
togglePromotionState: () => {
notImplemented();
},
fetchIssuesForList: ({ state, commit }, { listId, fetchNext = false, noEpicIssues = false }) => {
commit(types.REQUEST_ISSUES_FOR_LIST, { listId, fetchNext });
......
......@@ -4,8 +4,6 @@
modify the passed parameter in conformity with non-ee BoardsStore.
*/
import { sortBy } from 'lodash';
import Cookies from 'js-cookie';
import { __, sprintf } from '~/locale';
import sidebarEventHub from '~/sidebar/event_hub';
import { deprecatedCreateFlash as createFlash } from '~/flash';
......@@ -19,13 +17,7 @@ class BoardsStoreEE {
initEESpecific(boardsStore) {
this.$boardApp = document.getElementById('board-app');
this.store = boardsStore;
this.store.addPromotionState = () => {
this.addPromotion();
};
this.store.loadList = (listPath, listType) => this.loadList(listPath, listType);
this.store.removePromotionState = () => {
this.removePromotion();
};
const superSetCurrentBoard = this.store.setCurrentBoard.bind(this.store);
this.store.setCurrentBoard = board => {
......@@ -168,38 +160,6 @@ class BoardsStoreEE {
this.store.updateFiltersUrl(true);
}
addPromotion() {
if (
!this.$boardApp.hasAttribute('data-show-promotion') ||
this.promotionIsHidden() ||
this.store.disabled
) {
return;
}
this.store.addList({
id: 'promotion',
list_type: 'promotion',
title: __('Improve Issue boards'),
position: 0,
});
this.store.state.lists = sortBy(this.store.state.lists, 'position');
}
removePromotion() {
this.store.removeList('promotion', 'promotion');
Cookies.set('promotion_issue_board_hidden', 'true', {
expires: 365 * 10,
path: '',
});
}
promotionIsHidden() {
return parseBoolean(Cookies.get('promotion_issue_board_hidden'));
}
setMaxIssueCountOnList(id, maxIssueCount) {
this.store.findList('id', id).maxIssueCount = maxIssueCount;
}
......
- return unless @project
.board-promotion-state.p-3
.svg-container.center
= custom_icon('icon_issue_board')
%p
- if Gitlab::CurrentSettings.should_check_namespace_plan?
= _('Upgrade your plan to improve Issue boards.')
- else
= _('Improve Issue boards with GitLab Enterprise Edition.')
%ul
- unless @project.multiple_issue_boards_available?
%li
= link_to _('Multiple issue boards'), help_page_path('user/project/issue_board.md', anchor:'use-cases-for-multiple-issue-boards'), target: '_blank'
- unless @project.feature_available?(:scoped_issue_board)
%li
= link_to _('Scoped issue boards'), help_page_path('user/project/issue_board.md', anchor:'configurable-issue-boards'), target: '_blank'
= render 'shared/promotions/promotion_link_project'
.top-space
%button.d-block.mb-3.btn.btn-default.btn-block#hide-btn{ :href => "#", "@click.stop" => "clearPromotionState" }
= _("Thanks! Don't show me this again")
......@@ -103,34 +103,6 @@ RSpec.describe 'Promotions', :js do
end
end
describe 'for issue boards ', :js do
before do
stub_application_setting(check_namespace_plan: true)
allow(Gitlab).to receive(:com?) { true }
project.add_maintainer(user)
sign_in(user)
end
it 'appears in issue boards page' do
visit project_boards_path(project)
expect(find('.board-promotion-state')).to have_content "Upgrade your plan to improve Issue boards"
end
it 'does not show when cookie is set' do
visit project_boards_path(project)
within('.board-promotion-state') do
find('#hide-btn').click
end
visit project_boards_path(project, milestone)
expect(page).not_to have_selector('.board-promotion-state')
end
end
describe 'for epics in issues sidebar', :js do
shared_examples 'Epics promotion' do
it 'appears on the page' do
......
......@@ -8,10 +8,6 @@ import { ListType, inactiveId } from '~/boards/constants';
import List from '~/boards/models/list';
import sidebarEventHub from '~/sidebar/event_hub';
// board_promotion_state tries to mount on the real DOM,
// so we are mocking it in this test
jest.mock('ee/boards/components/board_promotion_state', () => ({}));
const localVue = createLocalVue();
localVue.use(Vuex);
......@@ -80,7 +76,7 @@ describe('Board List Header Component', () => {
describe('Settings Button', () => {
const hasSettings = [ListType.assignee, ListType.milestone, ListType.label];
const hasNoSettings = [ListType.backlog, ListType.blank, ListType.closed, ListType.promotion];
const hasNoSettings = [ListType.backlog, ListType.blank, ListType.closed];
it.each(hasSettings)('does render for List Type `%s`', listType => {
createComponent({ listType });
......
......@@ -12,10 +12,6 @@ import List from '~/boards/models/list';
import axios from '~/lib/utils/axios_utils';
import sidebarEventHub from '~/sidebar/event_hub';
// board_promotion_state tries to mount on the real DOM,
// so we are mocking it in this test
jest.mock('ee/boards/components/board_promotion_state', () => ({}));
const localVue = createLocalVue();
localVue.use(Vuex);
......@@ -86,7 +82,7 @@ describe('Board List Header Component', () => {
describe('Settings Button', () => {
const hasSettings = [ListType.assignee, ListType.milestone, ListType.label];
const hasNoSettings = [ListType.backlog, ListType.blank, ListType.closed, ListType.promotion];
const hasNoSettings = [ListType.backlog, ListType.blank, ListType.closed];
it.each(hasSettings)('does render for List Type `%s`', listType => {
createComponent({ listType });
......
......@@ -7,7 +7,6 @@ import * as types from 'ee/boards/stores/mutation_types';
import { TEST_HOST } from 'helpers/test_constants';
import testAction from 'helpers/vuex_action_helper';
import { formatListIssues } from '~/boards/boards_util';
import { ListType } from '~/boards/constants';
import * as typesCE from '~/boards/stores/mutation_types';
import * as commonUtils from '~/lib/utils/common_utils';
import { mergeUrlParams, removeParams } from '~/lib/utils/url_utility';
......@@ -344,34 +343,6 @@ describe('updateListWipLimit', () => {
});
});
describe('showPromotionList', () => {
it('should dispatch addList action when conditions showPromotion is true', done => {
const state = {
endpoints: { fullPath: 'gitlab-org', boardId: '1' },
boardType: 'group',
disabled: false,
boardLists: [{ type: 'backlog' }, { type: 'closed' }],
showPromotion: true,
};
const promotionList = {
id: 'promotion',
listType: ListType.promotion,
title: 'Improve Issue Boards',
position: 0,
};
testAction(
actions.showPromotionList,
{},
state,
[],
[{ type: 'addList', payload: promotionList }],
done,
);
});
});
describe('fetchAllBoards', () => {
expectNotImplemented(actions.fetchAllBoards);
});
......@@ -392,10 +363,6 @@ describe('updateIssueWeight', () => {
expectNotImplemented(actions.updateIssueWeight);
});
describe('togglePromotionState', () => {
expectNotImplemented(actions.updateIssueWeight);
});
describe('fetchIssuesForEpic', () => {
const listId = mockLists[0].id;
const epicId = mockEpic.id;
......
......@@ -14368,15 +14368,6 @@ msgstr ""
msgid "Imported requirements"
msgstr ""
msgid "Improve Issue Boards"
msgstr ""
msgid "Improve Issue boards"
msgstr ""
msgid "Improve Issue boards with GitLab Enterprise Edition."
msgstr ""
msgid "Improve Merge Requests and customer support with GitLab Enterprise Edition."
msgstr ""
......@@ -18011,9 +18002,6 @@ msgstr ""
msgid "Multiple domains are supported."
msgstr ""
msgid "Multiple issue boards"
msgstr ""
msgid "Multiple model types found: %{model_types}"
msgstr ""
......@@ -23941,9 +23929,6 @@ msgstr ""
msgid "Scope"
msgstr ""
msgid "Scoped issue boards"
msgstr ""
msgid "Scopes"
msgstr ""
......@@ -27101,9 +27086,6 @@ msgstr ""
msgid "Thanks for your purchase!"
msgstr ""
msgid "Thanks! Don't show me this again"
msgstr ""
msgid "That's it, well done!"
msgstr ""
......@@ -29560,9 +29542,6 @@ msgstr ""
msgid "Upgrade your plan to enable this feature of the Jira Integration."
msgstr ""
msgid "Upgrade your plan to improve Issue boards."
msgstr ""
msgid "Upgrade your plan to improve Merge Requests."
msgstr ""
......
......@@ -3,8 +3,8 @@ import { createLocalVue, shallowMount } from '@vue/test-utils';
import { GlAlert } from '@gitlab/ui';
import Draggable from 'vuedraggable';
import EpicsSwimlanes from 'ee_component/boards/components/epics_swimlanes.vue';
import BoardColumn from 'ee_else_ce/boards/components/board_column.vue';
import getters from 'ee_else_ce/boards/stores/getters';
import BoardColumn from '~/boards/components/board_column.vue';
import { mockListsWithModel } from '../mock_data';
import BoardContent from '~/boards/components/board_content.vue';
......@@ -13,7 +13,6 @@ localVue.use(Vuex);
const actions = {
moveList: jest.fn(),
showPromotionList: jest.fn(),
};
describe('BoardContent', () => {
......
......@@ -79,7 +79,7 @@ describe('Board List Header Component', () => {
const findCaret = () => wrapper.find('.board-title-caret');
describe('Add issue button', () => {
const hasNoAddButton = [ListType.promotion, ListType.blank, ListType.closed];
const hasNoAddButton = [ListType.blank, ListType.closed];
const hasAddButton = [ListType.backlog, ListType.label, ListType.milestone, ListType.assignee];
it.each(hasNoAddButton)('does not render when List Type is `%s`', listType => {
......
......@@ -73,7 +73,7 @@ describe('Board List Header Component', () => {
const findCaret = () => wrapper.find('.board-title-caret');
describe('Add issue button', () => {
const hasNoAddButton = [ListType.promotion, ListType.blank, ListType.closed];
const hasNoAddButton = [ListType.blank, ListType.closed];
const hasAddButton = [ListType.backlog, ListType.label, ListType.milestone, ListType.assignee];
it.each(hasNoAddButton)('does not render when List Type is `%s`', listType => {
......
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