mirror of https://github.com/doccano/doccano.git
6 changed files with 347 additions and 5 deletions
Split View
Diff Options
-
126frontend/components/tasks/Seq2Seq/Seq2seqBox.vue
-
24frontend/models/tasks/seq2seq.ts
-
138frontend/pages/projects/_id/sequence-to-sequence/index.vue
-
7frontend/plugins/services.ts
-
19frontend/repositories/tasks/seq2seq/api.ts
-
38frontend/services/application/tasks/seq2seqService.ts
@ -0,0 +1,126 @@ |
|||
<template> |
|||
<v-card> |
|||
<v-data-table |
|||
:headers="headers" |
|||
:items="annotations" |
|||
item-key="id" |
|||
hide-default-header |
|||
hide-default-footer |
|||
disable-pagination |
|||
class="elevation-1" |
|||
@input="update" |
|||
> |
|||
<template v-slot:top> |
|||
<v-text-field |
|||
v-model="newText" |
|||
prepend-inner-icon="mdi-pencil" |
|||
:label="$t('annotation.newText')" |
|||
autofocus |
|||
single-line |
|||
hide-details |
|||
filled |
|||
@keyup.enter="create" |
|||
@compositionstart="compositionStart" |
|||
@compositionend="compositionEnd" |
|||
/> |
|||
</template> |
|||
<template v-slot:[`item.text`]="{ item }"> |
|||
<v-edit-dialog> |
|||
<span class="title" style="font-weight:400"> |
|||
{{ item.text }} |
|||
</span> |
|||
<template v-slot:input> |
|||
<v-textarea |
|||
:value="item.text" |
|||
:label="$t('generic.edit')" |
|||
autofocus |
|||
@change="update(item.id, $event)" |
|||
/> |
|||
</template> |
|||
</v-edit-dialog> |
|||
</template> |
|||
<template v-slot:[`item.action`]="{ item }"> |
|||
<v-icon |
|||
small |
|||
@click="deleteAnnotation(item.id)" |
|||
> |
|||
mdi-delete-outline |
|||
</v-icon> |
|||
</template> |
|||
</v-data-table> |
|||
</v-card> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
props: { |
|||
annotations: { |
|||
type: Array, |
|||
default: () => ([]), |
|||
required: true |
|||
}, |
|||
deleteAnnotation: { |
|||
type: Function, |
|||
default: () => ([]), |
|||
required: true |
|||
}, |
|||
updateAnnotation: { |
|||
type: Function, |
|||
default: () => ([]), |
|||
required: true |
|||
}, |
|||
createAnnotation: { |
|||
type: Function, |
|||
default: () => ([]), |
|||
required: true |
|||
} |
|||
}, |
|||
|
|||
data() { |
|||
return { |
|||
newText: '', |
|||
headers: [ |
|||
{ |
|||
text: 'Text', |
|||
align: 'left', |
|||
value: 'text' |
|||
}, |
|||
{ |
|||
text: 'Actions', |
|||
align: 'right', |
|||
value: 'action' |
|||
} |
|||
], |
|||
isComposing: false, |
|||
hasCompositionJustEnded: false |
|||
} |
|||
}, |
|||
|
|||
methods: { |
|||
update(annotationId, text) { |
|||
if (text.length > 0) { |
|||
this.updateAnnotation(annotationId, text) |
|||
} else { |
|||
this.deleteAnnotation(annotationId) |
|||
} |
|||
}, |
|||
create() { |
|||
if (this.isComposing || this.hasCompositionJustEnded) { |
|||
this.hasCompositionJustEnded = false |
|||
return |
|||
} |
|||
if (this.newText.length > 0) { |
|||
this.createAnnotation(this.newText) |
|||
this.newText = '' |
|||
} |
|||
}, |
|||
compositionStart() { |
|||
this.isComposing = true |
|||
}, |
|||
compositionEnd() { |
|||
this.isComposing = false |
|||
this.hasCompositionJustEnded = true |
|||
} |
|||
} |
|||
} |
|||
</script> |
@ -0,0 +1,24 @@ |
|||
import { AnnotationModel } from './interface'; |
|||
|
|||
export class Seq2seqLabel implements AnnotationModel{ |
|||
constructor( |
|||
public id: number, |
|||
public text: string, |
|||
public user: number, |
|||
) {} |
|||
|
|||
static valueOf( |
|||
{ id, text, user }: |
|||
{ id: number, text: string, user: number } |
|||
) { |
|||
return new Seq2seqLabel(id, text, user) |
|||
} |
|||
|
|||
toObject() { |
|||
return { |
|||
id: this.id, |
|||
text: this.text, |
|||
user: this.user |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,19 @@ |
|||
import { AnnotationRepository } from '../interface' |
|||
import { Seq2seqLabel } from '~/models/tasks/seq2seq' |
|||
|
|||
|
|||
export class FromApiSeq2seqRepository extends AnnotationRepository<Seq2seqLabel> { |
|||
constructor() { |
|||
super(Seq2seqLabel) |
|||
} |
|||
|
|||
public async update(projectId: string, docId: number, annotationId: number, text: string) { |
|||
const url = this.baseUrl(projectId, docId) + `/${annotationId}` |
|||
const payload = { text } |
|||
await this.request.patch(url, payload) |
|||
} |
|||
|
|||
protected baseUrl(projectId: string, docId: number): string { |
|||
return `/projects/${projectId}/docs/${docId}/annotations` |
|||
} |
|||
} |
@ -0,0 +1,38 @@ |
|||
import { FromApiSeq2seqRepository } from '@/repositories/tasks/seq2seq/api' |
|||
import { Seq2seqLabel } from '@/models/tasks/seq2seq' |
|||
import { AnnotationApplicationService } from './annotationService' |
|||
import annotation from '~/i18n/de/projects/annotation' |
|||
|
|||
export class Seq2seqDTO { |
|||
id: number |
|||
text: string |
|||
user: number |
|||
|
|||
constructor(item: Seq2seqLabel) { |
|||
this.id = item.id |
|||
this.text = item.text |
|||
this.user = item.user |
|||
} |
|||
} |
|||
|
|||
export class Seq2seqApplicationService extends AnnotationApplicationService<Seq2seqLabel> { |
|||
constructor( |
|||
readonly repository: FromApiSeq2seqRepository |
|||
) { |
|||
super(new FromApiSeq2seqRepository()) |
|||
} |
|||
|
|||
public async list(projectId: string, docId: number): Promise<Seq2seqDTO[]> { |
|||
const items = await this.repository.list(projectId, docId) |
|||
return items.map(item => new Seq2seqDTO(item)) |
|||
} |
|||
|
|||
public async create(projectId: string, docId: number, text: string): Promise<void> { |
|||
const item = new Seq2seqLabel(0, text, 0) |
|||
await this.repository.create(projectId, docId, item) |
|||
} |
|||
|
|||
public async changeText(projectId: string, docId: number, annotationId: number, text: string): Promise<void> { |
|||
await this.repository.update(projectId, docId, annotationId, text) |
|||
} |
|||
} |
Write
Preview
Loading…
Cancel
Save