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

Replace DeprecatedModal with GlModal for boards

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