Ability to collapse checklists (#9158)

* ability to collapse checklists

* typo
This commit is contained in:
Matteo Pagliazzi 2017-10-04 20:35:59 +02:00 committed by GitHub
parent c4e5633e48
commit dc62ab7577
5 changed files with 71 additions and 3 deletions

View file

@ -13,6 +13,7 @@
@import './loading-screen';
// Global styles
@import './misc';
@import './typography';
@import './markdown';
@import './form';

View file

@ -0,0 +1,17 @@
.expand-toggle:after {
display: inline-block;
width: 0;
height: 0;
content: "";
border-bottom: 4px solid transparent;
border-top: 4px solid transparent;
border-right: 4px solid transparent;
border-left: 4px solid;
}
.expand-toggle.open:after {
border-top: 4px solid;
border-right: 4px solid transparent;
border-left: 4px solid transparent;
border-bottom: 0;
}

View file

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="8" viewBox="0 0 12 8">
<path fill="#878190" fill-rule="evenodd" d="M3 6h9v2H3V6zm0-3h7v2H3V3zm0-3h5v2H3V0zM0 6h2v2H0V6zm0-3h2v2H0V3zm0-3h2v2H0V0z"/>
</svg>

After

Width:  |  Height:  |  Size: 219 B

View file

@ -17,8 +17,16 @@
h3.task-title(:class="{ 'has-notes': task.notes }", v-markdown="task.text")
.task-notes.small-text(v-markdown="task.notes")
.checklist(v-if="canViewchecklist")
.d-inline-flex
.collapse-checklist.d-flex.align-items-center.expand-toggle(
v-if="isUser",
@click="collapseChecklist(task)",
:class="{open: !task.collapseChecklist}",
)
.svg-icon(v-html="icons.checklist")
span {{ checklistProgress }}
label.custom-control.custom-checkbox.checklist-item(
v-if='!castingSpell',
v-if='!castingSpell && !task.collapseChecklist',
v-for="item in task.checklist", :class="{'checklist-item-done': item.completed}",
)
input.custom-control-input(type="checkbox", :checked="item.completed", @change="toggleChecklistItem(item)")
@ -119,6 +127,26 @@
margin-top: 8px;
}
.collapse-checklist {
padding: 2px 6px;
margin-bottom: 9px;
border-radius: 1px;
background-color: $gray-600;
font-size: 10px;
line-height: 1.2;
text-align: center;
color: $gray-200;
span {
margin: 0px 4px;
}
.svg-icon {
width: 12px;
height: 8px;
}
}
.checklist-item {
color: $gray-50;
font-size: 14px;
@ -308,6 +336,7 @@ import calendarIcon from 'assets/svg/calendar.svg';
import challengeIcon from 'assets/svg/challenge.svg';
import tagsIcon from 'assets/svg/tags.svg';
import checkIcon from 'assets/svg/check.svg';
import checklistIcon from 'assets/svg/checklist.svg';
import bPopover from 'bootstrap-vue/lib/components/popover';
import markdownDirective from 'client/directives/markdown';
import notifications from 'client/mixins/notifications';
@ -336,6 +365,7 @@ export default {
challenge: challengeIcon,
tags: tagsIcon,
check: checkIcon,
checklist: checklistIcon,
}),
};
},
@ -353,6 +383,13 @@ export default {
let userIsTaskUser = this.task.userId ? this.task.userId === this.user._id : true;
return hasChecklist && userIsTaskUser;
},
checklistProgress () {
const totalItems = this.task.checklist.length;
const completedItems = this.task.checklist.reduce((total, item) => {
return item.completed ? total + 1 : total;
}, 0);
return `${completedItems}/${totalItems}`;
},
leftControl () {
const task = this.task;
if (task.type === 'reward') return false;
@ -392,10 +429,13 @@ export default {
},
},
methods: {
...mapActions({scoreChecklistItem: 'tasks:scoreChecklistItem'}),
...mapActions({
scoreChecklistItem: 'tasks:scoreChecklistItem',
collapseChecklist: 'tasks:collapseChecklist',
}),
toggleChecklistItem (item) {
if (this.castingSpell) return;
item.completed = !item.completed;
item.completed = !item.completed; // @TODO this should go into the action?
this.scoreChecklistItem({taskId: this.task._id, itemId: item.id});
},
edit (e, task) {

View file

@ -124,6 +124,13 @@ export async function scoreChecklistItem (store, {taskId, itemId}) {
await axios.post(`/api/v3/tasks/${taskId}/checklist/${itemId}/score`);
}
export async function collapseChecklist (store, task) {
task.collapseChecklist = !task.collapseChecklist;
await axios.put(`/api/v3/tasks/${task._id}`, {
collapseChecklist: task.collapseChecklist,
});
}
export async function destroy (store, task) {
const list = store.state.tasks.data[`${task.type}s`];
const taskIndex = list.findIndex(t => t._id === task._id);