Commit 698cdc74 authored by Florie Guibert's avatar Florie Guibert

Clean up board code

No user facing changes
parent 1e5a4697
import Vue from 'vue';
import { parseBoolean } from '~/lib/utils/common_utils';
import ConfigToggle from './components/config_toggle.vue';
export default () => {
const el = document.querySelector('.js-board-config');
if (!el) {
return;
}
// eslint-disable-next-line no-new
new Vue({
el,
name: 'ConfigToggleRoot',
render(h) {
return h(ConfigToggle, {
props: {
canAdminList: parseBoolean(el.dataset.canAdminList),
hasScope: parseBoolean(el.dataset.hasScope),
},
});
},
});
};
......@@ -13,7 +13,6 @@ import {
} from '~/lib/utils/common_utils';
import { queryToObject } from '~/lib/utils/url_utility';
import { fullBoardId } from './boards_util';
import initNewBoard from './new_board';
import { gqlClient } from './graphql';
Vue.use(VueApollo);
......@@ -112,6 +111,4 @@ export default () => {
});
mountBoardApp($boardApp);
initNewBoard();
};
import Vue from 'vue';
import IssueBoardFilteredSearch from 'ee_else_ce/boards/components/issue_board_filtered_search.vue';
import store from '~/boards/stores';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import { queryToObject } from '~/lib/utils/url_utility';
export default (
apolloProvider,
isSignedIn,
releasesFetchPath,
epicFeatureAvailable,
iterationFeatureAvailable,
) => {
const el = document.getElementById('js-issue-board-filtered-search');
const rawFilterParams = queryToObject(window.location.search, { gatherArrays: true });
const initialFilterParams = {
...convertObjectPropsToCamelCase(rawFilterParams, {}),
};
if (!el) {
return null;
}
return new Vue({
el,
name: 'BoardFilteredSearchRoot',
provide: {
initialFilterParams,
isSignedIn,
releasesFetchPath,
epicFeatureAvailable,
iterationFeatureAvailable,
},
store, // TODO: https://gitlab.com/gitlab-org/gitlab/-/issues/324094
apolloProvider,
render: (createElement) =>
createElement(IssueBoardFilteredSearch, {
props: { fullPath: store.state?.fullPath || '', boardType: store.state?.boardType || '' },
}),
});
};
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import BoardsSelector from 'ee_else_ce/boards/components/boards_selector.vue';
import store from '~/boards/stores';
import createDefaultClient from '~/lib/graphql';
import { parseBoolean } from '~/lib/utils/common_utils';
Vue.use(VueApollo);
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient(),
});
export default (params = {}) => {
const boardsSwitcherElement = document.getElementById('js-multiple-boards-switcher');
const { dataset } = boardsSwitcherElement;
return new Vue({
el: boardsSwitcherElement,
name: 'BoardsSelectorRoot',
components: {
BoardsSelector,
},
apolloProvider,
store,
provide: {
fullPath: params.fullPath,
rootPath: params.rootPath,
allowScopedLabels: params.allowScopedLabels,
labelsManagePath: params.labelsManagePath,
allowLabelCreate: parseBoolean(dataset.canAdminBoard),
},
data() {
const boardsSelectorProps = {
...dataset,
hasMissingBoards: parseBoolean(dataset.hasMissingBoards),
canAdminBoard: parseBoolean(dataset.canAdminBoard),
multipleIssueBoardsAvailable: parseBoolean(dataset.multipleIssueBoardsAvailable),
scopedIssueBoardFeatureEnabled: parseBoolean(dataset.scopedIssueBoardFeatureEnabled),
weights: JSON.parse(dataset.weights),
};
return { boardsSelectorProps };
},
render(createElement) {
return createElement(BoardsSelector, {
props: this.boardsSelectorProps,
});
},
});
};
import Vue from 'vue';
import { parseBoolean } from '~/lib/utils/common_utils';
import { getExperimentVariant } from '~/experimentation/utils';
import { CANDIDATE_VARIANT } from '~/experimentation/constants';
import NewBoardButton from './components/new_board_button.vue';
export default () => {
if (getExperimentVariant('prominent_create_board_btn') !== CANDIDATE_VARIANT) {
return;
}
const el = document.querySelector('.js-new-board');
if (!el) {
return;
}
// eslint-disable-next-line no-new
new Vue({
el,
provide: {
multipleIssueBoardsAvailable: parseBoolean(el.dataset.multipleIssueBoardsAvailable),
canAdminBoard: parseBoolean(el.dataset.canAdminBoard),
},
render(h) {
return h(NewBoardButton);
},
});
};
import Vue from 'vue';
import ToggleFocus from './components/toggle_focus.vue';
export default () => {
const issueBoardsContentSelector = '.content-wrapper > .js-focus-mode-board';
return new Vue({
el: '#js-toggle-focus-btn',
name: 'ToggleFocusRoot',
render(h) {
return h(ToggleFocus, {
props: {
issueBoardsContentSelector,
},
});
},
});
};
- parent = board.resource_parent
- milestone_filter_opts = { format: :json }
- milestone_filter_opts = milestone_filter_opts.merge(only_group_milestones: true) if board.group_board?
- weights = Gitlab.ee? ? ([Issue::WEIGHT_ANY] + Issue.weight_options) : []
#js-multiple-boards-switcher.inline.boards-switcher{ data: { milestone_path: milestones_filter_path(milestone_filter_opts),
board_base_url: board_base_url,
has_missing_boards: (!multiple_boards_available? && current_board_parent.boards.size > 1).to_s,
can_admin_board: can?(current_user, :admin_issue_board, parent).to_s,
multiple_issue_boards_available: parent.multiple_issue_boards_available?.to_s,
scoped_issue_board_feature_enabled: Gitlab.ee? && parent.feature_available?(:scoped_issue_board) ? 'true' : 'false',
weights: weights.to_json } }
- type = local_assigns.fetch(:type)
- board = local_assigns.fetch(:board, nil)
- show_sorting_dropdown = local_assigns.fetch(:show_sorting_dropdown, true)
- disable_target_branch = local_assigns.fetch(:disable_target_branch, false)
- placeholder = local_assigns[:placeholder] || _('Search or filter results...')
- block_css_class = type != :productivity_analytics ? 'row-content-block second-block' : ''
- is_epic_board = board&.to_type == "EpicBoard"
- if is_epic_board
- user_can_admin_list = can?(current_user, :admin_epic_board_list, board.resource_parent)
- elsif board
- user_can_admin_list = can?(current_user, :admin_issue_board_list, board.resource_parent)
.issues-filters
.issues-details-filters.filtered-search-block.d-flex.flex-column.flex-lg-row{ class: block_css_class }
.d-flex.flex-column.flex-md-row.flex-grow-1.mb-lg-0.mb-md-2.mb-sm-0.w-100
- if type == :boards
= render "shared/boards/switcher", board: board
.js-new-board{ data: { multiple_issue_boards_available: parent.multiple_issue_boards_available?.to_s, can_admin_board: can?(current_user, :admin_issue_board, parent).to_s, } }
= form_tag page_filter_path, method: :get, class: 'filter-form js-filter-form w-100' do
- if params[:search].present?
= hidden_field_tag :search, params[:search]
......@@ -25,11 +15,6 @@
- checkbox_id = 'check-all-issues'
%label.gl-sr-only{ for: checkbox_id }= _('Select all')
= check_box_tag checkbox_id, nil, false, class: "check-all-issues left"
- if is_epic_board
#js-board-filtered-search{ data: { full_path: @group&.full_path } }
- elsif board
#js-issue-board-filtered-search
- else
.issues-other-filters.filtered-search-wrapper.d-flex.flex-column.flex-md-row
.filtered-search-box
- if type != :boards
......@@ -213,13 +198,5 @@
%button.clear-search.hidden{ type: 'button' }
= sprite_icon('close', size: 16, css_class: 'clear-search-icon')
.filter-dropdown-container.gl-display-flex.gl-flex-direction-column.gl-md-flex-direction-row.gl-align-items-flex-start
- if type == :boards
#js-board-labels-toggle
- if current_user
#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
.js-create-column-trigger{ data: board_list_data }
#js-toggle-focus-btn
- elsif type != :productivity_analytics && show_sorting_dropdown
- if type != :productivity_analytics && show_sorting_dropdown
= render 'shared/issuable/sort_dropdown'
import Vue from 'vue';
import EpicFilteredSearch from 'ee_component/boards/components/epic_filtered_search.vue';
import store from '~/boards/stores';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import { queryToObject } from '~/lib/utils/url_utility';
export default (apolloProvider) => {
const el = document.getElementById('js-board-filtered-search');
const rawFilterParams = queryToObject(window.location.search, { gatherArrays: true });
const initialFilterParams = {
...convertObjectPropsToCamelCase(rawFilterParams, {}),
};
if (!el) {
return null;
}
return new Vue({
el,
name: 'EpicBoardFilteredSearchRoot',
provide: {
initialFilterParams,
},
store, // TODO: https://gitlab.com/gitlab-org/gitlab/-/issues/324094
apolloProvider,
render: (createElement) =>
createElement(EpicFilteredSearch, {
props: { fullPath: store.state?.fullPath || '', boardType: store.state?.boardType || '' },
}),
});
};
import Vue from 'vue';
import store from '~/boards/stores';
import ToggleEpicsSwimlanes from './components/toggle_epics_swimlanes.vue';
export default () => {
const el = document.getElementById('js-board-epics-swimlanes-toggle');
if (!el) {
return null;
}
return new Vue({
el,
name: 'ToggleEpicsSwimlanesRoot',
components: {
ToggleEpicsSwimlanes,
},
store,
render(createElement) {
return createElement(ToggleEpicsSwimlanes);
},
});
};
import Vue from 'vue';
import store from '~/boards/stores';
import ToggleLabels from './components/toggle_labels.vue';
export default () =>
new Vue({
el: document.getElementById('js-board-labels-toggle'),
name: 'ToggleLabelsRoot',
components: {
ToggleLabels,
},
store,
render: (createElement) => createElement('toggle-labels'),
});
......@@ -27,9 +27,6 @@ module EE
labels: board.labels.to_json(only: [:id, :title, :color, :text_color] ),
board_weight: board.weight,
show_promotion: show_feature_promotion,
can_update: can_update?.to_s,
can_admin_list: can_admin_list?.to_s,
can_admin_board: can_admin_board?.to_s,
disabled: board.disabled_for?(current_user).to_s,
emails_disabled: current_board_parent.emails_disabled?.to_s,
weights: ::Issue.weight_options
......
import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import Vue from 'vue';
import Vuex from 'vuex';
import ToggleEpicsSwimlanes from 'ee/boards/components/toggle_epics_swimlanes.vue';
Vue.use(Vuex);
describe('ToggleEpicsSwimlanes', () => {
let store;
let wrapper;
const createComponent = () => {
wrapper = mount(ToggleEpicsSwimlanes, { store });
};
afterEach(() => {
wrapper.destroy();
});
beforeEach(() => {
store = new Vuex.Store({ state: { isShowingEpicsSwimlanes: false } });
createComponent();
});
describe('dropdownLabel', () => {
it('displays "None" when isShowingEpicsSwimlanes is false', () => {
expect(wrapper.findComponent(GlDropdown).props('text')).toEqual('None');
});
it('returns "Epics" when isShowingEpicsSwimlanes is true', () => {
store = new Vuex.Store({ state: { isShowingEpicsSwimlanes: true } });
createComponent();
expect(wrapper.findComponent(GlDropdown).props('text')).toEqual('Epic');
});
});
describe('template', () => {
it('renders .board-swimlanes-toggle-wrapper container', () => {
expect(wrapper.find('[data-testid="toggle-swimlanes"]').exists()).toBe(true);
});
it('renders "Group by" label', () => {
expect(wrapper.find('[data-testid="toggle-swimlanes-label"]').text()).toEqual('Group by');
});
it('renders dropdown with 2 options', () => {
expect(wrapper.findComponent(GlDropdown).exists()).toBe(true);
expect(wrapper.findAllComponents(GlDropdownItem).length).toEqual(2);
});
});
});
import { GlToggle } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import ToggleLabels from 'ee/boards/components/toggle_labels.vue';
import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue';
Vue.use(Vuex);
describe('ToggleLabels component', () => {
let wrapper;
let setShowLabels;
function createComponent(state = {}) {
setShowLabels = jest.fn();
return shallowMount(ToggleLabels, {
store: new Vuex.Store({
state: {
isShowingLabels: true,
...state,
},
actions: {
setShowLabels,
},
}),
stubs: {
LocalStorageSync,
},
});
}
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
it('onStorageUpdate parses empty value as false', async () => {
wrapper = createComponent();
const localStorageSync = wrapper.findComponent(LocalStorageSync);
localStorageSync.vm.$emit('input', '');
await nextTick();
expect(setShowLabels).toHaveBeenCalledWith(expect.any(Object), false);
});
it('sets GlToggle value from store.isShowingLabels', () => {
wrapper = createComponent({ isShowingLabels: true });
expect(wrapper.findComponent(GlToggle).props('value')).toEqual(true);
wrapper = createComponent({ isShowingLabels: false });
expect(wrapper.findComponent(GlToggle).props('value')).toEqual(false);
});
});
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