mirror of https://github.com/doccano/doccano.git
Hironsan
5 years ago
11 changed files with 406 additions and 192 deletions
Split View
Diff Options
-
1frontend/api/routes/projects.js
-
63frontend/components/BaseCard.vue
-
104frontend/components/FormProjectCreation.vue
-
9frontend/components/containers/ProjectCreationButton.vue
-
45frontend/components/containers/ProjectList.vue
-
37frontend/components/organisms/ProjectCreationButton.vue
-
63frontend/components/organisms/ProjectDeletionButton.vue
-
57frontend/components/organisms/ProjectList.vue
-
15frontend/layouts/projects.vue
-
143frontend/pages/projects/index.vue
-
61frontend/store/ProjectList.js
@ -0,0 +1,63 @@ |
|||
<template> |
|||
<v-card> |
|||
<v-card-title class="grey lighten-2"> |
|||
{{ title }} |
|||
</v-card-title> |
|||
<v-container grid-list-sm> |
|||
<v-layout wrap> |
|||
<v-flex xs12> |
|||
<slot name="content" /> |
|||
</v-flex> |
|||
</v-layout> |
|||
</v-container> |
|||
<v-card-actions> |
|||
<v-spacer /> |
|||
<v-btn |
|||
class="text-capitalize" |
|||
text |
|||
color="primary" |
|||
@click="cancel" |
|||
> |
|||
Cancel |
|||
</v-btn> |
|||
<v-btn |
|||
:disabled="disabled" |
|||
class="text-none" |
|||
text |
|||
@click="agree" |
|||
> |
|||
{{ button }} |
|||
</v-btn> |
|||
</v-card-actions> |
|||
</v-card> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
props: { |
|||
title: { |
|||
type: String, |
|||
default: '', |
|||
required: true |
|||
}, |
|||
button: { |
|||
type: String, |
|||
default: '', |
|||
required: true |
|||
}, |
|||
disabled: { |
|||
type: Boolean, |
|||
default: false, |
|||
required: true |
|||
} |
|||
}, |
|||
methods: { |
|||
cancel() { |
|||
this.$emit('cancel') |
|||
}, |
|||
agree() { |
|||
this.$emit('agree') |
|||
} |
|||
} |
|||
} |
|||
</script> |
@ -0,0 +1,9 @@ |
|||
<template> |
|||
|
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
|
|||
} |
|||
</script> |
@ -0,0 +1,45 @@ |
|||
<template> |
|||
<project-list :headers="headers" :projects="projects" :selected="selected" @update="update" /> |
|||
</template> |
|||
|
|||
<script> |
|||
import { mapState } from 'vuex' |
|||
import ProjectList from '@/components/organisms/ProjectList' |
|||
|
|||
export default { |
|||
components: { |
|||
ProjectList |
|||
}, |
|||
data: () => ({ |
|||
headers: [ |
|||
{ |
|||
text: 'Name', |
|||
align: 'left', |
|||
value: 'name' |
|||
}, |
|||
{ |
|||
text: 'Description', |
|||
value: 'description' |
|||
}, |
|||
{ |
|||
text: 'Type', |
|||
value: 'project_type' |
|||
} |
|||
] |
|||
}), |
|||
|
|||
computed: { |
|||
...mapState('ProjectList', ['projects', 'selected']) |
|||
}, |
|||
|
|||
async created() { |
|||
await this.$store.dispatch('ProjectList/getProjectList') |
|||
}, |
|||
|
|||
methods: { |
|||
update(selected) { |
|||
this.$store.commit('ProjectList/updateSelected', selected) |
|||
} |
|||
} |
|||
} |
|||
</script> |
@ -0,0 +1,37 @@ |
|||
<template> |
|||
<div> |
|||
<v-btn |
|||
class="mb-2 text-capitalize" |
|||
color="primary" |
|||
@click="dialog=true" |
|||
> |
|||
Add Project |
|||
</v-btn> |
|||
<v-dialog |
|||
v-model="dialog" |
|||
width="800px" |
|||
> |
|||
<form-project-creation @cancel="dialog=false" @create-project="createProject" /> |
|||
</v-dialog> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import FormProjectCreation from '@/components/FormProjectCreation' |
|||
|
|||
export default { |
|||
components: { |
|||
FormProjectCreation |
|||
}, |
|||
data: () => ({ |
|||
dialog: false |
|||
}), |
|||
|
|||
methods: { |
|||
createProject(project) { |
|||
this.$store.dispatch('ProjectList/createProject', project) |
|||
this.dialog = false |
|||
} |
|||
} |
|||
} |
|||
</script> |
@ -0,0 +1,63 @@ |
|||
<template> |
|||
<div> |
|||
<v-btn |
|||
class="mb-2 ml-2 text-capitalize" |
|||
outlined |
|||
:disabled="selected.length === 0" |
|||
@click="dialog=true" |
|||
> |
|||
Remove |
|||
</v-btn> |
|||
|
|||
<v-dialog |
|||
v-model="dialog" |
|||
width="800px" |
|||
> |
|||
<base-card |
|||
title="Delete Project" |
|||
button="Yes, delete" |
|||
:disabled="disabled" |
|||
@cancel="dialog=false" |
|||
@agree="deleteProject" |
|||
> |
|||
<template #content> |
|||
Are you sure you want to remove these projects? |
|||
<v-list dense> |
|||
<v-list-item v-for="(item, i) in selected" :key="i"> |
|||
<v-list-item-content> |
|||
<v-list-item-title>{{ item.name }}</v-list-item-title> |
|||
</v-list-item-content> |
|||
</v-list-item> |
|||
</v-list> |
|||
</template> |
|||
</base-card> |
|||
</v-dialog> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import { mapState } from 'vuex' |
|||
import BaseCard from '@/components/BaseCard' |
|||
|
|||
export default { |
|||
components: { |
|||
BaseCard |
|||
}, |
|||
data: () => ({ |
|||
dialog: false, |
|||
disabled: false |
|||
}), |
|||
|
|||
computed: { |
|||
...mapState('ProjectList', ['projects', 'selected']) |
|||
}, |
|||
|
|||
methods: { |
|||
deleteProject() { |
|||
this.$store.dispatch('ProjectList/deleteProject') |
|||
// this.$emit('remove') |
|||
this.dialog = false |
|||
} |
|||
} |
|||
} |
|||
</script> |
@ -0,0 +1,57 @@ |
|||
<template> |
|||
<v-data-table |
|||
:value="selected" |
|||
:headers="headers" |
|||
:items="projects" |
|||
:search="search" |
|||
item-key="id" |
|||
show-select |
|||
@input="update" |
|||
> |
|||
<template v-slot:top> |
|||
<v-text-field |
|||
v-model="search" |
|||
prepend-inner-icon="search" |
|||
label="Search" |
|||
single-line |
|||
hide-details |
|||
filled |
|||
/> |
|||
</template> |
|||
<template v-slot:item.name="{ item }"> |
|||
<nuxt-link :to="`/projects/${item.id}`"> |
|||
<span>{{ item.name }}</span> |
|||
</nuxt-link> |
|||
</template> |
|||
</v-data-table> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
props: { |
|||
headers: { |
|||
type: Array, |
|||
default: () => [], |
|||
required: true |
|||
}, |
|||
projects: { |
|||
type: Array, |
|||
default: () => [], |
|||
required: true |
|||
}, |
|||
selected: { |
|||
type: Array, |
|||
default: () => [], |
|||
required: true |
|||
} |
|||
}, |
|||
data: () => ({ |
|||
search: '' |
|||
}), |
|||
methods: { |
|||
update(selected) { |
|||
this.$emit('update', selected) |
|||
} |
|||
} |
|||
} |
|||
</script> |
@ -1,141 +1,24 @@ |
|||
<template> |
|||
<v-content> |
|||
<v-container |
|||
fluid |
|||
fill-height |
|||
> |
|||
<v-layout |
|||
justify-center |
|||
> |
|||
<v-flex> |
|||
<v-card> |
|||
<v-card-title> |
|||
<v-btn |
|||
class="mb-2 text-capitalize" |
|||
color="primary" |
|||
@click="dialog=true" |
|||
> |
|||
Add Project |
|||
</v-btn> |
|||
<v-dialog |
|||
v-model="dialog" |
|||
width="800px" |
|||
> |
|||
<form-project-creation @cancel="dialog=false" @create-project="createProject" /> |
|||
</v-dialog> |
|||
<v-btn |
|||
class="mb-2 ml-2 text-capitalize" |
|||
outlined |
|||
:disabled="selected.length === 0" |
|||
@click="openRemoveModal" |
|||
> |
|||
Remove |
|||
</v-btn> |
|||
<Modal |
|||
ref="removeDialogue" |
|||
:title="removeModal.title" |
|||
:button="removeModal.button" |
|||
@agree="deleteProject" |
|||
> |
|||
Are you sure you want to remove these projects? |
|||
<v-list dense> |
|||
<v-list-item v-for="(item, i) in selected" :key="i"> |
|||
<v-list-item-content> |
|||
<v-list-item-title>{{ item.name }}</v-list-item-title> |
|||
</v-list-item-content> |
|||
</v-list-item> |
|||
</v-list> |
|||
</Modal> |
|||
</v-card-title> |
|||
<v-data-table |
|||
v-model="selected" |
|||
:headers="headers" |
|||
:items="projects" |
|||
:search="search" |
|||
item-key="id" |
|||
show-select |
|||
> |
|||
<template v-slot:top> |
|||
<v-text-field |
|||
v-model="search" |
|||
prepend-inner-icon="search" |
|||
label="Search" |
|||
single-line |
|||
hide-details |
|||
filled |
|||
/> |
|||
</template> |
|||
<template v-slot:item.name="{ item }"> |
|||
<nuxt-link :to="`/projects/${item.id}`"> |
|||
<span>{{ item.name }}</span> |
|||
</nuxt-link> |
|||
</template> |
|||
</v-data-table> |
|||
</v-card> |
|||
</v-flex> |
|||
</v-layout> |
|||
</v-container> |
|||
</v-content> |
|||
<v-card> |
|||
<v-card-title> |
|||
<project-creation-button /> |
|||
<project-deletion-button /> |
|||
</v-card-title> |
|||
<project-list /> |
|||
</v-card> |
|||
</template> |
|||
|
|||
<script> |
|||
import Modal from '~/components/Modal' |
|||
import FormProjectCreation from '~/components/FormProjectCreation' |
|||
import ProjectService from '~/services/project.service' |
|||
import ProjectList from '@/components/containers/ProjectList' |
|||
import ProjectCreationButton from '@/components/organisms/ProjectCreationButton' |
|||
import ProjectDeletionButton from '@/components/organisms/ProjectDeletionButton' |
|||
|
|||
export default { |
|||
layout: 'projects', |
|||
components: { |
|||
Modal, |
|||
FormProjectCreation |
|||
}, |
|||
data: () => ({ |
|||
dialog: false, |
|||
search: '', |
|||
selected: [], |
|||
selectedUser: null, |
|||
projects: [], |
|||
removeModal: { |
|||
title: 'Remove Project', |
|||
button: 'Yes, remove' |
|||
}, |
|||
headers: [ |
|||
{ |
|||
text: 'Name', |
|||
align: 'left', |
|||
value: 'name' |
|||
}, |
|||
{ |
|||
text: 'Description', |
|||
value: 'description' |
|||
}, |
|||
{ |
|||
text: 'Type', |
|||
value: 'project_type' |
|||
} |
|||
] |
|||
}), |
|||
|
|||
async created() { |
|||
this.projects = await ProjectService.getProjectList() |
|||
}, |
|||
|
|||
methods: { |
|||
createProject(project) { |
|||
this.projects.unshift(project) |
|||
this.dialog = false |
|||
}, |
|||
async deleteProject() { |
|||
// Todo: bulk delete. |
|||
for (const project of this.selected) { |
|||
await ProjectService.deleteProject(project.id) |
|||
this.projects = this.projects.filter(item => item.id !== project.id) |
|||
} |
|||
this.selected = [] |
|||
}, |
|||
openRemoveModal() { |
|||
this.$refs.removeDialogue.open() |
|||
} |
|||
ProjectList, |
|||
ProjectCreationButton, |
|||
ProjectDeletionButton |
|||
} |
|||
} |
|||
</script> |
@ -0,0 +1,61 @@ |
|||
import ProjectService from '@/services/project.service' |
|||
|
|||
export default { |
|||
namespaced: true, |
|||
|
|||
state: () => ({ |
|||
projects: [], |
|||
selected: [] |
|||
}), |
|||
|
|||
mutations: { |
|||
setProjectList(state, payload) { |
|||
state.projects = payload |
|||
}, |
|||
createProject(state, project) { |
|||
state.projects.unshift(project) |
|||
}, |
|||
deleteProject(state, projectId) { |
|||
state.projects = state.projects.filter(item => item.id !== projectId) |
|||
}, |
|||
updateSelected(state, selected) { |
|||
state.selected = selected |
|||
}, |
|||
resetSelected(state) { |
|||
state.selected = [] |
|||
} |
|||
}, |
|||
|
|||
actions: { |
|||
getProjectList(context, config) { |
|||
return ProjectService.getProjectList() |
|||
.then((response) => { |
|||
context.commit('setProjectList', response) |
|||
}) |
|||
.catch((error) => { |
|||
alert(error) |
|||
}) |
|||
}, |
|||
createProject({ commit }, project) { |
|||
ProjectService.createProject(project) |
|||
.then((response) => { |
|||
commit('createProject', response) |
|||
}) |
|||
.catch((error) => { |
|||
alert(error) |
|||
}) |
|||
}, |
|||
deleteProject({ commit, state }, config) { |
|||
for (const project of state.selected) { |
|||
ProjectService.deleteProject(project.id) |
|||
.then((response) => { |
|||
commit('deleteProject', project.id) |
|||
}) |
|||
.catch((error) => { |
|||
alert(error) |
|||
}) |
|||
} |
|||
commit('resetSelected') |
|||
} |
|||
} |
|||
} |
Write
Preview
Loading…
Cancel
Save