Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-08-20 21:42:06 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-08-20 21:42:06 +0300
commit6e4e1050d9dba2b7b2523fdd1768823ab85feef4 (patch)
tree78be5963ec075d80116a932011d695dd33910b4e /app/assets/javascripts/releases/components
parent1ce776de4ae122aba3f349c02c17cebeaa8ecf07 (diff)
Add latest changes from gitlab-org/gitlab@13-3-stable-ee
Diffstat (limited to 'app/assets/javascripts/releases/components')
-rw-r--r--app/assets/javascripts/releases/components/app_edit_new.vue (renamed from app/assets/javascripts/releases/components/app_edit.vue)86
-rw-r--r--app/assets/javascripts/releases/components/app_new.vue9
-rw-r--r--app/assets/javascripts/releases/components/asset_links_form.vue14
-rw-r--r--app/assets/javascripts/releases/components/form_field_container.vue12
-rw-r--r--app/assets/javascripts/releases/components/release_block_assets.vue4
-rw-r--r--app/assets/javascripts/releases/components/release_block_author.vue2
-rw-r--r--app/assets/javascripts/releases/components/release_block_milestone_info.vue2
-rw-r--r--app/assets/javascripts/releases/components/tag_field.vue20
-rw-r--r--app/assets/javascripts/releases/components/tag_field_existing.vue51
-rw-r--r--app/assets/javascripts/releases/components/tag_field_new.vue100
10 files changed, 229 insertions, 71 deletions
diff --git a/app/assets/javascripts/releases/components/app_edit.vue b/app/assets/javascripts/releases/components/app_edit_new.vue
index 01dd0638023..7b7c80a6269 100644
--- a/app/assets/javascripts/releases/components/app_edit.vue
+++ b/app/assets/javascripts/releases/components/app_edit_new.vue
@@ -1,18 +1,17 @@
<script>
import { mapState, mapActions, mapGetters } from 'vuex';
import { GlButton, GlFormInput, GlFormGroup } from '@gitlab/ui';
-import { escape } from 'lodash';
import { __, sprintf } from '~/locale';
import MarkdownField from '~/vue_shared/components/markdown/field.vue';
-import autofocusonshow from '~/vue_shared/directives/autofocusonshow';
import { BACK_URL_PARAM } from '~/releases/constants';
import { getParameterByName } from '~/lib/utils/common_utils';
import AssetLinksForm from './asset_links_form.vue';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import MilestoneCombobox from '~/milestones/project_milestone_combobox.vue';
+import TagField from './tag_field.vue';
export default {
- name: 'ReleaseEditApp',
+ name: 'ReleaseEditNewApp',
components: {
GlFormInput,
GlFormGroup,
@@ -20,9 +19,7 @@ export default {
MarkdownField,
AssetLinksForm,
MilestoneCombobox,
- },
- directives: {
- autofocusonshow,
+ TagField,
},
mixins: [glFeatureFlagsMixin()],
computed: {
@@ -39,9 +36,9 @@ export default {
'manageMilestonesPath',
'projectId',
]),
- ...mapGetters('detail', ['isValid']),
+ ...mapGetters('detail', ['isValid', 'isExistingRelease']),
showForm() {
- return !this.isFetchingRelease && !this.fetchError;
+ return Boolean(!this.isFetchingRelease && !this.fetchError && this.release);
},
subtitleText() {
return sprintf(
@@ -55,23 +52,6 @@ export default {
false,
);
},
- tagName() {
- return this.$store.state.detail.release.tagName;
- },
- tagNameHintText() {
- return sprintf(
- __(
- 'Changing a Release tag is only supported via Releases API. %{linkStart}More information%{linkEnd}',
- ),
- {
- linkStart: `<a href="${escape(
- this.updateReleaseApiDocsPath,
- )}" target="_blank" rel="noopener noreferrer">`,
- linkEnd: '</a>',
- },
- false,
- );
- },
releaseTitle: {
get() {
return this.$store.state.detail.release.name;
@@ -102,7 +82,10 @@ export default {
showAssetLinksForm() {
return this.glFeatures.releaseAssetLinkEditing;
},
- isSaveChangesDisabled() {
+ saveButtonLabel() {
+ return this.isExistingRelease ? __('Save changes') : __('Create release');
+ },
+ isFormSubmissionDisabled() {
return this.isUpdatingRelease || !this.isValid;
},
milestoneComboboxExtraLinks() {
@@ -118,53 +101,45 @@ export default {
];
},
},
- created() {
- this.fetchRelease();
+ mounted() {
+ // eslint-disable-next-line promise/catch-or-return
+ this.initializeRelease().then(() => {
+ // Focus the first non-disabled input element
+ this.$el.querySelector('input:enabled').focus();
+ });
},
methods: {
...mapActions('detail', [
- 'fetchRelease',
- 'updateRelease',
+ 'initializeRelease',
+ 'saveRelease',
'updateReleaseTitle',
'updateReleaseNotes',
'updateReleaseMilestones',
]),
+ submitForm() {
+ if (!this.isFormSubmissionDisabled) {
+ this.saveRelease();
+ }
+ },
},
};
</script>
<template>
<div class="d-flex flex-column">
<p class="pt-3 js-subtitle-text" v-html="subtitleText"></p>
- <form v-if="showForm" @submit.prevent="updateRelease()">
- <gl-form-group>
- <div class="row">
- <div class="col-md-6 col-lg-5 col-xl-4">
- <label for="git-ref">{{ __('Tag name') }}</label>
- <gl-form-input
- id="git-ref"
- v-model="tagName"
- type="text"
- class="form-control"
- aria-describedby="tag-name-help"
- disabled
- />
- </div>
- </div>
- <div id="tag-name-help" class="form-text text-muted" v-html="tagNameHintText"></div>
- </gl-form-group>
+ <form v-if="showForm" class="js-quick-submit" @submit.prevent="submitForm">
+ <tag-field />
<gl-form-group>
<label for="release-title">{{ __('Release title') }}</label>
<gl-form-input
id="release-title"
ref="releaseTitleInput"
v-model="releaseTitle"
- v-autofocusonshow
- autofocus
type="text"
class="form-control"
/>
</gl-form-group>
- <gl-form-group class="w-50">
+ <gl-form-group class="w-50" @keydown.enter.prevent.capture>
<label>{{ __('Milestones') }}</label>
<div class="d-flex flex-column col-md-6 col-sm-10 pl-0">
<milestone-combobox
@@ -182,7 +157,7 @@ export default {
:markdown-preview-path="markdownPreviewPath"
:markdown-docs-path="markdownDocsPath"
:add-spacing-classes="false"
- class="prepend-top-10 append-bottom-10"
+ class="gl-mt-3 gl-mb-3"
>
<template #textarea>
<textarea
@@ -193,8 +168,6 @@ export default {
data-supports-quick-actions="false"
:aria-label="__('Release notes')"
:placeholder="__('Write your release notes or drag your files hereā€¦')"
- @keydown.meta.enter="updateRelease()"
- @keydown.ctrl.enter="updateRelease()"
></textarea>
</template>
</markdown-field>
@@ -209,10 +182,11 @@ export default {
category="primary"
variant="success"
type="submit"
- :aria-label="__('Save changes')"
- :disabled="isSaveChangesDisabled"
- >{{ __('Save changes') }}</gl-button
+ :disabled="isFormSubmissionDisabled"
+ data-testid="submit-button"
>
+ {{ saveButtonLabel }}
+ </gl-button>
<gl-button :href="cancelPath" class="js-cancel-button">{{ __('Cancel') }}</gl-button>
</div>
</form>
diff --git a/app/assets/javascripts/releases/components/app_new.vue b/app/assets/javascripts/releases/components/app_new.vue
deleted file mode 100644
index 563f76b3281..00000000000
--- a/app/assets/javascripts/releases/components/app_new.vue
+++ /dev/null
@@ -1,9 +0,0 @@
-<script>
-export default {
- name: 'ReleaseNewApp',
- components: {},
-};
-</script>
-<template>
- <div></div>
-</template>
diff --git a/app/assets/javascripts/releases/components/asset_links_form.vue b/app/assets/javascripts/releases/components/asset_links_form.vue
index d0d1485d8e7..07fab840067 100644
--- a/app/assets/javascripts/releases/components/asset_links_form.vue
+++ b/app/assets/javascripts/releases/components/asset_links_form.vue
@@ -49,6 +49,12 @@ export default {
this.removeAssetLink(linkId);
this.ensureAtLeastOneLink();
},
+ updateUrl(link, newUrl) {
+ this.updateAssetLinkUrl({ linkIdToUpdate: link.id, newUrl });
+ },
+ updateName(link, newName) {
+ this.updateAssetLinkName({ linkIdToUpdate: link.id, newName });
+ },
hasDuplicateUrl(link) {
return Boolean(this.getLinkErrors(link).isDuplicate);
},
@@ -138,7 +144,9 @@ export default {
type="text"
class="form-control"
:state="isUrlValid(link)"
- @change="updateAssetLinkUrl({ linkIdToUpdate: link.id, newUrl: $event })"
+ @change="updateUrl(link, $event)"
+ @keydown.ctrl.enter="updateUrl(link, $event.target.value)"
+ @keydown.meta.enter="updateUrl(link, $event.target.value)"
/>
<template #invalid-feedback>
<span v-if="hasEmptyUrl(link)" class="invalid-feedback d-inline">
@@ -175,7 +183,9 @@ export default {
type="text"
class="form-control"
:state="isNameValid(link)"
- @change="updateAssetLinkName({ linkIdToUpdate: link.id, newName: $event })"
+ @change="updateName(link, $event)"
+ @keydown.ctrl.enter="updateName(link, $event.target.value)"
+ @keydown.meta.enter="updateName(link, $event.target.value)"
/>
<template #invalid-feedback>
<span v-if="hasEmptyName(link)" class="invalid-feedback d-inline">
diff --git a/app/assets/javascripts/releases/components/form_field_container.vue b/app/assets/javascripts/releases/components/form_field_container.vue
new file mode 100644
index 00000000000..19e275315a0
--- /dev/null
+++ b/app/assets/javascripts/releases/components/form_field_container.vue
@@ -0,0 +1,12 @@
+<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>
diff --git a/app/assets/javascripts/releases/components/release_block_assets.vue b/app/assets/javascripts/releases/components/release_block_assets.vue
index ab29ceb0ce6..9583f5737df 100644
--- a/app/assets/javascripts/releases/components/release_block_assets.vue
+++ b/app/assets/javascripts/releases/components/release_block_assets.vue
@@ -1,10 +1,10 @@
<script>
import { GlTooltipDirective, GlLink, GlButton, GlCollapse, GlIcon, GlBadge } from '@gitlab/ui';
+import { difference, get } from 'lodash';
import Icon from '~/vue_shared/components/icon.vue';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { ASSET_LINK_TYPE } from '../constants';
import { __, s__, sprintf } from '~/locale';
-import { difference, get } from 'lodash';
export default {
name: 'ReleaseBlockAssets',
@@ -138,7 +138,7 @@ export default {
:aria-label="$options.externalLinkTooltipText"
:title="$options.externalLinkTooltipText"
data-testid="external-link-indicator"
- class="gl-ml-2 gl-flex-shrink-0 gl-flex-grow-0 gl-text-gray-600"
+ class="gl-ml-2 gl-flex-shrink-0 gl-flex-grow-0 gl-text-gray-400"
/>
</gl-link>
</li>
diff --git a/app/assets/javascripts/releases/components/release_block_author.vue b/app/assets/javascripts/releases/components/release_block_author.vue
index 94f2b1795f0..72c578068cd 100644
--- a/app/assets/javascripts/releases/components/release_block_author.vue
+++ b/app/assets/javascripts/releases/components/release_block_author.vue
@@ -1,6 +1,6 @@
<script>
-import { __, sprintf } from '~/locale';
import { GlSprintf } from '@gitlab/ui';
+import { __, sprintf } from '~/locale';
import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue';
export default {
diff --git a/app/assets/javascripts/releases/components/release_block_milestone_info.vue b/app/assets/javascripts/releases/components/release_block_milestone_info.vue
index b16ae400d6b..deff673cc17 100644
--- a/app/assets/javascripts/releases/components/release_block_milestone_info.vue
+++ b/app/assets/javascripts/releases/components/release_block_milestone_info.vue
@@ -7,9 +7,9 @@ import {
GlTooltipDirective,
GlSprintf,
} from '@gitlab/ui';
+import { sum } from 'lodash';
import { __, n__, sprintf } from '~/locale';
import { MAX_MILESTONES_TO_DISPLAY } from '../constants';
-import { sum } from 'lodash';
export default {
name: 'ReleaseBlockMilestoneInfo',
diff --git a/app/assets/javascripts/releases/components/tag_field.vue b/app/assets/javascripts/releases/components/tag_field.vue
new file mode 100644
index 00000000000..ed8d6e62926
--- /dev/null
+++ b/app/assets/javascripts/releases/components/tag_field.vue
@@ -0,0 +1,20 @@
+<script>
+import { mapGetters } from 'vuex';
+import TagFieldExisting from './tag_field_existing.vue';
+import TagFieldNew from './tag_field_new.vue';
+
+export default {
+ components: {
+ TagFieldExisting,
+ TagFieldNew,
+ },
+ computed: {
+ ...mapGetters('detail', ['isExistingRelease']),
+ },
+};
+</script>
+
+<template>
+ <tag-field-existing v-if="isExistingRelease" />
+ <tag-field-new v-else />
+</template>
diff --git a/app/assets/javascripts/releases/components/tag_field_existing.vue b/app/assets/javascripts/releases/components/tag_field_existing.vue
new file mode 100644
index 00000000000..b84e713df26
--- /dev/null
+++ b/app/assets/javascripts/releases/components/tag_field_existing.vue
@@ -0,0 +1,51 @@
+<script>
+import { mapState } from 'vuex';
+import { uniqueId } from 'lodash';
+import { GlFormGroup, GlFormInput, GlLink, GlSprintf } from '@gitlab/ui';
+import FormFieldContainer from './form_field_container.vue';
+
+export default {
+ name: 'TagFieldExisting',
+ components: { GlFormGroup, GlFormInput, GlSprintf, GlLink, FormFieldContainer },
+ computed: {
+ ...mapState('detail', ['release', 'updateReleaseApiDocsPath']),
+ inputId() {
+ return uniqueId('tag-name-input-');
+ },
+ helpId() {
+ return uniqueId('tag-name-help-');
+ },
+ },
+};
+</script>
+<template>
+ <gl-form-group :label="__('Tag name')" :label-for="inputId">
+ <form-field-container>
+ <gl-form-input
+ :id="inputId"
+ :value="release.tagName"
+ type="text"
+ class="form-control"
+ :aria-describedby="helpId"
+ disabled
+ />
+ </form-field-container>
+ <template #description>
+ <div :id="helpId" data-testid="tag-name-help">
+ <gl-sprintf
+ :message="
+ __(
+ 'Changing a Release tag is only supported via Releases API. %{linkStart}More information%{linkEnd}',
+ )
+ "
+ >
+ <template #link="{ content }">
+ <gl-link :href="updateReleaseApiDocsPath" target="_blank">
+ {{ content }}
+ </gl-link>
+ </template>
+ </gl-sprintf>
+ </div>
+ </template>
+ </gl-form-group>
+</template>
diff --git a/app/assets/javascripts/releases/components/tag_field_new.vue b/app/assets/javascripts/releases/components/tag_field_new.vue
new file mode 100644
index 00000000000..4779feae886
--- /dev/null
+++ b/app/assets/javascripts/releases/components/tag_field_new.vue
@@ -0,0 +1,100 @@
+<script>
+import { mapState, mapActions, mapGetters } 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 {
+ name: 'TagFieldNew',
+ components: { GlFormGroup, GlFormInput, RefSelector, FormFieldContainer },
+ data() {
+ return {
+ // Keeps track of whether or not the user has interacted with
+ // the input field. This is used to avoid showing validation
+ // errors immediately when the page loads.
+ isInputDirty: false,
+ };
+ },
+ computed: {
+ ...mapState('detail', ['projectId', 'release', 'createFrom']),
+ ...mapGetters('detail', ['validationErrors']),
+ tagName: {
+ get() {
+ return this.release.tagName;
+ },
+ set(tagName) {
+ this.updateReleaseTagName(tagName);
+ },
+ },
+ createFromModel: {
+ get() {
+ return this.createFrom;
+ },
+ set(createFrom) {
+ this.updateCreateFrom(createFrom);
+ },
+ },
+ showTagNameValidationError() {
+ return this.isInputDirty && this.validationErrors.isTagNameEmpty;
+ },
+ tagNameInputId() {
+ return uniqueId('tag-name-input-');
+ },
+ createFromSelectorId() {
+ return uniqueId('create-from-selector-');
+ },
+ },
+ methods: {
+ ...mapActions('detail', ['updateReleaseTagName', 'updateCreateFrom']),
+ markInputAsDirty() {
+ this.isInputDirty = true;
+ },
+ },
+ translations: {
+ noRefSelected: __('No source selected'),
+ searchPlaceholder: __('Search branches, tags, and commits'),
+ dropdownHeader: __('Select source'),
+ },
+};
+</script>
+<template>
+ <div>
+ <gl-form-group
+ :label="__('Tag name')"
+ :label-for="tagNameInputId"
+ data-testid="tag-name-field"
+ :state="!showTagNameValidationError"
+ :invalid-feedback="__('Tag name is required')"
+ >
+ <form-field-container>
+ <gl-form-input
+ :id="tagNameInputId"
+ v-model="tagName"
+ :state="!showTagNameValidationError"
+ type="text"
+ class="form-control"
+ @blur.once="markInputAsDirty"
+ />
+ </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>