You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

244 lines
6.4 KiB

2 years ago
2 years ago
3 years ago
3 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. <template>
  2. <v-card>
  3. <v-card-title>{{ $t('overview.createProjectTitle') }}</v-card-title>
  4. <v-card-text>
  5. <v-form v-model="valid">
  6. <v-item-group
  7. v-model="selected"
  8. mandatory
  9. @change="updateValue('projectType', projectTypes[selected])"
  10. >
  11. <v-row no-gutters>
  12. <v-col v-for="(item, i) in projectTypes" :key="i">
  13. <v-item v-slot="{ active, toggle }">
  14. <v-card class="mb-6 me-6" max-width="350" outlined>
  15. <v-img
  16. :src="require(`~/assets/images/tasks/${images[i]}`)"
  17. height="200"
  18. contain
  19. @click="toggle"
  20. />
  21. <v-card-title>
  22. <v-icon v-if="active">
  23. {{ mdiCheckBold }}
  24. </v-icon>
  25. {{ translateTypeName(item, $t('overview.projectTypes')) }}
  26. </v-card-title>
  27. </v-card>
  28. </v-item>
  29. </v-col>
  30. </v-row>
  31. </v-item-group>
  32. <v-text-field
  33. :value="name"
  34. :rules="projectNameRules($t('rules.projectNameRules'))"
  35. :label="$t('overview.projectName')"
  36. outlined
  37. required
  38. autofocus
  39. @input="updateValue('name', $event)"
  40. />
  41. <v-text-field
  42. :value="description"
  43. :rules="descriptionRules($t('rules.descriptionRules'))"
  44. :label="$t('generic.description')"
  45. outlined
  46. required
  47. @input="updateValue('description', $event)"
  48. />
  49. <v-combobox
  50. :value="tags"
  51. :items="tags"
  52. label="Tags"
  53. multiple
  54. chips
  55. outlined
  56. dense
  57. deletable-chips
  58. hide-selected
  59. @input="updateValue('tags', $event)"
  60. />
  61. <v-checkbox
  62. v-if="hasSingleLabelOption"
  63. :value="singleClassClassification"
  64. :label="$t('overview.allowSingleLabel')"
  65. @change="updateValue('singleClassClassification', $event === true)"
  66. />
  67. <v-checkbox
  68. v-if="isSequenceLabelingProject"
  69. :value="allowOverlapping"
  70. label="Allow overlapping entity"
  71. @change="updateValue('allowOverlapping', $event === true)"
  72. />
  73. <v-img
  74. v-if="isSequenceLabelingProject"
  75. :src="require('~/assets/project/creation.gif')"
  76. height="200"
  77. position="left"
  78. contain
  79. />
  80. <v-checkbox
  81. v-if="isSequenceLabelingProject"
  82. :value="useRelation"
  83. label="Use relation labeling"
  84. @change="updateValue('useRelation', $event === true)"
  85. />
  86. <v-checkbox
  87. v-if="isSequenceLabelingProject"
  88. :value="graphemeMode"
  89. @change="updateValue('graphemeMode', $event === true)"
  90. >
  91. <template #label>
  92. <div>
  93. Count
  94. <v-tooltip bottom>
  95. <template #activator="{ on }">
  96. <a target="_blank" href="https://unicode.org/reports/tr29/" @click.stop v-on="on">
  97. grapheme clusters
  98. </a>
  99. </template>
  100. Like emoji(🌷, 💩, and 👍), CRLF(\r\n), and so on.
  101. </v-tooltip>
  102. as one character
  103. </div>
  104. </template>
  105. </v-checkbox>
  106. <v-checkbox
  107. :value="enableRandomOrder"
  108. :label="$t('overview.randomizeDocOrder')"
  109. @change="updateValue('enableRandomOrder', $event === true)"
  110. />
  111. <v-checkbox
  112. :value="enableShareAnnotation"
  113. :label="$t('overview.shareAnnotations')"
  114. @change="updateValue('enableShareAnnotation', $event === true)"
  115. />
  116. </v-form>
  117. </v-card-text>
  118. <v-card-actions class="ps-4">
  119. <v-btn
  120. :disabled="!valid"
  121. color="primary"
  122. style="text-transform: none"
  123. outlined
  124. @click="$emit('save')"
  125. >
  126. {{ $t('generic.create') }}
  127. </v-btn>
  128. </v-card-actions>
  129. </v-card>
  130. </template>
  131. <script lang="ts">
  132. import Vue from 'vue'
  133. import { mdiCheckBold } from '@mdi/js'
  134. import { projectNameRules, descriptionRules, projectTypeRules } from '@/rules/index'
  135. export default Vue.extend({
  136. props: {
  137. name: {
  138. type: String,
  139. default: '',
  140. required: true
  141. },
  142. description: {
  143. type: String,
  144. default: '',
  145. required: true
  146. },
  147. projectType: {
  148. type: String,
  149. default: '',
  150. required: true
  151. },
  152. enableRandomOrder: {
  153. type: Boolean,
  154. default: false,
  155. required: true
  156. },
  157. enableShareAnnotation: {
  158. type: Boolean,
  159. default: false,
  160. required: true
  161. },
  162. singleClassClassification: {
  163. type: Boolean,
  164. default: false,
  165. required: true
  166. },
  167. allowOverlapping: {
  168. type: Boolean,
  169. default: false
  170. },
  171. graphemeMode: {
  172. type: Boolean,
  173. default: false
  174. },
  175. useRelation: {
  176. type: Boolean,
  177. default: false
  178. },
  179. tags: {
  180. type: Array,
  181. default: () => []
  182. }
  183. },
  184. data() {
  185. return {
  186. valid: false,
  187. projectNameRules,
  188. projectTypeRules,
  189. descriptionRules,
  190. mdiCheckBold,
  191. selected: 0
  192. }
  193. },
  194. computed: {
  195. projectTypes() {
  196. return [
  197. 'DocumentClassification',
  198. 'SequenceLabeling',
  199. 'Seq2seq',
  200. 'IntentDetectionAndSlotFilling',
  201. 'ImageClassification',
  202. 'ImageCaptioning',
  203. 'BoundingBox',
  204. 'Segmentation',
  205. 'Speech2text'
  206. ]
  207. },
  208. images() {
  209. return [
  210. 'text_classification.png',
  211. 'sequence_labeling.png',
  212. 'seq2seq.png',
  213. 'intent_detection.png',
  214. 'image_classification.png',
  215. 'image_captioning.jpg',
  216. 'object_detection.jpg',
  217. 'segmentation.jpg',
  218. 'speech_to_text.png'
  219. ]
  220. },
  221. hasSingleLabelOption() {
  222. return ['DocumentClassification', 'ImageClassification'].includes(this.projectType)
  223. },
  224. isSequenceLabelingProject() {
  225. return this.projectType === 'SequenceLabeling'
  226. }
  227. },
  228. methods: {
  229. updateValue(key: string, value: string) {
  230. this.$emit(`update:${key}`, value)
  231. },
  232. translateTypeName(type: string, types: string[]): string {
  233. const index = this.projectTypes.indexOf(type)
  234. return types[index]
  235. }
  236. }
  237. })
  238. </script>