Commit 04e1f55e authored by Florie Guibert's avatar Florie Guibert

Replace DeprecatedModal with GlModal for boards

Refactor modals for board forms
parent bb9ef246
<script>
import { GlModal } from '@gitlab/ui';
import { __ } from '~/locale';
import { deprecatedCreateFlash as Flash } from '~/flash';
import DeprecatedModal from '~/vue_shared/components/deprecated_modal.vue';
import { visitUrl } from '~/lib/utils/url_utility';
import boardsStore from '~/boards/stores/boards_store';
......@@ -20,9 +20,24 @@ const boardDefaults = {
};
export default {
i18n: {
createBoardButtonText: __('Create board'),
deleteBoardButtonText: __('Delete'),
saveButtonText: __('Save changes'),
createModalTitle: __('Create new board'),
deleteModalTitle: __('Delete board'),
scopeModalTitle: __('Board scope'),
editModalTitle: __('Edit board'),
cancelButtonText: __('Cancel'),
deleteErrorMessage: __('Failed to delete board. Please try again.'),
saveErrorMessage: __('Unable to save your changes. Please try again.'),
deleteConfirmationMessage: __('Are you sure you want to delete this board?'),
titleFieldLabel: __('Title'),
titleFieldPlaceholder: __('Enter board name'),
},
components: {
BoardScope: () => import('ee_component/boards/components/board_scope.vue'),
DeprecatedModal,
GlModal,
BoardConfigurationOptions,
},
props: {
......@@ -82,17 +97,14 @@ export default {
isEditForm() {
return this.currentPage === 'edit';
},
isVisible() {
return this.currentPage !== '';
},
buttonText() {
if (this.isNewForm) {
return __('Create board');
return this.$options.i18n.createBoardButtonText;
}
if (this.isDeleteForm) {
return __('Delete');
return this.$options.i18n.deleteBoardButtonText;
}
return __('Save changes');
return this.$options.i18n.saveButtonText;
},
buttonKind() {
if (this.isNewForm) {
......@@ -105,15 +117,15 @@ export default {
},
title() {
if (this.isNewForm) {
return __('Create new board');
return this.$options.i18n.createModalTitle;
}
if (this.isDeleteForm) {
return __('Delete board');
return this.$options.i18n.deleteModalTitle;
}
if (this.readonly) {
return __('Board scope');
return this.$options.i18n.scopeModalTitle;
}
return __('Edit board');
return this.$options.i18n.editModalTitle;
},
readonly() {
return !this.canAdminBoard;
......@@ -121,6 +133,17 @@ export default {
submitDisabled() {
return this.isLoading || this.board.name.length === 0;
},
primaryProps() {
return {
text: this.buttonText,
attributes: [{ variant: this.buttonKind, disabled: this.submitDisabled }],
};
},
cancelProps() {
return {
text: this.$options.i18n.cancelButtonText,
};
},
},
mounted() {
this.resetFormState();
......@@ -139,7 +162,7 @@ export default {
visitUrl(boardsStore.rootPath);
})
.catch(() => {
Flash(__('Failed to delete board. Please try again.'));
Flash(this.$options.i18n.deleteErrorMessage);
this.isLoading = false;
});
} else {
......@@ -160,7 +183,7 @@ export default {
visitUrl(data.board_path);
})
.catch(() => {
Flash(__('Unable to save your changes. Please try again.'));
Flash(this.$options.i18n.saveErrorMessage);
this.isLoading = false;
});
}
......@@ -181,53 +204,54 @@ export default {
</script>
<template>
<deprecated-modal
v-show="isVisible"
<gl-modal
modal-id="board-config-modal"
modal-class="board-config-modal"
visible
:hide-footer="readonly"
:title="title"
:primary-button-label="buttonText"
:kind="buttonKind"
:submit-disabled="submitDisabled"
modal-dialog-class="board-config-modal"
:action-primary="primaryProps"
:action-cancel="cancelProps"
@primary="submit"
@cancel="cancel"
@submit="submit"
@close="cancel"
>
<template #body>
<p v-if="isDeleteForm">{{ __('Are you sure you want to delete this board?') }}</p>
<form v-else class="js-board-config-modal" @submit.prevent>
<div v-if="!readonly" class="gl-mb-5">
<label class="label-bold gl-font-lg" for="board-new-name">{{ __('Title') }}</label>
<input
id="board-new-name"
ref="name"
v-model="board.name"
class="form-control"
data-qa-selector="board_name_field"
type="text"
:placeholder="__('Enter board name')"
@keyup.enter="submit"
/>
</div>
<board-configuration-options
:is-new-form="isNewForm"
:board="board"
:current-board="currentBoard"
<p v-if="isDeleteForm">{{ $options.i18n.deleteConfirmationMessage }}</p>
<form v-else class="js-board-config-modal" @submit.prevent>
<div v-if="!readonly" class="gl-mb-5">
<label class="gl-font-weight-bold gl-font-lg" for="board-new-name">
{{ $options.i18n.titleFieldLabel }}
</label>
<input
id="board-new-name"
ref="name"
v-model="board.name"
class="form-control"
data-qa-selector="board_name_field"
type="text"
:placeholder="$options.i18n.titleFieldPlaceholder"
@keyup.enter="submit"
/>
</div>
<board-scope
v-if="scopedIssueBoardFeatureEnabled"
:collapse-scope="isNewForm"
:board="board"
:can-admin-board="canAdminBoard"
:labels-path="labelsPath"
:labels-web-url="labelsWebUrl"
:enable-scoped-labels="enableScopedLabels"
:project-id="projectId"
:group-id="groupId"
:weights="weights"
/>
</form>
</template>
</deprecated-modal>
<board-configuration-options
:is-new-form="isNewForm"
:board="board"
:current-board="currentBoard"
/>
<board-scope
v-if="scopedIssueBoardFeatureEnabled"
:collapse-scope="isNewForm"
:board="board"
:can-admin-board="canAdminBoard"
:labels-path="labelsPath"
:labels-web-url="labelsWebUrl"
:enable-scoped-labels="enableScopedLabels"
:project-id="projectId"
:group-id="groupId"
:weights="weights"
/>
</form>
</gl-modal>
</template>
......@@ -7,6 +7,7 @@ import {
GlDropdownDivider,
GlDropdownSectionHeader,
GlDropdownItem,
GlModalDirective,
} from '@gitlab/ui';
import httpStatusCodes from '~/lib/utils/http_status';
......@@ -31,6 +32,9 @@ export default {
GlDropdownSectionHeader,
GlDropdownItem,
},
directives: {
GlModalDirective,
},
props: {
currentBoard: {
type: Object,
......@@ -313,6 +317,7 @@ export default {
<gl-dropdown-item
v-if="multipleIssueBoardsAvailable"
v-gl-modal-directive="'board-config-modal'"
data-qa-selector="create_new_board_button"
@click.prevent="showPage('new')"
>
......@@ -321,6 +326,7 @@ export default {
<gl-dropdown-item
v-if="showDelete"
v-gl-modal-directive="'board-config-modal'"
class="text-danger js-delete-board"
@click.prevent="showPage('delete')"
>
......
import Vue from 'vue';
import { GlTooltipDirective } from '@gitlab/ui';
import { GlButton, GlModalDirective, GlTooltipDirective } from '@gitlab/ui';
import { s__, __ } from '~/locale';
export default boardsStore => {
......@@ -8,8 +8,12 @@ export default boardsStore => {
if (configEl) {
gl.boardConfigToggle = new Vue({
el: configEl,
components: {
GlButton,
},
directives: {
GlTooltip: GlTooltipDirective,
GlModalDirective,
},
data() {
return {
......@@ -31,17 +35,16 @@ export default boardsStore => {
},
template: `
<div class="gl-ml-3">
<button
<gl-button
v-gl-modal-directive="'board-config-modal'"
v-gl-tooltip
:title="tooltipTitle"
class="btn btn-inverted"
:class="{ 'dot-highlight': hasScope }"
type="button"
data-qa-selector="boards_config_button"
@click.prevent="showPage('edit')"
>
{{ buttonText }}
</button>
</gl-button>
</div>
`,
});
......
......@@ -76,7 +76,7 @@
}
}
.board-config-modal {
.board-config-modal .modal-dialog {
width: 440px;
.block {
......
......@@ -21,7 +21,7 @@ RSpec.describe 'Group Boards', :js do
wait_for_requests
find(:css, '.js-delete-board button').click
find(:css, '.board-config-modal .js-primary-button').click
find(:css, '.board-config-modal .js-modal-action-primary').click
click_boards_dropdown
......
......@@ -297,6 +297,9 @@ RSpec.describe 'Scoped issue boards', :js do
visit project_boards_path(project)
update_board_label(label_title)
wait_for_all_requests
update_board_label(label_2_title)
expect(page).to have_css('.js-visual-token')
......@@ -455,7 +458,7 @@ RSpec.describe 'Scoped issue boards', :js do
it "doesn't show the input when creating a board" do
click_on_create_new_board
page.within '.js-boards-selector' do
page.within '.js-board-config-modal' do
# To make sure the form is shown
expect(page).to have_field('board-new-name')
......@@ -469,14 +472,14 @@ RSpec.describe 'Scoped issue boards', :js do
end
def expect_dot_highlight(button_title)
button = first('.filter-dropdown-container .btn.btn-inverted')
button = first('.filter-dropdown-container .btn.gl-button')
expect(button.text).to include(button_title)
expect(button[:class]).to include('dot-highlight')
expect(button['title']).to include('This board\'s scope is reduced')
end
def expect_no_dot_highlight(button_title)
button = first('.filter-dropdown-container .btn.btn-inverted')
button = first('.filter-dropdown-container .btn.gl-button')
expect(button.text).to include(button_title)
expect(button[:class]).not_to include('dot-highlight')
expect(button['title']).not_to include('This board\'s scope is reduced')
......
import { mount } from '@vue/test-utils';
import { TEST_HOST } from 'jest/helpers/test_constants';
import { GlModal } from '@gitlab/ui';
import boardsStore from '~/boards/stores/boards_store';
import boardForm from '~/boards/components/board_form.vue';
import DeprecatedModal from '~/vue_shared/components/deprecated_modal.vue';
describe('board_form.vue', () => {
let wrapper;
......@@ -14,7 +14,7 @@ describe('board_form.vue', () => {
labelsWebUrl: `${TEST_HOST}/-/labels`,
};
const findModal = () => wrapper.find(DeprecatedModal);
const findModal = () => wrapper.find(GlModal);
beforeEach(() => {
boardsStore.state.currentPage = 'edit';
......
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