Commit e21ce873 authored by David O'Regan's avatar David O'Regan

Merge branch...

Merge branch '229684-migrate-deprecatedmodal-to-glmodal-in-app-assets-javascripts-boards-components-board_form-vue' into 'master'

Replace DeprecatedModal with GlModal for boards

See merge request gitlab-org/gitlab!48647
parents 7f385abb 80d2b143
<script> <script>
import { __ } from '~/locale'; import { GlModal } from '@gitlab/ui';
import { __, s__ } 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';
...@@ -19,10 +19,28 @@ const boardDefaults = { ...@@ -19,10 +19,28 @@ const boardDefaults = {
hide_closed_list: false, hide_closed_list: false,
}; };
const formType = {
new: 'new',
delete: 'delete',
edit: 'edit',
};
export default { export default {
i18n: {
[formType.new]: { title: s__('Board|Create new board'), btnText: s__('Board|Create board') },
[formType.delete]: { title: s__('Board|Delete board'), btnText: __('Delete') },
[formType.edit]: { title: s__('Board|Edit board'), btnText: __('Save changes') },
scopeModalTitle: s__('Board|Board scope'),
cancelButtonText: __('Cancel'),
deleteErrorMessage: s__('Board|Failed to delete board. Please try again.'),
saveErrorMessage: __('Unable to save your changes. Please try again.'),
deleteConfirmationMessage: s__('Board|Are you sure you want to delete this board?'),
titleFieldLabel: __('Title'),
titleFieldPlaceholder: s__('Board|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: {
...@@ -74,25 +92,16 @@ export default { ...@@ -74,25 +92,16 @@ export default {
}, },
computed: { computed: {
isNewForm() { isNewForm() {
return this.currentPage === 'new'; return this.currentPage === formType.new;
}, },
isDeleteForm() { isDeleteForm() {
return this.currentPage === 'delete'; return this.currentPage === formType.delete;
}, },
isEditForm() { isEditForm() {
return this.currentPage === 'edit'; return this.currentPage === formType.edit;
},
isVisible() {
return this.currentPage !== '';
}, },
buttonText() { buttonText() {
if (this.isNewForm) { return this.$options.i18n[this.currentPage].btnText;
return __('Create board');
}
if (this.isDeleteForm) {
return __('Delete');
}
return __('Save changes');
}, },
buttonKind() { buttonKind() {
if (this.isNewForm) { if (this.isNewForm) {
...@@ -104,16 +113,11 @@ export default { ...@@ -104,16 +113,11 @@ export default {
return 'info'; return 'info';
}, },
title() { title() {
if (this.isNewForm) {
return __('Create new board');
}
if (this.isDeleteForm) {
return __('Delete board');
}
if (this.readonly) { if (this.readonly) {
return __('Board scope'); return this.$options.i18n.scopeModalTitle;
} }
return __('Edit board');
return this.$options.i18n[this.currentPage].title;
}, },
readonly() { readonly() {
return !this.canAdminBoard; return !this.canAdminBoard;
...@@ -121,6 +125,24 @@ export default { ...@@ -121,6 +125,24 @@ 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,
loading: this.isLoading,
'data-qa-selector': 'save_changes_button',
},
],
};
},
cancelProps() {
return {
text: this.$options.i18n.cancelButtonText,
};
},
}, },
mounted() { mounted() {
this.resetFormState(); this.resetFormState();
...@@ -136,10 +158,11 @@ export default { ...@@ -136,10 +158,11 @@ export default {
boardsStore boardsStore
.deleteBoard(this.currentBoard) .deleteBoard(this.currentBoard)
.then(() => { .then(() => {
this.isLoading = false;
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 {
...@@ -157,10 +180,11 @@ export default { ...@@ -157,10 +180,11 @@ export default {
return resp.data ? resp.data : resp; return resp.data ? resp.data : resp;
}) })
.then(data => { .then(data => {
this.isLoading = false;
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 +205,56 @@ export default { ...@@ -181,53 +205,56 @@ export default {
</script> </script>
<template> <template>
<deprecated-modal <gl-modal
v-show="isVisible" modal-id="board-config-modal"
modal-class="board-config-modal"
content-class="gl-absolute gl-top-7"
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"
@hide.prevent
> >
<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')"
> >
......
...@@ -91,6 +91,7 @@ ...@@ -91,6 +91,7 @@
body.modal-open { body.modal-open {
overflow: hidden; overflow: hidden;
padding-right: 0 !important;
} }
.modal-no-backdrop { .modal-no-backdrop {
......
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')
...@@ -540,7 +543,7 @@ RSpec.describe 'Scoped issue boards', :js do ...@@ -540,7 +543,7 @@ RSpec.describe 'Scoped issue boards', :js do
click_on_board_modal click_on_board_modal
click_button 'Create' click_button 'Create board'
wait_for_requests wait_for_requests
...@@ -569,7 +572,7 @@ RSpec.describe 'Scoped issue boards', :js do ...@@ -569,7 +572,7 @@ RSpec.describe 'Scoped issue boards', :js do
click_on_board_modal click_on_board_modal
click_button 'Save' click_button 'Save changes'
wait_for_requests wait_for_requests
...@@ -579,6 +582,6 @@ RSpec.describe 'Scoped issue boards', :js do ...@@ -579,6 +582,6 @@ RSpec.describe 'Scoped issue boards', :js do
# Click on modal to make sure the dropdown is closed (e.g. label scenario) # Click on modal to make sure the dropdown is closed (e.g. label scenario)
# #
def click_on_board_modal def click_on_board_modal
find('.board-config-modal').click find('.board-config-modal .modal-content').click
end end
end end
...@@ -3686,9 +3686,6 @@ msgstr "" ...@@ -3686,9 +3686,6 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?" msgid "Are you sure you want to delete this SSH key?"
msgstr "" msgstr ""
msgid "Are you sure you want to delete this board?"
msgstr ""
msgid "Are you sure you want to delete this device? This action cannot be undone." msgid "Are you sure you want to delete this device? This action cannot be undone."
msgstr "" msgstr ""
...@@ -4489,9 +4486,6 @@ msgstr "" ...@@ -4489,9 +4486,6 @@ msgstr ""
msgid "Blog" msgid "Blog"
msgstr "" msgstr ""
msgid "Board scope"
msgstr ""
msgid "Board scope affects which issues are displayed for anyone who visits this board" msgid "Board scope affects which issues are displayed for anyone who visits this board"
msgstr "" msgstr ""
...@@ -4546,6 +4540,30 @@ msgstr "" ...@@ -4546,6 +4540,30 @@ msgstr ""
msgid "Boards|View scope" msgid "Boards|View scope"
msgstr "" msgstr ""
msgid "Board|Are you sure you want to delete this board?"
msgstr ""
msgid "Board|Board scope"
msgstr ""
msgid "Board|Create board"
msgstr ""
msgid "Board|Create new board"
msgstr ""
msgid "Board|Delete board"
msgstr ""
msgid "Board|Edit board"
msgstr ""
msgid "Board|Enter board name"
msgstr ""
msgid "Board|Failed to delete board. Please try again."
msgstr ""
msgid "Board|Load more issues" msgid "Board|Load more issues"
msgstr "" msgstr ""
...@@ -7946,9 +7964,6 @@ msgstr "" ...@@ -7946,9 +7964,6 @@ msgstr ""
msgid "Create and provide your GitHub %{link_start}Personal Access Token%{link_end}. You will need to select the %{code_open}repo%{code_close} scope, so we can display a list of your public and private repositories which are available to import." msgid "Create and provide your GitHub %{link_start}Personal Access Token%{link_end}. You will need to select the %{code_open}repo%{code_close} scope, so we can display a list of your public and private repositories which are available to import."
msgstr "" msgstr ""
msgid "Create board"
msgstr ""
msgid "Create branch" msgid "Create branch"
msgstr "" msgstr ""
...@@ -8006,9 +8021,6 @@ msgstr "" ...@@ -8006,9 +8021,6 @@ msgstr ""
msgid "Create new Value Stream" msgid "Create new Value Stream"
msgstr "" msgstr ""
msgid "Create new board"
msgstr ""
msgid "Create new branch" msgid "Create new branch"
msgstr "" msgstr ""
...@@ -8929,9 +8941,6 @@ msgstr "" ...@@ -8929,9 +8941,6 @@ msgstr ""
msgid "Delete badge" msgid "Delete badge"
msgstr "" msgstr ""
msgid "Delete board"
msgstr ""
msgid "Delete comment" msgid "Delete comment"
msgstr "" msgstr ""
...@@ -10065,9 +10074,6 @@ msgstr "" ...@@ -10065,9 +10074,6 @@ msgstr ""
msgid "Edit application" msgid "Edit application"
msgstr "" msgstr ""
msgid "Edit board"
msgstr ""
msgid "Edit comment" msgid "Edit comment"
msgstr "" msgstr ""
...@@ -10482,9 +10488,6 @@ msgstr "" ...@@ -10482,9 +10488,6 @@ msgstr ""
msgid "Enter at least three characters to search" msgid "Enter at least three characters to search"
msgstr "" msgstr ""
msgid "Enter board name"
msgstr ""
msgid "Enter domain" msgid "Enter domain"
msgstr "" msgstr ""
...@@ -11493,9 +11496,6 @@ msgstr "" ...@@ -11493,9 +11496,6 @@ msgstr ""
msgid "Failed to create wiki" msgid "Failed to create wiki"
msgstr "" msgstr ""
msgid "Failed to delete board. Please try again."
msgstr ""
msgid "Failed to deploy to" msgid "Failed to deploy to"
msgstr "" msgstr ""
......
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