<template>
<div>
<button
data-intro="Proposez une nouvelle version" data-position="left"
v-if="annotation && isAuthenticated"
@click="onCancelClick"
class="btn btn-xs pull-right"
v-bind:class="{ 'btn-primary': readonly, 'btn-warning': !readonly }">
<i class="fa fa-edit" v-if="readonly"></i>
<span v-if="readonly">Modifier</span>
<i class="fa fa-ban" v-if="!readonly"></i>
<span v-if="!readonly">Annuler</span>
</button>
<div v-if="!annotation" class="alert alert-warning text-center">
Aucune annotation sélectionnée
</div>
<form v-bind:action="formAction" method="post">
<slot>
<!-- CSRF token -->
</slot>
<input type="hidden" name="fragment" v-model="fragment">
<div v-if="annotation" class="form-group form-group-sm">
<label v-if="!readonly || title" class="small text-muted">Titre</label>
<input type="text" class="form-control" name="title" v-model="title" v-if="!readonly" ref="title">
<p v-if="readonly && title" v-bind:class="{ 'text-muted': !title }">{{ title || 'Pas de titre' }}</p>
</div>
<div v-if="annotation" class="form-group form-group-sm">
<label v-if="!readonly || description" class="small text-muted">Description</label>
<textarea class="form-control" name="description" v-model="description" v-if="!readonly" placeholder="Décrivez ce que vous voyez"></textarea>
<p v-if="readonly && description" v-bind:class="{ 'text-muted': !description }" v-html="descriptionComputed">{{ descriptionComputed || 'Pas de description' }}</p>
</div>
<div v-if="annotation" class="form-group form-group-sm">
<label class="small text-muted">Mots-clés</label>
<tag-list ref="taglist"
v-bind:original-tags="annotation.tags"
v-bind:readonly="readonly"
@change="onTagsChange($event.tags)"></tag-list>
<input type="hidden" name="tags" v-model="serializedTags">
</div>
<p class="small text-center text-muted" v-if="annotation && annotation.annotation_guid">
<a v-bind:href="revisionsUrlComputed">Dernière version</a>
<span>{{ dateComputed }} par</span>
<a v-bind:href="authorUrlComputed">{{ annotation.author }}</a>
</p>
<button type="submit" v-if="annotation && !readonly" v-bind:class="{ disabled: !hasChanged }"
class="btn btn-block btn-sm btn-primary">{{ submitButtonText }}</button>
</form>
</div>
</template>
<script>
import TagList from "../tagform/TagList.vue";
import _ from "lodash";
import showdown from "showdown";
import moment from "moment";
const converter = new showdown.Converter();
var defaults = {
title: "",
description: "",
fragment: "",
tags: [],
readonly: true
};
export default {
props: {
annotation: {
type: Object,
default: function() {
return null;
}
},
isAuthenticated: {
type: Boolean,
default: false
},
revisionsUrl: String,
authorUrl: String,
newAnnotationUrl: String,
editAnnotationUrl: String
},
components: {
"tag-list": TagList
},
data() {
return defaults;
},
mounted() {
if (this.annotation) {
this.loadAnnotation(this.annotation);
}
},
watch: {
annotation: function(annotation) {
if (annotation) {
this.loadAnnotation(annotation);
} else {
this.reset();
}
}
},
computed: {
descriptionComputed: function() {
return converter.makeHtml(this.description);
},
lastRevisionText: function() {
if (this.annotation) {
var date = moment(this.annotation.created).locale("fr");
return (
"Dernière version " +
date.fromNow() +
" par " +
this.annotation.author
);
}
},
revisionsUrlComputed: function() {
if (this.annotation) {
return this.revisionsUrl.replace(
":annotation_guid",
this.annotation.annotation_guid
);
}
},
authorUrlComputed: function() {
if (this.annotation) {
return this.authorUrl.replace("--username--", this.annotation.author);
}
},
dateComputed: function() {
if (this.annotation) {
return moment(this.annotation.created)
.locale("fr")
.fromNow();
}
},
formAction: function() {
if (this.annotation) {
if (this.annotation.annotation_guid) {
return this.editAnnotationUrl.replace(
":annotation_guid",
this.annotation.annotation_guid
);
}
return this.newAnnotationUrl;
}
},
submitButtonText: function() {
return this.isNewAnnotation
? "Enregistrer"
: "Enregister une nouvelle version";
},
isNewAnnotation: function() {
return this.annotation && !this.annotation.annotation_guid;
},
serializedTags: function() {
var tags = this.tags.map(function(tag) {
return {
tag_input:
typeof tag.tag_link === "string" && tag.tag_link.length
? tag.tag_link
: tag.tag_label,
tag_label: tag.tag_label,
accuracy: tag.accuracy,
relevancy: tag.relevancy
};
});
return JSON.stringify(tags);
},
hasChanged: function() {
if (!this.annotation) {
return false;
}
return (
this.title !== this.annotation.title ||
this.description !== this.annotation.description ||
!_.isEqual(this.annotation.tags, this.tags)
);
}
},
methods: {
onCancelClick: function() {
if (this.isNewAnnotation) {
this.$emit("close");
} else {
this.readonly = !this.readonly;
}
},
onTagsChange: function(tags) {
this.tags = tags;
},
reset: function() {
Object.assign(this, defaults);
},
loadAnnotation(annotation) {
// Make sure we have an actual copy
Object.assign(this, {
title: annotation.title,
description: annotation.description,
fragment: annotation.fragment,
tags: annotation.tags.slice(),
readonly: !this.isNewAnnotation
});
if (!annotation.annotation_guid) {
setTimeout(() => {
$(this.$refs.title).focus();
}, 500);
}
}
}
};
</script>
<style scoped>
form {
margin-bottom: 20px;
clear: both;
}
label {
font-weight: normal;
}
</style>