Browse Source

Implement a feature to validate and save a new auto labeling config

pull/1206/head
Hironsan 4 years ago
parent
commit
faaba2be84
7 changed files with 138 additions and 14 deletions
  1. 66
      frontend/components/containers/settings/ConfigCreationForm.vue
  2. 12
      frontend/components/containers/settings/ConfigList.vue
  3. 26
      frontend/models/config/config-item-list.ts
  4. 20
      frontend/models/config/config-template.ts
  5. 9
      frontend/repositories/config/api.ts
  6. 7
      frontend/repositories/config/interface.ts
  7. 12
      frontend/services/application/config.service.ts

66
frontend/components/containers/settings/ConfigCreationForm.vue

@ -26,7 +26,7 @@
</v-stepper-header>
<v-card>
<v-card-text>
<v-card-text class="pa-0">
<v-stepper-content step="1">
<h4 class="text-h6">Select a config template</h4>
<p class="font-weight-regular body-1">
@ -62,6 +62,7 @@
:key="item.name"
/>
</template>
<h4 class="text-h6">Set mapping template</h4>
<p class="font-weight-regular body-1">
You can set mapping template to convert API response to doccano format.
@ -71,10 +72,12 @@
outlined
label="Mapping Template"
/>
<h4 class="text-h6">Configure label mappings</h4>
<p class="font-weight-regular body-1">
Once you fetch the API response, you can convert the label into the defined one.
</p>
<label-mapping v-model="templateConfig.label_mapping" />
</v-stepper-content>
<v-stepper-content step="3">
@ -90,7 +93,7 @@
/>
</v-stepper-content>
</v-card-text>
<v-card-actions>
<v-card-actions class="me-4">
<v-spacer />
<v-btn
v-show="step.hasPrev()"
@ -110,10 +113,18 @@
Next
</v-btn>
<v-btn
v-show="!step.hasNext()"
:disabled="!passTesting"
v-show="step.isLast() && !passTesting"
color="primary"
class="text-capitalize"
@click="testConfig"
>
Test
</v-btn>
<v-btn
v-show="step.isLast() && passTesting"
color="success"
class="text-capitalize"
@click="saveConfig"
>
Save
</v-btn>
@ -125,11 +136,19 @@
<script lang="ts">
import Vue from 'vue'
import { FromApiTemplateRepository } from '@/repositories/template/api'
import { FromApiConfigItemListRepository } from '@/repositories/config/api'
import { TemplateApplicationService } from '@/services/application/template.service'
import { ConfigApplicationService } from '@/services/application/config.service'
import { ConfigTemplateItem } from '@/models/config/config-template'
import { StepCounter } from '@/models/config/stepper';
import { ConfigItem } from '@/models/config/config-item-list'
import { StepCounter } from '@/models/stepper'
import LabelMapping from '@/components/containers/settings/LabelMapping.vue'
export default Vue.extend({
components: {
LabelMapping
},
data() {
return {
passTesting: false,
@ -161,13 +180,44 @@ export default Vue.extend({
const repository = new FromApiTemplateRepository()
const service = new TemplateApplicationService(repository)
return service
},
configService(): ConfigApplicationService{
const repository = new FromApiConfigItemListRepository()
const service = new ConfigApplicationService(repository)
return service
}
},
methods: {
validate(): boolean {
return false
createConfig() {
const payload = {
// @ts-ignore
modelName: this.templateConfig.model_name,
// @ts-ignore
modelAttrs: this.templateConfig.model_attrs,
// @ts-ignore
template: this.templateConfig.template,
// @ts-ignore
labelMapping: this.templateConfig.label_mapping
}
return ConfigItem.parseFromUI(payload)
},
testConfig() {
const projectId = this.$route.params.id
const item = this.createConfig()
this.configService.testConfig(projectId, item, this.sampleText)
.then(value => {
this.passTesting = value.valid
})
},
saveConfig() {
const projectId = this.$route.params.id
const item = this.createConfig()
this.configService.save(projectId, item)
.then(item => {
this.$emit('onCreate')
})
}
}
})
</script>
</script>

12
frontend/components/containers/settings/ConfigList.vue

@ -21,7 +21,9 @@
</v-btn>
</template>
<template v-slot:content="modal">
<config-creation-form />
<config-creation-form
@onCreate="onCreate();modal.close()"
/>
</template>
</base-modal>
<base-modal>
@ -41,7 +43,7 @@
title="Delete Config"
message="Are you sure you want to delete these configs?"
item-key="modelName"
@ok="remove();modal.close"
@ok="remove();modal.close()"
@cancel="modal.close"
/>
</template>
@ -98,10 +100,16 @@ export default Vue.extend({
await this.configService.delete(projectId, item.id)
}
this.items = await this.configService.list(projectId)
this.selected = []
this.isLoading = false
},
isDeletable(): boolean {
return this.selected.length > 0
},
async onCreate() {
this.isLoading = true
this.items = await this.configService.list(this.$route.params.id)
this.isLoading = false
}
}
})

26
frontend/models/config/config-item-list.ts

@ -26,7 +26,21 @@ export class ConfigItem {
return new ConfigItem(id, model_name, model_attrs, template, label_mapping)
}
toObject(): Object {
static parseFromUI(
{ modelName, modelAttrs, template, labelMapping }:
{
modelName: string,
modelAttrs: {'name': string, 'value': string}[],
template: string,
labelMapping: {'from': string, 'to': string}[]
}
): ConfigItem {
const mapping = labelMapping.reduce((a, x) => ({...a, [x.from]: x.to}), {})
const attributes = modelAttrs.reduce((a, x) => ({...a, [x.name]: x.value}), {})
return new ConfigItem(99999, modelName, attributes, template, mapping)
}
toObject(): object {
return {
id: this.id,
modelName: this.modelName,
@ -35,6 +49,16 @@ export class ConfigItem {
labelMapping: this.labelMapping
}
}
toAPI(): object {
return {
id: this.id,
model_name: this.modelName,
model_attrs: this.modelAttrs,
template: this.template,
label_mapping: this.labelMapping
}
}
}
export const headers = [

20
frontend/models/config/config-template.ts

@ -56,3 +56,23 @@ export class ConfigTemplateItem {
}
}
}
export const headers = [
{
text: 'From',
align: 'left',
value: 'from',
sortable: false
},
{
text: 'To',
align: 'left',
value: 'to',
sortable: false
},
{
text: 'Actions',
value: 'actions',
sortable: false
}
]

9
frontend/repositories/config/api.ts

@ -1,5 +1,5 @@
import ApiService from '@/services/api.service'
import { ConfigItemListRepository } from '@/repositories/config/interface'
import { ConfigItemListRepository, ConfigTestResponse } from '@/repositories/config/interface'
import { ConfigItemList, ConfigItem } from '@/models/config/config-item-list'
export interface ConfigItemResponse {
@ -53,4 +53,11 @@ export class FromApiConfigItemListRepository implements ConfigItemListRepository
const url = `/projects/${projectId}/auto-labeling-configs/${itemId}`
await this.request.delete(url)
}
async testConfig(projectId: string, item: ConfigItem, text: string): Promise<ConfigTestResponse> {
const url = `/projects/${projectId}/auto-labeling-config-testing`
const response = await this.request.post(url, {config: {...item.toAPI()}, input: text})
const responseItem: ConfigTestResponse = response.data
return responseItem
}
}

7
frontend/repositories/config/interface.ts

@ -1,5 +1,10 @@
import { ConfigItem, ConfigItemList } from '@/models/config/config-item-list'
export interface ConfigTestResponse {
valid: boolean,
labels?: object[]
}
export interface ConfigItemListRepository {
list(projectId: string): Promise<ConfigItemList>
@ -8,4 +13,6 @@ export interface ConfigItemListRepository {
delete(projectId: string, itemId: number): Promise<void>
update(projectId: string, item: ConfigItem): Promise<ConfigItem>
testConfig(projectId: string, item: ConfigItem, text: string): Promise<ConfigTestResponse>
}

12
frontend/services/application/config.service.ts

@ -1,5 +1,5 @@
import { ConfigItemList } from '@/models/config/config-item-list'
import { ConfigItemListRepository } from '@/repositories/config/interface'
import { ConfigItemList, ConfigItem } from '@/models/config/config-item-list'
import { ConfigItemListRepository, ConfigTestResponse } from '@/repositories/config/interface'
export class ConfigApplicationService {
constructor(
@ -10,7 +10,15 @@ export class ConfigApplicationService {
return this.configRepository.list(id)
}
public save(projectId: string, item: ConfigItem): Promise<ConfigItem> {
return this.configRepository.create(projectId, item)
}
public delete(projectId: string, itemId: number) {
return this.configRepository.delete(projectId, itemId)
}
public testConfig(projectId: string, item: ConfigItem, text: string): Promise<ConfigTestResponse> {
return this.configRepository.testConfig(projectId, item, text)
}
}
Loading…
Cancel
Save