<template> <div class="zotero-vue-client"> <h2>Zotero Client <a role="button" v-if="isConfigEditable" @click="isConfigVisible=!isConfigVisible" title="Afficher/masquer la configuration">⚙</a> </h2> <div class="zotero-config-pane" v-if="isConfigVisible"> <div> <label>Type de collection</label> <select v-model="type"> <option value="group">Group</option> <option value="user">User</option> </select> </div> <div> <label>Identifiant de "{{type}}"</label> <input v-model="groupOrUserId"/> </div> <div> <label>Résultats par page</label> <input type="number" v-model="pageLength"/> </div> </div> <div> <input v-model="textQuery"/> <button class="zotero-query-btn" @click="doQuery()" :disabled="!canQuery"> <span>🔍</span> </button> </div> <progress v-if="isFetching"/> <template v-if="entries"> <div class="results-and-pager"> <div class="results-title">Résultats <span class="results-count">{{nbResults}}</span></div> <div class="zotero-pager">Page <a role="button" class="next-prev-btn" :class="{'active': currentPage !== 1}" @click="previousPage()">ᐸ</a> <span>{{currentPage}}/{{getTotalPages}}</span> <a role="button" class="next-prev-btn" :class="{'active': currentPage !== getTotalPages}" @click="nextPage()">ᐳ</a> </div> </div> <div class="zotero-entries"> <ul> <li class="zotero-entry" v-for="entry in entries" @click="entrySelected(entry.key)" :key="'entry-' + entry.key"> <ul> <li class="zotero-title">{{entry.data.title}}</li> <li class="zotero-type">{{entry.data.itemType}}</li> <li class="zotero-item-key">{{entry.key}}</li> </ul> </li> </ul> </div> </template> </div> </template> <script> const Zotero = require('libzotero'); export default { name: 'ZoteroVueClient', props: { defaultId : String, defaultType : { type : String, default : 'users' }, options : { type: Object, default: function() { return { editableConfig: true, pageLength: 5, format: 'tei' } } } }, data() { return { type: this.defaultType, groupOrUserId: this.defaultId, entries: null, isFetching: false, isConfigEditable : this.options.editableConfig, isConfigVisible: false, start:0, currentPage:1, pageLength: this.options.pageLength, nbResults: 0, textQuery : "", format : this.options.format } }, computed: { getTotalPages : function(){ return Math.ceil(this.nbResults / this.pageLength) }, canQuery : function(){ return this.textQuery && this.textQuery.trim() !== '' } }, methods: { doQuery() { this.isFetching = true; this.entries = null; let library = new Zotero.Library(this.type, this.groupOrUserId); library.loadItems({start: this.start, limit: this.pageLength, q: this.textQuery}).then((response)=>{ this.entries = response.data; this.nbResults = response.totalResults; this.isFetching = false; }) }, previousPage(){ this.start -= this.pageLength; this.currentPage --; this.doQuery(); }, nextPage(){ this.start += this.pageLength; this.currentPage ++; this.doQuery(); }, entrySelected(entryKey){ fetch('https://api.zotero.org/' + this.type + 's' +'/' + this.groupOrUserId + '/items/' + entryKey + '?format=' + this.format) .then(response => response.text()).then(entry => { this.$emit('entry-selected',entryKey, entry)}) } } } </script> <!-- Add "scoped" attribute to limit CSS to this component only --> <style scoped> * { --input-height: 34px; } input, button, select { height: var(--input-height); } h2 a:hover { color : darkgray; } a[role=button], button{ cursor: pointer; } label{ display: inline-block; width: 200px; } .results-and-pager{ margin-top : 15px; display: flex; justify-content: center; font-size: 1.2em; } .zotero-pager{ margin-left: 30px; } .next-prev-btn{ display: inline-block; margin-left: 15px; margin-right: 15px; } .zotero-entries ul{ list-style-type: none; margin-bottom : 15px; padding-left: 15px; } .results-count{ font-size: 0.8em; } .results-count:before{ content: ' ('; } .results-count:after{ content: ') '; } .zotero-config-pane{ background-color: gainsboro; padding:15px; margin-bottom: 15px; font-size: 0.8em; } .zotero-query-btn{ margin-left: 15px; } .next-prev-btn { visibility: hidden; } .next-prev-btn.active{ visibility: visible; } .zotero-entry{ margin-bottom: 25px; font-size: 0.9em; } .zotero-entry:hover{ background-color: #ededed; cursor: pointer; } .zotero-entry ul{ list-style-type: none; } .zotero-type{ color: #888; } .zotero-title{ font-style: italic; font-weight: 600; } .zotero-item-key{ font-size: 0.7em; } </style>