Merge branch 'main' into feature/login-improvements
This commit is contained in:
BIN
src/assets/audio/pop.mp3
Normal file
BIN
src/assets/audio/pop.mp3
Normal file
Binary file not shown.
@ -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)
|
||||
},
|
||||
|
@ -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 (
|
||||
|
@ -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
13
src/helpers/playPop.ts
Normal 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()
|
||||
}
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -374,6 +374,7 @@
|
||||
"includeNulls": "Inclure les tâches sans valeurs",
|
||||
"requireAll": "Exiger tous les filtres pour qu’une tâche s’affiche",
|
||||
"showDoneTasks": "Afficher les tâches terminées",
|
||||
"sortAlphabetically": "Sort Alphabetically",
|
||||
"enablePriority": "Activer le filtre par priorité",
|
||||
"enablePercentDone": "Par % d’achèvement",
|
||||
"dueDateRange": "Plage de dates d’échéance",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -374,6 +374,7 @@
|
||||
"includeNulls": "Включать задачи, у которых не установлено значение",
|
||||
"requireAll": "Для отображения задачи требовать истинность всех фильтров",
|
||||
"showDoneTasks": "Показывать завершённые задачи",
|
||||
"sortAlphabetically": "Sort Alphabetically",
|
||||
"enablePriority": "Вкл. фильтр по приоритету",
|
||||
"enablePercentDone": "По % завершения",
|
||||
"dueDateRange": "Диапазон срока",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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.",
|
||||
|
@ -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) {
|
||||
|
Reference in New Issue
Block a user