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.

322 lines
9.5 KiB

  1. import ProjectService from '@/services/project.service'
  2. export const state = () => ({
  3. projects: [],
  4. selected: [],
  5. current: {},
  6. loading: false
  7. })
  8. export const getters = {
  9. isDeletable(state) {
  10. const isProjectAdministrator = project => project.current_users_role.is_project_admin
  11. return state.selected.length > 0 && state.selected.every(isProjectAdministrator)
  12. },
  13. isEmpty(state) {
  14. return Object.keys(state.current).length === 0 && state.current.constructor === Object
  15. },
  16. currentProject(state) {
  17. return state.current
  18. },
  19. getCurrentUserRole(state) {
  20. return state.current.current_users_role || {}
  21. },
  22. canViewApproveButton(state) {
  23. const role = state.current.current_users_role
  24. return role && !role.is_annotator
  25. },
  26. getFilterOption(state) {
  27. if (state.current.project_type === 'DocumentClassification') {
  28. return 'doc_annotations__isnull'
  29. } else if (state.current.project_type === 'SequenceLabeling') {
  30. return 'seq_annotations__isnull'
  31. } else if (state.current.project_type === 'Seq2seq') {
  32. return 'seq2seq_annotations__isnull'
  33. } else {
  34. return ''
  35. }
  36. },
  37. getLink(state) {
  38. if (state.current.project_type === 'DocumentClassification') {
  39. return 'text-classification'
  40. } else if (state.current.project_type === 'SequenceLabeling') {
  41. return 'sequence-labeling'
  42. } else if (state.current.project_type === 'Seq2seq') {
  43. return 'sequence-to-sequence'
  44. } else {
  45. return ''
  46. }
  47. },
  48. getImportFormat(state) {
  49. const plain = {
  50. type: 'plain',
  51. text: 'Plain text',
  52. accept: '.txt',
  53. examples: [
  54. 'EU rejects German call to boycott British lamb.\n',
  55. 'Peter Blackburn\n',
  56. 'President Obama'
  57. ]
  58. }
  59. const csv = {
  60. type: 'csv',
  61. text: 'CSV',
  62. accept: '.csv'
  63. }
  64. const json = {
  65. type: 'json',
  66. text: 'JSONL',
  67. accept: '.json,.jsonl'
  68. }
  69. const conll = {
  70. type: 'conll',
  71. text: 'CoNLL',
  72. accept: '.conll'
  73. }
  74. const excel = {
  75. type: 'excel',
  76. text: 'Excel',
  77. accept: '.xlsx'
  78. }
  79. if (state.current.project_type === 'DocumentClassification') {
  80. json.examples = [
  81. '{"text": "Terrible customer service.", "labels": ["negative"]}\n',
  82. '{"text": "Really great transaction.", "labels": ["positive"]}\n',
  83. '{"text": "Great price.", "labels": ["positive"]}'
  84. ]
  85. csv.examples = [
  86. 'text,label\n',
  87. '"Terrible customer service.","negative"\n',
  88. '"Really great transaction.","positive"\n',
  89. '"Great price.","positive"'
  90. ]
  91. excel.examples = [
  92. 'text,label\n',
  93. '"Terrible customer service.","negative"\n',
  94. '"Really great transaction.","positive"\n',
  95. '"Great price.","positive"'
  96. ]
  97. return [
  98. plain,
  99. csv,
  100. json,
  101. excel
  102. ]
  103. } else if (state.current.project_type === 'SequenceLabeling') {
  104. json.examples = [
  105. '{"text": "EU rejects German call to boycott British lamb.", "labels": [ [0, 2, "ORG"], [11, 17, "MISC"], ... ]}\n',
  106. '{"text": "Peter Blackburn", "labels": [ [0, 15, "PERSON"] ]}\n',
  107. '{"text": "President Obama", "labels": [ [10, 15, "PERSON"] ]}'
  108. ]
  109. conll.examples = [
  110. 'EU\tB-ORG\n',
  111. 'rejects\tO\n',
  112. 'German\tB-MISC\n',
  113. 'call\tO\n',
  114. 'to\tO\n',
  115. 'boycott\tO\n',
  116. 'British\tB-MISC\n',
  117. 'lamb\tO\n',
  118. '.\tO\n\n',
  119. 'Peter\tB-PER\n',
  120. 'Blackburn\tI-PER'
  121. ]
  122. return [
  123. plain,
  124. json,
  125. conll
  126. ]
  127. } else if (state.current.project_type === 'Seq2seq') {
  128. json.examples = [
  129. '{"text": "Hello!", "labels": ["こんにちは!"]}\n',
  130. '{"text": "Good morning.", "labels": ["おはようございます。"]}\n',
  131. '{"text": "See you.", "labels": ["さようなら。"]}'
  132. ]
  133. csv.examples = [
  134. 'text,label\n',
  135. '"Hello!","こんにちは!"\n',
  136. '"Good morning.","おはようございます。"\n',
  137. '"See you.","さようなら。"'
  138. ]
  139. excel.examples = [
  140. 'text,label\n',
  141. '"Hello!","こんにちは!"\n',
  142. '"Good morning.","おはようございます。"\n',
  143. '"See you.","さようなら。"'
  144. ]
  145. return [
  146. plain,
  147. csv,
  148. json,
  149. excel
  150. ]
  151. } else {
  152. return []
  153. }
  154. },
  155. getExportFormat(state) {
  156. const csv = {
  157. type: 'csv',
  158. text: 'CSV'
  159. }
  160. const json = {
  161. type: 'json',
  162. text: 'JSONL'
  163. }
  164. const jsonl = {
  165. type: 'json1',
  166. text: 'JSONL(Text label)'
  167. }
  168. if (state.current.project_type === 'DocumentClassification') {
  169. json.examples = [
  170. '{"id": 1, "text": "Terrible customer service.", "annotations": [{"id": 1, "label": 1, "user": 1}]}\n',
  171. '{"id": 2, "text": "Really great transaction.", "annotations": [{"id": 2, "label": 2, "user": 1}]}\n',
  172. '{"id": 3, "text": "Great price.", "annotations": [{"id": 3, "label": 2, "user": 1}]}'
  173. ]
  174. csv.examples = [
  175. 'id,text,label,user\n',
  176. '1,"Terrible customer service.",1,1\n',
  177. '2,"Really great transaction.",2,1\n',
  178. '3,"Great price.",2,1'
  179. ]
  180. return [
  181. csv,
  182. json
  183. ]
  184. } else if (state.current.project_type === 'SequenceLabeling') {
  185. json.examples = [
  186. '{"id": 1, "text": "EU rejects ...", "annotations": [{"id": 1, "label": 2, "start_offset": 0, "end_offset": 2, "user": 1}]}\n',
  187. '{"id": 2, "text": "Peter Blackburn", "annotations": [{"id": 2, "label": 1, "start_offset": 0, "end_offset": 15, "user": 1}]}\n',
  188. '{"id": 3, "text": "President Obama", "annotations": [{"id": 3, "label": 1, "start_offset": 10, "end_offset": 15, "user": 1}]}'
  189. ]
  190. jsonl.examples = [
  191. '{"id": 1, "text": "EU rejects ...", "labels": [[0,2,"ORG"], [11,17, "MISC"], [34,41,"ORG"]]}\n',
  192. '{"id": 2, "text": "Peter Blackburn", "labels": [[0, 15, "PERSON"]]}\n',
  193. '{"id": 3, "text": "President Obama", "labels": [[10, 15, "PERSON"]]}\n'
  194. ]
  195. return [
  196. json,
  197. jsonl
  198. ]
  199. } else if (state.current.project_type === 'Seq2seq') {
  200. json.examples = [
  201. '{"id": 1, "text": "Hello!", "annotations": [{"id": 1, "label": "こんにちは!", "user": 1}]}\n',
  202. '{"id": 2, "text": "Good morning.", "annotations": [{"id": 2, "label": "おはようございます。", "user": 1}]}\n',
  203. '{"id": 3, "text": "See you.", "annotations": [{"id": 3, "label": "さようなら。", "user": 1}]}'
  204. ]
  205. csv.examples = [
  206. 'id,text,label,user\n',
  207. '1,"Hello!","こんにちは!",1\n',
  208. '2,"Good morning.","おはようございます。",1\n',
  209. '3,"See you.","さようなら。",1'
  210. ]
  211. return [
  212. csv,
  213. json
  214. ]
  215. } else {
  216. return []
  217. }
  218. },
  219. loadSearchOptions(state) {
  220. const checkpoint = JSON.parse(localStorage.getItem('checkpoint')) || {}
  221. return checkpoint[state.current.id] ? checkpoint[state.current.id] : { page: 1 }
  222. }
  223. }
  224. export const mutations = {
  225. setProjectList(state, payload) {
  226. state.projects = payload
  227. },
  228. createProject(state, project) {
  229. state.projects.unshift(project)
  230. },
  231. updateProject(state, project) {
  232. const item = state.projects.find(item => item.id === project.id)
  233. Object.assign(item, project)
  234. },
  235. deleteProject(state, projectId) {
  236. state.projects = state.projects.filter(item => item.id !== projectId)
  237. },
  238. updateSelected(state, selected) {
  239. state.selected = selected
  240. },
  241. resetSelected(state) {
  242. state.selected = []
  243. },
  244. setLoading(state, payload) {
  245. state.loading = payload
  246. },
  247. setCurrent(state, payload) {
  248. state.current = payload
  249. },
  250. saveSearchOptions(state, options) {
  251. const checkpoint = JSON.parse(localStorage.getItem('checkpoint')) || {}
  252. checkpoint[state.current.id] = options
  253. localStorage.setItem('checkpoint', JSON.stringify(checkpoint))
  254. }
  255. }
  256. export const actions = {
  257. getProjectList({ commit }, config) {
  258. commit('setLoading', true)
  259. ProjectService.getProjectList()
  260. .then((response) => {
  261. commit('setProjectList', response.data)
  262. })
  263. .catch((error) => {
  264. alert(error)
  265. })
  266. .finally(() => {
  267. commit('setLoading', false)
  268. })
  269. },
  270. createProject({ commit }, project) {
  271. ProjectService.createProject(project)
  272. .then((response) => {
  273. commit('createProject', response.data)
  274. })
  275. .catch((error) => {
  276. alert(error)
  277. })
  278. },
  279. updateProject({ commit }, data) {
  280. ProjectService.updateProject(data.projectId, data)
  281. .then((response) => {
  282. commit('updateProject', response.data)
  283. })
  284. .catch((error) => {
  285. alert(error)
  286. })
  287. },
  288. deleteProject({ commit, state }, config) {
  289. for (const project of state.selected) {
  290. ProjectService.deleteProject(project.id)
  291. .then((response) => {
  292. commit('deleteProject', project.id)
  293. })
  294. .catch((error) => {
  295. alert(error)
  296. })
  297. }
  298. commit('resetSelected')
  299. },
  300. setCurrentProject({ commit }, projectId) {
  301. return ProjectService.fetchProjectById(projectId)
  302. .then((response) => {
  303. commit('setCurrent', response.data)
  304. })
  305. .catch((error) => {
  306. alert(error)
  307. })
  308. },
  309. updateCurrentProject({ commit }, data) {
  310. ProjectService.updateProject(data.projectId, data)
  311. .then((response) => {
  312. commit('setCurrent', response.data)
  313. })
  314. .catch((error) => {
  315. alert(error)
  316. })
  317. }
  318. }