diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-10-13 15:08:41 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-10-13 15:08:41 +0300 |
commit | 6e91fbf77476011a7fd86ca3467aad6d7b110ff3 (patch) | |
tree | cace6db4e7ebef8b15a6a7fc8fbe8ff0d89bea90 /app/assets/javascripts/issuable_show | |
parent | 15ae4a8da83661f2b714d804721001a53b354d28 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/issuable_show')
4 files changed, 265 insertions, 0 deletions
diff --git a/app/assets/javascripts/issuable_show/components/issuable_description.vue b/app/assets/javascripts/issuable_show/components/issuable_description.vue new file mode 100644 index 00000000000..091a4be5bd8 --- /dev/null +++ b/app/assets/javascripts/issuable_show/components/issuable_description.vue @@ -0,0 +1,31 @@ +<script> +import $ from 'jquery'; +import { GlSafeHtmlDirective as SafeHtml } from '@gitlab/ui'; +import '~/behaviors/markdown/render_gfm'; + +export default { + directives: { + SafeHtml, + }, + props: { + issuable: { + type: Object, + required: true, + }, + }, + mounted() { + this.renderGFM(); + }, + methods: { + renderGFM() { + $(this.$refs.gfmContainer).renderGFM(); + }, + }, +}; +</script> + +<template> + <div class="description"> + <div ref="gfmContainer" v-safe-html="issuable.descriptionHtml" class="md"></div> + </div> +</template> diff --git a/app/assets/javascripts/issuable_show/components/issuable_edit_form.vue b/app/assets/javascripts/issuable_show/components/issuable_edit_form.vue new file mode 100644 index 00000000000..7b9a83a740f --- /dev/null +++ b/app/assets/javascripts/issuable_show/components/issuable_edit_form.vue @@ -0,0 +1,135 @@ +<script> +import $ from 'jquery'; +import { GlForm, GlFormGroup, GlFormInput } from '@gitlab/ui'; + +import Autosave from '~/autosave'; +import MarkdownField from '~/vue_shared/components/markdown/field.vue'; + +import eventHub from '../event_hub'; + +export default { + components: { + GlForm, + GlFormGroup, + GlFormInput, + MarkdownField, + }, + props: { + issuable: { + type: Object, + required: true, + }, + enableAutocomplete: { + type: Boolean, + required: true, + }, + descriptionPreviewPath: { + type: String, + required: true, + }, + descriptionHelpPath: { + type: String, + required: true, + }, + }, + data() { + const { title, description } = this.issuable; + + return { + title, + description, + }; + }, + created() { + eventHub.$on('update.issuable', this.resetAutosave); + eventHub.$on('close.form', this.resetAutosave); + }, + mounted() { + this.initAutosave(); + }, + beforeDestroy() { + eventHub.$off('update.issuable', this.resetAutosave); + eventHub.$off('close.form', this.resetAutosave); + }, + methods: { + initAutosave() { + const { titleInput, descriptionInput } = this.$refs; + + if (!titleInput || !descriptionInput) return; + + this.autosaveTitle = new Autosave($(titleInput.$el), [ + document.location.pathname, + document.location.search, + 'title', + ]); + + this.autosaveDescription = new Autosave($(descriptionInput.$el), [ + document.location.pathname, + document.location.search, + 'description', + ]); + }, + resetAutosave() { + this.autosaveTitle.reset(); + this.autosaveDescription.reset(); + }, + }, +}; +</script> + +<template> + <gl-form> + <gl-form-group + data-testid="title" + :label="__('Title')" + :label-sr-only="true" + label-for="issuable-title" + class="col-12" + > + <gl-form-input + id="issuable-title" + ref="titleInput" + v-model.trim="title" + :placeholder="__('Title')" + :aria-label="__('Title')" + :autofocus="true" + class="qa-title-input" + /> + </gl-form-group> + <gl-form-group + data-testid="description" + :label="__('Description')" + :label-sr-only="true" + label-for="issuable-description" + class="col-12 common-note-form" + > + <markdown-field + :markdown-preview-path="descriptionPreviewPath" + :markdown-docs-path="descriptionHelpPath" + :enable-autocomplete="enableAutocomplete" + :textarea-value="description" + > + <template #textarea> + <textarea + id="issuable-description" + ref="descriptionInput" + v-model="description" + :data-supports-quick-actions="enableAutocomplete" + :aria-label="__('Description')" + :placeholder="__('Write a comment or drag your files hereā¦')" + class="note-textarea js-gfm-input js-autosize markdown-area + qa-description-textarea" + dir="auto" + ></textarea> + </template> + </markdown-field> + </gl-form-group> + <div data-testid="actions" class="col-12 gl-mt-3 gl-mb-3 clearfix"> + <slot + name="edit-form-actions" + :issuable-title="title" + :issuable-description="description" + ></slot> + </div> + </gl-form> +</template> diff --git a/app/assets/javascripts/issuable_show/components/issuable_title.vue b/app/assets/javascripts/issuable_show/components/issuable_title.vue new file mode 100644 index 00000000000..d3b42fd2ffb --- /dev/null +++ b/app/assets/javascripts/issuable_show/components/issuable_title.vue @@ -0,0 +1,96 @@ +<script> +import { + GlIcon, + GlButton, + GlIntersectionObserver, + GlTooltipDirective, + GlSafeHtmlDirective as SafeHtml, +} from '@gitlab/ui'; + +export default { + components: { + GlIcon, + GlButton, + GlIntersectionObserver, + }, + directives: { + GlTooltip: GlTooltipDirective, + SafeHtml, + }, + props: { + issuable: { + type: Object, + required: true, + }, + statusBadgeClass: { + type: String, + required: true, + }, + statusIcon: { + type: String, + required: true, + }, + enableEdit: { + type: Boolean, + required: true, + }, + }, + data() { + return { + stickyTitleVisible: false, + }; + }, + methods: { + handleTitleAppear() { + this.stickyTitleVisible = false; + }, + handleTitleDisappear() { + this.stickyTitleVisible = true; + }, + }, +}; +</script> + +<template> + <div> + <div class="title-container"> + <h2 v-safe-html="issuable.titleHtml" class="title qa-title" dir="auto"></h2> + <gl-button + v-if="enableEdit" + v-gl-tooltip.bottom + :title="__('Edit title and description')" + icon="pencil" + class="btn-edit js-issuable-edit qa-edit-button" + @click="$emit('edit-issuable', $event)" + /> + </div> + <gl-intersection-observer @appear="handleTitleAppear" @disappear="handleTitleDisappear"> + <transition name="issuable-header-slide"> + <div + v-if="stickyTitleVisible" + class="issue-sticky-header gl-fixed gl-z-index-3 gl-bg-white gl-border-1 gl-border-b-solid gl-border-b-gray-100 gl-py-3" + data-testid="header" + > + <div + class="issue-sticky-header-text gl-display-flex gl-align-items-center gl-mx-auto gl-px-5" + > + <p + data-testid="status" + class="issuable-status-box status-box gl-my-0" + :class="statusBadgeClass" + > + <gl-icon :name="statusIcon" class="gl-display-block d-sm-none gl-h-6!" /> + <span class="gl-display-none d-sm-block"><slot name="status-badge"></slot></span> + </p> + <p + class="gl-font-weight-bold gl-overflow-hidden gl-white-space-nowrap gl-text-overflow-ellipsis gl-my-0" + :title="issuable.title" + > + {{ issuable.title }} + </p> + </div> + </div> + </transition> + </gl-intersection-observer> + </div> +</template> diff --git a/app/assets/javascripts/issuable_show/event_hub.js b/app/assets/javascripts/issuable_show/event_hub.js new file mode 100644 index 00000000000..e31806ad199 --- /dev/null +++ b/app/assets/javascripts/issuable_show/event_hub.js @@ -0,0 +1,3 @@ +import createEventHub from '~/helpers/event_hub_factory'; + +export default createEventHub(); |