1
0

Merge branch 'main' into feature/login-improvements

This commit is contained in:
kolaente
2021-12-26 12:19:44 +01:00
23 changed files with 435 additions and 295 deletions

BIN
src/assets/audio/pop.mp3 Normal file

Binary file not shown.

View File

@ -1,23 +1,24 @@
<template>
<card class="filters has-overflow">
<fancycheckbox v-model="params.filter_include_nulls">
{{ $t('filters.attributes.includeNulls') }}
</fancycheckbox>
<fancycheckbox
v-model="filters.requireAllFilters"
@change="setFilterConcat()"
>
{{ $t('filters.attributes.requireAll') }}
</fancycheckbox>
<div class="field">
<label class="label">
<fancycheckbox v-model="params.filter_include_nulls">
{{ $t('filters.attributes.includeNulls') }}
</fancycheckbox>
<fancycheckbox
v-model="filters.requireAllFilters"
@change="setFilterConcat()"
>
{{ $t('filters.attributes.requireAll') }}
</fancycheckbox>
<fancycheckbox @change="setDoneFilter" v-model="filters.done">
{{ $t('filters.attributes.showDoneTasks') }}
</label>
<div class="control">
<fancycheckbox @change="setDoneFilter" v-model="filters.done">
{{ $t('filters.attributes.showDoneTasks') }}
</fancycheckbox>
</div>
</fancycheckbox>
<fancycheckbox
v-if="!$route.name.includes('list.kanban') || !$route.name.includes('list.table')"
v-model="sortAlphabetically"
>
{{ $t('filters.attributes.sortAlphabetically') }}
</fancycheckbox>
</div>
<div class="field">
<label class="label">{{ $t('misc.search') }}</label>
@ -190,6 +191,7 @@ import NamespaceService from '@/services/namespace'
import EditLabels from '@/components/tasks/partials/editLabels.vue'
import {objectToSnakeCase} from '@/helpers/case'
import {getDefaultParams} from '@/components/tasks/mixins/taskList'
// FIXME: merge with DEFAULT_PARAMS in taskList.js
const DEFAULT_PARAMS = {
@ -220,6 +222,8 @@ const DEFAULT_FILTERS = {
namespace: '',
}
export const ALPHABETICAL_SORT = 'title'
export default {
name: 'filters',
components: {
@ -272,6 +276,18 @@ export default {
},
},
computed: {
sortAlphabetically: {
get() {
return this.params?.sort_by?.find(sortBy => sortBy === ALPHABETICAL_SORT) !== undefined
},
set(sortAlphabetically) {
this.params.sort_by = sortAlphabetically
? [ALPHABETICAL_SORT]
: getDefaultParams().sort_by
this.change()
},
},
foundLabels() {
return this.$store.getters['labels/filterLabelsByQuery'](this.labels, this.query)
},

View File

@ -44,7 +44,6 @@ export default {
params = null,
forceLoading = false,
) {
// Because this function is triggered every time on topNavigation, we're putting a condition here to only load it when we actually want to show tasks
// FIXME: This is a bit hacky -> Cleanup.
if (

View File

@ -1,11 +0,0 @@
export const playSoundWhenDoneKey = 'playSoundWhenTaskDone'
export const playPop = () => {
const enabled = localStorage.getItem(playSoundWhenDoneKey) === 'true' || localStorage.getItem(playSoundWhenDoneKey) === null
if(!enabled) {
return
}
const popSound = new Audio('/audio/pop.mp3')
popSound.play()
}

13
src/helpers/playPop.ts Normal file
View File

@ -0,0 +1,13 @@
import popSoundFile from '@/assets/audio/pop.mp3'
export const playSoundWhenDoneKey = 'playSoundWhenTaskDone'
export function playPop() {
const enabled = Boolean(localStorage.getItem(playSoundWhenDoneKey))
if(!enabled) {
return
}
const popSound = new Audio(popSoundFile)
popSound.play()
}

View File

@ -374,6 +374,7 @@
"includeNulls": "Zahrnout úkoly, které nemají nastavenou hodnotu",
"requireAll": "Vyžaduje aby všechny filtry odpovídaly, aby se úkol zobrazil",
"showDoneTasks": "Zobrazit dokončené úkoly",
"sortAlphabetically": "Řadit podle abecedy",
"enablePriority": "Povolit filtrování podle priority",
"enablePercentDone": "Povolit filtrování dle dokončenosti",
"dueDateRange": "Rozsah termínu",

View File

@ -374,6 +374,7 @@
"includeNulls": "Aufgaben ohne Werte einbeziehen",
"requireAll": "Alle Filterkriterien müssen erfüllt sein, damit eine Aufgabe angezeigt wird",
"showDoneTasks": "Erledigte Aufgaben anzeigen",
"sortAlphabetically": "Sort Alphabetically",
"enablePriority": "Filter nach Priorität aktivieren",
"enablePercentDone": "Filter nach % Erledigt aktivieren",
"dueDateRange": "Fälligkeitsbereich",

View File

@ -374,6 +374,7 @@
"includeNulls": "Uufgabe ohni Wert iihbezieh",
"requireAll": "Alli Filter mend wahr sii, demits die Uufgab ahzeigt",
"showDoneTasks": "Zeig die fertige Uufgabe",
"sortAlphabetically": "Sort Alphabetically",
"enablePriority": "Filter nach Priorität aktiviere",
"enablePercentDone": "Filter nach Prozent iihschalte",
"dueDateRange": "Fälligkeitsberiich",

View File

@ -380,6 +380,7 @@
"includeNulls": "Include Tasks which don't have a value set",
"requireAll": "Require all filters to be true for a task to show up",
"showDoneTasks": "Show Done Tasks",
"sortAlphabetically": "Sort Alphabetically",
"enablePriority": "Enable Filter By Priority",
"enablePercentDone": "Enable Filter By Percent Done",
"dueDateRange": "Due Date Range",

View File

@ -374,6 +374,7 @@
"includeNulls": "Include Tasks which don't have a value set",
"requireAll": "Require all filters to be true for a task to show up",
"showDoneTasks": "Show Done Tasks",
"sortAlphabetically": "Sort Alphabetically",
"enablePriority": "Enable Filter By Priority",
"enablePercentDone": "Enable Filter By Percent Done",
"dueDateRange": "Due Date Range",

View File

@ -374,6 +374,7 @@
"includeNulls": "Inclure les tâches sans valeurs",
"requireAll": "Exiger tous les filtres pour quune tâche saffiche",
"showDoneTasks": "Afficher les tâches terminées",
"sortAlphabetically": "Sort Alphabetically",
"enablePriority": "Activer le filtre par priorité",
"enablePercentDone": "Par % dachèvement",
"dueDateRange": "Plage de dates déchéance",

View File

@ -374,6 +374,7 @@
"includeNulls": "Includi attività che non hanno un valore impostato",
"requireAll": "Tutti i filtri devono essere veri affinché l'attività venga mostrata",
"showDoneTasks": "Mostra Attività Fatte",
"sortAlphabetically": "Sort Alphabetically",
"enablePriority": "Abilita Filtro Per Priorità",
"enablePercentDone": "Abilitare Filtro Per Percentuale Fatta",
"dueDateRange": "Intervallo Data Di Scadenza",

View File

@ -374,6 +374,7 @@
"includeNulls": "Include Tasks which don't have a value set",
"requireAll": "Require all filters to be true for a task to show up",
"showDoneTasks": "Show Done Tasks",
"sortAlphabetically": "Sort Alphabetically",
"enablePriority": "Enable Filter By Priority",
"enablePercentDone": "Enable Filter By Percent Done",
"dueDateRange": "Due Date Range",

View File

@ -374,6 +374,7 @@
"includeNulls": "Include Tasks which don't have a value set",
"requireAll": "Require all filters to be true for a task to show up",
"showDoneTasks": "Show Done Tasks",
"sortAlphabetically": "Sort Alphabetically",
"enablePriority": "Enable Filter By Priority",
"enablePercentDone": "Enable Filter By Percent Done",
"dueDateRange": "Due Date Range",

View File

@ -374,6 +374,7 @@
"includeNulls": "Include Tasks which don't have a value set",
"requireAll": "Require all filters to be true for a task to show up",
"showDoneTasks": "Show Done Tasks",
"sortAlphabetically": "Sort Alphabetically",
"enablePriority": "Enable Filter By Priority",
"enablePercentDone": "Enable Filter By Percent Done",
"dueDateRange": "Due Date Range",

View File

@ -374,6 +374,7 @@
"includeNulls": "Include Tasks which don't have a value set",
"requireAll": "Require all filters to be true for a task to show up",
"showDoneTasks": "Show Done Tasks",
"sortAlphabetically": "Sort Alphabetically",
"enablePriority": "Enable Filter By Priority",
"enablePercentDone": "Enable Filter By Percent Done",
"dueDateRange": "Due Date Range",

View File

@ -374,6 +374,7 @@
"includeNulls": "Включать задачи, у которых не установлено значение",
"requireAll": "Для отображения задачи требовать истинность всех фильтров",
"showDoneTasks": "Показывать завершённые задачи",
"sortAlphabetically": "Sort Alphabetically",
"enablePriority": "Вкл. фильтр по приоритету",
"enablePercentDone": "По % завершения",
"dueDateRange": "Диапазон срока",

View File

@ -374,6 +374,7 @@
"includeNulls": "Include Tasks which don't have a value set",
"requireAll": "Require all filters to be true for a task to show up",
"showDoneTasks": "Show Done Tasks",
"sortAlphabetically": "Sort Alphabetically",
"enablePriority": "Enable Filter By Priority",
"enablePercentDone": "Enable Filter By Percent Done",
"dueDateRange": "Due Date Range",

View File

@ -374,6 +374,7 @@
"includeNulls": "Include Tasks which don't have a value set",
"requireAll": "Require all filters to be true for a task to show up",
"showDoneTasks": "Show Done Tasks",
"sortAlphabetically": "Sort Alphabetically",
"enablePriority": "Enable Filter By Priority",
"enablePercentDone": "Enable Filter By Percent Done",
"dueDateRange": "Due Date Range",

View File

@ -36,7 +36,7 @@
"password": "Mật khẩu",
"passwordRepeat": "Nhập lại mật khẩu",
"passwordPlaceholder": "ví dụ: •••••••••••",
"forgotPassword": "Forgot your password?",
"forgotPassword": "Bạn quên mật khẩu?",
"resetPassword": "Reset mật khẩu của bạn",
"resetPasswordAction": "Gửi cho tôi liên kết reset mật khẩu",
"resetPasswordSuccess": "Kiểm tra hộp thư của bạn! Bạn sẽ nhận một e-mail với hướng dẫn reset mật khẩu của mình.",
@ -103,7 +103,7 @@
"title": "Avatar",
"initials": "Chữ cái viết tắt",
"gravatar": "Gravatar",
"marble": "Marble",
"marble": "Cẩm thạch",
"upload": "Tải lên",
"uploadAvatar": "Tải lên Avatar",
"statusUpdateSuccess": "Avatar đã được cập nhật!",
@ -374,6 +374,7 @@
"includeNulls": "Bao gồm các Công việc không có bộ giá trị",
"requireAll": "Yêu cầu tất cả các bộ lọc phải đúng để một công việc được hiển thị",
"showDoneTasks": "Hiển thị các công việc đã hoàn thành",
"sortAlphabetically": "Xếp theo bảng chữ cái",
"enablePriority": "Bật Bộ lọc theo mức độ ưu tiên",
"enablePercentDone": "Bật Bộ lọc theo tỉ lệ % hoàn thành",
"dueDateRange": "Phạm vi ngày đến hạn",
@ -474,8 +475,8 @@
"download": "Tải về",
"showMenu": "Hiển thị menu",
"hideMenu": "Ẩn menu",
"forExample": "For example:",
"welcomeBack": "Welcome Back!"
"forExample": "Ví dụ:",
"welcomeBack": "Mừng quá! Bạn trở lại rồi."
},
"input": {
"resetColor": "Đặt lại màu",
@ -725,8 +726,8 @@
"dateCurrentYear": "sẽ sử dụng năm hiện tại",
"dateNth": "sẽ sử dụng ngày {day} của tháng hiện tại",
"dateTime": "Kết hợp bất kì đinh dạng ngày với \"{time}\" (hoặc {timePM}) để thiết lập thời gian.",
"repeats": "Repeating tasks",
"repeatsDescription": "To set a task as repeating in an interval, simply add '{suffix}' to the task text. The amount needs to be a number and can be omitted to use just the type (see examples)."
"repeats": "Công việc định kỳ",
"repeatsDescription": "Để cài một công việc được lặp lại trong các khoảng thời gian, chỉ cần thêm '{suffix}' vào văn bản công việc. Số lượng phải là một số và có thể được bỏ qua để chỉ sử dụng loại (xem ví dụ)."
}
},
"team": {
@ -813,7 +814,7 @@
"url": "URL Vikunja",
"urlPlaceholder": "ví dụ: https://localhost:3456",
"change": "thay đổi",
"use": "Using Vikunja installation at {0}",
"use": "Sử dụng cài đặt Vikunja tại {0}",
"error": "Không thể tìm thấy hoặc sử dụng cài đặt Vikunja tại \"{domain}\". Vui lòng thử một url khác.",
"success": "Sử dụng cài đặt Vikunja tại \"{domain}\".",
"urlRequired": "Cần có một url."
@ -907,7 +908,7 @@
"5010": "Team này không có quyền bước vào góc làm việc đó.",
"5011": "Người này đã có quyền bước vào góc làm việc đó.",
"5012": "Góc làm việc đã được lưu trữ nên chỉ có thể vào đó để đọc.",
"6001": "The team name cannot be empty.",
"6001": "Tên của Team không được để trống.",
"6002": "Team không tồn tại.",
"6004": "Team đã có quyền bước vào góc làm việc và xem danh sách.",
"6005": "Người này đã là thành viên của Team đó rồi.",

View File

@ -81,7 +81,7 @@
:disabled="!canWrite"
item-key="id"
:component-data="{
class: { 'dragging-disabled': !canWrite },
class: { 'dragging-disabled': !canWrite || isAlphabeticalSorting },
}"
>
<template #item="{element: t}">
@ -148,6 +148,7 @@ import {HAS_TASKS} from '@/store/mutation-types'
import Nothing from '@/components/misc/nothing.vue'
import Pagination from '@/components/misc/pagination.vue'
import Popup from '@/components/misc/popup'
import { ALPHABETICAL_SORT } from '@/components/list/partials/filters'
import draggable from 'vuedraggable'
import {calculateItemPosition} from '../../../helpers/calculateItemPosition'
@ -206,6 +207,9 @@ export default {
saveListView(this.$route.params.listId, this.$route.name)
},
computed: {
isAlphabeticalSorting() {
return this.params.sort_by.find( sortBy => sortBy === ALPHABETICAL_SORT ) !== undefined
},
firstNewPosition() {
if (this.tasks.length === 0) {
return 0
@ -254,12 +258,18 @@ export default {
focusNewTaskInput() {
this.$refs.newTaskInput.$refs.newTaskInput.focus()
},
updateTaskList(task) {
const tasks = [
task,
...this.tasks,
]
this.tasks = tasks
updateTaskList( task ) {
if ( this.isAlphabeticalSorting ) {
// reload tasks with current filter and sorting
this.loadTasks(1, undefined, undefined, true)
}
else {
this.tasks = [
task,
...this.tasks,
]
}
this.$store.commit(HAS_TASKS, true)
},
editTask(id) {