Commit 75bf3251 authored by Nathan Friend's avatar Nathan Friend Committed by Miguel Rincon

Replace tag_field_new with real implementation

This commit updates the tag_field_new component and replaces the
placeholder content with a working real implementation.
parent a475c31f
<script>
export default {
name: 'FormFieldContainer',
};
</script>
<template>
<div class="row">
<div class="col-md-6 col-lg-5 col-xl-4 gl-display-flex gl-flex-direction-column">
<slot></slot>
</div>
</div>
</template>
...@@ -2,10 +2,11 @@ ...@@ -2,10 +2,11 @@
import { mapState } from 'vuex'; import { mapState } from 'vuex';
import { uniqueId } from 'lodash'; import { uniqueId } from 'lodash';
import { GlFormGroup, GlFormInput, GlLink, GlSprintf } from '@gitlab/ui'; import { GlFormGroup, GlFormInput, GlLink, GlSprintf } from '@gitlab/ui';
import FormFieldContainer from './form_field_container.vue';
export default { export default {
name: 'TagFieldExisting', name: 'TagFieldExisting',
components: { GlFormGroup, GlFormInput, GlSprintf, GlLink }, components: { GlFormGroup, GlFormInput, GlSprintf, GlLink, FormFieldContainer },
computed: { computed: {
...mapState('detail', ['release', 'updateReleaseApiDocsPath']), ...mapState('detail', ['release', 'updateReleaseApiDocsPath']),
inputId() { inputId() {
...@@ -19,18 +20,16 @@ export default { ...@@ -19,18 +20,16 @@ export default {
</script> </script>
<template> <template>
<gl-form-group :label="__('Tag name')" :label-for="inputId"> <gl-form-group :label="__('Tag name')" :label-for="inputId">
<div class="row"> <form-field-container>
<div class="col-md-6 col-lg-5 col-xl-4"> <gl-form-input
<gl-form-input :id="inputId"
:id="inputId" :value="release.tagName"
:value="release.tagName" type="text"
type="text" class="form-control"
class="form-control" :aria-describedby="helpId"
:aria-describedby="helpId" disabled
disabled />
/> </form-field-container>
</div>
</div>
<template #description> <template #description>
<div :id="helpId" data-testid="tag-name-help"> <div :id="helpId" data-testid="tag-name-help">
<gl-sprintf <gl-sprintf
......
<script> <script>
import { mapState, mapActions } from 'vuex';
import { GlFormGroup, GlFormInput } from '@gitlab/ui';
import { uniqueId } from 'lodash';
import { __ } from '~/locale';
import RefSelector from '~/ref/components/ref_selector.vue';
import FormFieldContainer from './form_field_container.vue';
export default { export default {
name: 'TagFieldNew', name: 'TagFieldNew',
components: { GlFormGroup, GlFormInput, RefSelector, FormFieldContainer },
computed: {
...mapState('detail', ['projectId', 'release', 'createFrom']),
tagName: {
get() {
return this.release.tagName;
},
set(tagName) {
this.updateReleaseTagName(tagName);
},
},
createFromModel: {
get() {
return this.createFrom;
},
set(createFrom) {
this.updateCreateFrom(createFrom);
},
},
tagNameInputId() {
return uniqueId('tag-name-input-');
},
createFromSelectorId() {
return uniqueId('create-from-selector-');
},
},
methods: {
...mapActions('detail', ['updateReleaseTagName', 'updateCreateFrom']),
},
translations: {
noRefSelected: __('No source selected'),
searchPlaceholder: __('Search branches, tags, and commits'),
dropdownHeader: __('Select source'),
},
}; };
</script> </script>
<template> <template>
<div></div> <div>
<gl-form-group :label="__('Tag name')" :label-for="tagNameInputId" data-testid="tag-name-field">
<form-field-container>
<gl-form-input :id="tagNameInputId" v-model="tagName" type="text" class="form-control" />
</form-field-container>
</gl-form-group>
<gl-form-group
:label="__('Create from')"
:label-for="createFromSelectorId"
data-testid="create-from-field"
>
<form-field-container>
<ref-selector
:id="createFromSelectorId"
v-model="createFromModel"
:project-id="projectId"
:translations="$options.translations"
/>
</form-field-container>
<template #description>
{{ __('Existing branch name, tag, or commit SHA') }}
</template>
</gl-form-group>
</div>
</template> </template>
...@@ -34,6 +34,10 @@ export const fetchRelease = ({ dispatch, state }) => { ...@@ -34,6 +34,10 @@ export const fetchRelease = ({ dispatch, state }) => {
}); });
}; };
export const updateReleaseTagName = ({ commit }, tagName) =>
commit(types.UPDATE_RELEASE_TAG_NAME, tagName);
export const updateCreateFrom = ({ commit }, createFrom) =>
commit(types.UPDATE_CREATE_FROM, createFrom);
export const updateReleaseTitle = ({ commit }, title) => commit(types.UPDATE_RELEASE_TITLE, title); export const updateReleaseTitle = ({ commit }, title) => commit(types.UPDATE_RELEASE_TITLE, title);
export const updateReleaseNotes = ({ commit }, notes) => commit(types.UPDATE_RELEASE_NOTES, notes); export const updateReleaseNotes = ({ commit }, notes) => commit(types.UPDATE_RELEASE_NOTES, notes);
export const updateReleaseMilestones = ({ commit }, milestones) => export const updateReleaseMilestones = ({ commit }, milestones) =>
......
...@@ -2,6 +2,8 @@ export const REQUEST_RELEASE = 'REQUEST_RELEASE'; ...@@ -2,6 +2,8 @@ export const REQUEST_RELEASE = 'REQUEST_RELEASE';
export const RECEIVE_RELEASE_SUCCESS = 'RECEIVE_RELEASE_SUCCESS'; export const RECEIVE_RELEASE_SUCCESS = 'RECEIVE_RELEASE_SUCCESS';
export const RECEIVE_RELEASE_ERROR = 'RECEIVE_RELEASE_ERROR'; export const RECEIVE_RELEASE_ERROR = 'RECEIVE_RELEASE_ERROR';
export const UPDATE_RELEASE_TAG_NAME = 'UPDATE_RELEASE_TAG_NAME';
export const UPDATE_CREATE_FROM = 'UPDATE_CREATE_FROM';
export const UPDATE_RELEASE_TITLE = 'UPDATE_RELEASE_TITLE'; export const UPDATE_RELEASE_TITLE = 'UPDATE_RELEASE_TITLE';
export const UPDATE_RELEASE_NOTES = 'UPDATE_RELEASE_NOTES'; export const UPDATE_RELEASE_NOTES = 'UPDATE_RELEASE_NOTES';
export const UPDATE_RELEASE_MILESTONES = 'UPDATE_RELEASE_MILESTONES'; export const UPDATE_RELEASE_MILESTONES = 'UPDATE_RELEASE_MILESTONES';
......
...@@ -22,6 +22,12 @@ export default { ...@@ -22,6 +22,12 @@ export default {
state.release = undefined; state.release = undefined;
}, },
[types.UPDATE_RELEASE_TAG_NAME](state, tagName) {
state.release.tagName = tagName;
},
[types.UPDATE_CREATE_FROM](state, createFrom) {
state.createFrom = createFrom;
},
[types.UPDATE_RELEASE_TITLE](state, title) { [types.UPDATE_RELEASE_TITLE](state, title) {
state.release.name = title; state.release.name = title;
}, },
......
...@@ -27,6 +27,7 @@ export default ({ ...@@ -27,6 +27,7 @@ export default ({
releasesPagePath, releasesPagePath,
defaultBranch, defaultBranch,
createFrom: defaultBranch,
/** The Release object */ /** The Release object */
release: null, release: null,
......
...@@ -7030,6 +7030,9 @@ msgstr "" ...@@ -7030,6 +7030,9 @@ msgstr ""
msgid "Create file" msgid "Create file"
msgstr "" msgstr ""
msgid "Create from"
msgstr ""
msgid "Create group" msgid "Create group"
msgstr "" msgstr ""
...@@ -9873,6 +9876,9 @@ msgstr "" ...@@ -9873,6 +9876,9 @@ msgstr ""
msgid "Excluding merge commits. Limited to 6,000 commits." msgid "Excluding merge commits. Limited to 6,000 commits."
msgstr "" msgstr ""
msgid "Existing branch name, tag, or commit SHA"
msgstr ""
msgid "Existing members and groups" msgid "Existing members and groups"
msgstr "" msgstr ""
...@@ -16302,6 +16308,9 @@ msgstr "" ...@@ -16302,6 +16308,9 @@ msgstr ""
msgid "No schedules" msgid "No schedules"
msgstr "" msgstr ""
msgid "No source selected"
msgstr ""
msgid "No stack trace for this error" msgid "No stack trace for this error"
msgstr "" msgstr ""
...@@ -21062,6 +21071,9 @@ msgstr "" ...@@ -21062,6 +21071,9 @@ msgstr ""
msgid "Search branches and tags" msgid "Search branches and tags"
msgstr "" msgstr ""
msgid "Search branches, tags, and commits"
msgstr ""
msgid "Search by Git revision" msgid "Search by Git revision"
msgstr "" msgstr ""
...@@ -21682,6 +21694,9 @@ msgstr "" ...@@ -21682,6 +21694,9 @@ msgstr ""
msgid "Select shards to replicate" msgid "Select shards to replicate"
msgstr "" msgstr ""
msgid "Select source"
msgstr ""
msgid "Select source branch" msgid "Select source branch"
msgstr "" msgstr ""
......
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { GlFormInput } from '@gitlab/ui';
import TagFieldNew from '~/releases/components/tag_field_new.vue'; import TagFieldNew from '~/releases/components/tag_field_new.vue';
import createStore from '~/releases/stores'; import createStore from '~/releases/stores';
import createDetailModule from '~/releases/stores/modules/detail'; import createDetailModule from '~/releases/stores/modules/detail';
import RefSelector from '~/ref/components/ref_selector.vue';
const TEST_TAG_NAME = 'test-tag-name';
const TEST_PROJECT_ID = '1234';
const TEST_CREATE_FROM = 'test-create-from';
describe('releases/components/tag_field_new', () => { describe('releases/components/tag_field_new', () => {
let store; let store;
...@@ -16,9 +22,17 @@ describe('releases/components/tag_field_new', () => { ...@@ -16,9 +22,17 @@ describe('releases/components/tag_field_new', () => {
beforeEach(() => { beforeEach(() => {
store = createStore({ store = createStore({
modules: { modules: {
detail: createDetailModule({}), detail: createDetailModule({
projectId: TEST_PROJECT_ID,
}),
}, },
}); });
store.state.detail.createFrom = TEST_CREATE_FROM;
store.state.detail.release = {
tagName: TEST_TAG_NAME,
};
}); });
afterEach(() => { afterEach(() => {
...@@ -26,9 +40,47 @@ describe('releases/components/tag_field_new', () => { ...@@ -26,9 +40,47 @@ describe('releases/components/tag_field_new', () => {
wrapper = null; wrapper = null;
}); });
it('renders a placeholder component', () => { const findTagNameFormGroup = () => wrapper.find('[data-testid="tag-name-field"]');
createComponent(); const findTagNameGlInput = () => findTagNameFormGroup().find(GlFormInput);
const findCreateFromFormGroup = () => wrapper.find('[data-testid="create-from-field"]');
const findCreateFromDropdown = () => findCreateFromFormGroup().find(RefSelector);
describe('"Tag name" field', () => {
beforeEach(createComponent);
it('renders a label', () => {
expect(findTagNameFormGroup().attributes().label).toBe('Tag name');
});
describe('when the user updates the field', () => {
it("updates the store's release.tagName property", () => {
const updatedTagName = 'updated-tag-name';
findTagNameGlInput().vm.$emit('input', updatedTagName);
return wrapper.vm.$nextTick().then(() => {
expect(store.state.detail.release.tagName).toBe(updatedTagName);
});
});
});
});
describe('"Create from" field', () => {
beforeEach(createComponent);
expect(wrapper.exists()).toBe(true); it('renders a label', () => {
expect(findCreateFromFormGroup().attributes().label).toBe('Create from');
});
describe('when the user selects a git ref', () => {
it("updates the store's createFrom property", () => {
const updatedCreateFrom = 'update-create-from';
findCreateFromDropdown().vm.$emit('input', updatedCreateFrom);
return wrapper.vm.$nextTick().then(() => {
expect(store.state.detail.createFrom).toBe(updatedCreateFrom);
});
});
});
}); });
}); });
...@@ -113,6 +113,24 @@ describe('Release detail actions', () => { ...@@ -113,6 +113,24 @@ describe('Release detail actions', () => {
}); });
}); });
describe('updateReleaseTagName', () => {
it(`commits ${types.UPDATE_RELEASE_TAG_NAME} with the updated tag name`, () => {
const newTag = 'updated-tag-name';
return testAction(actions.updateReleaseTagName, newTag, state, [
{ type: types.UPDATE_RELEASE_TAG_NAME, payload: newTag },
]);
});
});
describe('updateCreateFrom', () => {
it(`commits ${types.UPDATE_CREATE_FROM} with the updated ref`, () => {
const newRef = 'my-feature-branch';
return testAction(actions.updateCreateFrom, newRef, state, [
{ type: types.UPDATE_CREATE_FROM, payload: newRef },
]);
});
});
describe('updateReleaseTitle', () => { describe('updateReleaseTitle', () => {
it(`commits ${types.UPDATE_RELEASE_TITLE} with the updated release title`, () => { it(`commits ${types.UPDATE_RELEASE_TITLE} with the updated release title`, () => {
const newTitle = 'The new release title'; const newTitle = 'The new release title';
......
...@@ -56,6 +56,26 @@ describe('Release detail mutations', () => { ...@@ -56,6 +56,26 @@ describe('Release detail mutations', () => {
}); });
}); });
describe(`${types.UPDATE_RELEASE_TAG_NAME}`, () => {
it("updates the release's tag name", () => {
state.release = release;
const newTag = 'updated-tag-name';
mutations[types.UPDATE_RELEASE_TAG_NAME](state, newTag);
expect(state.release.tagName).toBe(newTag);
});
});
describe(`${types.UPDATE_CREATE_FROM}`, () => {
it('updates the ref that the ref will be created from', () => {
state.createFrom = 'main';
const newRef = 'my-feature-branch';
mutations[types.UPDATE_CREATE_FROM](state, newRef);
expect(state.createFrom).toBe(newRef);
});
});
describe(`${types.UPDATE_RELEASE_TITLE}`, () => { describe(`${types.UPDATE_RELEASE_TITLE}`, () => {
it("updates the release's title", () => { it("updates the release's title", () => {
state.release = release; state.release = release;
......
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