Compare commits

...

16 Commits

Author SHA1 Message Date
kolaente 04e88be8ce
Kind of fix registering the service worker 2021-03-10 14:04:15 +01:00
kolaente 16b2e14841
Pin dependencies 2021-03-10 12:23:44 +01:00
kolaente 5661acef36
Fix yarn scripts 2021-03-10 12:11:04 +01:00
kolaente 7e112ccd6d
Merge branch 'main' into feature/vite
# Conflicts:
#	package.json
2021-03-10 12:05:45 +01:00
kolaente cd2f691178
Fix local port for cypress 2021-02-23 23:07:57 +01:00
kolaente 04e0462cee
Fix port settings for vite dev server 2021-02-23 23:07:27 +01:00
kolaente 515eb28ba6
Wait on build for testing 2021-02-23 23:02:26 +01:00
kolaente aa52e29402
Fix url for testing 2021-02-23 22:57:22 +01:00
kolaente 978de3bfac
Switch to node:14 2021-02-23 22:51:12 +01:00
kolaente 8d1572ba47
Add vite as a dependency 2021-02-23 22:47:34 +01:00
kolaente 037338b8e3
Add 2021-02-23 22:32:43 +01:00
kolaente e7d24da035
Configure service worker 2021-02-23 22:17:16 +01:00
kolaente 006e9e8146
Configure chunks 2021-02-23 21:56:16 +01:00
kolaente 51c3b0dc36
Resolve all imports 2021-02-23 21:26:57 +01:00
kolaente b1afc5b1b7
Merge branch 'main' into feature/vite
# Conflicts:
#	yarn.lock
2021-02-23 20:44:35 +01:00
kolaente ee4b231afb
Add vite 2021-02-14 11:04:24 +01:00
52 changed files with 2853 additions and 843 deletions

View File

@ -37,7 +37,7 @@ steps:
- '.cache' - '.cache'
- name: dependencies - name: dependencies
image: node:12 image: node:14
pull: true pull: true
environment: environment:
YARN_CACHE_FOLDER: .cache/yarn/ YARN_CACHE_FOLDER: .cache/yarn/
@ -68,7 +68,7 @@ steps:
- dependencies - dependencies
- name: build - name: build
image: node:12 image: node:14
pull: true pull: true
environment: environment:
YARN_CACHE_FOLDER: .cache/yarn/ YARN_CACHE_FOLDER: .cache/yarn/
@ -80,7 +80,7 @@ steps:
- dependencies - dependencies
- name: test-unit - name: test-unit
image: node:12 image: node:14
pull: true pull: true
commands: commands:
- yarn test:unit - yarn test:unit
@ -88,7 +88,7 @@ steps:
- dependencies - dependencies
- name: test-frontend - name: test-frontend
image: cypress/browsers:node12.18.3-chrome87-ff82 image: cypress/browsers:node14.15.0-chrome86-ff82
pull: true pull: true
environment: environment:
CYPRESS_API_URL: http://api:3456/api/v1 CYPRESS_API_URL: http://api:3456/api/v1
@ -97,11 +97,11 @@ steps:
CYPRESS_CACHE_FOLDER: .cache/cypress/ CYPRESS_CACHE_FOLDER: .cache/cypress/
CYPRESS_DEFAULT_COMMAND_TIMEOUT: 10000 CYPRESS_DEFAULT_COMMAND_TIMEOUT: 10000
commands: commands:
- sed -i 's/localhost/api/g' public/index.html - sed -i 's/localhost/api/g' index.html
- yarn serve & npx wait-on http://localhost:8080 - yarn serve & npx wait-on http://localhost:5000
- yarn test:frontend --browser chrome - yarn test:frontend --browser chrome
depends_on: depends_on:
- dependencies - build
- name: upload-test-results - name: upload-test-results
image: plugins/s3:1 image: plugins/s3:1
@ -163,7 +163,7 @@ steps:
- '.cache' - '.cache'
- name: build - name: build
image: node:12 image: node:14
pull: true pull: true
group: build-static group: build-static
environment: environment:
@ -238,7 +238,7 @@ steps:
- '.cache' - '.cache'
- name: build - name: build
image: node:12 image: node:14
pull: true pull: true
group: build-static group: build-static
environment: environment:

View File

@ -1,5 +1,5 @@
# Stage 1: Build application # Stage 1: Build application
FROM node:13.14.0 AS compile-image FROM node:14 AS compile-image
WORKDIR /build WORKDIR /build

View File

@ -1,5 +1,5 @@
{ {
"baseUrl": "http://localhost:8080", "baseUrl": "http://localhost:5000",
"env": { "env": {
"API_URL": "http://localhost:3456/api/v1", "API_URL": "http://localhost:3456/api/v1",
"TEST_SECRET": "testingS3cr3et" "TEST_SECRET": "testingS3cr3et"

35
index.html Normal file
View File

@ -0,0 +1,35 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Vikunja</title>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<meta name="description" content="Vikunja (/vɪˈkuːnjə/) - The to-do app to organize your life.">
<link rel="icon" href="/favicon.ico">
<link rel="preload" crossorigin="anonymous" href="/fonts/open-sans-v15-latin-700italic.woff2" as="font">
<link rel="preload" crossorigin="anonymous" href="/fonts/open-sans-v15-latin-italic.woff2" as="font">
<link rel="preload" crossorigin="anonymous" href="/fonts/quicksand-v7-latin-300.woff2" as="font">
<link rel="preload" crossorigin="anonymous" href="/fonts/quicksand-v7-latin-500.woff2" as="font">
<link rel="preload" crossorigin="anonymous" href="/fonts/quicksand-v7-latin-700.woff2" as="font">
<link rel="preload" crossorigin="anonymous" href="/fonts/open-sans-v15-latin-regular.woff2" as="font">
<link rel="preload" crossorigin="anonymous" href="/fonts/open-sans-v15-latin-700.woff2" as="font">
<link rel="preload" crossorigin="anonymous" href="/fonts/quicksand-v7-latin-regular.woff2" as="font">
</head>
<body>
<noscript>
<strong>We're sorry but Vikunja doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<script type="module" src="./src/main.js"></script>
<script>
//
// This variable points the frontend to the api.
// It has to be the full url, including the last /api/v1 part and port.
// You can change this if your api is not reachable on the same port as the frontend.
window.API_URL = 'http://localhost:3456/api/v1'
//
</script>
</body>
</html>

View File

@ -3,9 +3,9 @@
"version": "0.10.0", "version": "0.10.0",
"private": true, "private": true,
"scripts": { "scripts": {
"serve": "vue-cli-service serve", "serve": "npx vite preview",
"serve:dist": "node scripts/serve-dist.js", "serve:dist": "node scripts/serve-dist.js",
"build": "vue-cli-service build --modern", "build": "npx workbox copyLibraries dist/ && npx vite build",
"build:report": "vue-cli-service build --report", "build:report": "vue-cli-service build --report",
"lint": "vue-cli-service lint --ignore-pattern '*.test.*'", "lint": "vue-cli-service lint --ignore-pattern '*.test.*'",
"cypress:open": "cypress open", "cypress:open": "cypress open",
@ -30,7 +30,8 @@
"vue-easymde": "1.3.2", "vue-easymde": "1.3.2",
"vue-shortkey": "3.1.7", "vue-shortkey": "3.1.7",
"vue-smooth-dnd": "0.8.1", "vue-smooth-dnd": "0.8.1",
"vuex": "3.6.2" "vuex": "3.6.2",
"workbox-precaching": "^6.1.1"
}, },
"devDependencies": { "devDependencies": {
"@fortawesome/fontawesome-svg-core": "1.2.34", "@fortawesome/fontawesome-svg-core": "1.2.34",
@ -46,17 +47,23 @@
"babel-eslint": "10.1.0", "babel-eslint": "10.1.0",
"cypress": "6.6.0", "cypress": "6.6.0",
"cypress-file-upload": "5.0.2", "cypress-file-upload": "5.0.2",
"esbuild": "0.8.51",
"eslint": "7.21.0", "eslint": "7.21.0",
"eslint-plugin-vue": "7.7.0", "eslint-plugin-vue": "7.7.0",
"faker": "5.4.0", "faker": "5.4.0",
"jest": "26.6.3", "jest": "26.6.3",
"node-sass": "5.0.0", "node-sass": "5.0.0",
"sass": "1.32.8",
"sass-loader": "10.1.1", "sass-loader": "10.1.1",
"vite": "2.0.2",
"vite-plugin-pwa": "0.5.6",
"vite-plugin-vue2": "1.2.1",
"vue-flatpickr-component": "8.1.6", "vue-flatpickr-component": "8.1.6",
"vue-notification": "1.3.20", "vue-notification": "1.3.20",
"vue-router": "3.5.1", "vue-router": "3.5.1",
"vue-template-compiler": "2.6.12", "vue-template-compiler": "2.6.12",
"wait-on": "5.2.1" "wait-on": "5.2.1",
"workbox-cli": "6.1.1"
}, },
"eslintConfig": { "eslintConfig": {
"root": true, "root": true,

View File

@ -16,9 +16,6 @@
height="1066.6667" height="1066.6667"
viewBox="0 0 1066.6667 1066.6667" viewBox="0 0 1066.6667 1066.6667"
sodipodi:docname="llama-nightscape.svg" sodipodi:docname="llama-nightscape.svg"
inkscape:export-filename="/home/konrad/www/vikunja/frontend/public/images/llama-nightscape.png"
inkscape:export-xdpi="172.8"
inkscape:export-ydpi="172.8"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"><metadata inkscape:version="0.92.4 (5da689c313, 2019-01-14)"><metadata
id="metadata8"><rdf:RDF><cc:Work id="metadata8"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type

Before

Width:  |  Height:  |  Size: 174 KiB

After

Width:  |  Height:  |  Size: 174 KiB

View File

@ -1,36 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Vikunja</title>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<meta name="description" content="Vikunja (/vɪˈkuːnjə/) - The to-do app to organize your life.">
<meta name="hash" content="<%= webpack.hash %>"/>
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<link rel="preload" crossorigin="anonymous" href="<%= BASE_URL %>fonts/open-sans-v15-latin-700italic.woff2" as="font">
<link rel="preload" crossorigin="anonymous" href="<%= BASE_URL %>fonts/open-sans-v15-latin-italic.woff2" as="font">
<link rel="preload" crossorigin="anonymous" href="<%= BASE_URL %>fonts/quicksand-v7-latin-300.woff2" as="font">
<link rel="preload" crossorigin="anonymous" href="<%= BASE_URL %>fonts/quicksand-v7-latin-500.woff2" as="font">
<link rel="preload" crossorigin="anonymous" href="<%= BASE_URL %>fonts/quicksand-v7-latin-700.woff2" as="font">
<link rel="preload" crossorigin="anonymous" href="<%= BASE_URL %>fonts/open-sans-v15-latin-regular.woff2" as="font">
<link rel="preload" crossorigin="anonymous" href="<%= BASE_URL %>fonts/open-sans-v15-latin-700.woff2" as="font">
<link rel="preload" crossorigin="anonymous" href="<%= BASE_URL %>fonts/quicksand-v7-latin-regular.woff2" as="font">
</head>
<body>
<noscript>
<strong>We're sorry but Vikunja doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
<script>
//
// This variable points the frontend to the api.
// It has to be the full url, including the last /api/v1 part and port.
// You can change this if your api is not reachable on the same port as the frontend.
window.API_URL = 'http://localhost:3456/api/v1'
//
</script>
</body>
</html>

View File

@ -3,7 +3,7 @@ const express = require('express')
const app = express() const app = express()
const p = path.join(__dirname, '..', 'dist') const p = path.join(__dirname, '..', 'dist')
const port = 8080 const port = 8000
app.use(express.static(p)) app.use(express.static(p))
// Handle urls set by the frontend // Handle urls set by the frontend

View File

@ -30,10 +30,10 @@ import authTypes from './models/authTypes'
import Notification from './components/misc/notification' import Notification from './components/misc/notification'
import {KEYBOARD_SHORTCUTS_ACTIVE, ONLINE} from './store/mutation-types' import {KEYBOARD_SHORTCUTS_ACTIVE, ONLINE} from './store/mutation-types'
import KeyboardShortcuts from './components/misc/keyboard-shortcuts' import KeyboardShortcuts from './components/misc/keyboard-shortcuts'
import TopNavigation from '@/components/home/topNavigation' import TopNavigation from './components/home/topNavigation'
import ContentAuth from '@/components/home/contentAuth' import ContentAuth from './components/home/contentAuth'
import ContentLinkShare from '@/components/home/contentLinkShare' import ContentLinkShare from './components/home/contentLinkShare'
import ContentNoAuth from '@/components/home/contentNoAuth' import ContentNoAuth from './components/home/contentNoAuth'
export default { export default {
name: 'app', name: 'app',

View File

@ -1,6 +1,12 @@
/* eslint-disable no-console */ /* eslint-disable no-console */
/* eslint-disable no-undef */ /* eslint-disable no-undef */
importScripts( "/workbox-v6.1.1/workbox-sw.js");
workbox.setConfig({modulePathPrefix: "/workbox-v6.1.1"});
import { precacheAndRoute } from 'workbox-precaching'
precacheAndRoute(self.__WB_MANIFEST)
// Cache assets // Cache assets
workbox.routing.registerRoute( workbox.routing.registerRoute(
// This regexp matches all files in precache-manifest // This regexp matches all files in precache-manifest

View File

@ -37,7 +37,7 @@
<script> <script>
import {mapState} from 'vuex' import {mapState} from 'vuex'
import {CURRENT_LIST, MENU_ACTIVE} from '@/store/mutation-types' import {CURRENT_LIST, MENU_ACTIVE} from '@/store/mutation-types'
import Navigation from '@/components/home/navigation' import Navigation from '@/components/home/navigation.vue'
export default { export default {
name: 'contentAuth', name: 'contentAuth',

View File

@ -115,7 +115,7 @@
<script> <script>
import {mapState} from 'vuex' import {mapState} from 'vuex'
import {CURRENT_LIST, MENU_ACTIVE, LOADING, LOADING_MODULE} from '@/store/mutation-types' import {CURRENT_LIST, MENU_ACTIVE, LOADING, LOADING_MODULE} from '@/store/mutation-types'
import ListSettingsDropdown from '@/components/list/list-settings-dropdown' import ListSettingsDropdown from '@/components/list/list-settings-dropdown.vue'
import NamespaceSettingsDropdown from '@/components/namespace/namespace-settings-dropdown.vue' import NamespaceSettingsDropdown from '@/components/namespace/namespace-settings-dropdown.vue'
export default { export default {

View File

@ -84,10 +84,10 @@
import {mapState} from 'vuex' import {mapState} from 'vuex'
import {CURRENT_LIST} from '@/store/mutation-types' import {CURRENT_LIST} from '@/store/mutation-types'
import Rights from '@/models/rights.json' import Rights from '@/models/rights.json'
import Update from '@/components/home/update' import Update from '@/components/home/update.vue'
import ListSettingsDropdown from '@/components/list/list-settings-dropdown' import ListSettingsDropdown from '@/components/list/list-settings-dropdown.vue'
import Dropdown from '@/components/misc/dropdown' import Dropdown from '@/components/misc/dropdown.vue'
import Notifications from '@/components/notifications/notifications' import Notifications from '@/components/notifications/notifications.vue'
export default { export default {
name: 'topNavigation', name: 'topNavigation',

View File

@ -26,7 +26,6 @@
<script> <script>
import verte from 'verte' import verte from 'verte'
import 'verte/dist/verte.css'
export default { export default {
name: 'colorPicker', name: 'colorPicker',
@ -91,6 +90,8 @@ export default {
</script> </script>
<style lang="scss"> <style lang="scss">
@import 'verte/dist/verte.css';
.verte.is-empty { .verte.is-empty {
.verte__icon { .verte__icon {
opacity: 0; opacity: 0;

View File

@ -75,9 +75,9 @@
<script> <script>
import {getSavedFilterIdFromListId} from '@/helpers/savedFilter' import {getSavedFilterIdFromListId} from '@/helpers/savedFilter'
import Dropdown from '@/components/misc/dropdown' import Dropdown from '@/components/misc/dropdown.vue'
import DropdownItem from '@/components/misc/dropdown-item' import DropdownItem from '@/components/misc/dropdown-item.vue'
import TaskSubscription from '@/components/misc/subscription' import TaskSubscription from '@/components/misc/subscription.vue'
export default { export default {
name: 'list-settings-dropdown', name: 'list-settings-dropdown',

View File

@ -185,9 +185,9 @@ import 'flatpickr/dist/flatpickr.css'
import {formatISO} from 'date-fns' import {formatISO} from 'date-fns'
import differenceWith from 'lodash/differenceWith' import differenceWith from 'lodash/differenceWith'
import PrioritySelect from '@/components/tasks/partials/prioritySelect' import PrioritySelect from '@/components/tasks/partials/prioritySelect.vue'
import PercentDoneSelect from '@/components/tasks/partials/percentDoneSelect' import PercentDoneSelect from '@/components/tasks/partials/percentDoneSelect.vue'
import Multiselect from '@/components/input/multiselect' import Multiselect from '@/components/input/multiselect.vue'
import UserService from '@/services/user' import UserService from '@/services/user'
import LabelService from '@/services/label' import LabelService from '@/services/label'

View File

@ -53,7 +53,7 @@
<script> <script>
import {KEYBOARD_SHORTCUTS_ACTIVE} from '@/store/mutation-types' import {KEYBOARD_SHORTCUTS_ACTIVE} from '@/store/mutation-types'
import Shortcut from '@/components/misc/shortcut' import Shortcut from '@/components/misc/shortcut.vue'
export default { export default {
name: 'keyboard-shortcuts', name: 'keyboard-shortcuts',

View File

@ -14,7 +14,7 @@
import NamespaceService from '../../services/namespace' import NamespaceService from '../../services/namespace'
import NamespaceModel from '../../models/namespace' import NamespaceModel from '../../models/namespace'
import Multiselect from '@/components/input/multiselect' import Multiselect from '@/components/input/multiselect.vue'
export default { export default {
name: 'namespace-search', name: 'namespace-search',

View File

@ -53,9 +53,9 @@
</template> </template>
<script> <script>
import Dropdown from '@/components/misc/dropdown' import Dropdown from '@/components/misc/dropdown.vue'
import DropdownItem from '@/components/misc/dropdown-item' import DropdownItem from '@/components/misc/dropdown-item.vue'
import TaskSubscription from '@/components/misc/subscription' import TaskSubscription from '@/components/misc/subscription.vue'
export default { export default {
name: 'namespace-settings-dropdown', name: 'namespace-settings-dropdown',

View File

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

View File

@ -148,8 +148,8 @@ import TeamService from '../../services/team'
import TeamModel from '../../models/team' import TeamModel from '../../models/team'
import rights from '../../models/rights' import rights from '../../models/rights'
import Multiselect from '@/components/input/multiselect' import Multiselect from '@/components/input/multiselect.vue'
import Nothing from '@/components/misc/nothing' import Nothing from '@/components/misc/nothing.vue'
export default { export default {
name: 'userTeamShare', name: 'userTeamShare',

View File

@ -201,7 +201,7 @@ import PriorityLabel from './partials/priorityLabel'
import TaskCollectionService from '../../services/taskCollection' import TaskCollectionService from '../../services/taskCollection'
import {mapState} from 'vuex' import {mapState} from 'vuex'
import Rights from '../../models/rights.json' import Rights from '../../models/rights.json'
import FilterPopup from '@/components/list/partials/filter-popup' import FilterPopup from '@/components/list/partials/filter-popup.vue'
export default { export default {
name: 'GanttChart', name: 'GanttChart',

View File

@ -28,8 +28,8 @@
</template> </template>
<script> <script>
import LoadingComponent from '@/components/misc/loading' import LoadingComponent from '@/components/misc/loading.vue'
import ErrorComponent from '@/components/misc/error' import ErrorComponent from '@/components/misc/error.vue'
import {LOADING} from '@/store/mutation-types' import {LOADING} from '@/store/mutation-types'
import {mapState} from 'vuex' import {mapState} from 'vuex'
@ -38,7 +38,7 @@ export default {
name: 'description', name: 'description',
components: { components: {
editor: () => ({ editor: () => ({
component: import(/* webpackChunkName: "editor" */ '@/components/input/editor'), component: import(/* webpackChunkName: "editor" */ '@/components/input/editor.vue'),
loading: LoadingComponent, loading: LoadingComponent,
error: ErrorComponent, error: ErrorComponent,
timeout: 60000, timeout: 60000,

View File

@ -29,7 +29,7 @@ import UserModel from '../../../models/user'
import ListUserService from '../../../services/listUsers' import ListUserService from '../../../services/listUsers'
import TaskAssigneeService from '../../../services/taskAssignee' import TaskAssigneeService from '../../../services/taskAssignee'
import User from '../../misc/user' import User from '../../misc/user'
import Multiselect from '@/components/input/multiselect' import Multiselect from '@/components/input/multiselect.vue'
export default { export default {
name: 'editAssignees', name: 'editAssignees',

View File

@ -43,7 +43,7 @@ import LabelService from '../../../services/label'
import LabelModel from '../../../models/label' import LabelModel from '../../../models/label'
import LabelTaskService from '../../../services/labelTask' import LabelTaskService from '../../../services/labelTask'
import Multiselect from '@/components/input/multiselect' import Multiselect from '@/components/input/multiselect.vue'
export default { export default {
name: 'edit-labels', name: 'edit-labels',

View File

@ -21,7 +21,7 @@
<script> <script>
import ListService from '../../../services/list' import ListService from '../../../services/list'
import ListModel from '../../../models/list' import ListModel from '../../../models/list'
import Multiselect from '@/components/input/multiselect' import Multiselect from '@/components/input/multiselect.vue'
export default { export default {
name: 'listSearch', name: 'listSearch',

View File

@ -123,7 +123,7 @@ import TaskRelationService from '../../../services/taskRelation'
import relationKinds from '../../../models/relationKinds' import relationKinds from '../../../models/relationKinds'
import TaskRelationModel from '../../../models/taskRelation' import TaskRelationModel from '../../../models/taskRelation'
import Multiselect from '@/components/input/multiselect' import Multiselect from '@/components/input/multiselect.vue'
export default { export default {
name: 'relatedTasks', name: 'relatedTasks',

View File

@ -26,7 +26,7 @@
</template> </template>
<script> <script>
import datepicker from '@/components/input/datepicker' import datepicker from '@/components/input/datepicker.vue'
export default { export default {
name: 'reminders', name: 'reminders',

View File

@ -160,10 +160,10 @@ Vue.component('icon', FontAwesomeIcon)
Vue.use(vueShortkey, { prevent: ['input', 'textarea', '.input'] }) Vue.use(vueShortkey, { prevent: ['input', 'textarea', '.input'] })
import focus from '@/directives/focus' import focus from './directives/focus'
Vue.directive('focus', focus) Vue.directive('focus', focus)
import tooltip from '@/directives/tooltip' import tooltip from './directives/tooltip'
Vue.directive('tooltip', tooltip) Vue.directive('tooltip', tooltip)
const formatDate = (date, f) => { const formatDate = (date, f) => {
@ -173,10 +173,10 @@ const formatDate = (date, f) => {
return date ? format(date, f) : '' return date ? format(date, f) : ''
} }
import Button from '@/components/input/button' import Button from './components/input/button'
Vue.component('x-button', Button) Vue.component('x-button', Button)
import Card from '@/components/misc/card' import Card from './components/misc/card'
Vue.component('card', Card) Vue.component('card', Card)
Vue.mixin({ Vue.mixin({

View File

@ -4,7 +4,7 @@ import {register} from 'register-service-worker'
import swEvents from './ServiceWorker/events' import swEvents from './ServiceWorker/events'
if (process.env.NODE_ENV === 'production') { if (process.env.NODE_ENV === 'production') {
register(`${process.env.BASE_URL}sw.js`, { register('/sw.js', {
ready() { ready() {
console.log('App is being served from cache by a service worker.') console.log('App is being served from cache by a service worker.')
}, },

View File

@ -8,7 +8,7 @@ import ErrorComponent from '../components/misc/error'
// User Handling // User Handling
import LoginComponent from '../views/user/Login' import LoginComponent from '../views/user/Login'
import RegisterComponent from '../views/user/Register' import RegisterComponent from '../views/user/Register'
import OpenIdAuth from '@/views/user/OpenIdAuth' import OpenIdAuth from '../views/user/OpenIdAuth'
// Tasks // Tasks
import ShowTasksInRangeComponent from '../views/tasks/ShowTasksInRange' import ShowTasksInRangeComponent from '../views/tasks/ShowTasksInRange'
import LinkShareAuthComponent from '../views/sharing/LinkSharingAuth' import LinkShareAuthComponent from '../views/sharing/LinkSharingAuth'
@ -30,63 +30,63 @@ import List from '../views/list/views/List'
import Gantt from '../views/list/views/Gantt' import Gantt from '../views/list/views/Gantt'
import Table from '../views/list/views/Table' import Table from '../views/list/views/Table'
// List Settings // List Settings
import ListSettingEdit from '@/views/list/settings/edit' import ListSettingEdit from '../views/list/settings/edit'
import ListSettingBackground from '@/views/list/settings/background' import ListSettingBackground from '../views/list/settings/background'
import ListSettingDuplicate from '@/views/list/settings/duplicate' import ListSettingDuplicate from '../views/list/settings/duplicate'
import ListSettingShare from '@/views/list/settings/share' import ListSettingShare from '../views/list/settings/share'
import ListSettingDelete from '@/views/list/settings/delete' import ListSettingDelete from '../views/list/settings/delete'
import ListSettingArchive from '@/views/list/settings/archive' import ListSettingArchive from '../views/list/settings/archive'
import FilterSettingEdit from '@/views/filters/settings/edit' import FilterSettingEdit from '../views/filters/settings/edit'
import FilterSettingDelete from '@/views/filters/settings/delete' import FilterSettingDelete from '../views/filters/settings/delete'
// Namespace Settings // Namespace Settings
import NamespaceSettingEdit from '@/views/namespaces/settings/edit' import NamespaceSettingEdit from '../views/namespaces/settings/edit'
import NamespaceSettingShare from '@/views/namespaces/settings/share' import NamespaceSettingShare from '../views/namespaces/settings/share'
import NamespaceSettingArchive from '@/views/namespaces/settings/archive' import NamespaceSettingArchive from '../views/namespaces/settings/archive'
import NamespaceSettingDelete from '@/views/namespaces/settings/delete' import NamespaceSettingDelete from '../views/namespaces/settings/delete'
// Saved Filters // Saved Filters
import CreateSavedFilter from '@/views/filters/CreateSavedFilter' import CreateSavedFilter from '../views/filters/CreateSavedFilter'
const PasswordResetComponent = () => ({ const PasswordResetComponent = () => ({
component: import(/* webpackChunkName: "user-settings" */'../views/user/PasswordReset'), component: import('../views/user/PasswordReset'),
loading: LoadingComponent, loading: LoadingComponent,
error: ErrorComponent, error: ErrorComponent,
timeout: 60000, timeout: 60000,
}) })
const GetPasswordResetComponent = () => ({ const GetPasswordResetComponent = () => ({
component: import(/* webpackChunkName: "user-settings" */'../views/user/RequestPasswordReset'), component: import('../views/user/RequestPasswordReset'),
loading: LoadingComponent, loading: LoadingComponent,
error: ErrorComponent, error: ErrorComponent,
timeout: 60000, timeout: 60000,
}) })
const UserSettingsComponent = () => ({ const UserSettingsComponent = () => ({
component: import(/* webpackChunkName: "user-settings" */'../views/user/Settings'), component: import('../views/user/Settings'),
loading: LoadingComponent, loading: LoadingComponent,
error: ErrorComponent, error: ErrorComponent,
timeout: 60000, timeout: 60000,
}) })
// List Handling // List Handling
const NewListComponent = () => ({ const NewListComponent = () => ({
component: import(/* webpackChunkName: "settings" */'../views/list/NewList'), component: import('../views/list/NewList'),
loading: LoadingComponent, loading: LoadingComponent,
error: ErrorComponent, error: ErrorComponent,
timeout: 60000, timeout: 60000,
}) })
// Namespace Handling // Namespace Handling
const NewNamespaceComponent = () => ({ const NewNamespaceComponent = () => ({
component: import(/* webpackChunkName: "settings" */'../views/namespaces/NewNamespace'), component: import('../views/namespaces/NewNamespace'),
loading: LoadingComponent, loading: LoadingComponent,
error: ErrorComponent, error: ErrorComponent,
timeout: 60000, timeout: 60000,
}) })
const EditTeamComponent = () => ({ const EditTeamComponent = () => ({
component: import(/* webpackChunkName: "settings" */'../views/teams/EditTeam'), component: import('../views/teams/EditTeam'),
loading: LoadingComponent, loading: LoadingComponent,
error: ErrorComponent, error: ErrorComponent,
timeout: 60000, timeout: 60000,
}) })
const NewTeamComponent = () => ({ const NewTeamComponent = () => ({
component: import(/* webpackChunkName: "settings" */'../views/teams/NewTeam'), component: import('../views/teams/NewTeam'),
loading: LoadingComponent, loading: LoadingComponent,
error: ErrorComponent, error: ErrorComponent,
timeout: 60000, timeout: 60000,

View File

@ -1,5 +1,5 @@
.offline { .offline {
background: url('../../public/images/llama-nightscape.png') no-repeat center; background: url('/images/llama-nightscape.png') no-repeat center;
-webkit-background-size: cover; -webkit-background-size: cover;
background-size: cover; background-size: cover;
height: 100vh; height: 100vh;

View File

@ -62,9 +62,9 @@
</template> </template>
<script> <script>
import LoadingComponent from '@/components/misc/loading' import LoadingComponent from '@/components/misc/loading.vue'
import ErrorComponent from '@/components/misc/error' import ErrorComponent from '@/components/misc/error.vue'
import Filters from '@/components/list/partials/filters' import Filters from '@/components/list/partials/filters.vue'
import SavedFilterService from '@/services/savedFilter' import SavedFilterService from '@/services/savedFilter'
import SavedFilterModel from '@/models/savedFilter' import SavedFilterModel from '@/models/savedFilter'

View File

@ -52,14 +52,14 @@
</template> </template>
<script> <script>
import ErrorComponent from '@/components/misc/error' import ErrorComponent from '@/components/misc/error.vue'
import LoadingComponent from '@/components/misc/loading' import LoadingComponent from '@/components/misc/loading.vue'
import CreateEdit from '@/components/misc/create-edit' import CreateEdit from '@/components/misc/create-edit.vue'
import SavedFilterModel from '@/models/savedFilter' import SavedFilterModel from '@/models/savedFilter'
import SavedFilterService from '@/services/savedFilter' import SavedFilterService from '@/services/savedFilter'
import ListModel from '@/models/list' import ListModel from '@/models/list'
import Filters from '@/components/list/partials/filters' import Filters from '@/components/list/partials/filters.vue'
import {objectToSnakeCase} from '@/helpers/case' import {objectToSnakeCase} from '@/helpers/case'
export default { export default {
@ -85,7 +85,7 @@ export default {
CreateEdit, CreateEdit,
Filters, Filters,
editor: () => ({ editor: () => ({
component: import(/* webpackChunkName: "editor" */ '@/components/input/editor'), component: import(/* webpackChunkName: "editor" */ '@/components/input/editor.vue'),
loading: LoadingComponent, loading: LoadingComponent,
error: ErrorComponent, error: ErrorComponent,
timeout: 60000, timeout: 60000,

View File

@ -39,7 +39,7 @@ import labelModel from '../../models/label'
import labelService from '../../services/label' import labelService from '../../services/label'
import LabelModel from '../../models/label' import LabelModel from '../../models/label'
import LabelService from '../../services/label' import LabelService from '../../services/label'
import CreateEdit from '@/components/misc/create-edit' import CreateEdit from '@/components/misc/create-edit.vue'
import ColorPicker from '../../components/input/colorPicker' import ColorPicker from '../../components/input/colorPicker'
export default { export default {

View File

@ -34,7 +34,7 @@
<script> <script>
import ListService from '../../services/list' import ListService from '../../services/list'
import ListModel from '../../models/list' import ListModel from '../../models/list'
import CreateEdit from '@/components/misc/create-edit' import CreateEdit from '@/components/misc/create-edit.vue'
import ColorPicker from '../../components/input/colorPicker' import ColorPicker from '../../components/input/colorPicker'
export default { export default {

View File

@ -63,7 +63,7 @@
import BackgroundUnsplashService from '../../../services/backgroundUnsplash' import BackgroundUnsplashService from '../../../services/backgroundUnsplash'
import BackgroundUploadService from '../../../services/backgroundUpload' import BackgroundUploadService from '../../../services/backgroundUpload'
import {CURRENT_LIST} from '@/store/mutation-types' import {CURRENT_LIST} from '@/store/mutation-types'
import CreateEdit from '@/components/misc/create-edit' import CreateEdit from '@/components/misc/create-edit.vue'
export default { export default {
name: 'list-setting-background', name: 'list-setting-background',

View File

@ -13,9 +13,9 @@
<script> <script>
import ListDuplicateService from '@/services/listDuplicateService' import ListDuplicateService from '@/services/listDuplicateService'
import NamespaceSearch from '@/components/namespace/namespace-search' import NamespaceSearch from '@/components/namespace/namespace-search.vue'
import ListDuplicateModel from '@/models/listDuplicateModel' import ListDuplicateModel from '@/models/listDuplicateModel'
import CreateEdit from '@/components/misc/create-edit' import CreateEdit from '@/components/misc/create-edit.vue'
export default { export default {
name: 'list-setting-duplicate', name: 'list-setting-duplicate',

View File

@ -68,12 +68,12 @@
<script> <script>
import ListModel from '@/models/list' import ListModel from '@/models/list'
import ListService from '@/services/list' import ListService from '@/services/list'
import ColorPicker from '@/components/input/colorPicker' import ColorPicker from '@/components/input/colorPicker.vue'
import LoadingComponent from '@/components/misc/loading' import LoadingComponent from '@/components/misc/loading.vue'
import ErrorComponent from '@/components/misc/error' import ErrorComponent from '@/components/misc/error.vue'
import ListDuplicateService from '@/services/listDuplicateService' import ListDuplicateService from '@/services/listDuplicateService'
import {CURRENT_LIST} from '@/store/mutation-types' import {CURRENT_LIST} from '@/store/mutation-types'
import CreateEdit from '@/components/misc/create-edit' import CreateEdit from '@/components/misc/create-edit.vue'
export default { export default {
name: 'list-setting-edit', name: 'list-setting-edit',
@ -87,7 +87,7 @@ export default {
CreateEdit, CreateEdit,
ColorPicker, ColorPicker,
editor: () => ({ editor: () => ({
component: import(/* webpackChunkName: "editor" */ '@/components/input/editor'), component: import(/* webpackChunkName: "editor" */ '@/components/input/editor.vue'),
loading: LoadingComponent, loading: LoadingComponent,
error: ErrorComponent, error: ErrorComponent,
timeout: 60000, timeout: 60000,

View File

@ -25,9 +25,9 @@ import ListService from '@/services/list'
import ListModel from '@/models/list' import ListModel from '@/models/list'
import {CURRENT_LIST} from '@/store/mutation-types' import {CURRENT_LIST} from '@/store/mutation-types'
import CreateEdit from '@/components/misc/create-edit' import CreateEdit from '@/components/misc/create-edit.vue'
import LinkSharing from '@/components/sharing/linkSharing' import LinkSharing from '@/components/sharing/linkSharing.vue'
import userTeam from '@/components/sharing/userTeam' import userTeam from '@/components/sharing/userTeam.vue'
export default { export default {
name: 'list-setting-share', name: 'list-setting-share',

View File

@ -263,8 +263,8 @@ import {mapState} from 'vuex'
import {saveListView} from '@/helpers/saveListView' import {saveListView} from '@/helpers/saveListView'
import Rights from '../../../models/rights.json' import Rights from '../../../models/rights.json'
import {LOADING, LOADING_MODULE} from '@/store/mutation-types' import {LOADING, LOADING_MODULE} from '@/store/mutation-types'
import FilterPopup from '@/components/list/partials/filter-popup' import FilterPopup from '@/components/list/partials/filter-popup.vue'
import Dropdown from '@/components/misc/dropdown' import Dropdown from '@/components/misc/dropdown.vue'
import {playPop} from '@/helpers/playPop' import {playPop} from '@/helpers/playPop'
export default { export default {

View File

@ -171,9 +171,9 @@ import taskList from '../../../components/tasks/mixins/taskList'
import {saveListView} from '@/helpers/saveListView' import {saveListView} from '@/helpers/saveListView'
import Rights from '../../../models/rights.json' import Rights from '../../../models/rights.json'
import {mapState} from 'vuex' import {mapState} from 'vuex'
import FilterPopup from '@/components/list/partials/filter-popup' import FilterPopup from '@/components/list/partials/filter-popup.vue'
import {HAS_TASKS} from '@/store/mutation-types' import {HAS_TASKS} from '@/store/mutation-types'
import Nothing from '@/components/misc/nothing' import Nothing from '@/components/misc/nothing.vue'
export default { export default {
name: 'List', name: 'List',

View File

@ -199,7 +199,7 @@ import DateTableCell from '../../../components/tasks/partials/date-table-cell'
import Fancycheckbox from '../../../components/input/fancycheckbox' import Fancycheckbox from '../../../components/input/fancycheckbox'
import Sort from '../../../components/tasks/partials/sort' import Sort from '../../../components/tasks/partials/sort'
import {saveListView} from '@/helpers/saveListView' import {saveListView} from '@/helpers/saveListView'
import FilterPopup from '@/components/list/partials/filter-popup' import FilterPopup from '@/components/list/partials/filter-popup.vue'
export default { export default {
name: 'Table', name: 'Table',

View File

@ -45,7 +45,7 @@
<script> <script>
import NamespaceModel from '../../models/namespace' import NamespaceModel from '../../models/namespace'
import NamespaceService from '../../services/namespace' import NamespaceService from '../../services/namespace'
import CreateEdit from '@/components/misc/create-edit' import CreateEdit from '@/components/misc/create-edit.vue'
import ColorPicker from '../../components/input/colorPicker' import ColorPicker from '../../components/input/colorPicker'
export default { export default {

View File

@ -59,11 +59,11 @@
<script> <script>
import NamespaceService from '@/services/namespace' import NamespaceService from '@/services/namespace'
import NamespaceModel from '@/models/namespace' import NamespaceModel from '@/models/namespace'
import Fancycheckbox from '@/components/input/fancycheckbox' import Fancycheckbox from '@/components/input/fancycheckbox.vue'
import ColorPicker from '@/components/input/colorPicker' import ColorPicker from '@/components/input/colorPicker.vue'
import LoadingComponent from '@/components/misc/loading' import LoadingComponent from '@/components/misc/loading.vue'
import ErrorComponent from '@/components/misc/error' import ErrorComponent from '@/components/misc/error.vue'
import CreateEdit from '@/components/misc/create-edit' import CreateEdit from '@/components/misc/create-edit.vue'
export default { export default {
name: 'namespace-setting-edit', name: 'namespace-setting-edit',
@ -80,7 +80,7 @@ export default {
ColorPicker, ColorPicker,
Fancycheckbox, Fancycheckbox,
editor: () => ({ editor: () => ({
component: import(/* webpackChunkName: "editor" */ '@/components/input/editor'), component: import(/* webpackChunkName: "editor" */ '@/components/input/editor.vue'),
loading: LoadingComponent, loading: LoadingComponent,
error: ErrorComponent, error: ErrorComponent,
timeout: 60000, timeout: 60000,

View File

@ -19,8 +19,8 @@
</template> </template>
<script> <script>
import manageSharing from '@/components/sharing/userTeam' import manageSharing from '@/components/sharing/userTeam.vue'
import CreateEdit from '@/components/misc/create-edit' import CreateEdit from '@/components/misc/create-edit.vue'
import NamespaceService from '@/services/namespace' import NamespaceService from '@/services/namespace'
import NamespaceModel from '@/models/namespace' import NamespaceModel from '@/models/namespace'

View File

@ -422,13 +422,13 @@ import RepeatAfter from '../../components/tasks/partials/repeatAfter'
import Reminders from '../../components/tasks/partials/reminders' import Reminders from '../../components/tasks/partials/reminders'
import Comments from '../../components/tasks/partials/comments' import Comments from '../../components/tasks/partials/comments'
import ListSearch from '../../components/tasks/partials/listSearch' import ListSearch from '../../components/tasks/partials/listSearch'
import description from '@/components/tasks/partials/description' import description from '@/components/tasks/partials/description.vue'
import ColorPicker from '../../components/input/colorPicker' import ColorPicker from '../../components/input/colorPicker'
import attachmentUpload from '../../components/tasks/mixins/attachmentUpload' import attachmentUpload from '../../components/tasks/mixins/attachmentUpload'
import heading from '@/components/tasks/partials/heading' import heading from '@/components/tasks/partials/heading.vue'
import Datepicker from '@/components/input/datepicker' import Datepicker from '@/components/input/datepicker.vue'
import {playPop} from '@/helpers/playPop' import {playPop} from '@/helpers/playPop'
import TaskSubscription from '@/components/misc/subscription' import TaskSubscription from '@/components/misc/subscription.vue'
export default { export default {
name: 'TaskDetailView', name: 'TaskDetailView',

View File

@ -184,7 +184,7 @@ import Rights from '../../models/rights.json'
import LoadingComponent from '../../components/misc/loading' import LoadingComponent from '../../components/misc/loading'
import ErrorComponent from '../../components/misc/error' import ErrorComponent from '../../components/misc/error'
import Multiselect from '@/components/input/multiselect' import Multiselect from '@/components/input/multiselect.vue'
export default { export default {
name: 'EditTeam', name: 'EditTeam',

View File

@ -31,7 +31,7 @@
<script> <script>
import TeamModel from '../../models/team' import TeamModel from '../../models/team'
import TeamService from '../../services/team' import TeamService from '../../services/team'
import CreateEdit from '@/components/misc/create-edit' import CreateEdit from '@/components/misc/create-edit.vue'
export default { export default {
name: 'NewTeam', name: 'NewTeam',

View File

@ -107,7 +107,7 @@ import {HTTPFactory} from '@/http-common'
import message from '../../message' import message from '../../message'
import {ERROR_MESSAGE, LOADING} from '@/store/mutation-types' import {ERROR_MESSAGE, LOADING} from '@/store/mutation-types'
import legal from '../../components/misc/legal' import legal from '../../components/misc/legal'
import ApiConfig from '@/components/misc/api-config' import ApiConfig from '@/components/misc/api-config.vue'
export default { export default {
components: { components: {

102
vite.config.js Normal file
View File

@ -0,0 +1,102 @@
const {createVuePlugin} = require('vite-plugin-vue2')
const {VitePWA} = require('vite-plugin-pwa')
const path = require('path')
module.exports = {
plugins: [
createVuePlugin(),
VitePWA({
strategies: 'injectManifest',
injectRegister: false,
injectManifest: {
swSrc: './src/ServiceWorker/sw.js',
swDest: './dist/sw.js',
},
manifest: {
name: 'Vikunja',
short_name: 'Vikunja',
theme_color: '#1973ff',
icons: [
{
src: './images/icons/android-chrome-192x192.png',
sizes: '192x192',
type: 'image/png'
},
{
src: './images/icons/android-chrome-512x512.png',
sizes: '512x512',
type: 'image/png'
},
{
src: './images/icons/icon-maskable.png',
sizes: '1024x1024',
type: 'image/png',
purpose: 'maskable'
}
],
start_url: '.',
display: 'standalone',
background_color: '#000000',
shortcuts: [
{
name: 'Overview',
url: '/'
},
{
name: 'Namespaces And Lists Overview',
short_name: 'Namespaces & Lists',
url: '/namespaces'
},
{
name: 'Tasks Next Week',
short_name: 'Next Week',
url: '/tasks/by/week'
},
{
name: 'Tasks Next Month',
short_name: 'Next Month',
url: '/tasks/by/month'
},
{
name: 'Teams Overview',
short_name: 'Teams',
url: '/teams'
}
]
},
}),
],
resolve: {
alias: [
{
find: '@',
replacement: path.resolve(__dirname, 'src'),
},
],
extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue'],
},
server: {
port: 5000,
strictPort: true,
},
build: {
target: 'es2015',
rollupOptions: {
output: {
manualChunks: {
'user-settings': [
'./src/views/user/PasswordReset',
'./src/views/user/RequestPasswordReset',
'./src/views/user/Settings',
],
'settings': [
'./src/views/list/NewList',
'./src/views/namespaces/NewNamespace',
'./src/views/teams/EditTeam',
'./src/views/teams/NewTeam',
],
},
},
},
},
}

3268
yarn.lock

File diff suppressed because it is too large Load Diff