Commit 76cdb8ee authored by Regis's avatar Regis

render description - tasks work - gfm is juicy

parent d3a788da
import Vue from 'vue';
import IssueTitle from './issue_title.vue';
import IssueTitle from './issue_title_description.vue';
import '../vue_shared/vue_resource_interceptor';
(() => {
const issueTitleData = document.querySelector('.issue-title-data').dataset;
const { initialTitle, endpoint } = issueTitleData;
const { candescription, endpoint } = issueTitleData;
const vm = new Vue({
el: '.issue-title-entrypoint',
render: createElement => createElement(IssueTitle, {
props: {
initialTitle,
candescription,
endpoint,
},
}),
......
......@@ -5,8 +5,8 @@ import Service from './services/index';
export default {
props: {
initialTitle: { required: true, type: String },
endpoint: { required: true, type: String },
candescription: { required: true, type: String },
},
data() {
const resource = new Service(this.$http, this.endpoint);
......@@ -30,7 +30,8 @@ export default {
return {
poll,
timeoutId: null,
title: this.initialTitle,
title: null,
description: null,
};
},
methods: {
......@@ -39,26 +40,50 @@ export default {
this.triggerAnimation(body);
},
triggerAnimation(body) {
const { title } = body;
const { title, description } = body;
this.descriptionText = body.description_text;
/**
* since opacity is changed, even if there is no diff for Vue to update
* we must check the title even on a 304 to ensure no visual change
*/
if (this.title === title) return;
const noTitleChange = this.title === title;
const noDescriptionChange = this.description === description;
if (noTitleChange && noDescriptionChange) return;
const elementsToVisualize = [];
this.$el.style.opacity = 0;
if (!noTitleChange) {
elementsToVisualize.push(this.$el.querySelector('.title'));
} else if (!noDescriptionChange) {
elementsToVisualize.push(this.$el.querySelector('.wiki'));
}
elementsToVisualize.forEach((element) => {
element.classList.remove('issue-realtime-trigger-pulse');
element.classList.add('issue-realtime-pre-pulse');
});
this.timeoutId = setTimeout(() => {
this.title = title;
this.description = description;
this.$el.style.transition = 'opacity 0.2s ease';
this.$el.style.opacity = 1;
elementsToVisualize.forEach((element) => {
element.classList.remove('issue-realtime-pre-pulse');
element.classList.add('issue-realtime-trigger-pulse');
});
clearTimeout(this.timeoutId);
}, 100);
},
},
computed: {
descriptionClass() {
return `description ${this.candescription} is-task-list-enabled`;
},
},
created() {
if (!Visibility.hidden()) {
this.poll.makeRequest();
......@@ -72,9 +97,32 @@ export default {
}
});
},
updated() {
new gl.TaskList({
dataType: 'issue',
fieldName: 'description',
selector: '.detail-page-description',
}).init();
$(this.$refs['issue-content-container-gfm-entry']).renderGFM();
},
};
</script>
<template>
<h2 class="title" v-html="title"></h2>
<div>
<h2 class="title issue-realtime-trigger-pulse" v-html="title"></h2>
<div
:class="descriptionClass"
v-if="description"
>
<div
class="wiki issue-realtime-trigger-pulse"
v-html="description"
ref="issue-content-container-gfm-entry"
>
</div>
<textarea class="hidden js-task-list-field" v-if="descriptionText">{{descriptionText}}</textarea>
</div>
</div>
</template>
......@@ -18,6 +18,15 @@
}
}
.issue-realtime-pre-pulse {
opacity: 0;
}
.issue-realtime-trigger-pulse {
transition: opacity 0.2s ease;
opacity: 1;
}
.check-all-holder {
line-height: 36px;
float: left;
......
......@@ -198,7 +198,11 @@ class Projects::IssuesController < Projects::ApplicationController
def rendered_title
Gitlab::PollingInterval.set_header(response, interval: 3_000)
render json: { title: view_context.markdown_field(@issue, :title) }
render json: {
title: view_context.markdown_field(@issue, :title),
description: view_context.markdown_field(@issue, :description),
description_text: @issue.description,
}
end
protected
......
......@@ -51,17 +51,11 @@
.issue-details.issuable-details
.detail-page-description.content-block{ class: ('hide-bottom-border' unless @issue.description.present? ) }
.issue-title-data.hidden{ "data" => { "initial-title" => markdown_field(@issue, :title),
"endpoint" => rendered_title_namespace_project_issue_path(@project.namespace, @project, @issue),
.issue-title-data.hidden{ "data" => { "endpoint" => rendered_title_namespace_project_issue_path(@project.namespace, @project, @issue),
"canDescription" => can?(current_user, :update_issue, @issue) ? 'js-task-list-container' : '',
} }
.issue-title-entrypoint
- if @issue.description.present?
.description{ class: can?(current_user, :update_issue, @issue) ? 'js-task-list-container' : '' }
.wiki
= preserve do
= markdown_field(@issue, :description)
%textarea.hidden.js-task-list-field
= @issue.description
= edited_time_ago_with_tooltip(@issue, placement: 'bottom', html_class: 'issue_edited_ago')
#merge-requests{ data: { url: referenced_merge_requests_namespace_project_issue_url(@project.namespace, @project, @issue) } }
......
import Vue from 'vue';
import issueTitle from '~/issue_show/issue_title.vue';
import issueTitle from '~/issue_show/issue_title_description.vue';
describe('Issue Title', () => {
let IssueTitleComponent;
......
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