mirror of https://github.com/doccano/doccano.git
10 changed files with 208 additions and 155 deletions
Unified View
Diff Options
-
BINapp/db.sqlite3
-
4app/server/static/bundle/document_classification.js
-
2app/server/static/bundle/seq2seq.js
-
2app/server/static/bundle/sequence_labeling.js
-
3app/server/static/css/admin.css
-
4app/server/static/js/.jsbeautifyrc
-
58app/server/static/js/document_classification.js
-
271app/server/static/js/mixin.js
-
2app/server/templates/annotation/annotation_base.html
-
17app/server/templates/annotation/document_classification.html
@ -0,0 +1,4 @@ |
|||||
|
{ |
||||
|
"indent_size": 2, |
||||
|
"indent_char": " " |
||||
|
} |
@ -1,31 +1,41 @@ |
|||||
import Vue from 'vue'; |
import Vue from 'vue'; |
||||
Vue.use(require('vue-shortkey'), { prevent: ['input', 'textarea'] }); |
|
||||
import annotationMixin from './mixin.js'; |
|
||||
import HTTP from './http.js'; |
|
||||
|
import annotationMixin from './mixin'; |
||||
|
import HTTP from './http'; |
||||
|
|
||||
var vm = new Vue({ |
|
||||
el: '#mail-app', |
|
||||
delimiters: ['[[', ']]'], |
|
||||
mixins: [annotationMixin], |
|
||||
|
Vue.use(require('vue-shortkey'), { |
||||
|
prevent: ['input', 'textarea'], |
||||
|
}); |
||||
|
|
||||
methods: { |
|
||||
addLabel: async function (label_id) { |
|
||||
for (var i = 0; i < this.items[this.cur]['labels'].length; i++) { |
|
||||
var item = this.items[this.cur]['labels'][i]; |
|
||||
if (label_id == item.label.id) { |
|
||||
this.deleteLabel(i); |
|
||||
return; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
var payload = { |
|
||||
'label': label_id |
|
||||
}; |
|
||||
|
const vm = new Vue({ |
||||
|
el: '#mail-app', |
||||
|
delimiters: ['[[', ']]'], |
||||
|
mixins: [annotationMixin], |
||||
|
|
||||
var doc_id = this.items[this.cur].id; |
|
||||
await HTTP.post(`docs/${doc_id}/annotations/`, payload).then(response => { |
|
||||
this.items[this.cur]['labels'].push(response.data); |
|
||||
}) |
|
||||
|
methods: { |
||||
|
isIn(label) { |
||||
|
for (let i = 0; i < this.annotations[this.cur].length; i++) { |
||||
|
const a = this.annotations[this.cur][i]; |
||||
|
if (a.label === label.id) { |
||||
|
return a; |
||||
} |
} |
||||
} |
|
||||
|
} |
||||
|
return false; |
||||
|
}, |
||||
|
|
||||
|
async addLabel(label) { |
||||
|
const a = this.isIn(label); |
||||
|
if (a) { |
||||
|
this.removeLabel(a); |
||||
|
} else { |
||||
|
const docId = this.items[this.cur].id; |
||||
|
const payload = { |
||||
|
label: label.id, |
||||
|
}; |
||||
|
await HTTP.post(`docs/${docId}/annotations/`, payload).then((response) => { |
||||
|
this.annotations[this.cur].push(response.data); |
||||
|
}); |
||||
|
} |
||||
|
}, |
||||
|
}, |
||||
}); |
}); |
@ -1,125 +1,166 @@ |
|||||
import HTTP from './http.js'; |
|
||||
|
|
||||
var annotationMixin = { |
|
||||
data: function () { |
|
||||
return { |
|
||||
cur: 0, |
|
||||
items: [{ |
|
||||
id: null, |
|
||||
text: '', |
|
||||
labels: [] |
|
||||
}], |
|
||||
labels: [], |
|
||||
guideline: 'Here is the Annotation Guideline Text', |
|
||||
total: 0, |
|
||||
remaining: 0, |
|
||||
searchQuery: '', |
|
||||
url: '', |
|
||||
picked: 'all', |
|
||||
|
import HTTP from './http'; |
||||
|
|
||||
|
const annotationMixin = { |
||||
|
data() { |
||||
|
return { |
||||
|
cur: 0, |
||||
|
items: [{ |
||||
|
id: null, |
||||
|
text: '', |
||||
|
labels: [], |
||||
|
}], |
||||
|
labels: [], |
||||
|
guideline: '', |
||||
|
total: 0, |
||||
|
remaining: 0, |
||||
|
searchQuery: '', |
||||
|
url: '', |
||||
|
picked: 'all', |
||||
|
annotations: [], |
||||
|
}; |
||||
|
}, |
||||
|
|
||||
|
methods: { |
||||
|
async nextPage() { |
||||
|
this.cur += 1; |
||||
|
if (this.cur === this.items.length) { |
||||
|
if (this.next) { |
||||
|
this.url = this.next; |
||||
|
await this.search(); |
||||
|
this.cur = 0; |
||||
|
} else { |
||||
|
this.cur = this.items.length - 1; |
||||
} |
} |
||||
|
} |
||||
|
this.showMessage(this.cur); |
||||
}, |
}, |
||||
methods: { |
|
||||
nextPage: async function () { |
|
||||
this.cur += 1; |
|
||||
if (this.cur == this.items.length) { |
|
||||
if (this.next) { |
|
||||
this.url = this.next; |
|
||||
await this.search(); |
|
||||
this.cur = 0; |
|
||||
} else { |
|
||||
this.cur = this.items.length - 1; |
|
||||
} |
|
||||
} |
|
||||
this.showMessage(this.cur); |
|
||||
}, |
|
||||
prevPage: async function () { |
|
||||
this.cur -= 1; |
|
||||
if (this.cur == -1) { |
|
||||
if (this.prev) { |
|
||||
this.url = this.prev; |
|
||||
await this.search(); |
|
||||
this.cur = this.items.length - 1; |
|
||||
} else { |
|
||||
this.cur = 0; |
|
||||
} |
|
||||
} |
|
||||
this.showMessage(this.cur); |
|
||||
}, |
|
||||
search: async function () { |
|
||||
await HTTP.get(this.url).then(response => { |
|
||||
this.items = response.data['results']; |
|
||||
this.next = response.data['next']; |
|
||||
this.prev = response.data['previous']; |
|
||||
}) |
|
||||
}, |
|
||||
showMessage: function (index) { |
|
||||
this.cur = index; |
|
||||
}, |
|
||||
getState: function () { |
|
||||
if (this.picked == 'all') { |
|
||||
return '' |
|
||||
} else if (this.picked == 'active') { |
|
||||
return 'true' |
|
||||
} else { |
|
||||
return 'false' |
|
||||
} |
|
||||
}, |
|
||||
submit: async function () { |
|
||||
var state = this.getState(); |
|
||||
this.url = `docs/?q=${this.searchQuery}&is_checked=${state}`; |
|
||||
await this.search(); |
|
||||
this.cur = 0; |
|
||||
}, |
|
||||
deleteLabel: async function (index) { |
|
||||
var doc_id = this.items[this.cur].id; |
|
||||
var annotation_id = this.items[this.cur]['labels'][index].id; |
|
||||
HTTP.delete(`docs/${doc_id}/annotations/${annotation_id}`).then(response => { |
|
||||
this.items[this.cur]['labels'].splice(index, 1) |
|
||||
}) |
|
||||
}, |
|
||||
|
|
||||
removeLabel: function (label) { |
|
||||
var doc_id = this.items[this.cur].id; |
|
||||
HTTP.delete(`docs/${doc_id}/annotations/${label.id}`).then(response => { |
|
||||
var index = this.items[this.cur]['labels'].indexOf(label) |
|
||||
this.items[this.cur]['labels'].splice(index, 1) |
|
||||
}) |
|
||||
|
|
||||
|
async prevPage() { |
||||
|
this.cur -= 1; |
||||
|
if (this.cur === -1) { |
||||
|
if (this.prev) { |
||||
|
this.url = this.prev; |
||||
|
await this.search(); |
||||
|
this.cur = this.items.length - 1; |
||||
|
} else { |
||||
|
this.cur = 0; |
||||
} |
} |
||||
|
} |
||||
|
this.showMessage(this.cur); |
||||
|
}, |
||||
|
|
||||
|
async search() { |
||||
|
await HTTP.get(this.url).then((response) => { |
||||
|
this.items = response.data.results; |
||||
|
this.next = response.data.next; |
||||
|
this.prev = response.data.previous; |
||||
|
}); |
||||
|
for (let i = 0; i < this.items.length; i++) { |
||||
|
const docId = this.items[i].id; |
||||
|
HTTP.get(`docs/${docId}/annotations/`).then((response) => { |
||||
|
this.annotations.push(response.data); |
||||
|
}); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
showMessage(index) { |
||||
|
this.cur = index; |
||||
}, |
}, |
||||
watch: { |
|
||||
picked: function (){ |
|
||||
this.submit(); |
|
||||
}, |
|
||||
items: function () { |
|
||||
// fetch progress info.
|
|
||||
HTTP.get('progress').then(response => { |
|
||||
this.total = response.data['total']; |
|
||||
this.remaining = response.data['remaining']; |
|
||||
}) |
|
||||
|
|
||||
|
getState() { |
||||
|
if (this.picked === 'all') { |
||||
|
return ''; |
||||
|
} |
||||
|
if (this.picked === 'active') { |
||||
|
return 'true'; |
||||
|
} |
||||
|
return 'false'; |
||||
|
}, |
||||
|
|
||||
|
async submit() { |
||||
|
const state = this.getState(); |
||||
|
this.url = `docs/?q=${this.searchQuery}&is_checked=${state}`; |
||||
|
await this.search(); |
||||
|
this.cur = 0; |
||||
|
}, |
||||
|
|
||||
|
getTextColor(labelId) { |
||||
|
for (let i = 0; i < this.labels.length; i++) { |
||||
|
const label = this.labels[i]; |
||||
|
if (label.id === labelId) { |
||||
|
return label.text_color; |
||||
} |
} |
||||
|
} |
||||
|
return '#ffffff'; |
||||
}, |
}, |
||||
created: function () { |
|
||||
HTTP.get('labels').then(response => { |
|
||||
this.labels = response.data |
|
||||
}); |
|
||||
this.submit(); |
|
||||
|
|
||||
|
getBgColor(labelId) { |
||||
|
for (let i = 0; i < this.labels.length; i++) { |
||||
|
const label = this.labels[i]; |
||||
|
if (label.id === labelId) { |
||||
|
return label.background_color; |
||||
|
} |
||||
|
} |
||||
|
return '#333333'; |
||||
}, |
}, |
||||
computed: { |
|
||||
achievement: function () { |
|
||||
var done = this.total - this.remaining; |
|
||||
var percentage = Math.round(done / this.total * 100); |
|
||||
return this.total > 0 ? percentage : 0; |
|
||||
}, |
|
||||
progressColor: function () { |
|
||||
if (this.achievement < 30) { |
|
||||
return 'is-danger' |
|
||||
} else if (this.achievement < 70) { |
|
||||
return 'is-warning' |
|
||||
} else { |
|
||||
return 'is-primary' |
|
||||
} |
|
||||
|
|
||||
|
getLabelText(labelId) { |
||||
|
for (let i = 0; i < this.labels.length; i++) { |
||||
|
const label = this.labels[i]; |
||||
|
if (label.id === labelId) { |
||||
|
return label.text; |
||||
} |
} |
||||
} |
|
||||
|
} |
||||
|
return 'NO'; |
||||
|
}, |
||||
|
|
||||
|
removeLabel(label) { |
||||
|
const docId = this.items[this.cur].id; |
||||
|
HTTP.delete(`docs/${docId}/annotations/${label.id}`).then((response) => { |
||||
|
const index = this.annotations[this.cur].indexOf(response.data); |
||||
|
this.annotations[this.cur].splice(index, 1); |
||||
|
}); |
||||
|
}, |
||||
|
}, |
||||
|
|
||||
|
watch: { |
||||
|
picked() { |
||||
|
this.submit(); |
||||
|
}, |
||||
|
|
||||
|
items() { |
||||
|
// fetch progress info.
|
||||
|
HTTP.get('progress').then((response) => { |
||||
|
this.total = response.data.total; |
||||
|
this.remaining = response.data.remaining; |
||||
|
}); |
||||
|
}, |
||||
|
}, |
||||
|
|
||||
|
created() { |
||||
|
HTTP.get('labels').then((response) => { |
||||
|
this.labels = response.data; |
||||
|
}); |
||||
|
this.submit(); |
||||
|
}, |
||||
|
|
||||
|
computed: { |
||||
|
achievement() { |
||||
|
const done = this.total - this.remaining; |
||||
|
const percentage = Math.round(done / this.total * 100); |
||||
|
return this.total > 0 ? percentage : 0; |
||||
|
}, |
||||
|
|
||||
|
progressColor() { |
||||
|
if (this.achievement < 30) { |
||||
|
return 'is-danger'; |
||||
|
} |
||||
|
if (this.achievement < 70) { |
||||
|
return 'is-warning'; |
||||
|
} |
||||
|
return 'is-primary'; |
||||
|
}, |
||||
|
}, |
||||
}; |
}; |
||||
|
|
||||
export default annotationMixin; |
|
||||
|
export default annotationMixin; |
Write
Preview
Loading…
Cancel
Save