forked from vikunja/frontend
Compare commits
1 Commits
main
...
feature/cr
Author | SHA1 | Date | |
---|---|---|---|
acf52fbe16 |
51
.drone.yml
51
.drone.yml
@ -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
|
||||
|
346
CHANGELOG.md
346
CHANGELOG.md
@ -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
|
||||
|
||||
|
@ -4,8 +4,8 @@
|
||||
|
||||
[](https://drone.kolaente.de/vikunja/frontend)
|
||||
[](LICENSE)
|
||||
[](https://dl.vikunja.io)
|
||||
[](https://crowdin.com/project/vikunja)
|
||||
[](https://dl.vikunja.io)
|
||||
[](https://hosted.weblate.org/engage/vikunja/)
|
||||
|
||||
This is the web frontend for Vikunja, written in Vue.js.
|
||||
|
||||
|
24
crowdin.yml
Normal file
24
crowdin.yml
Normal 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" : "",
|
@ -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
|
26
package.json
26
package.json
@ -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,
|
||||
|
10
src/App.vue
10
src/App.vue
@ -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() {
|
||||
|
@ -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,
|
||||
|
@ -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'
|
||||
|
@ -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)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -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: [],
|
||||
|
@ -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: {
|
||||
|
@ -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
|
||||
|
@ -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'
|
||||
|
||||
|
@ -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'
|
||||
|
@ -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'
|
||||
|
||||
|
@ -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'
|
||||
|
@ -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>
|
||||
|
@ -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,
|
||||
},
|
||||
}
|
@ -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 |