Introduce readonly prop in AnnotationForm & child components.
--- a/src_js/iconolab-bundle/src/components/editor/AnnotationForm.vue Wed Feb 22 12:10:03 2017 +0100
+++ b/src_js/iconolab-bundle/src/components/editor/AnnotationForm.vue Wed Feb 22 13:16:21 2017 +0100
@@ -1,28 +1,43 @@
<template>
- <form v-bind:action="formAction" method="post">
- <slot>
- <!-- CSRF token -->
- </slot>
- <input type="hidden" name="fragment" v-model="fragment">
+ <div>
+ <button v-if="annotation" @click="readonly = !readonly"
+ 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">
Aucune annotation sélectionnée.
</div>
- <div v-if="annotation" class="form-group form-group-sm">
- <label class="control-label">Titre</label>
- <input type="text" class="form-control" name="title" v-model="title">
- </div>
- <div v-if="annotation" class="form-group form-group-sm">
- <label class="control-label">Description</label>
- <textarea class="form-control" name="description" v-model="description"></textarea>
- </div>
- <div v-if="annotation" class="form-group form-group-sm">
- <label class="control-label">Mots-clé</label>
- <tag-list ref="taglist" v-bind:original-tags="annotation.tags" @change="onTagsChange($event.tags)"></tag-list>
- <input type="hidden" name="tags" v-model="serializedTags">
- </div>
- <button type="submit" v-if="annotation" v-bind:class="{ disabled: !hasChanged }"
- class="btn btn-block btn-sm btn-primary">Sauvegarder</button>
- </form>
+ <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 class="control-label">Titre</label>
+ <input type="text" class="form-control" name="title" v-model="title" v-if="!readonly">
+ <p v-if="readonly" class="small" v-bind:class="{ 'text-muted': !title }">{{ title || 'Pas de titre' }}</p>
+ </div>
+ <div v-if="annotation" class="form-group form-group-sm">
+ <label class="control-label">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" class="small" v-bind:class="{ 'text-muted': !description }">{{ description || 'Pas de description' }}</p>
+ </div>
+ <div v-if="annotation" class="form-group form-group-sm">
+ <label class="control-label">Mots-clé</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>
+ <button type="submit" v-if="annotation && !readonly" v-bind:class="{ disabled: !hasChanged }"
+ class="btn btn-block btn-sm btn-primary">Enregistrer une nouvelle version</button>
+ </form>
+ </div>
</template>
<script>
@@ -31,14 +46,23 @@
import _ from 'lodash'
var defaults = {
- 'title': '',
- 'description': '',
- 'fragment': '',
- 'tags': [],
+ title: '',
+ description: '',
+ fragment: '',
+ tags: [],
+ readonly: true,
}
export default {
- props: ['action', 'annotation'],
+ props: {
+ action: String,
+ annotation: {
+ type: Object,
+ default: function () {
+ return null;
+ }
+ },
+ },
components: {
'tag-list': TagList
},
@@ -50,10 +74,11 @@
if (annotation) {
// Make sure we have an actual copy
Object.assign(this, {
- 'title': annotation.title,
- 'description': annotation.description,
- 'fragment': annotation.fragment,
- 'tags': annotation.tags.slice()
+ title: annotation.title,
+ description: annotation.description,
+ fragment: annotation.fragment,
+ tags: annotation.tags.slice(),
+ readonly: true,
});
} else {
this.reset();
@@ -101,5 +126,6 @@
<style scoped>
form {
margin-bottom: 20px;
+ clear: both;
}
</style>
--- a/src_js/iconolab-bundle/src/components/tagform/TagList.vue Wed Feb 22 12:10:03 2017 +0100
+++ b/src_js/iconolab-bundle/src/components/tagform/TagList.vue Wed Feb 22 13:16:21 2017 +0100
@@ -2,14 +2,16 @@
<div>
<div class="tag-list">
<tag-list-item ref="items"
+ class="tag-list-item"
v-for="(tag, index) in tags"
v-if="tags.length > 0"
v-bind:label="tag.tag_label"
v-bind:index="index"
v-bind:accuracy="tag.accuracy"
- v-bind:relevancy="tag.relevancy"></tag-list-item>
+ v-bind:relevancy="tag.relevancy"
+ v-bind:readonly="readonly"></tag-list-item>
</div>
- <typeahead ref="typeahead" placeholder="Rechercher"></typeahead>
+ <typeahead ref="typeahead" placeholder="Rechercher" v-show="!readonly"></typeahead>
</div>
</template>
@@ -27,6 +29,12 @@
return [];
}
},
+ readonly: {
+ type: Boolean,
+ default: function () {
+ return false;
+ }
+ },
},
data() {
return {
@@ -76,4 +84,14 @@
margin-bottom: 15px;
}
+.tag-list-item:first-of-type {
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+}
+
+.tag-list-item:last-of-type {
+ border-bottom-left-radius: 4px;
+ border-bottom-right-radius: 4px;
+}
+
</style>
--- a/src_js/iconolab-bundle/src/components/tagform/TagListItem.vue Wed Feb 22 12:10:03 2017 +0100
+++ b/src_js/iconolab-bundle/src/components/tagform/TagListItem.vue Wed Feb 22 13:16:21 2017 +0100
@@ -4,14 +4,13 @@
<span class="tag-title">{{ label }}</span>
<div class="tag-item-buttons">
<div class="tag-item-btn tag-item-accuracy" v-bind:data-value="accuracy">
- <button class="btn btn-default">{{ accuracy || '?' }}</button>
+ <button class="btn btn-default" v-bind:title="accuracyTitle">{{ accuracy || '?' }}</button>
</div>
<div class="tag-item-btn tag-item-relevancy" v-bind:data-value="relevancy">
- <button class="btn btn-default">{{ relevancy || '?' }}</button>
+ <button class="btn btn-default" v-bind:title="relevancyTitle">{{ relevancy || '?' }}</button>
</div>
- <div class="tag-item-btn tag-item-delete">
- <button class="btn btn-default"
- @click="remove"><i class="fa fa-times" aria-hidden="true"></i></button>
+ <div v-show="!readonly" class="tag-item-btn tag-item-delete">
+ <button class="btn btn-default" @click="remove"><i class="fa fa-times" aria-hidden="true"></i></button>
</div>
</div>
</div>
@@ -46,7 +45,8 @@
'index',
'label',
'accuracy',
- 'relevancy'
+ 'relevancy',
+ 'readonly'
],
components: {
"typeahead": Typeahead,
@@ -57,6 +57,14 @@
isNew: true,
}
},
+ computed: {
+ accuracyTitle: function() {
+ return 'Fiabilité : ' + this.accuracy;
+ },
+ relevancyTitle: function() {
+ return 'Pertinence : ' + this.relevancy;
+ }
+ },
watch: {
accuracy: function(accuracy) {
if (this.isNew && this.isComplete()) {
@@ -105,12 +113,16 @@
},
toggle: function(e) {
e.preventDefault();
+ if (this.readonly) { return; }
+
this.$parent.hideAll();
$(this.$el).find('.collapse').collapse('toggle');
},
remove: function(e) {
e.preventDefault();
e.stopPropagation();
+ if (this.readonly) { return; }
+
this.$parent.removeItemAt(this.index);
},
}
@@ -151,7 +163,8 @@
}
.tag-title {
- padding: 5px;
+ padding: 5px 5px 5px 10px;
+ font-size: 12px;
max-width: 140px;
overflow: hidden;
text-overflow: ellipsis;
--- a/src_js/iconolab-bundle/src/components/tagform/Typeahead.vue Wed Feb 22 12:10:03 2017 +0100
+++ b/src_js/iconolab-bundle/src/components/tagform/Typeahead.vue Wed Feb 22 13:16:21 2017 +0100
@@ -2,6 +2,7 @@
<div>
<input type="text"
class="form-control input-sm"
+ v-bind:disabled="readonly"
v-bind:placeholder="placeholder"
autocomplete="off"
v-model="query"
@@ -45,9 +46,12 @@
export default {
mixins: [typeahead],
- props: ['placeholder'],
-
- mounted() {
+ props: {
+ placeholder: String,
+ readonly: {
+ type: Boolean,
+ default: false
+ }
},
data() {