Compare commits

..

11 Commits

Author SHA1 Message Date
renovate 78fcf74aca chore(deps): update dependency node to v20.11.1
continuous-integration/drone/pr Build was killed Details
2024-02-27 19:04:59 +00:00
kolaente 5d127c2897 feat: run frontend tests with api build from the same branch (#2137)
continuous-integration/drone/push Build is passing Details
Reviewed-on: #2137
Co-authored-by: kolaente <k@knt.li>
Co-committed-by: kolaente <k@knt.li>
2024-02-27 18:06:34 +00:00
kolaente 1275dfc260
fix: lint
continuous-integration/drone/push Build is failing Details
2024-02-27 16:38:20 +01:00
kolaente 997fb6bc54
fix(migration): show correct help message when a migration was started 2024-02-27 16:36:18 +01:00
kolaente b2e5de88ff
fix(labels): make sure labels are aligned in the middle
continuous-integration/drone/push Build is failing Details
2024-02-27 16:29:27 +01:00
kolaente baa5d14ca6
fix(assignees): spacing of users
continuous-integration/drone/push Build is failing Details
2024-02-27 16:15:35 +01:00
kolaente 2d5c496397
fix(kanban): pass active filters down to task lazy loading
continuous-integration/drone/push Build is failing Details
Before this change, applying a filter and then scrolling a bucket would not use that filter when lazy loading the tasks in that bucket. That resulted in all tasks being loaded, regardless if the filter applied to them.
2024-02-27 16:10:19 +01:00
kolaente b8533d2bfc
fix(gantt): use color variables for gantt header so that it works in dark mode 2024-02-27 15:55:07 +01:00
kolaente 8a82093233
fix(project): don't allow archival or deletion of default projects in UI
continuous-integration/drone/push Build is failing Details
2024-02-27 15:37:30 +01:00
kolaente 3d39fc3960
fix(ci): sign drone config
continuous-integration/drone/push Build is failing Details
2024-02-26 10:56:21 +01:00
kolaente 43e13d9cdd
fix(ci): run test db in memory
continuous-integration/drone/push Build is pending Details
2024-02-26 10:54:53 +01:00
13 changed files with 109 additions and 80 deletions

View File

@ -1,7 +1,7 @@
---
kind: pipeline
type: docker
name: build-and-test-api
name: build-and-test
workspace:
base: /go
@ -122,7 +122,7 @@ steps:
when:
event: [ push, tag, pull_request ]
- name: build
- name: api-build
image: vikunja/golang-build:latest
pull: always
environment:
@ -133,7 +133,7 @@ steps:
when:
event: [ push, tag, pull_request ]
- name: lint
- name: api-lint
image: golangci/golangci-lint:v1.55.2
pull: always
environment:
@ -156,7 +156,9 @@ steps:
- name: test-migration-sqlite
image: vikunja/golang-build:latest
pull: always
depends_on: [ test-migration-prepare, build ]
depends_on:
- test-migration-prepare
- api-build
environment:
VIKUNJA_DATABASE_TYPE: sqlite
VIKUNJA_DATABASE_PATH: /db/vikunja-migration-test.db
@ -175,7 +177,9 @@ steps:
- name: test-migration-mysql
image: vikunja/golang-build:latest
pull: always
depends_on: [ test-migration-prepare, build ]
depends_on:
- test-migration-prepare
- api-build
environment:
VIKUNJA_DATABASE_TYPE: mysql
VIKUNJA_DATABASE_HOST: test-mysql-migration
@ -194,7 +198,9 @@ steps:
- name: test-migration-psql
image: vikunja/golang-build:latest
pull: always
depends_on: [ test-migration-prepare, build ]
depends_on:
- test-migration-prepare
- api-build
environment:
VIKUNJA_DATABASE_TYPE: postgres
VIKUNJA_DATABASE_HOST: test-postgres-migration
@ -211,7 +217,7 @@ steps:
when:
event: [ push, tag, pull_request ]
- name: test
- name: api-test-unit
image: vikunja/golang-build:latest
pull: always
environment:
@ -222,7 +228,7 @@ steps:
when:
event: [ push, tag, pull_request ]
- name: test-sqlite
- name: api-test-unit-sqlite
image: vikunja/golang-build:latest
pull: always
environment:
@ -239,7 +245,7 @@ steps:
when:
event: [ push, tag, pull_request ]
- name: test-mysql
- name: api-test-unit-mysql
image: vikunja/golang-build:latest
pull: always
environment:
@ -256,7 +262,7 @@ steps:
when:
event: [ push, tag, pull_request ]
- name: test-postgres
- name: api-test-unit-postgres
image: vikunja/golang-build:latest
pull: always
environment:
@ -337,31 +343,22 @@ steps:
when:
event: [ push, tag, pull_request ]
---
kind: pipeline
type: docker
name: build-and-test-frontend
trigger:
branch:
include:
- main
event:
include:
- push
- pull_request
services:
- name: api
image: vikunja/vikunja:unstable
- name: test-api-run
image: vikunja/golang-build:latest
pull: always
environment:
VIKUNJA_SERVICE_TESTINGTOKEN: averyLongSecretToSe33dtheDB
VIKUNJA_LOG_LEVEL: DEBUG
VIKUNJA_CORS_ENABLE: 1
VIKUNJA_DATABASE_PATH: memory
VIKUNJA_DATABASE_TYPE: sqlite
commands:
- ./vikunja
detach: true
depends_on:
- api-build
steps:
- name: dependencies
- name: frontend-dependencies
image: node:20.11.1-alpine
pull: always
environment:
@ -375,7 +372,7 @@ steps:
# depends_on:
# - restore-cache
- name: lint
- name: frontend-lint
image: node:20.11.1-alpine
pull: always
environment:
@ -385,9 +382,9 @@ steps:
- corepack enable && pnpm config set store-dir .cache/pnpm
- pnpm run lint
depends_on:
- dependencies
- frontend-dependencies
- name: build-prod
- name: frontend-build-prod
image: node:20.11.1-alpine
pull: always
environment:
@ -395,11 +392,11 @@ steps:
commands:
- cd frontend
- corepack enable && pnpm config set store-dir .cache/pnpm
- pnpm run build
- pnpm run build:test
depends_on:
- dependencies
- frontend-dependencies
- name: test-unit
- name: frontend-test-unit
image: node:20.11.1-alpine
pull: always
commands:
@ -407,9 +404,9 @@ steps:
- corepack enable && pnpm config set store-dir .cache/pnpm
- pnpm run test:unit
depends_on:
- dependencies
- frontend-dependencies
- name: typecheck
- name: frontend-typecheck
failure: ignore
image: node:20.11.1-alpine
pull: always
@ -420,13 +417,13 @@ steps:
- corepack enable && pnpm config set store-dir .cache/pnpm
- pnpm run typecheck
depends_on:
- dependencies
- frontend-dependencies
- name: test-frontend
- name: frontend-test
image: cypress/browsers:node18.12.0-chrome107
pull: always
environment:
CYPRESS_API_URL: http://api:3456/api/v1
CYPRESS_API_URL: http://test-api-run:3456/api/v1
CYPRESS_TEST_SECRET: averyLongSecretToSe33dtheDB
PNPM_CACHE_FOLDER: .cache/pnpm
CYPRESS_CACHE_FOLDER: .cache/cypress
@ -435,14 +432,15 @@ steps:
from_secret: cypress_project_key
commands:
- cd frontend
- sed -i 's/localhost/api/g' dist/index.html
- sed -i 's/localhost/test-api-run/g' dist-test/index.html
- corepack enable && pnpm config set store-dir .cache/pnpm
- pnpm cypress install
- pnpm run test:e2e-record
- pnpm run test:e2e-record-test
depends_on:
- build-prod
- frontend-build-prod
- test-api-run
- name: deploy-preview
- name: frontend-deploy-preview
image: williamjackson/netlify-cli
pull: always
user: root # The rest runs as root and thus the permissions wouldn't work
@ -455,7 +453,7 @@ steps:
from_secret: gitea_token
commands:
- cd frontend
- cp -r dist dist-preview
- cp -r dist-test dist-preview
# Override the default api url used for preview
- sed -i 's|http://localhost:3456|https://try.vikunja.io|g' dist-preview/index.html
- apk add --no-cache perl-utils
@ -464,7 +462,7 @@ steps:
- shasum -a 384 -c ./scripts/deploy-preview-netlify.mjs.sha384
- node ./scripts/deploy-preview-netlify.mjs
depends_on:
- build-prod
- frontend-build-prod
when:
event:
include:
@ -476,7 +474,7 @@ type: docker
name: generate-swagger-docs
depends_on:
- build-and-test-api
- build-and-test
workspace:
base: /go
@ -520,8 +518,7 @@ type: docker
name: release
depends_on:
- build-and-test-api
- build-and-test-frontend
- build-and-test
workspace:
base: /source
@ -805,8 +802,7 @@ type: docker
name: docker-release
depends_on:
- build-and-test-api
- build-and-test-frontend
- build-and-test
trigger:
ref:
@ -880,7 +876,7 @@ type: docker
name: frontend-release-unstable
depends_on:
- build-and-test-frontend
- build-and-test
trigger:
branch:
@ -943,7 +939,7 @@ type: docker
name: frontend-release-version
depends_on:
- build-and-test-frontend
- build-and-test
trigger:
event:
@ -1366,8 +1362,7 @@ trigger:
- "refs/tags/**"
depends_on:
- build-and-test-api
- build-and-test-frontend
- build-and-test
- release
- deploy-docs
- docker-release
@ -1389,6 +1384,6 @@ steps:
- failure
---
kind: signature
hmac: aa9bd51fc7d73686ee169060dcb4d6540214825a0d5134035f477a97f77dd24d
hmac: 008b86263a8d03806da907c128a837a380901f1a2190a658c22d4e06cadc1b64
...

View File

@ -28,13 +28,15 @@
"serve": "pnpm run dev",
"preview": "vite preview --port 4173",
"preview:dev": "vite preview --outDir dist-dev --mode development --port 4173",
"preview:test": "vite preview --port 4173 --outDir dist-test",
"build": "vite build && workbox copyLibraries dist/",
"build:test": "vite build --outDir dist-test && workbox copyLibraries dist-dev/",
"build:modern-only": "BUILD_MODERN_ONLY=true vite build && workbox copyLibraries dist/",
"build:dev": "vite build --mode development --outDir dist-dev/",
"lint": "eslint 'src/**/*.{js,ts,vue}'",
"lint:fix": "pnpm run lint --fix",
"test:e2e": "start-server-and-test preview http://127.0.0.1:4173 'cypress run --e2e --browser chrome'",
"test:e2e-record": "start-server-and-test preview http://127.0.0.1:4173 'cypress run --e2e --browser chrome --record'",
"test:e2e-record-test": "start-server-and-test preview:test http://127.0.0.1:4173 'cypress run --e2e --browser chrome --record'",
"test:e2e-dev-dev": "start-server-and-test preview:dev http://127.0.0.1:4173 'cypress open --e2e'",
"test:e2e-dev": "start-server-and-test preview http://127.0.0.1:4173 'cypress open --e2e'",
"test:unit": "vitest --dir ./src",

View File

@ -1,5 +1,8 @@
<template>
<BaseButton class="dropdown-item">
<BaseButton
class="dropdown-item"
:class="{'is-disabled': disabled}"
>
<span
v-if="icon"
class="icon is-small"
@ -21,6 +24,7 @@ import type {IconProp} from '@fortawesome/fontawesome-svg-core'
export interface DropDownItemProps extends /* @vue-ignore */ BaseButtonProps {
icon?: IconProp,
iconClass?: object | string,
disabled?: boolean,
}
defineProps<DropDownItemProps>()

View File

@ -67,8 +67,10 @@
{{ $t('menu.duplicate') }}
</DropdownItem>
<DropdownItem
v-tooltip="isDefaultProject ? $t('menu.cantArchiveIsDefault') : ''"
:to="{ name: 'project.settings.archive', params: { projectId: project.id } }"
icon="archive"
:disabled="isDefaultProject"
>
{{ $t('menu.archive') }}
</DropdownItem>
@ -95,9 +97,11 @@
{{ $t('menu.createProject') }}
</DropdownItem>
<DropdownItem
v-tooltip="isDefaultProject ? $t('menu.cantDeleteIsDefault') : ''"
:to="{ name: 'project.settings.delete', params: { projectId: project.id } }"
icon="trash-alt"
class="has-text-danger"
:disabled="isDefaultProject"
>
{{ $t('menu.delete') }}
</DropdownItem>
@ -106,7 +110,7 @@
</template>
<script setup lang="ts">
import {ref, computed, watchEffect, type PropType} from 'vue'
import {computed, type PropType, ref, watchEffect} from 'vue'
import BaseButton from '@/components/base/BaseButton.vue'
import Dropdown from '@/components/misc/dropdown.vue'
@ -118,6 +122,7 @@ import type {ISubscription} from '@/modelTypes/ISubscription'
import {isSavedFilter} from '@/services/savedFilter'
import {useConfigStore} from '@/stores/config'
import {useProjectStore} from '@/stores/projects'
import {useAuthStore} from '@/stores/auth'
const props = defineProps({
project: {
@ -146,4 +151,7 @@ function setSubscriptionInStore(sub: ISubscription) {
}
projectStore.setProject(updatedProject)
}
const authStore = useAuthStore()
const isDefaultProject = computed(() => props.project?.id === authStore.settings.defaultProjectId)
</script>

View File

@ -17,6 +17,7 @@
bar-end="endDate"
:grid="true"
:width="ganttChartWidth"
:color-scheme="GANTT_COLOR_SCHEME"
@dragendBar="updateGanttTask"
@dblclickBar="openTask"
>
@ -59,7 +60,7 @@ import {
extendDayjs,
GGanttChart,
GGanttRow,
type GanttBarObject,
type GanttBarObject, type ColorScheme,
} from '@infectoone/vue-ganttastic'
import Loading from '@/components/misc/loading.vue'
@ -113,6 +114,16 @@ const ganttChartWidth = computed(() => {
const ganttBars = ref<GanttBarObject[][]>([])
const GANTT_COLOR_SCHEME: ColorScheme = {
primary: 'var(--grey-100)',
secondary: 'var(--grey-300)',
ternary: 'var(--grey-500)',
quartenary: 'var(--grey-600)',
hoverHighlight: 'var(--grey-700)',
text: 'var(--grey-800)',
background: 'var(--white)',
}
/**
* Update ganttBars when tasks change
*/

View File

@ -59,7 +59,7 @@ const hasDelete = computed(() => typeof remove !== 'undefined' && !disabled)
}
&:hover .assignee:not(:first-child) {
margin-left: -1rem;
margin-left: -0.5rem;
}
}
@ -68,7 +68,7 @@ const hasDelete = computed(() => typeof remove !== 'undefined' && !disabled)
transition: all $transition;
&:not(:first-child) {
margin-left: -1.5rem;
margin-left: -1rem;
}
:deep(.user img) {

View File

@ -27,7 +27,8 @@ defineProps({
display: inline;
:deep(.tag) {
margin-bottom: .25rem;
margin-top: .125rem;
margin-bottom: .125rem;
}
}
</style>

View File

@ -103,7 +103,7 @@ import {getHexColor} from '@/models/task'
import type {ITask} from '@/modelTypes/ITask'
import PriorityLabel from '@/components/tasks/partials/priorityLabel.vue'
import Labels from '@/components/tasks/partials//labels.vue'
import Labels from '@/components/tasks/partials/labels.vue'
import ChecklistSummary from '@/components/tasks/partials/checklist-summary.vue'
import ColorBubble from '@/components/misc/colorBubble.vue'
@ -197,6 +197,7 @@ const project = computed(() => projectStore.projects[task.projectId])
span.parent-tasks {
color: var(--grey-500);
width: auto;
margin-left: .25rem;
}
}
</style>

View File

@ -978,7 +978,9 @@
"setBackground": "Set background",
"share": "Share",
"newProject": "New project",
"createProject": "Create project"
"createProject": "Create project",
"cantArchiveIsDefault": "You cannot archive this because it is your default project.",
"cantDeleteIsDefault": "You cannot delete this because it is your default project."
},
"apiConfig": {
"url": "Vikunja URL",

View File

@ -246,8 +246,9 @@ export const useKanbanStore = defineStore('kanban', () => {
}
async function loadNextTasksForBucket(
{projectId, ps = {}, bucketId} :
{projectId: IProject['id'], ps, bucketId: IBucket['id']},
projectId: IProject['id'],
ps,
bucketId: IBucket['id'],
) {
const isLoading = bucketLoading.value[bucketId] ?? false
if (isLoading) {

View File

@ -53,7 +53,7 @@
<p>{{ $t('migrate.inProgress') }}</p>
</div>
</template>
<div v-else-if="lastMigrationStartedAt && lastMigrationFinishedAt === null">
<div v-else-if="!migrationJustStarted && lastMigrationStartedAt && lastMigrationFinishedAt === null">
<Message class="mb-4">
{{ $t('migrate.migrationInProgress') }}
</Message>
@ -145,6 +145,7 @@ const lastMigrationFinishedAt = ref<Date | null>(null)
const lastMigrationStartedAt = ref<Date | null>(null)
const message = ref('')
const migratorAuthCode = ref('')
const migrationJustStarted = ref(false)
const migrator = computed<Migrator>(() => MIGRATORS[props.service])
@ -207,12 +208,15 @@ async function migrate() {
}
try {
const result = migrator.value.isFileMigrator
? await migrationFileService.migrate(migrationConfig as File)
: await migrationService.migrate(migrationConfig as MigrationConfig)
message.value = result.message
const projectStore = useProjectStore()
return projectStore.loadProjects()
if (migrator.value.isFileMigrator) {
const result = await migrationFileService.migrate(migrationConfig as File)
message.value = result.message
const projectStore = useProjectStore()
return projectStore.loadProjects()
}
await migrationService.migrate(migrationConfig as MigrationConfig)
migrationJustStarted.value = true
} catch (e) {
console.log(e)
} finally {

View File

@ -416,11 +416,11 @@ function handleTaskContainerScroll(id: IBucket['id'], projectId: IProject['id'],
return
}
kanbanStore.loadNextTasksForBucket({
projectId: projectId,
params: params.value,
bucketId: id,
})
kanbanStore.loadNextTasksForBucket(
projectId,
params.value,
id,
)
}
function updateTasks(bucketId: IBucket['id'], tasks: IBucket['tasks']) {

View File

@ -158,7 +158,7 @@ func setRootPath() {
func setGoFiles() {
// GOFILES := $(shell find . -name "*.go" -type f ! -path "*/bindata.go")
files, err := runCmdWithOutput("find", ".", "-name", "*.go", "-type", "f", "!", "-path", "*/bindata.go")
files, err := runCmdWithOutput("find", "./pkg", "-name", "*.go", "-type", "f", "!", "-path", "*/bindata.go")
if err != nil {
fmt.Printf("Error getting go files: %s\n", err)
os.Exit(1)