1
0

Compare commits

...

10 Commits

Author SHA1 Message Date
ami
3fc33dd3db
Update translations 2025-01-24 17:01:56 -05:00
ami
247a411262
Update translations 2025-01-24 17:01:21 -05:00
ami
1f06d252a4
Update spanish translation 2025-01-24 16:22:14 -05:00
kolaente
c934124b88
fix: release bucket name
(cherry picked from commit af11a6527f3813f1049f6bed2640f6e7eade50f7)
2024-12-22 21:24:18 +01:00
kolaente
b7bba814e3
chore: release preperations 2024-12-22 20:02:08 +01:00
kolaente
8c285968af
chore: do not generate config yaml 2024-12-22 20:00:44 +01:00
kolaente
b91a5d9adf
chore: sign drone config 2024-12-22 19:54:02 +01:00
kolaente
17b281072f
chore: release preparation 2024-12-22 19:52:12 +01:00
kolaente
d47555e3c2
fix(export): update only current user export file id 2024-12-22 19:49:39 +01:00
kolaente
3f98f47256
feat: use hetzner object storage for releases
(cherry picked from commit 0472acac980d31c37863d34a8eed988ee1dc6523)
2024-11-21 16:58:44 +01:00
8 changed files with 582 additions and 558 deletions

View File

@ -676,13 +676,13 @@ steps:
image: plugins/s3
pull: always
settings:
bucket: vikunja-releases
bucket: vikunja
access_key:
from_secret: aws_access_key_id
from_secret: hetzner_access_key_id
secret_key:
from_secret: aws_secret_access_key
endpoint: https://s3.fr-par.scw.cloud
region: fr-par
from_secret: hetzner_secret_access_key
endpoint: https://fsn1.your-objectstorage.com
region: fsn1
path_style: true
strip_prefix: dist/zip/
source: dist/zip/*
@ -698,13 +698,13 @@ steps:
image: plugins/s3
pull: always
settings:
bucket: vikunja-releases
bucket: vikunja
access_key:
from_secret: aws_access_key_id
from_secret: hetzner_access_key_id
secret_key:
from_secret: aws_secret_access_key
endpoint: https://s3.fr-par.scw.cloud
region: fr-par
from_secret: hetzner_secret_access_key
endpoint: https://fsn1.your-objectstorage.com
region: fsn1
path_style: true
strip_prefix: dist/zip/
source: dist/zip/*
@ -750,13 +750,13 @@ steps:
image: plugins/s3
pull: always
settings:
bucket: vikunja-releases
bucket: vikunja
access_key:
from_secret: aws_access_key_id
from_secret: hetzner_access_key_id
secret_key:
from_secret: aws_secret_access_key
endpoint: https://s3.fr-par.scw.cloud
region: fr-par
from_secret: hetzner_secret_access_key
endpoint: https://fsn1.your-objectstorage.com
region: fsn1
path_style: true
strip_prefix: dist/os-packages/
source: dist/os-packages/*
@ -772,13 +772,13 @@ steps:
image: plugins/s3
pull: always
settings:
bucket: vikunja-releases
bucket: vikunja
access_key:
from_secret: aws_access_key_id
from_secret: hetzner_access_key_id
secret_key:
from_secret: aws_secret_access_key
endpoint: https://s3.fr-par.scw.cloud
region: fr-par
from_secret: hetzner_secret_access_key
endpoint: https://fsn1.your-objectstorage.com
region: fsn1
path_style: true
strip_prefix: dist/os-packages/
source: dist/os-packages/*
@ -929,13 +929,13 @@ steps:
image: plugins/s3
pull: always
settings:
bucket: vikunja-releases
bucket: vikunja
access_key:
from_secret: aws_access_key_id
from_secret: hetzner_access_key_id
secret_key:
from_secret: aws_secret_access_key
endpoint: https://s3.fr-par.scw.cloud
region: fr-par
from_secret: hetzner_secret_access_key
endpoint: https://fsn1.your-objectstorage.com
region: fsn1
path_style: true
source: frontend/vikunja-frontend-unstable.zip
target: /
@ -988,13 +988,13 @@ steps:
image: plugins/s3
pull: always
settings:
bucket: vikunja-releases
bucket: vikunja
access_key:
from_secret: aws_access_key_id
from_secret: hetzner_access_key_id
secret_key:
from_secret: aws_secret_access_key
endpoint: https://s3.fr-par.scw.cloud
region: fr-par
from_secret: hetzner_secret_access_key
endpoint: https://fsn1.your-objectstorage.com
region: fsn1
path_style: true
source: frontend/vikunja-frontend-${DRONE_TAG##v}.zip
target: /
@ -1093,8 +1093,8 @@ steps:
# settings:
# restore: true
# bucket: kolaente.dev-drone-dependency-cache
# endpoint: https://s3.fr-par.scw.cloud
# region: fr-par
# endpoint: https://fsn1.your-objectstorage.com
# region: fsn1
# path_style: true
# cache_key: '{{ .Repo.Name }}_{{ checksum "desktop/yarn.lock" }}_{{ arch }}_{{ os }}'
# mount:
@ -1131,8 +1131,8 @@ steps:
# settings:
# rebuild: true
# bucket: kolaente.dev-drone-dependency-cache
# endpoint: https://s3.fr-par.scw.cloud
# region: fr-par
# endpoint: https://fsn1.your-objectstorage.com
# region: fsn1
# path_style: true
# cache_key: '{{ .Repo.Name }}_{{ checksum "desktop/yarn.lock" }}_{{ arch }}_{{ os }}'
# mount:
@ -1174,8 +1174,8 @@ steps:
# settings:
# restore: true
# bucket: kolaente.dev-drone-dependency-cache
# endpoint: https://s3.fr-par.scw.cloud
# region: fr-par
# endpoint: https://fsn1.your-objectstorage.com
# region: fsn1
# path_style: true
# cache_key: '{{ .Repo.Name }}_{{ checksum "desktop/yarn.lock" }}_{{ arch }}_{{ os }}'
# mount:
@ -1198,30 +1198,30 @@ steps:
- unzip vikunja-frontend-$$VERSION.zip -d frontend
- sed -i 's/\\/api\\/v1//g' frontend/index.html
- ./bumpp.sh
- yarn install
- cat package.json
- yarn dist --linux --windows
# - name: rebuild-cache
# image: meltwater/drone-cache:dev
# pull: true
# environment:
# AWS_ACCESS_KEY_ID:
# from_secret: cache_aws_access_key_id
# AWS_SECRET_ACCESS_KEY:
# from_secret: cache_aws_secret_access_key
# settings:
# rebuild: true
# bucket: kolaente.dev-drone-dependency-cache
# endpoint: https://s3.fr-par.scw.cloud
# region: fr-par
# path_style: true
# cache_key: '{{ .Repo.Name }}_{{ checksum "desktop/yarn.lock" }}_{{ arch }}_{{ os }}'
# mount:
# - '.cache'
# depends_on:
# - build
- corepack enable && pnpm config set store-dir .cache/pnpm
- pnpm install --fetch-timeout 100000
- pnpm dist --linux --windows
# - name: rebuild-cache
# image: meltwater/drone-cache:dev
# pull: true
# environment:
# AWS_ACCESS_KEY_ID:
# from_secret: cache_aws_access_key_id
# AWS_SECRET_ACCESS_KEY:
# from_secret: cache_aws_secret_access_key
# settings:
# rebuild: true
# bucket: kolaente.dev-drone-dependency-cache
# endpoint: https://fsn1.your-objectstorage.com
# region: fsn1
# path_style: true
# cache_key: '{{ .Repo.Name }}_{{ checksum "desktop/yarn.lock" }}_{{ arch }}_{{ os }}'
# mount:
# - '.cache'
# depends_on:
# - build
- name: rename-unstable
image: bash
pull: true
@ -1239,13 +1239,13 @@ steps:
image: plugins/s3
pull: true
settings:
bucket: vikunja-releases
bucket: vikunja
access_key:
from_secret: aws_access_key_id
from_secret: hetzner_access_key_id
secret_key:
from_secret: aws_secret_access_key
endpoint: https://s3.fr-par.scw.cloud
region: fr-par
from_secret: hetzner_secret_access_key
endpoint: https://fsn1.your-objectstorage.com
region: fsn1
path_style: true
strip_prefix: desktop/dist/
source: desktop/dist/Vikunja-Desktop*
@ -1261,13 +1261,13 @@ steps:
image: plugins/s3
pull: true
settings:
bucket: vikunja-releases
bucket: vikunja
access_key:
from_secret: aws_access_key_id
from_secret: hetzner_access_key_id
secret_key:
from_secret: aws_secret_access_key
endpoint: https://s3.fr-par.scw.cloud
region: fr-par
from_secret: hetzner_secret_access_key
endpoint: https://fsn1.your-objectstorage.com
region: fsn1
path_style: true
strip_prefix: desktop/dist/
source: desktop/dist/*
@ -1296,9 +1296,9 @@ steps:
# - name: build
# environment:
# ACCESS_KEY:
# from_secret: aws_access_key_id
# from_secret: hetzner_access_key_id
# SECRET_KEY:
# from_secret: aws_secret_access_key
# from_secret: hetzner_secret_access_key
# commands:
# - git fetch --tags
# - export VERSION=${DRONE_TAG##v}
@ -1311,9 +1311,9 @@ steps:
# - sed -i '' "s/\$${version}/$$VERSION/g" package.json
# - yarn install
# - yarn dist --mac
# - mc config host add scw-fr-par https://s3.fr-par.scw.cloud $ACCESS_KEY $SECRET_KEY --api S3v4
# - mc cp ./dist/*.dmg scw-fr-par/vikunja-releases/desktop/$VERSION/
# - mc cp ./dist/*.dmg.blockmap scw-fr-par/vikunja-releases/desktop/$VERSION/
# - mc config host add scw-fsn1 https://fsn1.your-objectstorage.com $ACCESS_KEY $SECRET_KEY --api S3v4
# - mc cp ./dist/*.dmg scw-fsn1/vikunja/desktop/$VERSION/
# - mc cp ./dist/*.dmg.blockmap scw-fsn1/vikunja/desktop/$VERSION/
---
kind: pipeline
@ -1350,6 +1350,6 @@ steps:
- failure
---
kind: signature
hmac: a06d088bd62507aeb2be9cd4bfcd313bdc6fe0629b82816bef81770f8a34a3ef
hmac: 02fb3097f3e50facb2579de5c3b94e513b97e535a049a28ddb67f85e494d65b1
...

View File

@ -7,6 +7,22 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
All releases can be found on https://code.vikunja.io/vikunja/releases.
## [0.24.6] - 2024-12-22
### Bug Fixes
* *(export)* Update only current user export file id
### Features
* Use hetzner object storage for releases ([3f98f47](3f98f47256628ac559a947f6c9541c0bf03001b6))
### Miscellaneous Tasks
* Release preparation ([17b2810](17b281072f095730a0fbb28458d713fa883f43ec))
* Sign drone config ([b91a5d9](b91a5d9adfb7144126f5824224970ad4015dcd6a))
* Do not generate config yaml ([8c28596](8c285968afff7ebd087ce824b52b0a9f28a8ec20))
## [0.24.5] - 2024-11-21
### Bug Fixes

View File

@ -2,7 +2,7 @@
[![Build Status](https://drone.kolaente.de/api/badges/vikunja/vikunjaa/status.svg)](https://drone.kolaente.de/vikunja/vikunja)
[![License: AGPL v3](https://img.shields.io/badge/License-AGPL%20v3-blue.svg)](LICENSE)
[![Install](https://img.shields.io/badge/download-v0.24.5,brightgreen.svg)](https://vikunja.io/docs/installing)
[![Install](https://img.shields.io/badge/download-v0.24.6,brightgreen.svg)](https://vikunja.io/docs/installing)
[![Docker Pulls](https://img.shields.io/docker/pulls/vikunja/vikunja.svg)](https://hub.docker.com/r/vikunja/vikunja/)
[![Swagger Docs](https://img.shields.io/badge/swagger-docs-brightgreen.svg)](https://try.vikunja.io/api/v1/docs)
[![Go Report Card](https://goreportcard.com/badge/kolaente.dev/vikunja/vikunja)](https://goreportcard.com/report/kolaente.dev/vikunja/vikunja)

File diff suppressed because it is too large Load Diff

View File

@ -73,29 +73,29 @@ export default class NotificationModel extends AbstractModel<INotification> impl
switch (this.name) {
case NOTIFICATION_NAMES.TASK_COMMENT:
return `commented on ${this.notification.task.getTextIdentifier()}`
return `comentó en ${this.notification.task.getTextIdentifier()}`
case NOTIFICATION_NAMES.TASK_ASSIGNED:
who = `${getDisplayName(this.notification.assignee)}`
if (user !== null && user.id === this.notification.assignee.id) {
who = 'you'
who = ''
}
return `assigned ${who} to ${this.notification.task.getTextIdentifier()}`
return `asignó ${who} a ${this.notification.task.getTextIdentifier()}`
case NOTIFICATION_NAMES.TASK_DELETED:
return `deleted ${this.notification.task.getTextIdentifier()}`
return `eliminó ${this.notification.task.getTextIdentifier()}`
case NOTIFICATION_NAMES.PROJECT_CREATED:
return `created ${this.notification.project.title}`
return `creó ${this.notification.project.title}`
case NOTIFICATION_NAMES.TEAM_MEMBER_ADDED:
who = `${getDisplayName(this.notification.member)}`
if (user !== null && user.id === this.notification.member.id) {
who = 'you'
who = ''
}
return `added ${who} to the ${this.notification.team.name} team`
return `te añadió ${who} a el equipo ${this.notification.team.name}`
case NOTIFICATION_NAMES.TASK_REMINDER:
return `Reminder for ${this.notification.task.getTextIdentifier()} ${this.notification.task.title} (${this.notification.project.title})`
return `Recordatorio para ${this.notification.task.getTextIdentifier()} ${this.notification.task.title} (${this.notification.project.title})`
}
return ''

View File

@ -36,6 +36,7 @@ import (
"code.vikunja.io/api/pkg/user"
"code.vikunja.io/api/pkg/utils"
"code.vikunja.io/api/pkg/version"
"xorm.io/xorm"
)
@ -106,7 +107,10 @@ func ExportUserData(s *xorm.Session, u *user.User) (err error) {
// Save the file id with the user
u.ExportFileID = exportFile.ID
_, err = s.Cols("export_file_id").Update(u)
_, err = s.
Where("id = ?", u.ID).
Cols("export_file_id").
Update(u)
if err != nil {
return
}

View File

@ -39,11 +39,11 @@ type ReminderDueNotification struct {
func (n *ReminderDueNotification) ToMail() *notifications.Mail {
return notifications.NewMail().
To(n.User.Email).
Subject(`Reminder for "`+n.Task.Title+`" (`+n.Project.Title+`)`).
Greeting("Hi "+n.User.GetName()+",").
Line(`This is a friendly reminder of the task "`+n.Task.Title+`" (`+n.Project.Title+`).`).
Action("Open Task", config.ServicePublicURL.GetString()+"tasks/"+strconv.FormatInt(n.Task.ID, 10)).
Line("Have a nice day!")
Subject(`Recordatorio para "`+n.Task.Title+`" (`+n.Project.Title+`)`).
Greeting("Hola "+n.User.GetName()+",").
Line(`Este es un amigable recordatorio de la tarea "`+n.Task.Title+`" (`+n.Project.Title+`).`).
Action("Abrir Tarea", config.ServicePublicURL.GetString()+"tasks/"+strconv.FormatInt(n.Task.ID, 10)).
Line("¡Qué tengas un buen día!")
}
// ToDB returns the ReminderDueNotification notification in a format which can be saved in the db
@ -80,14 +80,14 @@ func (n *TaskCommentNotification) ToMail() *notifications.Mail {
if n.Mentioned {
mail.
Line("**" + n.Doer.GetName() + "** mentioned you in a comment:").
Subject(n.Doer.GetName() + ` mentioned you in a comment in "` + n.Task.Title + `"`)
Line("**" + n.Doer.GetName() + "** te mencionó en un comentario:").
Subject(n.Doer.GetName() + ` the mencionó en un comentario de la tarea "` + n.Task.Title + `"`)
}
mail.HTML(n.Comment.Comment)
return mail.
Action("View Task", n.Task.GetFrontendURL())
Action("Ver Tarea", n.Task.GetFrontendURL())
}
// ToDB returns the TaskCommentNotification notification in a format which can be saved in the db
@ -112,15 +112,15 @@ type TaskAssignedNotification struct {
func (n *TaskAssignedNotification) ToMail() *notifications.Mail {
if n.Target.ID == n.Assignee.ID {
return notifications.NewMail().
Subject("You have been assigned to "+n.Task.Title+"("+n.Task.GetFullIdentifier()+")").
Line(n.Doer.GetName()+" has assigned you to "+n.Task.Title+".").
Action("View Task", n.Task.GetFrontendURL())
Subject("Has sido asignado a "+n.Task.Title+"("+n.Task.GetFullIdentifier()+")").
Line(n.Doer.GetName()+" te ha asignado a la tarea "+n.Task.Title+".").
Action("Ver Tarea", n.Task.GetFrontendURL())
}
return notifications.NewMail().
Subject(n.Task.Title+"("+n.Task.GetFullIdentifier()+")"+" has been assigned to "+n.Assignee.GetName()).
Line(n.Doer.GetName()+" has assigned this task to "+n.Assignee.GetName()+".").
Action("View Task", n.Task.GetFrontendURL())
Subject(n.Task.Title+"("+n.Task.GetFullIdentifier()+")"+" ha sido asignado a "+n.Assignee.GetName()).
Line(n.Doer.GetName()+" ha asignado esta tarea a "+n.Assignee.GetName()+".").
Action("Ver Tarea", n.Task.GetFrontendURL())
}
// ToDB returns the TaskAssignedNotification notification in a format which can be saved in the db
@ -142,8 +142,8 @@ type TaskDeletedNotification struct {
// ToMail returns the mail notification for TaskDeletedNotification
func (n *TaskDeletedNotification) ToMail() *notifications.Mail {
return notifications.NewMail().
Subject(n.Task.Title + " (" + n.Task.GetFullIdentifier() + ")" + " has been deleted").
Line(n.Doer.GetName() + " has deleted the task " + n.Task.Title + " (" + n.Task.GetFullIdentifier() + ")")
Subject(n.Task.Title + " (" + n.Task.GetFullIdentifier() + ")" + " ha sido borrado").
Line(n.Doer.GetName() + " ha borrado la tarea " + n.Task.Title + " (" + n.Task.GetFullIdentifier() + ")")
}
// ToDB returns the TaskDeletedNotification notification in a format which can be saved in the db
@ -165,9 +165,9 @@ type ProjectCreatedNotification struct {
// ToMail returns the mail notification for ProjectCreatedNotification
func (n *ProjectCreatedNotification) ToMail() *notifications.Mail {
return notifications.NewMail().
Subject(n.Doer.GetName()+` created the project "`+n.Project.Title+`"`).
Line(n.Doer.GetName()+` created the project "`+n.Project.Title+`"`).
Action("View Project", config.ServicePublicURL.GetString()+"projects/")
Subject(n.Doer.GetName()+` creó el proyecto "`+n.Project.Title+`"`).
Line(n.Doer.GetName()+` creó el proyecto "`+n.Project.Title+`"`).
Action("Ver Proyecto", config.ServicePublicURL.GetString()+"projects/")
}
// ToDB returns the ProjectCreatedNotification notification in a format which can be saved in the db
@ -190,11 +190,11 @@ type TeamMemberAddedNotification struct {
// ToMail returns the mail notification for TeamMemberAddedNotification
func (n *TeamMemberAddedNotification) ToMail() *notifications.Mail {
return notifications.NewMail().
Subject(n.Doer.GetName()+" added you to the "+n.Team.Name+" team in Vikunja").
Subject(n.Doer.GetName()+" te añadió al equipo "+n.Team.Name).
From(n.Doer.GetNameAndFromEmail()).
Greeting("Hi "+n.Member.GetName()+",").
Line(n.Doer.GetName()+" has just added you to the "+n.Team.Name+" team in Vikunja.").
Action("View Team", config.ServicePublicURL.GetString()+"teams/"+strconv.FormatInt(n.Team.ID, 10)+"/edit")
Line(n.Doer.GetName()+" te acaba de añadir al equipo "+n.Team.Name+".").
Action("Ver Equipo", config.ServicePublicURL.GetString()+"teams/"+strconv.FormatInt(n.Team.ID, 10)+"/edit")
}
// ToDB returns the TeamMemberAddedNotification notification in a format which can be saved in the db
@ -218,11 +218,11 @@ type UndoneTaskOverdueNotification struct {
func (n *UndoneTaskOverdueNotification) ToMail() *notifications.Mail {
until := time.Until(n.Task.DueDate).Round(1*time.Hour) * -1
return notifications.NewMail().
Subject(`Task "`+n.Task.Title+`" (`+n.Project.Title+`) is overdue`).
Greeting("Hi "+n.User.GetName()+",").
Line(`This is a friendly reminder of the task "`+n.Task.Title+`" (`+n.Project.Title+`) which is overdue since `+utils.HumanizeDuration(until)+` and not yet done.`).
Action("Open Task", config.ServicePublicURL.GetString()+"tasks/"+strconv.FormatInt(n.Task.ID, 10)).
Line("Have a nice day!")
Subject(`La tarea "`+n.Task.Title+`" (`+n.Project.Title+`) está vencida`).
Greeting("Hola "+n.User.GetName()+",").
Line(`Este es un recordatorio amigable de que la tarea "`+n.Task.Title+`" (`+n.Project.Title+`) está vencida desde `+utils.HumanizeDuration(until)+` y aún no está completada.`).
Action("Abrir Tarea", config.ServicePublicURL.GetString()+"tasks/"+strconv.FormatInt(n.Task.ID, 10)).
Line("¡Qué tengas un buen día!")
}
// ToDB returns the UndoneTaskOverdueNotification notification in a format which can be saved in the db
@ -257,16 +257,16 @@ func (n *UndoneTasksOverdueNotification) ToMail() *notifications.Mail {
overdueLine := ""
for _, task := range sortedTasks {
until := time.Until(task.DueDate).Round(1*time.Hour) * -1
overdueLine += `* [` + task.Title + `](` + config.ServicePublicURL.GetString() + "tasks/" + strconv.FormatInt(task.ID, 10) + `) (` + n.Projects[task.ProjectID].Title + `), overdue since ` + utils.HumanizeDuration(until) + "\n"
overdueLine += `* [` + task.Title + `](` + config.ServicePublicURL.GetString() + "tasks/" + strconv.FormatInt(task.ID, 10) + `) (` + n.Projects[task.ProjectID].Title + `), vencida desde ` + utils.HumanizeDuration(until) + "\n"
}
return notifications.NewMail().
Subject(`Your overdue tasks`).
Greeting("Hi "+n.User.GetName()+",").
Line("You have the following overdue tasks:").
Subject(`Tus tareas vencidas`).
Greeting("Hola "+n.User.GetName()+",").
Line("Tienes las siguientes tareas vencidas:").
Line(overdueLine).
Action("Open Vikunja", config.ServicePublicURL.GetString()).
Line("Have a nice day!")
Action("Abrir Tareas", config.ServicePublicURL.GetString()).
Line("¡Qué tengas un buen día!")
}
// ToDB returns the UndoneTasksOverdueNotification notification in a format which can be saved in the db
@ -292,19 +292,19 @@ func (n *UserMentionedInTaskNotification) SubjectID() int64 {
// ToMail returns the mail notification for UserMentionedInTaskNotification
func (n *UserMentionedInTaskNotification) ToMail() *notifications.Mail {
subject := n.Doer.GetName() + ` mentioned you in a new task "` + n.Task.Title + `"`
subject := n.Doer.GetName() + ` te mencionó en la nueva tarea "` + n.Task.Title + `"`
if n.IsNew {
subject = n.Doer.GetName() + ` mentioned you in a task "` + n.Task.Title + `"`
subject = n.Doer.GetName() + ` te mencionó en la tarea "` + n.Task.Title + `"`
}
mail := notifications.NewMail().
From(n.Doer.GetNameAndFromEmail()).
Subject(subject).
Line("**" + n.Doer.GetName() + "** mentioned you in a task:").
Line("**" + n.Doer.GetName() + "** te mencionó en la tarea:").
HTML(n.Task.Description)
return mail.
Action("View Task", n.Task.GetFrontendURL())
Action("Ver Tarea", n.Task.GetFrontendURL())
}
// ToDB returns the UserMentionedInTaskNotification notification in a format which can be saved in the db
@ -325,12 +325,12 @@ type DataExportReadyNotification struct {
// ToMail returns the mail notification for DataExportReadyNotification
func (n *DataExportReadyNotification) ToMail() *notifications.Mail {
return notifications.NewMail().
Subject("Your Vikunja Data Export is ready").
Greeting("Hi "+n.User.GetName()+",").
Line("Your Vikunja Data Export is ready for you to download. Click the button below to download it:").
Action("Download", config.ServicePublicURL.GetString()+"user/export/download").
Line("The download will be available for the next 7 days.").
Line("Have a nice day!")
Subject("Tus datos exportados están listos").
Greeting("Hola "+n.User.GetName()+",").
Line("Tus datos exportados están listos para descargar. Oprime el siguiente botón para descargarlos:").
Action("Descargar", config.ServicePublicURL.GetString()+"user/export/download").
Line("La descarga estará disponible por los siguientes 7 días.").
Line("¡Qué tengas un buen día!")
}
// ToDB returns the DataExportReadyNotification notification in a format which can be saved in the db

View File

@ -77,7 +77,7 @@ const mailTemplateHTML = `
{{ if .ActionURL }}
<p style="color: #9CA3AF;font-size:12px;border-top: 1px solid #dbdbdb;margin-top:20px;padding-top:20px;">
If the button above doesn't work, copy the url below and paste it in your browser's address bar:<br/>
Si el botón de arriba no funciona, copia el enlace de abajo y pégalo en la barra de búsqueda de tu navegador:<br/>
{{ .ActionURL }}
</p>
{{ end }}