mirror of https://github.com/doccano/doccano.git
10 changed files with 208 additions and 155 deletions
Split 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'; |
|||
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