Browse Source

Implement label creation/deletion button

pull/341/head
Hironsan 5 years ago
parent
commit
8ce5f87d5d
13 changed files with 275 additions and 190 deletions
  1. 1
      frontend/api/routes/labels.js
  2. 30
      frontend/components/containers/LabelCreationButton.vue
  3. 35
      frontend/components/containers/LabelDeletionButton.vue
  4. 2
      frontend/components/containers/MemberAdditionButton.vue
  5. 24
      frontend/components/containers/MemberDeletionButton.vue
  6. 2
      frontend/components/containers/ProjectCreationButton.vue
  7. 24
      frontend/components/containers/ProjectDeletionButton.vue
  8. 80
      frontend/components/organisms/ConfirmDialog.vue
  9. 99
      frontend/components/organisms/LabelCreationForm.vue
  10. 47
      frontend/components/organisms/MemberDeletionForm.vue
  11. 47
      frontend/components/organisms/ProjectDeletionForm.vue
  12. 68
      frontend/pages/projects/_id/labels/index.vue
  13. 6
      frontend/store/labels.js

1
frontend/api/routes/labels.js

@ -23,6 +23,7 @@ router.post('/', (req, res) => {
background_color: req.body.background_color, background_color: req.body.background_color,
text_color: '#ffffff' text_color: '#ffffff'
} }
db.push(label)
res.json(label) res.json(label)
}) })

30
frontend/components/containers/LabelCreationButton.vue

@ -0,0 +1,30 @@
<template>
<base-modal
text="Create"
:is-create="true"
>
<template v-slot="slotProps">
<label-creation-form
:create-label="createLabel"
@close="slotProps.close"
/>
</template>
</base-modal>
</template>
<script>
import { mapActions } from 'vuex'
import BaseModal from '@/components/molecules/BaseModal'
import LabelCreationForm from '@/components/organisms/LabelCreationForm'
export default {
components: {
BaseModal,
LabelCreationForm
},
methods: {
...mapActions('labels', ['createLabel'])
}
}
</script>

35
frontend/components/containers/LabelDeletionButton.vue

@ -0,0 +1,35 @@
<template>
<confirm-dialog
title="Delete Label"
message="Are you sure you want to remove these labels from this project?"
item-key="text"
:disabled="!isLabelSelected"
:items="selected"
@ok="handleDeleteLabel()"
/>
</template>
<script>
import { mapState, mapGetters, mapActions } from 'vuex'
import ConfirmDialog from '@/components/organisms/ConfirmDialog'
export default {
components: {
ConfirmDialog
},
computed: {
...mapState('labels', ['selected']),
...mapGetters('labels', ['isLabelSelected'])
},
methods: {
...mapActions('labels', ['deleteLabel']),
handleDeleteLabel() {
const projectId = this.$route.params.id
this.deleteLabel(projectId)
}
}
}
</script>

2
frontend/components/containers/MemberAdditionButton.vue

@ -1,6 +1,6 @@
<template> <template>
<base-modal <base-modal
text="Add Member"
text="Add"
:is-create="true" :is-create="true"
> >
<template v-slot="slotProps"> <template v-slot="slotProps">

24
frontend/components/containers/MemberDeletionButton.vue

@ -1,27 +1,21 @@
<template> <template>
<base-modal
text="Remove"
<confirm-dialog
title="Remove Member"
message="Are you sure you want to remove these members?"
item-key="username"
:disabled="!isMemberSelected" :disabled="!isMemberSelected"
>
<template v-slot="slotProps">
<member-deletion-form
:selected="selected"
@remove="handleRemoveMember(); slotProps.close()"
@close="slotProps.close"
/>
</template>
</base-modal>
:items="selected"
@ok="handleRemoveMember()"
/>
</template> </template>
<script> <script>
import { mapState, mapGetters, mapActions } from 'vuex' import { mapState, mapGetters, mapActions } from 'vuex'
import BaseModal from '@/components/molecules/BaseModal'
import MemberDeletionForm from '@/components/organisms/MemberDeletionForm'
import ConfirmDialog from '@/components/organisms/ConfirmDialog'
export default { export default {
components: { components: {
BaseModal,
MemberDeletionForm
ConfirmDialog
}, },
computed: { computed: {

2
frontend/components/containers/ProjectCreationButton.vue

@ -1,6 +1,6 @@
<template> <template>
<base-modal <base-modal
text="Add Project"
text="Create"
:is-create="true" :is-create="true"
> >
<template v-slot="slotProps"> <template v-slot="slotProps">

24
frontend/components/containers/ProjectDeletionButton.vue

@ -1,27 +1,21 @@
<template> <template>
<base-modal
text="Delete"
<confirm-dialog
title="Delete Project"
message="Are you sure you want to delete these projects?"
item-key="name"
:disabled="!isProjectSelected" :disabled="!isProjectSelected"
>
<template v-slot="slotProps">
<project-deletion-form
:selected="selected"
@delete="handleDeleteProject(); slotProps.close()"
@close="slotProps.close"
/>
</template>
</base-modal>
:items="selected"
@ok="handleDeleteProject"
/>
</template> </template>
<script> <script>
import { mapState, mapGetters } from 'vuex' import { mapState, mapGetters } from 'vuex'
import BaseModal from '@/components/molecules/BaseModal'
import ProjectDeletionForm from '@/components/organisms/ProjectDeletionForm'
import ConfirmDialog from '@/components/organisms/ConfirmDialog'
export default { export default {
components: { components: {
BaseModal,
ProjectDeletionForm
ConfirmDialog
}, },
computed: { computed: {

80
frontend/components/organisms/ConfirmDialog.vue

@ -0,0 +1,80 @@
<template>
<base-modal
text="Delete"
:disabled="disabled"
>
<template v-slot="slotProps">
<base-card
:title="title"
:agree-text="buttonTrueText"
:cancel-text="buttonFalseText"
@agree="ok(); slotProps.close()"
@cancel="slotProps.close"
>
<template #content>
{{ message }}
<v-list dense>
<v-list-item v-for="(item, i) in items" :key="i">
<v-list-item-content>
<v-list-item-title>{{ item[itemKey] }}</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list>
</template>
</base-card>
</template>
</base-modal>
</template>
<script>
import BaseCard from '@/components/molecules/BaseCard'
import BaseModal from '@/components/molecules/BaseModal'
export default {
components: {
BaseCard,
BaseModal
},
props: {
title: {
type: String,
default: '',
required: true
},
message: {
type: String,
default: '',
required: true
},
items: {
type: Array,
default: () => [],
required: true
},
itemKey: {
type: String,
default: '',
required: true
},
disabled: {
type: Boolean,
default: false
},
buttonTrueText: {
type: String,
default: 'Yes'
},
buttonFalseText: {
type: String,
default: 'Cancel'
}
},
methods: {
ok() {
this.$emit('ok')
}
}
}
</script>

99
frontend/components/organisms/LabelCreationForm.vue

@ -0,0 +1,99 @@
<template>
<base-card
title="Create Label"
agree-text="Create"
cancel-text="Cancel"
:disabled="!valid"
@agree="create"
@cancel="cancel"
>
<template #content>
<v-form
ref="form"
v-model="valid"
>
<v-text-field
v-model="labelName"
:rules="nameRules"
label="Label name"
prepend-icon="label"
/>
<v-select
v-model="suffixKey"
:items="keys"
label="Key"
prepend-icon="mdi-keyboard"
/>
<v-color-picker
v-model="color"
:rules="colorRules"
show-swatches
hide-mode-switch
width="800"
mode="hexa"
class="ma-2"
/>
</v-form>
</template>
</base-card>
</template>
<script>
import BaseCard from '@/components/molecules/BaseCard'
export default {
components: {
BaseCard
},
props: {
createLabel: {
type: Function,
default: () => {},
required: true
},
keys: {
type: Array,
default: () => 'abcdefghijklmnopqrstuvwxyz'.split('')
}
},
data() {
return {
valid: false,
labelName: '',
suffixKey: '',
color: '',
nameRules: [
v => !!v || 'Label name is required',
v =>
(v && v.length <= 30) || 'Label name must be less than 30 characters'
],
colorRules: [
v => !!v || 'Color is required'
]
}
},
methods: {
cancel() {
this.$emit('close')
},
validate() {
return this.$refs.form.validate()
},
reset() {
this.$refs.form.reset()
},
create() {
if (this.validate()) {
this.createLabel({
text: this.labelName,
suffix_key: this.suffixKey,
background_color: this.color
})
this.reset()
this.cancel()
}
}
}
}
</script>

47
frontend/components/organisms/MemberDeletionForm.vue

@ -1,47 +0,0 @@
<template>
<base-card
title="Remove Member"
agree-text="Yes, remove"
cancel-text="Cancel"
@agree="removeMember"
@cancel="cancel"
>
<template #content>
Are you sure you want to remove these members?
<v-list dense>
<v-list-item v-for="(item, i) in selected" :key="i">
<v-list-item-content>
<v-list-item-title>{{ item.username }}</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list>
</template>
</base-card>
</template>
<script>
import BaseCard from '@/components/molecules/BaseCard'
export default {
components: {
BaseCard
},
props: {
selected: {
type: Array,
default: () => [],
required: true
}
},
methods: {
cancel() {
this.$emit('close')
},
removeMember() {
this.$emit('remove')
}
}
}
</script>

47
frontend/components/organisms/ProjectDeletionForm.vue

@ -1,47 +0,0 @@
<template>
<base-card
title="Delete Project"
agree-text="Yes, delete"
cancel-text="Cancel"
@agree="deleteProject"
@cancel="cancel"
>
<template #content>
Are you sure you want to delete 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>
</template>
<script>
import BaseCard from '@/components/molecules/BaseCard'
export default {
components: {
BaseCard
},
props: {
selected: {
type: Array,
default: () => [],
required: true
}
},
methods: {
cancel() {
this.$emit('close')
},
deleteProject() {
this.$emit('delete')
}
}
}
</script>

68
frontend/pages/projects/_id/labels/index.vue

@ -1,78 +1,24 @@
<template> <template>
<v-card> <v-card>
<v-card-title> <v-card-title>
<!--
<member-addition-button />
<member-deletion-button />
-->
<label-creation-button />
<label-deletion-button />
</v-card-title> </v-card-title>
<label-list /> <label-list />
</v-card> </v-card>
<!--
<v-content>
<v-container
fluid
fill-height
>
<v-layout
justify-center
>
<v-flex>
<v-card>
<v-card-title>
<Modal
ref="childDialogue"
:title="addModal.title"
:button="addModal.button"
>
<v-text-field
label="Label name"
prepend-icon="label"
/>
<v-select
:items="keys"
label="Key"
prepend-icon="mdi-keyboard"
/>
<v-color-picker
v-model="color"
show-swatches
hide-mode-switch
width="800"
:mode.sync="mode"
class="ma-2"
/>
</Modal>
<Modal
ref="removeDialogue"
:title="removeModal.title"
:button="removeModal.button"
>
Are you sure you want to remove these labels from this project?
<v-list dense>
<v-list-item v-for="(label, i) in selected" :key="i">
<v-list-item-content>
<v-list-item-title>{{ label.name }}</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list>
</Modal>
</v-card-title>
</v-card>
</v-flex>
</v-layout>
</v-container>
</v-content>
-->
</template> </template>
<script> <script>
import LabelList from '@/components/containers/LabelList' import LabelList from '@/components/containers/LabelList'
import LabelCreationButton from '@/components/containers/LabelCreationButton'
import LabelDeletionButton from '@/components/containers/LabelDeletionButton'
export default { export default {
layout: 'project', layout: 'project',
components: { components: {
LabelList
LabelList,
LabelCreationButton,
LabelDeletionButton
}, },
validate({ params }) { validate({ params }) {
return /^\d+$/.test(params.id) return /^\d+$/.test(params.id)

6
frontend/store/labels.js

@ -43,8 +43,8 @@ export const actions = {
alert(error) alert(error)
}) })
}, },
addMember({ commit }, data) {
LabelService.addLabel(data.projectId, data.labelId, data)
createLabel({ commit }, data) {
LabelService.addLabel(data.projectId, data)
.then((response) => { .then((response) => {
commit('addLabel', response) commit('addLabel', response)
}) })
@ -61,7 +61,7 @@ export const actions = {
alert(error) alert(error)
}) })
}, },
removeLabel({ commit, state }, projectId) {
deleteLabel({ commit, state }, projectId) {
for (const label of state.selected) { for (const label of state.selected) {
LabelService.deleteLabel(projectId, label.id) LabelService.deleteLabel(projectId, label.id)
.then((response) => { .then((response) => {

Loading…
Cancel
Save