Merge branch 'main' into vue3
This commit is contained in:
commit
8e1ab8e09b
16 changed files with 126 additions and 80 deletions
20
.drone.yml
20
.drone.yml
|
@ -80,25 +80,13 @@ steps:
|
|||
depends_on:
|
||||
- dependencies
|
||||
|
||||
# Building in dev mode to avoid the service worker for testing
|
||||
- name: build-dev
|
||||
image: node:16
|
||||
pull: true
|
||||
environment:
|
||||
YARN_CACHE_FOLDER: .cache/yarn/
|
||||
CYPRESS_CACHE_FOLDER: .cache/cypress/
|
||||
commands:
|
||||
- yarn build:dev
|
||||
depends_on:
|
||||
- dependencies
|
||||
|
||||
- name: build-prod
|
||||
image: node:16
|
||||
pull: true
|
||||
environment:
|
||||
YARN_CACHE_FOLDER: .cache/yarn/
|
||||
commands:
|
||||
- yarn build --dest dist-prod
|
||||
- yarn build
|
||||
depends_on:
|
||||
- dependencies
|
||||
|
||||
|
@ -120,12 +108,12 @@ steps:
|
|||
CYPRESS_CACHE_FOLDER: .cache/cypress/
|
||||
CYPRESS_DEFAULT_COMMAND_TIMEOUT: 60000
|
||||
commands:
|
||||
- sed -i 's/localhost/api/g' dist-dev/index.html
|
||||
- yarn serve:dist-dev & npx wait-on http://localhost:5000
|
||||
- sed -i 's/localhost/api/g' dist/index.html
|
||||
- yarn serve:dist & npx wait-on http://localhost:5000
|
||||
- yarn test:frontend --browser chrome
|
||||
depends_on:
|
||||
- dependencies
|
||||
- build-dev
|
||||
- build-prod
|
||||
|
||||
- name: upload-test-results
|
||||
image: plugins/s3
|
||||
|
|
|
@ -2,3 +2,10 @@
|
|||
import './commands'
|
||||
import 'cypress-file-upload'
|
||||
import '@4tw/cypress-drag-drop'
|
||||
|
||||
// see https://github.com/cypress-io/cypress/issues/702#issuecomment-587127275
|
||||
Cypress.on('window:before:load', (win) => {
|
||||
// disable service workers
|
||||
// @ts-ignore
|
||||
delete win.navigator.__proto__.ServiceWorker
|
||||
})
|
|
@ -19,6 +19,7 @@
|
|||
import {mapState} from 'vuex'
|
||||
|
||||
import logoUrl from '@/assets/logo-full.svg'
|
||||
import { saveLastVisited } from '@/helpers/saveLastVisited'
|
||||
|
||||
export default {
|
||||
name: 'contentNoAuth',
|
||||
|
@ -57,6 +58,7 @@ export default {
|
|||
localStorage.getItem('passwordResetToken') === null &&
|
||||
localStorage.getItem('emailConfirmToken') === null
|
||||
) {
|
||||
saveLastVisited(this.$route.name, this.$route.params)
|
||||
this.$router.push({name: 'user.login'})
|
||||
}
|
||||
},
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
v-focus
|
||||
v-model="newTaskTitle"
|
||||
ref="newTaskInput"
|
||||
:style="{'height': `${textAreaHeight}px`}"
|
||||
:style="{'height': `calc(${textAreaHeight}px - 2px + 1rem)`}"
|
||||
@keyup="errorMessage = ''"
|
||||
@keydown.enter="handleEnter"
|
||||
/>
|
||||
|
@ -40,7 +40,8 @@
|
|||
import TaskService from '../../services/task'
|
||||
import QuickAddMagic from '@/components/tasks/partials/quick-add-magic.vue'
|
||||
|
||||
const INITIAL_SCROLL_HEIGHT = 40
|
||||
const INPUT_BORDER_PX = 2
|
||||
const LINE_HEIGHT = 1.5 // using getComputedStyles().lineHeight returns an (wrong) absolute pixel value, we need the factor to do calculations with it.
|
||||
|
||||
const cleanupTitle = title => {
|
||||
return title.replace(/^((\* |\+ |- )(\[ \] )?)/g, '')
|
||||
|
@ -54,7 +55,8 @@ export default {
|
|||
newTaskTitle: '',
|
||||
taskService: new TaskService(),
|
||||
errorMessage: '',
|
||||
textAreaHeight: INITIAL_SCROLL_HEIGHT,
|
||||
textAreaHeight: null,
|
||||
initialTextAreaHeight: null,
|
||||
}
|
||||
},
|
||||
components: {
|
||||
|
@ -68,14 +70,17 @@ export default {
|
|||
},
|
||||
watch: {
|
||||
newTaskTitle(newVal) {
|
||||
let scrollHeight = this.$refs.newTaskInput.scrollHeight
|
||||
if (scrollHeight < INITIAL_SCROLL_HEIGHT || newVal === '') {
|
||||
scrollHeight = INITIAL_SCROLL_HEIGHT
|
||||
}
|
||||
// Calculating the textarea height based on lines of input in it. That is more reliable when removing a
|
||||
// line from the input.
|
||||
const numberOfLines = newVal.split(/\r\n|\r|\n/).length
|
||||
const fontSize = parseInt(window.getComputedStyle(this.$refs.newTaskInput, null).getPropertyValue('font-size'))
|
||||
|
||||
this.textAreaHeight = scrollHeight
|
||||
this.textAreaHeight = numberOfLines * fontSize * LINE_HEIGHT + INPUT_BORDER_PX
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.initialTextAreaHeight = this.$refs.newTaskInput.scrollHeight + INPUT_BORDER_PX
|
||||
},
|
||||
methods: {
|
||||
addTask() {
|
||||
if (this.newTaskTitle === '') {
|
||||
|
|
18
src/helpers/saveLastVisited.ts
Normal file
18
src/helpers/saveLastVisited.ts
Normal file
|
@ -0,0 +1,18 @@
|
|||
const LAST_VISITED_KEY = 'lastVisited'
|
||||
|
||||
export const saveLastVisited = (name: string, params: object) => {
|
||||
localStorage.setItem(LAST_VISITED_KEY, JSON.stringify({name, params}))
|
||||
}
|
||||
|
||||
export const getLastVisited = () => {
|
||||
const lastVisited = localStorage.getItem(LAST_VISITED_KEY)
|
||||
if (lastVisited === null) {
|
||||
return null
|
||||
}
|
||||
|
||||
return JSON.parse(lastVisited)
|
||||
}
|
||||
|
||||
export const clearLastVisited = () => {
|
||||
return localStorage.removeItem(LAST_VISITED_KEY)
|
||||
}
|
|
@ -128,7 +128,7 @@
|
|||
}
|
||||
},
|
||||
"list": {
|
||||
"archived": "This list is archived. It is not possible to create new or edit tasks for it.",
|
||||
"archived": "Diese Liste ist archiviert. Es ist nicht möglich, neue Aufgaben zu erstellen oder sie zu bearbeiten.",
|
||||
"title": "Listentitel",
|
||||
"color": "Farbe",
|
||||
"lists": "Listen",
|
||||
|
@ -626,7 +626,7 @@
|
|||
"addSuccess": "Das Label wurde erfolgreich hinzugefügt.",
|
||||
"createSuccess": "Das Label wurde erfolgreich erstellt.",
|
||||
"removeSuccess": "Das Label wurde erfolgreich entfernt.",
|
||||
"addCreateSuccess": "The label has been created and added successfully."
|
||||
"addCreateSuccess": "Das Label wurde erfolgreich erstellt und hinzugefügt."
|
||||
},
|
||||
"priority": {
|
||||
"unset": "Nicht eingestellt",
|
||||
|
@ -646,19 +646,19 @@
|
|||
"delete": "Aufgabenbeziehung entfernen",
|
||||
"deleteText1": "Willst du diese Aufgabenbeziehung wirklich entfernen?",
|
||||
"deleteText2": "Dies kann nicht rückgängig gemacht werden!",
|
||||
"select": "Select a relation kind",
|
||||
"select": "Beziehungsart auswählen",
|
||||
"kinds": {
|
||||
"subtask": "Subtask | Subtasks",
|
||||
"parenttask": "Parent Task | Parent Tasks",
|
||||
"related": "Related Task | Related Tasks",
|
||||
"duplicateof": "Duplicate Of | Duplicates Of",
|
||||
"duplicates": "Duplicates | Duplicates",
|
||||
"blocking": "Blocking | Blocking",
|
||||
"blocked": "Blocked By | Blocked By",
|
||||
"precedes": "Precedes | Precedes",
|
||||
"follows": "Follows | Follows",
|
||||
"copiedfrom": "Copied From | Copied From",
|
||||
"copiedto": "Copied To | Copied To"
|
||||
"subtask": "Unteraufgabe | Unteraufgaben",
|
||||
"parenttask": "Übergeordnete Aufgabe | Übergeordnete Aufgaben",
|
||||
"related": "Zugehörige Aufgabe | Zugehörige Aufgaben",
|
||||
"duplicateof": "Duplikat von | Duplikate von",
|
||||
"duplicates": "Dupliziert | Duplizierte",
|
||||
"blocking": "Blockiert | Blockiert",
|
||||
"blocked": "Blockiert von | Blockiert von",
|
||||
"precedes": "Vorgänger | Vorgänger",
|
||||
"follows": "Folgt | Folgen",
|
||||
"copiedfrom": "Kopiert von | Kopiert von",
|
||||
"copiedto": "Kopiert nach | Kopiert nach"
|
||||
}
|
||||
},
|
||||
"repeat": {
|
||||
|
|
|
@ -128,7 +128,7 @@
|
|||
}
|
||||
},
|
||||
"list": {
|
||||
"archived": "This list is archived. It is not possible to create new or edit tasks for it.",
|
||||
"archived": "Diese Liste ist archiviert. Es ist nicht möglich, neue Aufgaben zu erstellen oder sie zu bearbeiten.",
|
||||
"title": "Liste Titl",
|
||||
"color": "Farb",
|
||||
"lists": "Listene",
|
||||
|
@ -626,7 +626,7 @@
|
|||
"addSuccess": "Das Label isch erfolgriich hinzuegfüegt worde.",
|
||||
"createSuccess": "Das Label isch erfolgriich erstellt worde.",
|
||||
"removeSuccess": "Das Label isch erfolgriich glöscht.",
|
||||
"addCreateSuccess": "The label has been created and added successfully."
|
||||
"addCreateSuccess": "Das Label wurde erfolgreich erstellt und hinzugefügt."
|
||||
},
|
||||
"priority": {
|
||||
"unset": "Nid iihgstellt",
|
||||
|
@ -646,19 +646,19 @@
|
|||
"delete": "Uufgabe Beziehig chüble",
|
||||
"deleteText1": "Bisch du dir sicher, dass du die Zueghörigkeit chüblä wetsch?",
|
||||
"deleteText2": "Das chan nid rückgängig gmacht werde!",
|
||||
"select": "Select a relation kind",
|
||||
"select": "Beziehungsart auswählen",
|
||||
"kinds": {
|
||||
"subtask": "Subtask | Subtasks",
|
||||
"parenttask": "Parent Task | Parent Tasks",
|
||||
"related": "Related Task | Related Tasks",
|
||||
"duplicateof": "Duplicate Of | Duplicates Of",
|
||||
"duplicates": "Duplicates | Duplicates",
|
||||
"blocking": "Blocking | Blocking",
|
||||
"blocked": "Blocked By | Blocked By",
|
||||
"precedes": "Precedes | Precedes",
|
||||
"follows": "Follows | Follows",
|
||||
"copiedfrom": "Copied From | Copied From",
|
||||
"copiedto": "Copied To | Copied To"
|
||||
"subtask": "Unteraufgabe | Unteraufgaben",
|
||||
"parenttask": "Übergeordnete Aufgabe | Übergeordnete Aufgaben",
|
||||
"related": "Zugehörige Aufgabe | Zugehörige Aufgaben",
|
||||
"duplicateof": "Duplikat von | Duplikate von",
|
||||
"duplicates": "Dupliziert | Duplizierte",
|
||||
"blocking": "Blockiert | Blockiert",
|
||||
"blocked": "Blockiert von | Blockiert von",
|
||||
"precedes": "Vorgänger | Vorgänger",
|
||||
"follows": "Folgt | Folgen",
|
||||
"copiedfrom": "Kopiert von | Kopiert von",
|
||||
"copiedto": "Kopiert nach | Kopiert nach"
|
||||
}
|
||||
},
|
||||
"repeat": {
|
||||
|
@ -720,13 +720,13 @@
|
|||
"delete": {
|
||||
"header": "Das Team chüble",
|
||||
"text1": "Bischder sicher, dasst wetsch da Team mit allne Mitglieder lösche?",
|
||||
"text2": "Alli Teammitglider werded ihren Zuegang zu de Liste und Namensrüüm wo mit dem Team verbunde sind verlüüre. Das CHAN NID RÜCKGÄNIG gmacht werde!",
|
||||
"text2": "All team members will lose access to lists and namespaces shared with this team. This CANNOT BE UNDONE!",
|
||||
"success": "Da Team isch erfolgriich g'chüblet wore."
|
||||
},
|
||||
"deleteUser": {
|
||||
"header": "Benutzer usem Team entferne",
|
||||
"text1": "Bisch du dir sicher, dass du de Benutzer usm Team werfe wetsch?",
|
||||
"text2": "Er wird Zuegriff uf alli Liste und Namensrüüm verlüüre, wo da Team zuegriff druff het. Das CHAN NID RÜCKGÄNIG GMACHT WERDE!",
|
||||
"text2": "They will lose access to all lists and namespaces this team has access to. This CANNOT BE UNDONE!",
|
||||
"success": "Benutzer erfolgriich usegworfe."
|
||||
}
|
||||
},
|
||||
|
|
|
@ -720,13 +720,13 @@
|
|||
"delete": {
|
||||
"header": "Delete the team",
|
||||
"text1": "Are you sure you want to delete this team and all of its members?",
|
||||
"text2": "All team members will loose access to lists and namespaces shared with this team. This CANNOT BE UNDONE!",
|
||||
"text2": "All team members will lose access to lists and namespaces shared with this team. This CANNOT BE UNDONE!",
|
||||
"success": "The team was successfully deleted."
|
||||
},
|
||||
"deleteUser": {
|
||||
"header": "Remove a user from the team",
|
||||
"text1": "Are you sure you want to remove this user from the team?",
|
||||
"text2": "They will loose access to all lists and namespaces this team has access to. This CANNOT BE UNDONE!",
|
||||
"text2": "They will lose access to all lists and namespaces this team has access to. This CANNOT BE UNDONE!",
|
||||
"success": "The user was successfully deleted from the team."
|
||||
}
|
||||
},
|
||||
|
|
|
@ -626,7 +626,7 @@
|
|||
"addSuccess": "Étiquette ajoutée.",
|
||||
"createSuccess": "Étiquette créée.",
|
||||
"removeSuccess": "Étiquette retirée.",
|
||||
"addCreateSuccess": "The label has been created and added successfully."
|
||||
"addCreateSuccess": "L'étiquette a bien été créée et ajoutée."
|
||||
},
|
||||
"priority": {
|
||||
"unset": "Non définie",
|
||||
|
@ -646,19 +646,19 @@
|
|||
"delete": "Supprimer la relation de tâche",
|
||||
"deleteText1": "Supprimer cette relation de tâche ?",
|
||||
"deleteText2": "Ceci ne peut pas être annulé !",
|
||||
"select": "Select a relation kind",
|
||||
"select": "Sélectionnez un genre de relation",
|
||||
"kinds": {
|
||||
"subtask": "Subtask | Subtasks",
|
||||
"parenttask": "Parent Task | Parent Tasks",
|
||||
"related": "Related Task | Related Tasks",
|
||||
"duplicateof": "Duplicate Of | Duplicates Of",
|
||||
"duplicates": "Duplicates | Duplicates",
|
||||
"blocking": "Blocking | Blocking",
|
||||
"blocked": "Blocked By | Blocked By",
|
||||
"precedes": "Precedes | Precedes",
|
||||
"follows": "Follows | Follows",
|
||||
"copiedfrom": "Copied From | Copied From",
|
||||
"copiedto": "Copied To | Copied To"
|
||||
"subtask": "Sous-tâche | Sous-tâches",
|
||||
"parenttask": "Tâche parente | Tâches parentes",
|
||||
"related": "Tâche connexe | Tâches connexes",
|
||||
"duplicateof": "Doublon de | Doublons de",
|
||||
"duplicates": "Doublon | Doublons",
|
||||
"blocking": "Blocage | Blocages",
|
||||
"blocked": "Bloqué par | Bloqués par",
|
||||
"precedes": "Précède | Précède",
|
||||
"follows": "Suit | Suit",
|
||||
"copiedfrom": "Copié depuis | Copiés depuis",
|
||||
"copiedto": "Copié vers | Copiés vers"
|
||||
}
|
||||
},
|
||||
"repeat": {
|
||||
|
|
|
@ -292,6 +292,10 @@ $list-spacing: 1rem;
|
|||
|
||||
.list-cards-wrapper-2-rows {
|
||||
flex-wrap: wrap;
|
||||
max-height: calc(#{$list-height * 2} + #{$list-spacing * 2});
|
||||
max-height: calc(#{$list-height * 2} + #{$list-spacing * 2} - 4px);
|
||||
overflow: hidden;
|
||||
|
||||
@media screen and (max-width: $mobile) {
|
||||
max-height: calc(#{$list-height * 4} + #{$list-spacing * 4} - 4px);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
line-height: 1;
|
||||
|
||||
.button {
|
||||
padding: 0 0.25rem;
|
||||
padding: 0 .5rem;
|
||||
height: 1rem;
|
||||
|
||||
.icon {
|
||||
|
|
|
@ -38,9 +38,9 @@ $scrollbar-hover-color: $grey-500;
|
|||
|
||||
$button-height: 34px;
|
||||
|
||||
$switch-view-height: 43px;
|
||||
$switch-view-height: 2.69rem;
|
||||
|
||||
$user-dropdown-width-mobile: 4rem;
|
||||
$user-dropdown-width-mobile: 5rem;
|
||||
$hamburger-menu-icon-spacing: 1rem;
|
||||
$hamburger-menu-icon-width: 28px;
|
||||
$navbar-height: 4rem;
|
||||
|
|
|
@ -163,6 +163,9 @@ export default {
|
|||
// object passed to this function here still has a reference to the store.
|
||||
this.labelEditLabel = new LabelModel({
|
||||
...label,
|
||||
// The model does not support passing dates into it directly so we need to convert them first
|
||||
created: +label.created,
|
||||
updated: +label.updated,
|
||||
})
|
||||
this.isLabelEdit = true
|
||||
|
||||
|
|
|
@ -104,13 +104,13 @@
|
|||
<script>
|
||||
import {mapState} from 'vuex'
|
||||
|
||||
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.vue'
|
||||
import {getErrorText} from '@/message'
|
||||
import {redirectToProvider} from '../../helpers/redirectToProvider'
|
||||
import {getLastVisited, clearLastVisited} from '../../helpers/saveLastVisited'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
@ -142,9 +142,18 @@ export default {
|
|||
})
|
||||
}
|
||||
|
||||
// Check if the user is already logged in, if so, redirect him to the homepage
|
||||
// Check if the user is already logged in, if so, redirect them to the homepage
|
||||
if (this.authenticated) {
|
||||
router.push({name: 'home'})
|
||||
const last = getLastVisited()
|
||||
if (last !== null) {
|
||||
this.$router.push({
|
||||
name: last.name,
|
||||
params: last.params,
|
||||
})
|
||||
clearLastVisited()
|
||||
} else {
|
||||
this.$router.push({name: 'home'})
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
|
|
|
@ -14,6 +14,7 @@ import {mapState} from 'vuex'
|
|||
|
||||
import {ERROR_MESSAGE, LOADING} from '@/store/mutation-types'
|
||||
import {getErrorText} from '@/message'
|
||||
import {clearLastVisited, getLastVisited} from '../../helpers/saveLastVisited'
|
||||
|
||||
export default {
|
||||
name: 'Auth',
|
||||
|
@ -63,7 +64,16 @@ export default {
|
|||
code: this.$route.query.code,
|
||||
})
|
||||
.then(() => {
|
||||
const last = getLastVisited()
|
||||
if (last !== null) {
|
||||
this.$router.push({
|
||||
name: last.name,
|
||||
params: last.params,
|
||||
})
|
||||
clearLastVisited()
|
||||
} else {
|
||||
this.$router.push({name: 'home'})
|
||||
}
|
||||
})
|
||||
.catch(e => {
|
||||
const err = getErrorText(e)
|
||||
|
|
|
@ -116,7 +116,7 @@ export default {
|
|||
}
|
||||
},
|
||||
beforeMount() {
|
||||
// Check if the user is already logged in, if so, redirect him to the homepage
|
||||
// Check if the user is already logged in, if so, redirect them to the homepage
|
||||
if (this.authenticated) {
|
||||
router.push({name: 'home'})
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue