mirror of https://github.com/doccano/doccano.git
2 changed files with 268 additions and 1 deletions
Split View
Diff Options
@ -0,0 +1,253 @@ |
|||
<template> |
|||
<v-card> |
|||
<v-card-title>Create a Label Type</v-card-title> |
|||
<v-card-text> |
|||
<v-form |
|||
ref="form" |
|||
v-model="valid" |
|||
> |
|||
<v-row> |
|||
<v-col cols="12" sm="6"> |
|||
<v-text-field |
|||
v-model="editedItem.text" |
|||
:counter="100" |
|||
:label="$t('labels.labelName')" |
|||
:rules="[rules.required, rules.counter, rules.nameDuplicated]" |
|||
outlined |
|||
required |
|||
/> |
|||
</v-col> |
|||
<v-col cols="12" sm="6"> |
|||
<v-select |
|||
v-model="editedItem.suffixKey" |
|||
:items="shortkeys" |
|||
:label="$t('labels.key')" |
|||
:rules="[rules.keyDuplicated]" |
|||
outlined |
|||
/> |
|||
</v-col> |
|||
</v-row> |
|||
|
|||
<v-row> |
|||
<v-col cols="12" sm="12"> |
|||
<v-text-field |
|||
v-model="editedItem.backgroundColor" |
|||
:rules="[rules.validColor]" |
|||
label="Color" |
|||
hide-details="auto" |
|||
outlined |
|||
required |
|||
/> |
|||
<v-chip-group |
|||
v-model="selectedColorIndex" |
|||
column |
|||
mandatory |
|||
> |
|||
<v-chip |
|||
v-for="color in predefinedColors" |
|||
:key="color" |
|||
:color="color" |
|||
filter |
|||
label |
|||
style="height: 32px; width: 32px;" |
|||
/> |
|||
<v-tooltip bottom> |
|||
<template #activator="{ on, attrs }"> |
|||
<v-chip |
|||
label |
|||
v-bind="attrs" |
|||
v-on="on" |
|||
@click="setRandomColor" |
|||
> |
|||
<v-icon>{{ mdiReload }}</v-icon> |
|||
</v-chip> |
|||
</template> |
|||
<span>Random color</span> |
|||
</v-tooltip> |
|||
</v-chip-group> |
|||
</v-col> |
|||
</v-row> |
|||
|
|||
<v-row> |
|||
<v-col> |
|||
<div class="title black--text mb-2">Preview</div> |
|||
<v-chip |
|||
:color="editedItem.backgroundColor" |
|||
:text-color="textColor" |
|||
> |
|||
{{ editedItem.text }} |
|||
<v-avatar |
|||
v-if="editedItem.suffixKey" |
|||
right |
|||
color="white" |
|||
class="black--text font-weight-bold" |
|||
> |
|||
{{ editedItem.suffixKey }} |
|||
</v-avatar> |
|||
</v-chip> |
|||
</v-col> |
|||
</v-row> |
|||
|
|||
<v-row> |
|||
<v-col cols="12" sm="12"> |
|||
<v-btn |
|||
:disabled="!valid" |
|||
color="primary" |
|||
class="text-capitalize" |
|||
@click="save" |
|||
> |
|||
Save |
|||
</v-btn> |
|||
|
|||
<v-btn |
|||
:disabled="!valid" |
|||
color="primary" |
|||
style="text-transform: none" |
|||
outlined |
|||
@click="saveAndAnother" |
|||
> |
|||
Save and add another |
|||
</v-btn> |
|||
</v-col> |
|||
</v-row> |
|||
</v-form> |
|||
</v-card-text> |
|||
</v-card> |
|||
</template> |
|||
|
|||
<script lang="ts"> |
|||
import Vue from 'vue' |
|||
import { mdiReload } from '@mdi/js'; |
|||
import { LabelDTO } from '~/services/application/label/labelData' |
|||
import { ProjectDTO } from '~/services/application/project/projectData' |
|||
|
|||
export default Vue.extend({ |
|||
|
|||
components: { |
|||
}, |
|||
|
|||
layout: 'project', |
|||
|
|||
validate({ params, app }) { |
|||
if (/^\d+$/.test(params.id)) { |
|||
return app.$services.project.findById(params.id) |
|||
.then((res:ProjectDTO) => { |
|||
return res.canDefineLabel |
|||
}) |
|||
} |
|||
return false |
|||
}, |
|||
|
|||
data() { |
|||
return { |
|||
editedItem: { |
|||
text: '', |
|||
prefixKey: null, |
|||
suffixKey: null, |
|||
backgroundColor: '#2196F3', |
|||
textColor: '#ffffff' |
|||
} as LabelDTO, |
|||
defaultItem: { |
|||
text: '', |
|||
prefixKey: null, |
|||
suffixKey: null, |
|||
backgroundColor: '#2196F3', |
|||
textColor: '#ffffff' |
|||
} as LabelDTO, |
|||
items: [] as LabelDTO[], |
|||
selectedColorIndex: 0, |
|||
valid: false, |
|||
rules: { |
|||
required: (v: string) => !!v || 'Required', |
|||
// @ts-ignore |
|||
counter: (v: string) => (v && v.length <= 100) || this.$t('rules.labelNameRules').labelLessThan100Chars, |
|||
// @ts-ignore |
|||
nameDuplicated: (v: string) => (!this.usedNames.includes(v)) || this.$t('rules.labelNameRules').duplicated, |
|||
// @ts-ignore |
|||
keyDuplicated: (v: string) => !this.usedKeys.includes(v) || this.$t('rules.keyNameRules').duplicated, |
|||
validColor: (v: string) => (/^#[0-9A-F]{6}$/i.test(v)) || 'This string is NOT a valid hex color.' |
|||
}, |
|||
mdiReload |
|||
} |
|||
}, |
|||
|
|||
computed: { |
|||
projectId(): string { |
|||
return this.$route.params.id |
|||
}, |
|||
usedNames(): string[] { |
|||
return this.items.map(item => item.text) |
|||
}, |
|||
usedKeys(): string[] { |
|||
return this.items.map(item => item.suffixKey) |
|||
.filter(item => item !==null) as string[] |
|||
}, |
|||
|
|||
service(): any { |
|||
const type = this.$route.query.type |
|||
if (type === 'category') { |
|||
return this.$services.categoryType |
|||
} else { |
|||
return this.$services.spanType |
|||
} |
|||
}, |
|||
|
|||
shortkeys() { |
|||
return '0123456789abcdefghijklmnopqrstuvwxyz'.split('') |
|||
}, |
|||
|
|||
predefinedColors(): string[] { |
|||
return [ |
|||
'#73D8FF', '#009CE0', '#0062B1', |
|||
'#AEA1FF', '#7B64FF', '#653294', |
|||
'#FDA1FF', '#FA28FF', '#AB149E', |
|||
'#68CCCA', '#16A5A5', '#0C797D', |
|||
'#A4DD00', '#68BC00', '#194D33', |
|||
'#FCDC00', '#FCC400', '#FB9E00', |
|||
'#F44E3B', '#D33115', '#9F0500' |
|||
] |
|||
}, |
|||
|
|||
textColor(): string { |
|||
return this.$contrastColor(this.editedItem.backgroundColor) |
|||
} |
|||
}, |
|||
|
|||
watch: { |
|||
selectedColorIndex(value) { |
|||
if (value < this.predefinedColors.length) { |
|||
this.editedItem.backgroundColor = this.predefinedColors[this.selectedColorIndex] |
|||
} |
|||
} |
|||
}, |
|||
|
|||
async created() { |
|||
this.items = await this.service.list(this.projectId) |
|||
}, |
|||
|
|||
methods: { |
|||
async save() { |
|||
await this.service.create(this.projectId, this.editedItem) |
|||
this.$router.push(`/projects/${this.projectId}/labels`) |
|||
}, |
|||
|
|||
async saveAndAnother() { |
|||
await this.service.create(this.projectId, this.editedItem) |
|||
this.editedItem = Object.assign({}, this.defaultItem) |
|||
}, |
|||
|
|||
setRandomColor() { |
|||
const color = this.generateRandomColor() |
|||
this.editedItem.backgroundColor = color |
|||
}, |
|||
|
|||
generateRandomColor(){ |
|||
const maxVal = 0xFFFFFF |
|||
const randomNumber = Math.floor(Math.random() * maxVal) |
|||
const randomString = randomNumber.toString(16) |
|||
const randColor = randomString.padStart(6, '0') |
|||
return `#${randColor.toUpperCase()}` |
|||
} |
|||
} |
|||
}) |
|||
</script> |
Write
Preview
Loading…
Cancel
Save