mirror of
https://github.com/sudoxnym/habitica.git
synced 2026-05-22 13:48:46 +00:00
Ability to collapse checklists (#9158)
* ability to collapse checklists * typo
This commit is contained in:
parent
c4e5633e48
commit
dc62ab7577
5 changed files with 71 additions and 3 deletions
|
|
@ -13,6 +13,7 @@
|
|||
@import './loading-screen';
|
||||
|
||||
// Global styles
|
||||
@import './misc';
|
||||
@import './typography';
|
||||
@import './markdown';
|
||||
@import './form';
|
||||
|
|
|
|||
17
website/client/assets/scss/misc.scss
Normal file
17
website/client/assets/scss/misc.scss
Normal 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;
|
||||
}
|
||||
3
website/client/assets/svg/checklist.svg
Normal file
3
website/client/assets/svg/checklist.svg
Normal 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 |
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in a new issue