Compare commits

..

15 Commits

Author SHA1 Message Date
70a50ca1c2 chore(deps): update typescript-eslint monorepo to v5.3.1 (#962)
Reviewed-on: vikunja/frontend#962
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-11-09 07:16:11 +00:00
99d38e1f8e chore(deps): update dependency vue-tsc to v0.29.2 (#963)
Reviewed-on: vikunja/frontend#963
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-11-09 07:15:08 +00:00
00be1d4095 chore(deps): update dependency vue-tsc to v0.29.0 (#960)
Reviewed-on: vikunja/frontend#960
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-11-07 16:40:32 +00:00
04a971e767 chore(deps): update dependency eslint to v8.2.0 (#959)
Reviewed-on: vikunja/frontend#959
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-11-06 00:38:09 +00:00
917006b69f fix(deps): update sentry-javascript monorepo to v6.14.1 (#958)
Reviewed-on: vikunja/frontend#958
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-11-05 16:32:20 +00:00
a87d5836c1 chore(deps): pin dependency vue-tsc to 0.28.10 (#955)
Reviewed-on: vikunja/frontend#955
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-11-04 22:32:43 +00:00
dpschen
e23f3c2570 feat: add vue-tsc (#949)
Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Reviewed-on: vikunja/frontend#949
Co-authored-by: dpschen <dpschen@noreply.kolaente.de>
Co-committed-by: dpschen <dpschen@noreply.kolaente.de>
2021-11-04 21:28:10 +00:00
dpschen
b7207c6eaf chore: remove some unused notification styles (#953)
Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Reviewed-on: vikunja/frontend#953
Co-authored-by: dpschen <dpschen@noreply.kolaente.de>
Co-committed-by: dpschen <dpschen@noreply.kolaente.de>
2021-11-04 16:32:00 +00:00
58986c4a7a fix: adding or creating a label with quick add magic (#944)
Co-authored-by: kolaente <k@knt.li>
Reviewed-on: vikunja/frontend#944
Reviewed-by: dpschen <dpschen@noreply.kolaente.de>
Co-authored-by: konrad <k@knt.li>
Co-committed-by: konrad <k@knt.li>
2021-11-04 16:30:30 +00:00
7e82aa83e6 fix: label spacing (#946)
Co-authored-by: kolaente <k@knt.li>
Reviewed-on: vikunja/frontend#946
Reviewed-by: dpschen <dpschen@noreply.kolaente.de>
Co-authored-by: konrad <k@knt.li>
Co-committed-by: konrad <k@knt.li>
2021-11-04 16:28:20 +00:00
b6c4bb1801 [skip ci] Updated translations via Crowdin 2021-11-04 07:24:24 +00:00
a47d106926
chore: remove weblate ping script 2021-11-03 18:12:40 +01:00
3be15b0a5f chore(deps): update dependency eslint-plugin-vue to v8 (#913)
Co-authored-by: kolaente <k@knt.li>
Reviewed-on: vikunja/frontend#913
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-11-03 17:11:31 +00:00
6e44f9eaba chore(deps): update dependency @vue/eslint-config-typescript to v9.0.1 (#941)
Reviewed-on: vikunja/frontend#941
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-11-03 16:12:35 +00:00
525ff7903c fix(deps): update sentry-javascript monorepo to v6.14.0 (#940)
Reviewed-on: vikunja/frontend#940
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-11-03 12:58:17 +00:00
20 changed files with 864 additions and 416 deletions

View File

@ -219,10 +219,10 @@ describe('Lists', () => {
cy.get('.table-view .filter-container .items .button')
.contains('Columns')
.click()
cy.get('.table-view .filter-container .card.columns-filter .card-content .fancycheckbox .check')
cy.get('.table-view .filter-container .card .card-content .fancycheckbox .check')
.contains('Priority')
.click()
cy.get('.table-view .filter-container .card.columns-filter .card-content .fancycheckbox .check')
cy.get('.table-view .filter-container .card .card-content .fancycheckbox .check')
.contains('Done')
.click()

View File

@ -10,6 +10,7 @@
"build:modern-only": "BUILD_MODERN_ONLY=true vite build && workbox copyLibraries dist/",
"build:dev": "vite build -m development --outDir dist-dev/",
"lint": "eslint --ignore-pattern '*.test.*' ./src --ext .vue,.js,.ts",
"lint:markup": "vue-tsc --noEmit",
"cypress:open": "cypress open",
"test:unit": "jest",
"test:frontend": "cypress run",
@ -17,8 +18,8 @@
},
"dependencies": {
"@kyvg/vue3-notification": "2.3.4",
"@sentry/tracing": "6.13.3",
"@sentry/vue": "6.13.3",
"@sentry/tracing": "6.14.1",
"@sentry/vue": "6.14.1",
"@vue/compat": "3.2.21",
"bulma": "0.9.3",
"camel-case": "4.1.2",
@ -53,19 +54,19 @@
"@fortawesome/free-solid-svg-icons": "5.15.4",
"@fortawesome/vue-fontawesome": "3.0.0-5",
"@types/jest": "27.0.2",
"@typescript-eslint/eslint-plugin": "5.3.0",
"@typescript-eslint/parser": "5.3.0",
"@typescript-eslint/eslint-plugin": "5.3.1",
"@typescript-eslint/parser": "5.3.1",
"@vitejs/plugin-legacy": "1.6.2",
"@vitejs/plugin-vue": "1.9.4",
"@vue/eslint-config-typescript": "9.0.0",
"@vue/eslint-config-typescript": "9.0.1",
"autoprefixer": "10.4.0",
"axios": "0.24.0",
"browserslist": "4.17.6",
"cypress": "8.7.0",
"cypress-file-upload": "5.0.8",
"esbuild": "0.13.12",
"eslint": "8.1.0",
"eslint-plugin-vue": "7.20.0",
"eslint": "8.2.0",
"eslint-plugin-vue": "8.0.3",
"express": "4.17.1",
"faker": "5.5.3",
"jest": "27.3.1",
@ -77,6 +78,7 @@
"typescript": "4.4.4",
"vite": "2.6.13",
"vite-plugin-pwa": "0.11.3",
"vue-tsc": "0.29.2",
"wait-on": "6.0.0",
"workbox-cli": "6.3.0"
},
@ -108,7 +110,8 @@
"semi": [
"error",
"never"
]
],
"vue/multi-word-component-names": 0
},
"parser": "vue-eslint-parser",
"parserOptions": {

View File

@ -1,8 +0,0 @@
#!/bin/sh
set -e
# Shell script because yaml doesn't understand the header is a string literal and not a yaml symbol
curl -d operation=pull -H "Authorization: Token $WEBLATE_TOKEN" https://hosted.weblate.org/api/projects/vikunja/repository/
curl -d operation=push -H "Authorization: Token $WEBLATE_TOKEN" https://hosted.weblate.org/api/projects/vikunja/repository/

View File

@ -1,49 +1,37 @@
<template>
<x-button
v-if="hasFilters"
type="secondary"
@click="clearFilters"
>
{{ $t('filters.clear') }}
</x-button>
<popup>
<template #trigger="{toggle}">
<x-button
@click.prevent.stop="toggle()"
type="secondary"
icon="filter"
>
{{ $t('filters.title') }}
</x-button>
</template>
<template #content="{isOpen}">
<filters
v-model="value"
ref="filters"
class="filter-popup"
:class="{'is-open': isOpen}"
/>
</template>
</popup>
<transition name="fade">
<filters
v-if="visibleInternal"
v-model="value"
ref="filters"
/>
</transition>
</template>
<script>
import {closeWhenClickedOutside} from '@/helpers/closeWhenClickedOutside'
import Filters from '../../../components/list/partials/filters'
import {getDefaultParams} from '../../tasks/mixins/taskList'
import Popup from '../../misc/popup'
export default {
name: 'filter-popup',
components: {
Popup,
Filters,
},
props: {
modelValue: {
required: true,
},
visible: {
type: Boolean,
default: false,
},
},
emits: ['update:modelValue'],
data() {
return {
visibleInternal: false,
}
},
computed: {
value: {
get() {
@ -53,46 +41,34 @@ export default {
this.$emit('update:modelValue', value)
},
},
hasFilters() {
// this.value also contains the page parameter which we don't want to include in filters
// eslint-disable-next-line no-unused-vars
const {filter_by, filter_value, filter_comparator, filter_concat, s} = this.value
const def = {...getDefaultParams()}
const params = {filter_by, filter_value, filter_comparator, filter_concat, s}
const defaultParams = {
filter_by: def.filter_by,
filter_value: def.filter_value,
filter_comparator: def.filter_comparator,
filter_concat: def.filter_concat,
s: s ? def.s : undefined,
}
return JSON.stringify(params) !== JSON.stringify(defaultParams)
},
},
mounted() {
document.addEventListener('click', this.hidePopup)
},
beforeUnmount() {
document.removeEventListener('click', this.hidePopup)
},
watch: {
modelValue: {
handler(value) {
this.value = value
this.params = value
},
immediate: true,
},
visible() {
this.visibleInternal = !this.visibleInternal
},
},
methods: {
clearFilters() {
this.value = {...getDefaultParams()}
hidePopup(e) {
if (!this.visibleInternal) {
return
}
closeWhenClickedOutside(e, this.$refs.filters.$el, () => {
this.visibleInternal = false
})
},
},
}
</script>
<style scoped lang="scss">
.filter-popup {
margin: 0 !important;
&.is-open {
margin: 2rem 0 1rem !important;
}
}
</style>

View File

@ -458,7 +458,15 @@ export default {
return
}
this.filters.done = this.params.filter_by.some((f) => f === 'done') === false
let foundDone = false
this.params.filter_by.forEach((f, i) => {
if (f === 'done') {
foundDone = i
}
})
if (foundDone === false) {
this.filters.done = true
}
},
async prepareRelatedObjectFilter(kind, filterName = null, servicePrefix = null) {
if (filterName === null) {

View File

@ -10,7 +10,6 @@
}"
:to="{ name: 'list.index', params: { listId: list.id} }"
class="list-card"
tag="span"
v-if="list !== null && (showArchived ? true : !list.isArchived)"
>
<div class="is-archived-container">

View File

@ -8,15 +8,13 @@
<router-link
:disabled="currentPage === 1 || null"
:to="getRouteForPagination(currentPage - 1)"
class="pagination-previous"
tag="button">
class="pagination-previous">
{{ $t('misc.previous') }}
</router-link>
<router-link
:disabled="currentPage === totalPages || null"
:to="getRouteForPagination(currentPage + 1)"
class="pagination-next"
tag="button">
class="pagination-next">
{{ $t('misc.next') }}
</router-link>
<ul class="pagination-list">

View File

@ -1,54 +0,0 @@
<template>
<slot name="trigger" :isOpen="open" :toggle="toggle"></slot>
<div class="popup" :class="{'is-open': open}" ref="popup">
<slot name="content" :isOpen="open"/>
</div>
</template>
<script setup>
import {closeWhenClickedOutside} from '@/helpers/closeWhenClickedOutside'
import {onBeforeUnmount, onMounted, ref} from 'vue'
const open = ref(false)
const popup = ref(null)
const toggle = () => {
open.value = !open.value
}
const hidePopup = e => {
if (!open.value) {
return
}
// we actually want to use popup.$el, not its value.
// eslint-disable-next-line vue/no-ref-as-operand
closeWhenClickedOutside(e, popup.value, () => {
open.value = false
})
}
onMounted(() => {
document.addEventListener('click', hidePopup)
})
onBeforeUnmount(() => {
document.removeEventListener('click', hidePopup)
})
</script>
<style scoped lang="scss">
.popup {
transition: opacity $transition;
opacity: 0;
height: 0;
overflow: hidden;
position: absolute;
top: 1rem;
&.is-open {
opacity: 1;
height: auto;
}
}
</style>

View File

@ -9,12 +9,12 @@
>
{{ $t('filters.title') }}
</x-button>
<filter-popup
:visible="showTaskFilter"
v-model="params"
@update:modelValue="loadTasks()"
/>
</div>
<filter-popup
:visible="showTaskFilter"
v-model="params"
@update:modelValue="loadTasks()"
/>
</div>
<div class="dates">
<template v-for="(y, yk) in days" :key="yk + 'year'">
@ -349,7 +349,7 @@ export default {
return
}
let newTask = {...taskDragged}
let newTask = { ...taskDragged }
const didntHaveDates = newTask.startDate === null ? true : false

View File

@ -1,14 +1,14 @@
import TaskCollectionService from '@/services/taskCollection'
// FIXME: merge with DEFAULT_PARAMS in filters.vue
export const getDefaultParams = () => ({
const DEFAULT_PARAMS = {
sort_by: ['position', 'id'],
order_by: ['asc', 'desc'],
filter_by: ['done'],
filter_value: ['false'],
filter_comparator: ['equals'],
filter_concat: 'and',
})
}
/**
* This mixin provides a base set of methods and properties to get tasks on a list.
@ -26,7 +26,7 @@ export default {
searchTerm: '',
showTaskFilter: false,
params: {...getDefaultParams()},
params: DEFAULT_PARAMS,
}
},
watch: {
@ -94,7 +94,7 @@ export default {
this.initTasks(page, search)
},
loadTasksOnSavedFilter() {
if (typeof this.$route.params.listId !== 'undefined' && parseInt(this.$route.params.listId) < 0) {
if(typeof this.$route.params.listId !== 'undefined' && parseInt(this.$route.params.listId) < 0) {
this.loadTasks(1, '', null, true)
}
},

View File

@ -148,3 +148,9 @@ export default {
},
}
</script>
<style lang="scss" scoped>
.tag {
margin: .5rem 0 0 .5rem;
}
</style>

View File

@ -344,7 +344,6 @@
},
"filters": {
"title": "Filters",
"clear": "Clear Filters",
"attributes": {
"title": "Title",
"titlePlaceholder": "The saved filter title goes here…",

View File

@ -234,7 +234,7 @@
"list": {
"title": "Danh sách",
"add": "Thêm",
"addPlaceholder": "Thêm một công việc mới…",
"addPlaceholder": "Thêm việc cần làm…",
"empty": "Danh sách này đang trống trơn.",
"newTaskCta": "Thêm một công việc mới.",
"editTask": "Chỉnh sửa Công việc"
@ -459,7 +459,7 @@
"nextMonday": "Thứ Hai tới",
"thisWeekend": "Cuối tuần này",
"laterThisWeek": "Cuối tuần này",
"nextWeek": "Tuần kế tiếp",
"nextWeek": "Tuần ti",
"chooseDate": "Chọn một ngày"
},
"editor": {
@ -509,8 +509,8 @@
"from": "Công việc từ",
"until": "cho đến",
"today": "Hôm nay",
"nextWeek": "Tuần kế tiếp",
"nextMonth": "Tháng kế tiếp",
"nextWeek": "Tuần ti",
"nextMonth": "Tháng ti",
"noTasks": "Hôm nay thảnh thơi — Hãy tận hưởng ngày tuyệt vời!"
},
"detail": {

View File

@ -223,13 +223,12 @@ export default {
const labelAddsToWaitFor = parsedLabels.map(async labelTitle => {
let label = validateLabel(labels, labelTitle)
if (typeof label !== 'undefined') {
return label
if (typeof label === 'undefined') {
// label not found, create it
const labelModel = new LabelModel({title: labelTitle})
label = await dispatch('labels/createLabel', labelModel, {root: true})
}
// label not found, create it
const labelModel = new LabelModel({title: labelTitle})
await dispatch('labels/createLabel', labelModel, {root: true})
return addLabelToTask(task, label)
})

View File

@ -47,6 +47,10 @@ $filter-container-top-link-share-list: -47px;
justify-content: space-between;
margin-right: .5rem;
.button, .input {
height: $switch-view-height;
}
.field {
transition: width $transition;
width: 100%;

View File

@ -5,14 +5,6 @@
.notifications {
left: 0.5rem !important;
bottom: 1rem !important;
.notification-wrapper .notification {
border-radius: 0;
border-top-width: 0;
border-right-width: 0;
border-bottom-width: 0;
border-left-width: 0.4rem;
}
}
.message .message-body {

View File

@ -2,11 +2,18 @@
<div class="kanban-view">
<div class="filter-container" v-if="isSavedFilter">
<div class="items">
<filter-popup
v-model="params"
@update:modelValue="loadBuckets"
/>
<x-button
@click.prevent.stop="toggleFilterPopup"
icon="filter"
type="secondary"
>
{{ $t('filters.title') }}
</x-button>
</div>
<filter-popup
:visible="showFilters"
v-model="params"
/>
</div>
<div
:class="{ 'is-loading': loading && !oneTaskUpdating}"
@ -136,7 +143,7 @@
:component-data="taskDraggableTaskComponentData"
>
<template #item="{element: task}">
<kanban-card :task="task"/>
<kanban-card :task="task" />
</template>
</draggable>
</div>
@ -206,7 +213,7 @@
<!-- This router view is used to show the task popup while keeping the kanban board itself -->
<router-view v-slot="{ Component }">
<transition name="modal">
<component :is="Component"/>
<component :is="Component" />
</transition>
</router-view>
@ -217,10 +224,10 @@
v-if="showBucketDeleteModal"
>
<template #header><span>{{ $t('list.kanban.deleteHeaderBucket') }}</span></template>
<template #text>
<p>{{ $t('list.kanban.deleteBucketText1') }}<br/>
{{ $t('list.kanban.deleteBucketText2') }}</p>
{{ $t('list.kanban.deleteBucketText2') }}</p>
</template>
</modal>
</transition>
@ -293,6 +300,7 @@ export default {
filter_comparator: [],
filter_concat: 'and',
},
showFilters: false,
}
},
created() {
@ -320,10 +328,10 @@ export default {
return {
type: 'transition',
tag: 'div',
name: !this.dragBucket ? 'move-bucket' : null,
name: !this.dragBucket ? 'move-bucket': null,
class: [
'kanban-bucket-container',
{'dragging-disabled': !this.canWrite},
{ 'dragging-disabled': !this.canWrite },
],
}
},
@ -331,10 +339,10 @@ export default {
return {
type: 'transition',
tag: 'div',
name: !this.drag ? 'move-card' : null,
name: !this.drag ? 'move-card': null,
class: [
'dropper',
{'dragging-disabled': !this.canWrite},
{ 'dragging-disabled': !this.canWrite },
],
}
},
@ -349,15 +357,19 @@ export default {
list: state => state.currentList,
}),
},
methods: {
toggleFilterPopup() {
this.showFilters = !this.showFilters
},
loadBuckets() {
// Prevent trying to load buckets if the task popup view is active
if (this.$route.name !== 'list.kanban') {
return
}
const {listId, params} = this.loadBucketParameter
const { listId, params } = this.loadBucketParameter
this.collapsedBuckets = getCollapsedBucketState(listId)
@ -412,7 +424,7 @@ export default {
const newTask = cloneDeep(task) // cloning the task to avoid vuex store mutations
newTask.bucketId = newBucket.id,
newTask.kanbanPosition = calculateItemPosition(taskBefore !== null ? taskBefore.kanbanPosition : null, taskAfter !== null ? taskAfter.kanbanPosition : null)
newTask.kanbanPosition = calculateItemPosition(taskBefore !== null ? taskBefore.kanbanPosition : null, taskAfter !== null ? taskAfter.kanbanPosition : null)
try {
await this.$store.dispatch('tasks/update', newTask)

View File

@ -41,11 +41,19 @@
v-if="!showTaskSearch"
/>
</div>
<filter-popup
v-model="params"
@update:modelValue="loadTasks()"
/>
<x-button
@click.prevent.stop="showTaskFilter = !showTaskFilter"
type="secondary"
icon="filter"
>
{{ $t('filters.title') }}
</x-button>
</div>
<filter-popup
:visible="showTaskFilter"
v-model="params"
@update:modelValue="loadTasks()"
/>
</div>
<card :padding="false" :has-content="false" class="has-overflow">
@ -117,7 +125,7 @@
</card>
</div>
<Pagination
<Pagination
:total-pages="taskCollectionService.totalPages"
:current-page="currentPage"
/>
@ -126,7 +134,7 @@
<!-- This router view is used to show the task popup while keeping the kanban board itself -->
<router-view v-slot="{ Component }">
<transition name="modal">
<component :is="Component"/>
<component :is="Component" />
</transition>
</router-view>
</div>
@ -146,7 +154,6 @@ import FilterPopup from '@/components/list/partials/filter-popup.vue'
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 draggable from 'vuedraggable'
import {calculateItemPosition} from '../../../helpers/calculateItemPosition'
@ -190,7 +197,6 @@ export default {
taskList,
],
components: {
Popup,
Nothing,
FilterPopup,
SingleTaskInList,
@ -287,11 +293,11 @@ export default {
async saveTaskPosition(e) {
this.drag = false
const task = this.tasks[e.newIndex]
const taskBefore = this.tasks[e.newIndex - 1] ?? null
const taskAfter = this.tasks[e.newIndex + 1] ?? null
const taskAfter = this.tasks[e.newIndex + 1] ?? null
const newTask = {
...task,
position: calculateItemPosition(taskBefore !== null ? taskBefore.position : null, taskAfter !== null ? taskAfter.position : null),

View File

@ -2,63 +2,67 @@
<div :class="{'is-loading': taskCollectionService.loading}" class="table-view loader-container">
<div class="filter-container">
<div class="items">
<popup>
<template #trigger="{toggle}">
<x-button
@click.prevent.stop="toggle()"
icon="th"
type="secondary"
>
{{ $t('list.table.columns') }}
</x-button>
</template>
<template #content="{isOpen}">
<card class="columns-filter" :class="{'is-open': isOpen}">
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.id">#</fancycheckbox>
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.done">
{{ $t('task.attributes.done') }}
</fancycheckbox>
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.title">
{{ $t('task.attributes.title') }}
</fancycheckbox>
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.priority">
{{ $t('task.attributes.priority') }}
</fancycheckbox>
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.labels">
{{ $t('task.attributes.labels') }}
</fancycheckbox>
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.assignees">
{{ $t('task.attributes.assignees') }}
</fancycheckbox>
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.dueDate">
{{ $t('task.attributes.dueDate') }}
</fancycheckbox>
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.startDate">
{{ $t('task.attributes.startDate') }}
</fancycheckbox>
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.endDate">
{{ $t('task.attributes.endDate') }}
</fancycheckbox>
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.percentDone">
{{ $t('task.attributes.percentDone') }}
</fancycheckbox>
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.created">
{{ $t('task.attributes.created') }}
</fancycheckbox>
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.updated">
{{ $t('task.attributes.updated') }}
</fancycheckbox>
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.createdBy">
{{ $t('task.attributes.createdBy') }}
</fancycheckbox>
</card>
</template>
</popup>
<filter-popup
v-model="params"
@update:modelValue="loadTasks()"
/>
<x-button
@click.prevent.stop="() => {showActiveColumnsFilter = !showActiveColumnsFilter; showTaskFilter = false}"
icon="th"
type="secondary"
>
{{ $t('list.table.columns') }}
</x-button>
<x-button
@click.prevent.stop="() => {showTaskFilter = !showTaskFilter; showActiveColumnsFilter = false}"
icon="filter"
type="secondary"
>
{{ $t('filters.title') }}
</x-button>
</div>
<transition name="fade">
<card v-if="showActiveColumnsFilter">
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.id">#</fancycheckbox>
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.done">
{{ $t('task.attributes.done') }}
</fancycheckbox>
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.title">
{{ $t('task.attributes.title') }}
</fancycheckbox>
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.priority">
{{ $t('task.attributes.priority') }}
</fancycheckbox>
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.labels">
{{ $t('task.attributes.labels') }}
</fancycheckbox>
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.assignees">
{{ $t('task.attributes.assignees') }}
</fancycheckbox>
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.dueDate">
{{ $t('task.attributes.dueDate') }}
</fancycheckbox>
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.startDate">
{{ $t('task.attributes.startDate') }}
</fancycheckbox>
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.endDate">
{{ $t('task.attributes.endDate') }}
</fancycheckbox>
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.percentDone">
{{ $t('task.attributes.percentDone') }}
</fancycheckbox>
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.created">
{{ $t('task.attributes.created') }}
</fancycheckbox>
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.updated">
{{ $t('task.attributes.updated') }}
</fancycheckbox>
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.createdBy">
{{ $t('task.attributes.createdBy') }}
</fancycheckbox>
</card>
</transition>
<filter-popup
:visible="showTaskFilter"
v-model="params"
@update:modelValue="loadTasks()"
/>
</div>
<card :padding="false" :has-content="false">
@ -196,12 +200,10 @@ import Sort from '../../../components/tasks/partials/sort'
import {saveListView} from '@/helpers/saveListView'
import FilterPopup from '@/components/list/partials/filter-popup.vue'
import Pagination from '@/components/misc/pagination.vue'
import Popup from '../../../components/misc/popup'
export default {
name: 'Table',
components: {
Popup,
Done,
FilterPopup,
Sort,
@ -217,6 +219,7 @@ export default {
],
data() {
return {
showActiveColumnsFilter: false,
activeColumns: {
id: true,
done: true,
@ -320,12 +323,4 @@ export default {
}
}
}
.columns-filter {
margin: 0 !important;
&.is-open {
margin: 2rem 0 1rem !important;
}
}
</style>

831
yarn.lock

File diff suppressed because it is too large Load Diff