Compare commits

..

1 Commits

Author SHA1 Message Date
acf52fbe16
Add crowdin cli config 2021-09-05 13:01:53 +02:00
69 changed files with 2114 additions and 1598 deletions

View File

@ -341,7 +341,7 @@ trigger:
- "refs/tags/**"
steps:
- name: docker-unstable
- name: docker-latest
image: plugins/docker:linux-arm
pull: true
settings:
@ -350,7 +350,7 @@ steps:
password:
from_secret: docker_password
repo: vikunja/frontend
tags: unstable-linux-arm
tags: latest-linux-arm
build_args:
- USE_RELEASE=true
- RELEASE_VERSION=unstable
@ -380,7 +380,7 @@ steps:
depends_on:
- clone
- name: docker-unstable-arm64
- name: docker-latest-arm64
image: plugins/docker:linux-arm64
pull: true
settings:
@ -389,7 +389,7 @@ steps:
password:
from_secret: docker_password
repo: vikunja/frontend
tags: unstable-linux-arm64
tags: latest-linux-arm64
build_args:
- USE_RELEASE=true
- RELEASE_VERSION=unstable
@ -438,7 +438,7 @@ trigger:
- "refs/tags/**"
steps:
- name: docker-unstable
- name: docker-latest
image: plugins/docker:linux-amd64
pull: true
settings:
@ -447,7 +447,7 @@ steps:
password:
from_secret: docker_password
repo: vikunja/frontend
tags: unstable-linux-amd64
tags: latest-linux-amd64
build_args:
- USE_RELEASE=true
- RELEASE_VERSION=unstable
@ -488,12 +488,12 @@ depends_on:
- docker-arm-release
steps:
- name: manifest-unstable
- name: manifest-latest
pull: always
image: plugins/manifest
settings:
tags: unstable
spec: docker-manifest-unstable.tmpl
tags: latest
spec: docker-manifest-latest.tmpl
password:
from_secret: docker_password
username:
@ -516,23 +516,6 @@ steps:
when:
ref:
- "refs/tags/**"
- name: manifest-release-latest
pull: always
image: plugins/manifest
depends_on:
- clone
settings:
tags: latest
ignore_missing: true
spec: docker-manifest.tmpl
password:
from_secret: docker_password
username:
from_secret: docker_username
when:
ref:
- "refs/tags/**"
---
kind: pipeline
@ -572,8 +555,8 @@ kind: pipeline
type: docker
name: update-translations
depends_on:
- build
#depends_on:
# - build
trigger:
branch:
@ -594,19 +577,9 @@ steps:
CROWDIN_KEY:
from_secret: crowdin_key
- name: move-files
pull: always
image: bash
depends_on:
- download
commands:
- mv src/i18n/lang/*/*.json src/i18n/lang
- name: push
pull: always
image: appleboy/drone-git-push
depends_on:
- move-files
settings:
author_email: "frederik@vikunja.io"
author_name: Frederick [Bot]
@ -620,8 +593,6 @@ steps:
- name: upload
pull: always
image: jonasfranz/crowdin
depends_on:
- clone
settings:
files:
en.json: src/i18n/lang/en.json

View File

@ -2,347 +2,13 @@
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres
to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
All releases can be found on https://code.vikunja.io/frontend/releases.
The releases aim at the api versions which is why there are missing versions.
## [0.18.1] - 2021-09-08
### Added
* feat: make it possible to fake online state via dev env (#720)
### Fixed
* fix: call to /null from background image (#714)
* Fix data export download progress
* fix: kanban-card mutatation violation (#712)
* Fix missing translation when creating a new task on the kanban board
* Fix rearranging tasks in a kanban bucket when its limit was reached
* Fix sort order for table view
* Fix task attributes overridden when saving the task title with enter
* Fix translation badge
### Dependency Updates
* Update dependency @4tw/cypress-drag-drop to v2 (#711)
* Update dependency axios to v0.21.4 (#705)
* Update dependency jest to v27.1.1 (#716)
* Update dependency vite-plugin-vue2 to v1.8.2 (#707)
* Update dependency vite to v2.5.4 (#708)
* Update dependency vite to v2.5.5 (#709)
* Update typescript-eslint monorepo to v4.31.0 (#706)
## [0.18.0] - 2021-09-05
### Added
* Add a button to copy an attachment url from the attachment overview
* Add collapsing kanban buckets
* Add confirm with enter when setting a new password
* Add default list setting & creating tasks from home (#520)
* Add depends_on for push step
* Add depends_on for upload step
* Add drag delay on mobile
* Add express for serve:dev
* Add filters for quick action bar
* Add frontend tests for list history
* Add making tasks favorite from the task detail view
* Add missing position property to list and bucket models
* Add more debug logs for gantt charts
* Add more global state tests (#521)
* Add proofread languages to available languages
* Add quick action bar shortcut to shortcut overview
* Add setting for the first day of the week
* Add showing version info in GUI
* Add syncing translations to crowdin
* Add timeout to fix race condition when authenticating as a link share and renewing the token simultaneously
* Add translations (#562)
* Add typescript support for helper functions (#598)
* Add vite (#416)
* Allow failure of the weblate update step
* Always set the kanban board to full width for share links
* Another day, another js date edge-case
* Automatically update approved translations from crowdin
* Break long list titles in list overview
* Preload labels and use locally stored in vuex
* PWA improvments (#622)
* Quick Actions & global search (#528)
* Quick add magic for tasks (#570)
* Reorder tasks, lists and kanban buckets (#620)
* Show last visited list on home page
* Show recently visited lists in quick actions
* Show salutation based on the time of day
* Sort labels alphabetically on tasks
* Switch the :latest docker image tag to contain the latest release instead of the latest unstable
### Changed
* Change building latest docker image
* Change desktop downstream trigger plugin with our own debug build
* Change menu hamburger icon
* Change quick add magic characters to be more familiar with the todoist ones
* Change the docker builder image to a working one on arm
* chore: discard old font file formats (#673)
* chore: only import common languages (#671)
* Cleanup broken sw functions
* Cleanup drone pipeline
* Cleanup old vue cli config
* Configure tests retries
* Decrease page padding on task detail page
* Directly redirect to the openid auth provider if that's the only auth method
* Don't allow dragging a list when the user does not have the rights
* Don't load already loaded task attachments again when saving an edited task description
* Don't prefetch all i18n files
* Don't show archived lists/namespaces in quick actions
* feat: provide global variables in all components (#669)
* Hide favorite list edit menu
* Hide keyboard shortcuts indicator on mobile
* Improve chunk size
* Improve some translations (#581)
* Improve tests
* Indicate done tasks in quick actions
* Load list background in list card
* Make editor edit button at the bottom the default and make sure the done button stands out more
* Make saving a text edit a button
* Make sure highlight.js is always lazy-loaded
* Make sure the task popup view takes up all the space it can on mobile
* Make tests less flaky
* Make the logo smaller on link shared lists
* Make the progress bar color lighter
* Move creation of new items to the bottom of the multiselect list
* Move general settings to the top
* Move translated files after downloading them
* Move weblate ping to shell script
* Only add a drag delay if on mobile instead of setting it to 0
* Only build a bundle for modern browsers
* Refactor success and error messages
* Refactor success and error notifications to prevent html in them
* Remove logout button for link shares
* Run frontend-tests with dist in ci (#605)
* Save auth tokens from link shares only in memory, don't persist them to localStorage
* Search namespaces locally only when duplicating a list
* Show errors from openid provider
* Show labels alphabetically sorted in the overview
* Small cleanups & code improvements
* TOTP UX improvements & translation fixes
### Fixed
* Fix changing the repeat mode of a task when no value is entered yet
* Fix comment on different task after clicking on a task notification
* Fix CTA spacings
* Fix date parsing parsing words with weekdays in them (#607)
* fix(deps): update dependency marked to v3.0.1 (#677)
* fix(deps): update dependency marked to v3.0.2 (#682)
* Fix error property already defined as a function
* Fix flickering pre-loaded search results when focusing the search input
* Fix Gantt layout overflowsing on mobile
* Fix gantt months being wrong
* Fix git push remote to update crowdin translations
* Fix global mutation of has tasks state
* Fix header layout for long list titles
* Fix highlight.js in editor
* Fix home page tests
* Fix keyboard shortcuts not working on the task detail page
* Fix label changes appearing to be saved immediately when editing them
* Fix labels list in saved filter spacing
* Fix lint
* Fix list archived notification mobile layout
* Fix list settings not being available when list backgrounds are disabled
* Fix lists showing up multiple times in history
* Fix llama background url
* Fix loading a list when it was already partially saved in vuex
* Fix loading & disabled state on inputs when creating a new task
* Fix loading labels when editing a saved filter
* Fix menu styles
* Fix missing background for tasks on a shared list with a background
* Fix multiselect search padding
* Fix new lists created with quick actions not showing up in the menu
* fix: non unique ids (#672)
* Fix not reloading tasks of a saved filter after editing it
* Fix not updating list name in store when changing it
* Fix other values getting pushed away when creating a new one through multiselect
* Fix padding for kanban cards
* Fix parsing dates on the last day of the month
* Fix populating task details ater updating the description
* Fix quick actions not opening
* Fix quick actions not working when nonexisting lists where left over in history
* Fix redirecting to /login for some routes
* Fix removing a namespace from state after it was deleted
* Fix resetting date filters from upcoming after viewing a task detail page (popup)
* Fix sass division
* Fix saving showing archived setting
* Fix selecting a single value from multiselect
* Fix sending openid scopes when authenticating
* Fix sending the user back to the list view they came from when opening a task in detail view
* Fix setting a task as favorite button
* Fix setting delete button for newly created task comments
* Fix setting filters for reminders
* Fix setting secret for updating translations
* Fix setting task favorite status in test fixtures
* Fix showing an editor save button in cases where it wasn't required
* Fix showing edit buttons when the user does not have the rights to use them
* Fix showing import tasks cta when tasks are loading
* Fix some translation strings
* Fix sorting labels
* Fix spacing for task detail view in lists with a background
* Fix table headers wrapping in table view
* Fix table text alignment in task detail page
* Fix table view scrolling on mobile
* Fix test for saving a task description
* Fix tests failing on thursdays
* Fix token in storage not getting renewed
* Fix translating dates
* Fix usage of / in sass
* Fix user name and avatar alignment in navbar
* Fix users not removed from the list in settings when unshared
* Fix user test fixtures
* fix: vuex mutation violation from draggable (#674)
### Dependency Updates
* chore(deps): update dependency @4tw/cypress-drag-drop to v1.8.1 (#693)
* chore(deps): update dependency autoprefixer to v10.3.3 (#684)
* chore(deps): update dependency autoprefixer to v10.3.4 (#697)
* chore(deps): update dependency axios to v0.21.2 (#698)
* chore(deps): update dependency axios to v0.21.3 (#700)
* chore(deps): update dependency cypress to v8.3.1 (#689)
* chore(deps): update dependency esbuild to v0.12.23 (#683)
* chore(deps): update dependency esbuild to v0.12.24 (#688)
* chore(deps): update dependency esbuild to v0.12.25 (#696)
* chore(deps): update dependency eslint-plugin-vue to v7.17.0 (#686)
* chore(deps): update dependency jest to v27.1.0 (#687)
* chore(deps): update dependency sass to v1.38.1 (#679)
* chore(deps): update dependency sass to v1.38.2 (#690)
* chore(deps): update dependency sass to v1.39.0 (#695)
* chore(deps): update dependency typescript to v4.4.2 (#685)
* chore(deps): update dependency vite-plugin-pwa to v0.11.2 (#681)
* chore(deps): update dependency vite to v2.5.1 (#680)
* chore(deps): update dependency vite to v2.5.2 (#692)
* chore(deps): update dependency vite to v2.5.3 (#694)
* chore(deps): update typescript-eslint monorepo to v4.29.3 (#676)
* chore(deps): update typescript-eslint monorepo to v4.30.0 (#691)
* Update dependency autoprefixer to v10.3.2 (#670)
* Update dependency browserslist to v4.16.7 (#634)
* Update dependency browserslist to v4.16.8 (#664)
* Update dependency browserslist to v4.17.0 (#701)
* Update dependency bulma to v0.9.3 (#554)
* Update dependency cypress-file-upload to v5.0.8 (#556)
* Update dependency cypress to v7.3.0 (#507)
* Update dependency cypress to v7.4.0 (#517)
* Update dependency cypress to v7.5.0 (#541)
* Update dependency cypress to v7.6.0 (#561)
* Update dependency cypress to v7.7.0 (#577)
* Update dependency cypress to v8.1.0 (#624)
* Update dependency cypress to v8.2.0 (#637)
* Update dependency cypress to v8.3.0 (#660)
* Update dependency cypress to v8 (#601)
* Update dependency date-fns to v2.22.0 (#523)
* Update dependency date-fns to v2.22.1 (#524)
* Update dependency date-fns to v2.23.0 (#604)
* Update dependency dompurify to v2.2.9 (#529)
* Update dependency dompurify to v2.3.0 (#573)
* Update dependency dompurify to v2.3.1 (#655)
* Update dependency esbuild to v0.12.15 (#610)
* Update dependency esbuild to v0.12.16 (#614)
* Update dependency esbuild to v0.12.17 (#623)
* Update dependency esbuild to v0.12.18 (#638)
* Update dependency esbuild to v0.12.19 (#643)
* Update dependency esbuild to v0.12.20 (#654)
* Update dependency esbuild to v0.12.21 (#666)
* Update dependency esbuild to v0.12.22 (#668)
* Update dependency eslint-plugin-vue to v7.10.0 (#525)
* Update dependency eslint-plugin-vue to v7.11.0 (#547)
* Update dependency eslint-plugin-vue to v7.11.1 (#548)
* Update dependency eslint-plugin-vue to v7.12.1 (#565)
* Update dependency eslint-plugin-vue to v7.13.0 (#574)
* Update dependency eslint-plugin-vue to v7.14.0 (#597)
* Update dependency eslint-plugin-vue to v7.15.0 (#625)
* Update dependency eslint-plugin-vue to v7.15.1 (#633)
* Update dependency eslint-plugin-vue to v7.16.0 (#648)
* Update dependency eslint to v7.27.0 (#514)
* Update dependency eslint to v7.28.0 (#539)
* Update dependency eslint to v7.29.0 (#555)
* Update dependency eslint to v7.30.0 (#571)
* Update dependency eslint to v7.31.0 (#596)
* Update dependency eslint to v7.32.0 (#627)
* Update dependency highlight.js to v11.0.1 (#538)
* Update dependency highlight.js to v11.1.0 (#582)
* Update dependency highlight.js to v11.2.0 (#630)
* Update dependency highlight.js to v11 (#527)
* Update dependency jest to v27.0.3 (#526)
* Update dependency jest to v27.0.4 (#535)
* Update dependency jest to v27.0.5 (#558)
* Update dependency jest to v27.0.6 (#569)
* Update dependency jest to v27 (#519)
* Update dependency marked to v2.0.4 (#510)
* Update dependency marked to v2.0.5 (#513)
* Update dependency marked to v2.0.6 (#522)
* Update dependency marked to v2.0.7 (#532)
* Update dependency marked to v2.1.0 (#552)
* Update dependency marked to v2.1.1 (#553)
* Update dependency marked to v2.1.2 (#559)
* Update dependency marked to v2.1.3 (#567)
* Update dependency marked to v3 (#657)
* Update dependency @rollup/plugin-commonjs to v19.0.2 (#617)
* Update dependency sass to v1.33.0 (#512)
* Update dependency sass to v1.34.0 (#515)
* Update dependency sass to v1.34.1 (#534)
* Update dependency sass to v1.35.0 (#550)
* Update dependency sass to v1.35.1 (#551)
* Update dependency sass to v1.35.2 (#579)
* Update dependency sass to v1.36.0 (#606)
* Update dependency sass to v1.37.0 (#628)
* Update dependency sass to v1.37.2 (#632)
* Update dependency sass to v1.37.5 (#635)
* Update dependency sass to v1.38.0 (#661)
* Update dependency ts-jest to v27.0.4 (#602)
* Update dependency ts-jest to v27.0.5 (#662)
* Update dependency @types/jest to v27.0.1 (#653)
* Update dependency @types/jest to v27 (#650)
* Update dependency vite-plugin-pwa to v0.10.0 (#644)
* Update dependency vite-plugin-pwa to v0.11.0 (#667)
* Update dependency vite-plugin-pwa to v0.8.2 (#612)
* Update dependency vite-plugin-pwa to v0.9.3 (#629)
* Update dependency vite-plugin-vue2 to v1.7.3 (#613)
* Update dependency vite-plugin-vue2 to v1.8.0 (#646)
* Update dependency vite-plugin-vue2 to v1.8.1 (#656)
* Update dependency vite to v2.4.3 (#611)
* Update dependency vite to v2.4.4 (#619)
* Update dependency vite to v2.5.0 (#658)
* Update dependency vue-advanced-cropper to v1.6.0 (#516)
* Update dependency vue-advanced-cropper to v1.7.0 (#543)
* Update dependency vue-advanced-cropper to v1.8.0 (#641)
* Update dependency vue-advanced-cropper to v1.8.1 (#642)
* Update dependency vue-advanced-cropper to v1.8.2 (#645)
* Update dependency vue-flatpickr-component to v8.1.7 (#572)
* Update dependency vue-i18n to v8.24.5 (#564)
* Update dependency vue-i18n to v8.25.0 (#595)
* Update dependency vue-router to v3.5.2 (#557)
* Update dependency wait-on to v6 (#568)
* Update dependency workbox-cli to v6.1.5 (#609)
* Update Font Awesome (#636)
* Update Node.js (#549)
* Update Node.js to v16.4.1 (#576)
* Update Node.js to v16.4.2 (#578)
* Update typescript-eslint monorepo to v4.28.4 (#600)
* Update typescript-eslint monorepo to v4.28.5 (#618)
* Update typescript-eslint monorepo to v4.29.0 (#631)
* Update typescript-eslint monorepo to v4.29.1 (#647)
* Update typescript-eslint monorepo to v4.29.2 (#659)
* Update vue monorepo to v2.6.13 (#530)
* Update vue monorepo to v2.6.14 (#540)
* Update workbox monorepo to v6.2.0 (#639)
* Update workbox monorepo to v6.2.2 (#640)
* Update workbox monorepo to v6.2.4 (#649)
* User account deletion (#651)
* User Data Export and import (#699)
## [0.17.0 - 2021-05-14]
### Added
@ -482,8 +148,7 @@ The releases aim at the api versions which is why there are missing versions.
* Make sure all arm64 build steps run in parallel
* Make sure all empty pages have a call to action
* Make sure all popups & dropdowns are animated
* Make sure attachements are only added once to the list after uploading + Make sure the attachment list shows up every
time after adding an attachment
* Make sure attachements are only added once to the list after uploading + Make sure the attachment list shows up every time after adding an attachment
* Make sure no cta's are visible while the page is loading
* Make sure the loading spinner is always visible at the end of the page
* Make the button shadow lighter
@ -1010,7 +675,7 @@ The releases aim at the api versions which is why there are missing versions.
* Hide totp settings if it is disabled server side
* Increase network timeout when building docker image
* Make sure the version includes the tag when building docker images
* # PrideMonth
* #PrideMonth
* Only renew user token on tab focus events
* Redirect the user to login page if the token expired when the tab gets focus again
* Remove title length restrictions
@ -1045,7 +710,7 @@ The releases aim at the api versions which is why there are missing versions.
## [0.13] - 2020-05-12
#### Added
#### Added
* Add docker run script to change api url on startup
* Add github token for renovate (#89)
@ -1390,7 +1055,6 @@ The releases aim at the api versions which is why there are missing versions.
* Use email instead of username when resetting a password
### Fixed
* Fixed trying to verify an email when there was none
* Fixed loading tasks when the user was not authenticated

View File

@ -4,8 +4,8 @@
[![Build Status](https://drone.kolaente.de/api/badges/vikunja/frontend/status.svg)](https://drone.kolaente.de/vikunja/frontend)
[![License: AGPL v3](https://img.shields.io/badge/License-AGPL%20v3-blue.svg)](LICENSE)
[![Download](https://img.shields.io/badge/download-v0.18.1-brightgreen.svg)](https://dl.vikunja.io)
[![Translation](https://badges.crowdin.net/vikunja/localized.svg)](https://crowdin.com/project/vikunja)
[![Download](https://img.shields.io/badge/download-v0.17.0-brightgreen.svg)](https://dl.vikunja.io)
[![Translation](https://hosted.weblate.org/widgets/vikunja/-/frontend/svg-badge.svg)](https://hosted.weblate.org/engage/vikunja/)
This is the web frontend for Vikunja, written in Vue.js.

24
crowdin.yml Normal file
View File

@ -0,0 +1,24 @@
project_id: 462614
api_token_env: CROWDIN_API_TOKEN
base_path: .
base_url: https://api.crowdin.com
preserve_hierarchy: false
files:
- source: /src/i18n/lang/*.json
#
# Where translations will be placed
# e.g. "/resources/%two_letters_code%/%original_file_name%"
#
translation: /src/i18n/lang/%two_letters_code%/%original_file_name%
#
# files or directories for ignore
# e.g. ["/**/?.txt", "/**/[0-9].txt", "/**/*\?*.txt"]
#
#"ignore" : [],
#
# The dest allows you to specify a file name in Crowdin
# e.g. "/messages.json"
#
#"dest" : "",

View File

@ -1,17 +1,17 @@
image: vikunja/frontend:unstable
image: vikunja/frontend:latest
manifests:
-
image: vikunja/frontend:unstable-linux-amd64
image: vikunja/frontend:latest-linux-amd64
platform:
architecture: amd64
os: linux
-
image: vikunja/frontend:unstable-linux-arm64
image: vikunja/frontend:latest-linux-arm64
platform:
architecture: arm64
os: linux
-
image: vikunja/frontend:unstable-linux-arm
image: vikunja/frontend:latest-linux-arm
platform:
architecture: arm
os: linux

View File

@ -14,7 +14,7 @@
"test:frontend": "cypress run"
},
"dependencies": {
"browserslist": "4.17.0",
"browserslist": "4.16.8",
"bulma": "0.9.3",
"camel-case": "4.1.2",
"copy-to-clipboard": "3.3.1",
@ -23,7 +23,7 @@
"highlight.js": "11.2.0",
"is-touch-device": "1.0.1",
"lodash": "4.17.21",
"marked": "3.0.3",
"marked": "3.0.2",
"register-service-worker": "1.7.2",
"snake-case": "3.0.4",
"verte": "0.0.12",
@ -35,44 +35,44 @@
"vue-shortkey": "3.1.7",
"vuedraggable": "2.24.3",
"vuex": "3.6.2",
"workbox-precaching": "6.3.0"
"workbox-precaching": "6.2.4"
},
"devDependencies": {
"@4tw/cypress-drag-drop": "2.0.0",
"@4tw/cypress-drag-drop": "1.8.1",
"@fortawesome/fontawesome-svg-core": "1.2.36",
"@fortawesome/free-regular-svg-icons": "5.15.4",
"@fortawesome/free-solid-svg-icons": "5.15.4",
"@fortawesome/vue-fontawesome": "2.0.2",
"@types/jest": "27.0.1",
"@typescript-eslint/eslint-plugin": "4.31.0",
"@typescript-eslint/parser": "4.31.0",
"@typescript-eslint/eslint-plugin": "4.30.0",
"@typescript-eslint/parser": "4.30.0",
"@vue/babel-preset-app": "4.5.13",
"@vue/eslint-config-typescript": "7.0.0",
"autoprefixer": "10.3.4",
"axios": "0.21.4",
"axios": "0.21.3",
"babel-eslint": "10.1.0",
"cypress": "8.3.1",
"cypress-file-upload": "5.0.8",
"esbuild": "0.12.26",
"esbuild": "0.12.25",
"eslint": "7.32.0",
"eslint-plugin-vue": "7.17.0",
"express": "4.17.1",
"faker": "5.5.3",
"jest": "27.1.1",
"jest": "27.1.0",
"rollup-plugin-terser": "7.0.2",
"rollup-plugin-visualizer": "5.5.2",
"sass": "1.39.2",
"sass": "1.39.0",
"ts-jest": "27.0.5",
"typescript": "4.4.2",
"vite": "2.5.6",
"vite": "2.5.3",
"vite-plugin-pwa": "0.11.2",
"vite-plugin-vue2": "1.8.2",
"vite-plugin-vue2": "1.8.1",
"vue-flatpickr-component": "8.1.7",
"vue-notification": "1.3.20",
"vue-router": "3.5.2",
"vue-template-compiler": "2.6.14",
"wait-on": "6.0.0",
"workbox-cli": "6.3.0"
"workbox-cli": "6.2.4"
},
"eslintConfig": {
"root": true,

View File

@ -23,9 +23,11 @@
</template>
<script>
import {mapState, mapGetters} from 'vuex'
import {mapState} from 'vuex'
import isTouchDevice from 'is-touch-device'
import authTypes from './models/authTypes'
import Notification from './components/misc/notification'
import {KEYBOARD_SHORTCUTS_ACTIVE, ONLINE} from './store/mutation-types'
import KeyboardShortcuts from './components/misc/keyboard-shortcuts'
@ -72,13 +74,11 @@ export default {
return isTouchDevice()
},
...mapState({
authUser: state => state.auth.authenticated && (state.auth.info && state.auth.info.type === authTypes.USER),
authLinkShare: state => state.auth.authenticated && (state.auth.info && state.auth.info.type === authTypes.LINK_SHARE),
online: ONLINE,
keyboardShortcutsActive: KEYBOARD_SHORTCUTS_ACTIVE,
}),
...mapGetters('auth', [
'authUser',
'authLinkShare',
]),
},
methods: {
setupOnlineStatus() {

View File

@ -5,7 +5,7 @@
</a>
<div
:class="{'has-background': background}"
:style="{'background-image': background && `url(${background})`}"
:style="{'background-image': `url(${background})`}"
class="app-container"
>
<navigation/>
@ -62,7 +62,7 @@ export default {
return state.namespaces.namespaces.filter(n => !n.isArchived)
},
currentList: CURRENT_LIST,
background: 'background',
background: 'background', // FIXME: Return the full thing or nothing at all to prevent calls to /null
menuActive: MENU_ACTIVE,
userInfo: state => state.auth.info,
authenticated: state => state.auth.authenticated,

View File

@ -97,7 +97,7 @@
<script>
import {mapState} from 'vuex'
import {CURRENT_LIST, QUICK_ACTIONS_ACTIVE} from '@/store/mutation-types'
import Rights from '@/models/constants/rights.json'
import Rights from '@/models/rights.json'
import Update from '@/components/home/update.vue'
import ListSettingsDropdown from '@/components/list/list-settings-dropdown.vue'
import Dropdown from '@/components/misc/dropdown.vue'

View File

@ -4,7 +4,7 @@
:checked="checked"
:disabled="disabled"
:id="checkBoxId"
@change="(event) => updateData(event.target.checked)"
@change="updateData"
style="display: none;"
type="checkbox"/>
<label :for="checkBoxId" class="check">
@ -51,10 +51,10 @@ export default {
this.checkBoxId = 'fancycheckbox' + Math.random()
},
methods: {
updateData(checked) {
this.checked = checked
this.$emit('input', checked)
this.$emit('change', checked)
updateData(e) {
this.checked = e.target.checked
this.$emit('input', this.checked)
this.$emit('change', e.target.checked)
},
},
}

View File

@ -190,35 +190,6 @@ import ListService from '@/services/list'
import NamespaceService from '@/services/namespace'
import EditLabels from '@/components/tasks/partials/editLabels.vue'
// FIXME: merge with DEFAULT_PARAMS in taskList.js
const DEFAULT_PARAMS = {
sort_by: [],
order_by: [],
filter_by: [],
filter_value: [],
filter_comparator: [],
filter_include_nulls: true,
filter_concat: 'or',
s: '',
}
const DEFAULT_FILTERS = {
done: false,
dueDate: '',
requireAllFilters: false,
priority: 0,
usePriority: false,
startDate: '',
endDate: '',
percentDone: 0,
usePercentDone: false,
reminders: '',
assignees: '',
labels: '',
list_id: '',
namespace: '',
}
export default {
name: 'filters',
components: {
@ -231,8 +202,32 @@ export default {
},
data() {
return {
params: DEFAULT_PARAMS,
filters: DEFAULT_FILTERS,
params: {
sort_by: [],
order_by: [],
filter_by: [],
filter_value: [],
filter_comparator: [],
filter_include_nulls: true,
filter_concat: 'or',
s: '',
},
filters: {
done: false,
dueDate: '',
requireAllFilters: false,
priority: 0,
usePriority: false,
startDate: '',
endDate: '',
percentDone: 0,
usePercentDone: false,
reminders: '',
assignees: '',
labels: '',
list_id: '',
namespace: '',
},
usersService: UserService,
foundusers: [],

View File

@ -36,7 +36,14 @@
<div class="migration-in-progress">
<img :alt="name" :src="`/images/migration/${identifier}.png`"/>
<div class="progress-dots">
<span v-for="i in progressDotsCount" :key="i" />
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
</div>
<img alt="Vikunja" src="/images/logo.svg">
</div>
@ -67,19 +74,15 @@
import AbstractMigrationService from '../../services/migrator/abstractMigration'
import AbstractMigrationFileService from '../../services/migrator/abstractMigrationFile'
const PROGRESS_DOTS_COUNT = 8
export default {
name: 'migration',
data() {
return {
progressDotsCount: PROGRESS_DOTS_COUNT,
authUrl: '',
isMigrating: false,
lastMigrationDate: null,
message: '',
migratorAuthCode: '',
migrationService: null,
}
},
props: {

View File

@ -24,7 +24,7 @@
</div>
<div class="api-url-info" v-else>
<i18n path="apiConfig.signInOn">
<span class="url" v-tooltip="apiUrl"> {{ apiDomain }} </span>
<span class="url" v-tooltip="apiUrl"> {{ apiDomain() }} </span>
</i18n>
<br />
<a @click="() => (configureApi = true)">{{ $t('apiConfig.change') }}</a>
@ -46,24 +46,23 @@
</template>
<script>
const API_DEFAULT_PORT = 3456
export default {
name: 'apiConfig',
data() {
return {
configureApi: false,
apiUrl: window.API_URL,
apiUrl: '',
errorMsg: '',
successMsg: '',
}
},
created() {
this.apiUrl = window.API_URL
if (this.apiUrl === '') {
this.configureApi = true
}
},
computed: {
methods: {
apiDomain() {
if (window.API_URL.startsWith('/api/v1')) {
return window.location.host
@ -73,8 +72,6 @@ export default {
.split(/[/?#]/)
return urlParts[0]
},
},
methods: {
setApiUrl() {
if (this.apiUrl === '') {
return
@ -134,17 +131,17 @@ export default {
return Promise.reject(e)
})
.catch((e) => {
// Check if it is reachable at port API_DEFAULT_PORT and https
if (urlToCheck.port !== API_DEFAULT_PORT) {
// Check if it is reachable at port 3456 and https
if (urlToCheck.port !== 3456) {
urlToCheck.protocol = 'https:'
urlToCheck.port = API_DEFAULT_PORT
urlToCheck.port = 3456
window.API_URL = urlToCheck.toString()
return this.$store.dispatch('config/update')
}
return Promise.reject(e)
})
.catch((e) => {
// Check if it is reachable at :API_DEFAULT_PORT and /api/v1 and https
// Check if it is reachable at :3456 and /api/v1 and https
urlToCheck.pathname = origUrlToCheck.pathname
if (
!urlToCheck.pathname.endsWith('/api/v1') &&
@ -157,17 +154,17 @@ export default {
return Promise.reject(e)
})
.catch((e) => {
// Check if it is reachable at port API_DEFAULT_PORT and http
if (urlToCheck.port !== API_DEFAULT_PORT) {
// Check if it is reachable at port 3456 and http
if (urlToCheck.port !== 3456) {
urlToCheck.protocol = 'http:'
urlToCheck.port = API_DEFAULT_PORT
urlToCheck.port = 3456
window.API_URL = urlToCheck.toString()
return this.$store.dispatch('config/update')
}
return Promise.reject(e)
})
.catch((e) => {
// Check if it is reachable at :API_DEFAULT_PORT and /api/v1 and http
// Check if it is reachable at :3456 and /api/v1 and http
urlToCheck.pathname = origUrlToCheck.pathname
if (
!urlToCheck.pathname.endsWith('/api/v1') &&
@ -182,14 +179,14 @@ export default {
.catch(() => {
// Still not found, url is still invalid
this.successMsg = ''
this.errorMsg = this.$t('apiConfig.error', {domain: this.apiDomain})
this.errorMsg = this.$t('apiConfig.error', {domain: this.apiDomain()})
window.API_URL = oldUrl
})
.then((r) => {
if (typeof r !== 'undefined') {
// Set it + save it to local storage to save us the hoops
this.errorMsg = ''
this.successMsg = this.$t('apiConfig.success', {domain: this.apiDomain})
this.successMsg = this.$t('apiConfig.success', {domain: this.apiDomain()})
localStorage.setItem('API_URL', window.API_URL)
this.configureApi = false
this.apiUrl = window.API_URL

View File

@ -50,7 +50,7 @@
<script>
import NotificationService from '@/services/notification'
import User from '@/components/misc/user.vue'
import names from '@/models/constants/notificationNames.json'
import names from '@/models/notificationNames.json'
import {closeWhenClickedOutside} from '@/helpers/closeWhenClickedOutside'
import {mapState} from 'vuex'

View File

@ -173,7 +173,7 @@
</template>
<script>
import rights from '../../models/constants/rights'
import rights from '../../models/rights'
import LinkShareService from '../../services/linkShare'
import LinkShareModel from '../../models/linkShare'

View File

@ -145,7 +145,7 @@ import TeamListService from '../../services/teamList'
import TeamService from '../../services/team'
import TeamModel from '../../models/team'
import rights from '../../models/constants/rights.json'
import rights from '../../models/rights'
import Multiselect from '@/components/input/multiselect.vue'
import Nothing from '@/components/misc/nothing.vue'

View File

@ -72,7 +72,7 @@
import ListService from '../../services/list'
import TaskService from '../../services/task'
import TaskModel from '../../models/task'
import priorities from '../../models/constants/priorities'
import priorities from '../../models/priorities'
import EditLabels from './partials/editLabels'
import Reminders from './partials/reminders'
import ColorPicker from '../input/colorPicker'

View File

@ -11,7 +11,7 @@
</x-button>
</div>
<filter-popup
@change="loadTasks()"
@change="loadTasks"
:visible="showTaskFilter"
v-model="params"
/>
@ -24,7 +24,10 @@
class="month"
v-for="(m, mk) in days[yk]"
>
{{ formatYear(new Date(`${yk}-${parseInt(mk) + 1}-01`)) }}
{{
new Date(new Date(`${yk}-${parseInt(mk) + 1}-01`)).toLocaleString('en-us', {month: 'long'})
}},
{{ new Date(yk).getFullYear() }}
<div class="days">
<div
:class="{ today: d.toDateString() === now.toDateString() }"
@ -188,13 +191,12 @@ import EditTask from './edit-task'
import TaskService from '../../services/task'
import TaskModel from '../../models/task'
import priorities from '../../models/constants/priorities'
import priorities from '../../models/priorities'
import PriorityLabel from './partials/priorityLabel'
import TaskCollectionService from '../../services/taskCollection'
import {mapState} from 'vuex'
import Rights from '../../models/constants/rights.json'
import Rights from '../../models/rights.json'
import FilterPopup from '@/components/list/partials/filter-popup.vue'
import {format} from 'date-fns'
export default {
name: 'GanttChart',
@ -479,9 +481,6 @@ export default {
this.error(e)
})
},
formatYear(date) {
return format(date, 'MMMM, yyyy')
},
},
}
</script>

View File

@ -1,70 +1,17 @@
import TaskCollectionService from '@/services/taskCollection'
import TaskCollectionService from '../../../services/taskCollection'
import cloneDeep from 'lodash/cloneDeep'
import {calculateItemPosition} from '../../../helpers/calculateItemPosition'
// FIXME: merge with DEFAULT_PARAMS in filters.vue
const DEFAULT_PARAMS = {
sort_by: ['position', 'id'],
order_by: ['asc', 'desc'],
filter_by: ['done'],
filter_value: ['false'],
filter_comparator: ['equals'],
filter_concat: 'and',
}
function createPagination(totalPages, currentPage) {
const pages = []
for (let i = 0; i < totalPages; i++) {
// Show ellipsis instead of all pages
if (
i > 0 && // Always at least the first page
(i + 1) < totalPages && // And the last page
(
// And the current with current + 1 and current - 1
(i + 1) > currentPage + 1 ||
(i + 1) < currentPage - 1
)
) {
// Only add an ellipsis if the last page isn't already one
if (pages[i - 1] && !pages[i - 1].isEllipsis) {
pages.push({
number: 0,
isEllipsis: true,
})
}
continue
}
pages.push({
number: i + 1,
isEllipsis: false,
})
}
return pages
}
export function getRouteForPagination(page = 1, type = 'list') {
return {
name: 'list.' + type,
params: {
type: type,
},
query: {
page: page,
},
}
}
/**
* This mixin provides a base set of methods and properties to get tasks on a list.
*/
export default {
data() {
return {
taskCollectionService: new TaskCollectionService(),
taskCollectionService: TaskCollectionService,
tasks: [],
pages: [],
currentPage: 0,
loadedList: null,
@ -73,21 +20,27 @@ export default {
searchTerm: '',
showTaskFilter: false,
params: DEFAULT_PARAMS,
params: {
sort_by: ['position', 'id'],
order_by: ['asc', 'desc'],
filter_by: ['done'],
filter_value: ['false'],
filter_comparator: ['equals'],
filter_concat: 'and',
},
}
},
watch: {
// Only listen for query path changes
'$route.query': {
handler: 'loadTasksForPage',
immediate: true,
},
'$route.query': 'loadTasksForPage', // Only listen for query path changes
'$route.path': 'loadTasksOnSavedFilter',
},
computed: {
pages() {
return createPagination(this.taskCollectionService.totalPages, this.currentPage)
},
beforeMount() {
// Triggering loading the tasks in beforeMount lets the component maintain the current page, therefore the page
// is not lost after navigating back from a task detail page for example.
this.loadTasksForPage(this.$route.query)
},
created() {
this.taskCollectionService = new TaskCollectionService()
},
methods: {
loadTasks(
@ -127,20 +80,48 @@ export default {
return
}
this.tasks = []
this.$set(this, 'tasks', [])
this.taskCollectionService.getAll(list, params, page)
.then(r => {
this.tasks = r
this.$set(this, 'tasks', r)
this.$set(this, 'pages', [])
this.currentPage = page
for (let i = 0; i < this.taskCollectionService.totalPages; i++) {
// Show ellipsis instead of all pages
if (
i > 0 && // Always at least the first page
(i + 1) < this.taskCollectionService.totalPages && // And the last page
(
// And the current with current + 1 and current - 1
(i + 1) > this.currentPage + 1 ||
(i + 1) < this.currentPage - 1
)
) {
// Only add an ellipsis if the last page isn't already one
if (this.pages[i - 1] && !this.pages[i - 1].isEllipsis) {
this.pages.push({
number: 0,
isEllipsis: true,
})
}
continue
}
this.pages.push({
number: i + 1,
isEllipsis: false,
})
}
this.loadedList = cloneDeep(currentList)
})
.catch(e => {
this.error(e)
})
},
loadTasksForPage(e) {
// The page parameter can be undefined, in the case where the user loads a new list from the side bar menu
let page = Number(e.page)
@ -196,6 +177,17 @@ export default {
this.showTaskSearch = false
}, 200)
},
getRouteForPagination(page = 1, type = 'list') {
return {
name: 'list.' + type,
params: {
type: type,
},
query: {
page: page,
},
}
},
saveTaskPosition(e) {
this.drag = false
@ -213,6 +205,5 @@ export default {
this.error(e)
})
},
getRouteForPagination,
},
}

View File

@ -7,17 +7,16 @@
<h1
class="title input"
:class="{'disabled': !canWrite}"
@blur="save($event.target.textContent)"
@keydown.enter.prevent.stop="$event.target.blur()"
@focusout="save()"
@keydown.enter.prevent.stop="save()"
:contenteditable="canWrite ? 'true' : 'false'"
spellcheck="false"
ref="taskTitle">{{ task.title.trim() }}</h1>
<transition name="fade">
<span class="is-inline-flex is-align-items-center" v-if="loading && saving">
<span class="loader is-inline-block mr-2"></span>
{{ $t('misc.saving') }}
</span>
<span class="has-text-success is-inline-flex is-align-content-center" v-if="!loading && showSavedMessage">
<span class="has-text-success is-inline-flex is-align-content-center" v-if="!loading && saved">
<icon icon="check" class="mr-2"/>
{{ $t('misc.saved') }}
</span>
@ -26,22 +25,22 @@
</template>
<script>
import {LOADING} from '@/store/mutation-types'
import {mapState} from 'vuex'
export default {
name: 'heading',
data() {
return {
showSavedMessage: false,
task: {title: '', identifier: '', index:''},
taskTitle: '',
saved: false,
saving: false, // Since loading is global state, this variable ensures we're