Co-authored-by: kolaente <k@knt.li>
Reviewed-on: vikunja/frontend#416
Co-authored-by: konrad <konrad@kola-entertainments.de>
Co-committed-by: konrad <konrad@kola-entertainments.de>
This commit is contained in:
konrad 2021-07-25 13:27:15 +00:00
parent 92c15b435c
commit a08306d612
63 changed files with 4353 additions and 3935 deletions

View File

@ -86,7 +86,7 @@ steps:
YARN_CACHE_FOLDER: .cache/yarn/
CYPRESS_CACHE_FOLDER: .cache/cypress/
commands:
- yarn build --mode dev
- yarn build:dev
depends_on:
- dependencies
@ -95,7 +95,6 @@ steps:
pull: true
environment:
YARN_CACHE_FOLDER: .cache/yarn/
CYPRESS_CACHE_FOLDER: .cache/cypress/
commands:
- yarn build --dest dist-prod
depends_on:
@ -119,8 +118,8 @@ steps:
CYPRESS_CACHE_FOLDER: .cache/cypress/
CYPRESS_DEFAULT_COMMAND_TIMEOUT: 60000
commands:
- sed -i 's/localhost/api/g' dist/index.html
- yarn serve:dist & npx wait-on http://localhost:8080
- sed -i 's/localhost/api/g' dist-dev/index.html
- yarn serve:dist-dev & npx wait-on http://localhost:5000
- yarn test:frontend --browser chrome
depends_on:
- dependencies

3
.gitignore vendored
View File

@ -1,6 +1,6 @@
.DS_Store
node_modules
/dist
/dist*
*.zip
# local env files
@ -20,6 +20,7 @@ yarn-error.log*
*.njsproj
*.sln
*.sw*
!rollup.sw.js
# Test files
cypress/screenshots

View File

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

View File

@ -253,11 +253,11 @@ describe('Lists', () => {
describe('Gantt View', () => {
it('Hides tasks with no dates', () => {
TaskFactory.create(1)
const tasks = TaskFactory.create(1)
cy.visit('/lists/1/gantt')
cy.get('.gantt-chart-container .gantt-chart .tasks')
.should('be.empty')
.should('not.contain', tasks[0].title)
})
it('Shows tasks from the current and next month', () => {

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.ts"></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,10 @@
"version": "0.10.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"serve:dist": "node scripts/serve-dist.js",
"build": "vue-cli-service build",
"serve": "vite",
"serve:dist-dev": "node scripts/serve-dist.js",
"build": "vite build && rollup -c ./rollup.sw.js && workbox copyLibraries dist/",
"build:dev": "vite build -m development --outDir dist-dev/",
"build:report": "vue-cli-service build --report",
"lint": "vue-cli-service lint --ignore-pattern '*.test.*'",
"cypress:open": "cypress open",
@ -23,7 +24,6 @@
"lodash": "4.17.21",
"marked": "2.1.3",
"register-service-worker": "1.7.2",
"sass": "1.36.0",
"snake-case": "3.0.4",
"verte": "0.0.12",
"vue": "2.6.14",
@ -33,13 +33,18 @@
"vue-i18n": "8.25.0",
"vue-shortkey": "3.1.7",
"vue-smooth-dnd": "0.8.1",
"vuex": "3.6.2"
"vuex": "3.6.2",
"workbox-precaching": "^6.1.1"
},
"devDependencies": {
"@fortawesome/fontawesome-svg-core": "1.2.35",
"@fortawesome/free-regular-svg-icons": "5.15.3",
"@fortawesome/free-solid-svg-icons": "5.15.3",
"@fortawesome/vue-fontawesome": "2.0.2",
"@rollup/plugin-babel": "^5.3.0",
"@rollup/plugin-commonjs": "^19.0.1",
"@rollup/plugin-node-resolve": "^13.0.4",
"@rollup/plugin-replace": "^3.0.0",
"@types/jest": "26.0.24",
"@typescript-eslint/eslint-plugin": "4.28.4",
"@typescript-eslint/parser": "4.28.4",
@ -54,18 +59,25 @@
"babel-eslint": "10.1.0",
"cypress": "8.0.0",
"cypress-file-upload": "5.0.8",
"esbuild": "0.8.51",
"eslint": "7.31.0",
"eslint-plugin-vue": "7.14.0",
"faker": "5.5.3",
"jest": "27.0.6",
"rollup-plugin-terser": "^7.0.2",
"sass": "1.36.0",
"sass-loader": "10.2.0",
"ts-jest": "27.0.4",
"typescript": "4.3.5",
"vite": "2.0.2",
"vite-plugin-pwa": "0.5.6",
"vite-plugin-vue2": "1.2.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"
"wait-on": "6.0.0",
"workbox-cli": "6.1.1"
},
"eslintConfig": {
"root": true,

View File

@ -16,9 +16,6 @@
height="1066.6667"
viewBox="0 0 1066.6667 1066.6667"
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
id="metadata8"><rdf:RDF><cc:Work
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>

43
rollup.sw.js Normal file
View File

@ -0,0 +1,43 @@
import { nodeResolve } from '@rollup/plugin-node-resolve'
import babel from '@rollup/plugin-babel'
import commonjs from '@rollup/plugin-commonjs'
import { terser } from 'rollup-plugin-terser'
import replace from '@rollup/plugin-replace'
// Building the sw stuff ourselves to have more controle over it - see https://github.com/antfu/vite-plugin-pwa/issues/35#issuecomment-797942573
export default {
input: './dist/sw.js',
output: {
dir: 'dist',
format: 'esm',
},
plugins: [
replace({
'process.env.NODE_ENV': JSON.stringify('production'),
'preventAssignment': true,
}),
nodeResolve({
browser: true,
}),
commonjs(),
babel({
exclude: '**/node_modules/**',
extensions: ['js'],
babelHelpers: 'runtime',
presets: [
[
'@babel/preset-env',
{
corejs: 3,
useBuiltIns: 'entry',
targets: {
'esmodules': true,
},
modules: false,
},
],
],
}),
terser(),
],
}

View File

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

View File

@ -30,11 +30,11 @@ 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'
import TopNavigation from '@/components/home/topNavigation'
import ContentAuth from '@/components/home/contentAuth'
import ContentLinkShare from '@/components/home/contentLinkShare'
import ContentNoAuth from '@/components/home/contentNoAuth'
import {setLanguage} from '@/i18n/setup'
import TopNavigation from './components/home/topNavigation'
import ContentAuth from './components/home/contentAuth'
import ContentLinkShare from './components/home/contentLinkShare'
import ContentNoAuth from './components/home/contentNoAuth'
import {setLanguage} from './i18n/setup'
export default {
name: 'app',

View File

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

View File

@ -44,8 +44,8 @@
<script>
import {mapState} from 'vuex'
import {CURRENT_LIST, KEYBOARD_SHORTCUTS_ACTIVE, MENU_ACTIVE} from '@/store/mutation-types'
import Navigation from '@/components/home/navigation'
import QuickActions from '@/components/quick-actions/quick-actions'
import Navigation from '@/components/home/navigation.vue'
import QuickActions from '@/components/quick-actions/quick-actions.vue'
export default {
name: 'contentAuth',

View File

@ -118,7 +118,7 @@
<script>
import {mapState} from 'vuex'
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'
export default {

View File

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

View File

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

View File

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

View File

@ -181,14 +181,14 @@ import 'flatpickr/dist/flatpickr.css'
import {formatISO} from 'date-fns'
import differenceWith from 'lodash/differenceWith'
import PrioritySelect from '@/components/tasks/partials/prioritySelect'
import PercentDoneSelect from '@/components/tasks/partials/percentDoneSelect'
import Multiselect from '@/components/input/multiselect'
import PrioritySelect from '@/components/tasks/partials/prioritySelect.vue'
import PercentDoneSelect from '@/components/tasks/partials/percentDoneSelect.vue'
import Multiselect from '@/components/input/multiselect.vue'
import UserService from '@/services/user'
import ListService from '@/services/list'
import NamespaceService from '@/services/namespace'
import EditLabels from '@/components/tasks/partials/editLabels'
import EditLabels from '@/components/tasks/partials/editLabels.vue'
export default {
name: 'filters',

View File

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

View File

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

View File

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

View File

@ -49,7 +49,7 @@
<script>
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 {closeWhenClickedOutside} from '@/helpers/closeWhenClickedOutside'
import {mapState} from 'vuex'

View File

@ -62,7 +62,7 @@ import TeamModel from '@/models/team'
import {CURRENT_LIST, LOADING, LOADING_MODULE, QUICK_ACTIONS_ACTIVE} from '@/store/mutation-types'
import ListModel from '@/models/list'
import createTask from '@/components/tasks/mixins/createTask'
import QuickAddMagic from '@/components/tasks/partials/quick-add-magic'
import QuickAddMagic from '@/components/tasks/partials/quick-add-magic.vue'
import {getHistory} from '../../modules/listHistory'
const TYPE_LIST = 'list'

View File

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

View File

@ -40,7 +40,7 @@ import TaskService from '../../services/task'
import LabelService from '../../services/label'
import LabelTaskService from '../../services/labelTask'
import createTask from '@/components/tasks/mixins/createTask'
import QuickAddMagic from '@/components/tasks/partials/quick-add-magic'
import QuickAddMagic from '@/components/tasks/partials/quick-add-magic.vue'
export default {
name: 'add-task',

View File

@ -100,7 +100,7 @@ export default {
Reminders,
EditLabels,
editor: () => ({
component: import(/* webpackChunkName: "editor" */ '../../components/input/editor'),
component: import('../../components/input/editor'),
loading: LoadingComponent,
error: ErrorComponent,
timeout: 60000,

View File

@ -201,7 +201,7 @@ import PriorityLabel from './partials/priorityLabel'
import TaskCollectionService from '../../services/taskCollection'
import {mapState} from 'vuex'
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 {
name: 'GanttChart',

View File

@ -159,7 +159,7 @@ export default {
name: 'comments',
components: {
editor: () => ({
component: import(/* webpackChunkName: "editor" */ '../../input/editor'),
component: import('../../input/editor'),
loading: LoadingComponent,
error: ErrorComponent,
timeout: 60000,

View File

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

View File

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

View File

@ -43,7 +43,7 @@ import differenceWith from 'lodash/differenceWith'
import LabelModel from '../../../models/label'
import LabelTaskService from '../../../services/labelTask'
import Multiselect from '@/components/input/multiselect'
import Multiselect from '@/components/input/multiselect.vue'
import {LOADING, LOADING_MODULE} from '@/store/mutation-types'
export default {

View File

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

View File

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

View File

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

View File

@ -1,5 +1,6 @@
import Vue from 'vue'
import VueI18n from 'vue-i18n'
import langEN from './lang/en.json'
Vue.use(VueI18n)
@ -7,7 +8,7 @@ export const i18n = new VueI18n({
locale: 'en', // set locale
fallbackLocale: 'en',
messages: {
en: require('./lang/en.json'),
en: langEN,
},
})
@ -36,7 +37,7 @@ export const loadLanguageAsync = lang => {
}
// If the language hasn't been loaded yet
return import(/* webpackChunkName: "lang-[request]" */ `@/i18n/lang/${lang}.json`).then(
return import(`./lang/${lang}.json`).then(
messages => {
i18n.setLocaleMessage(lang, messages.default)
loadedLanguages.push(lang)

View File

@ -184,23 +184,20 @@ Vue.component('icon', FontAwesomeIcon)
Vue.use(vueShortkey, {prevent: ['input', 'textarea', '.input']})
import focus from '@/directives/focus'
import focus from './directives/focus'
Vue.directive('focus', focus)
import tooltip from '@/directives/tooltip'
import tooltip from './directives/tooltip'
// @ts-ignore
Vue.directive('tooltip', tooltip)
// @ts-ignore
import Button from '@/components/input/button'
import Button from './components/input/button'
Vue.component('x-button', Button)
// @ts-ignore
import Card from '@/components/misc/card'
import Card from './components/misc/card'
Vue.component('card', Card)
Vue.mixin({

View File

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

View File

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

View File

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

View File

@ -45,10 +45,10 @@
<script>
import {mapState} from 'vuex'
import ShowTasks from './tasks/ShowTasks'
import ShowTasks from './tasks/ShowTasks.vue'
import {getHistory} from '../modules/listHistory'
import ListCard from '@/components/list/partials/list-card'
import AddTask from '../components/tasks/add-task'
import ListCard from '@/components/list/partials/list-card.vue'
import AddTask from '../components/tasks/add-task.vue'
export default {
name: 'Home',

View File

@ -61,9 +61,9 @@
</template>
<script>
import LoadingComponent from '@/components/misc/loading'
import ErrorComponent from '@/components/misc/error'
import Filters from '@/components/list/partials/filters'
import LoadingComponent from '@/components/misc/loading.vue'
import ErrorComponent from '@/components/misc/error.vue'
import Filters from '@/components/list/partials/filters.vue'
import SavedFilterService from '@/services/savedFilter'
import SavedFilterModel from '@/models/savedFilter'
@ -88,7 +88,7 @@ export default {
components: {
Filters,
editor: () => ({
component: import(/* webpackChunkName: "editor" */ '../../components/input/editor'),
component: import('../../components/input/editor'),
loading: LoadingComponent,
error: ErrorComponent,
timeout: 60000,

View File

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

View File

@ -110,7 +110,7 @@ export default {
components: {
ColorPicker,
editor: () => ({
component: import(/* webpackChunkName: "editor" */ '../../components/input/editor'),
component: import('../../components/input/editor'),
loading: LoadingComponent,
error: ErrorComponent,
timeout: 60000,

View File

@ -37,7 +37,7 @@
<script>
import labelModel from '../../models/label'
import LabelModel from '../../models/label'
import CreateEdit from '@/components/misc/create-edit'
import CreateEdit from '@/components/misc/create-edit.vue'
import ColorPicker from '../../components/input/colorPicker'
import {mapState} from 'vuex'
import {LOADING, LOADING_MODULE} from '@/store/mutation-types'

View File

@ -34,7 +34,7 @@
<script>
import ListService from '../../services/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'
export default {

View File

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

View File

@ -15,9 +15,9 @@
<script>
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 CreateEdit from '@/components/misc/create-edit'
import CreateEdit from '@/components/misc/create-edit.vue'
export default {
name: 'list-setting-duplicate',

View File

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

View File

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

View File

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

View File

@ -166,9 +166,9 @@ import taskList from '../../../components/tasks/mixins/taskList'
import { saveListView } from '@/helpers/saveListView'
import Rights from '../../../models/rights.json'
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 Nothing from '@/components/misc/nothing'
import Nothing from '@/components/misc/nothing.vue'
import createTask from '@/components/tasks/mixins/createTask'
export default {

View File

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

View File

@ -66,9 +66,9 @@
<script>
import {mapState} from 'vuex'
import Fancycheckbox from '../../components/input/fancycheckbox'
import Fancycheckbox from '../../components/input/fancycheckbox.vue'
import {LOADING} from '@/store/mutation-types'
import ListCard from '@/components/list/partials/list-card'
import ListCard from '@/components/list/partials/list-card.vue'
export default {
name: 'ListNamespaces',

View File

@ -43,7 +43,7 @@
<script>
import NamespaceModel from '../../models/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'
export default {

View File

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

View File

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

View File

@ -427,13 +427,13 @@ import RepeatAfter from '../../components/tasks/partials/repeatAfter'
import Reminders from '../../components/tasks/partials/reminders'
import Comments from '../../components/tasks/partials/comments'
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 attachmentUpload from '../../components/tasks/mixins/attachmentUpload'
import heading from '@/components/tasks/partials/heading'
import Datepicker from '@/components/input/datepicker'
import heading from '@/components/tasks/partials/heading.vue'
import Datepicker from '@/components/input/datepicker.vue'
import {playPop} from '@/helpers/playPop'
import TaskSubscription from '@/components/misc/subscription'
import TaskSubscription from '@/components/misc/subscription.vue'
import {CURRENT_LIST} from '@/store/mutation-types'
export default {

View File

@ -172,7 +172,7 @@ import Rights from '../../models/rights.json'
import LoadingComponent from '../../components/misc/loading'
import ErrorComponent from '../../components/misc/error'
import Multiselect from '@/components/input/multiselect'
import Multiselect from '@/components/input/multiselect.vue'
export default {
name: 'EditTeam',
@ -198,7 +198,7 @@ export default {
components: {
Multiselect,
editor: () => ({
component: import(/* webpackChunkName: "editor" */ '../../components/input/editor'),
component: import('../../components/input/editor'),
loading: LoadingComponent,
error: ErrorComponent,
timeout: 60000,

View File

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

View File

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

View File

@ -286,9 +286,9 @@ import {availableLanguages, saveLanguage, getCurrentLanguage} from '@/i18n/setup
import {mapState} from 'vuex'
import AvatarSettings from '../../components/user/avatar-settings'
import AvatarSettings from '../../components/user/avatar-settings.vue'
import copy from 'copy-to-clipboard'
import ListSearch from '@/components/tasks/partials/listSearch'
import ListSearch from '@/components/tasks/partials/listSearch.vue'
export default {
name: 'Settings',

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',
],
},
},
},
},
}

7768
yarn.lock

File diff suppressed because it is too large Load Diff