fix: Fix title selection and editing
Signed-off-by: Julius Knorr <jus@bitgrid.net>
This commit is contained in:
@@ -19,12 +19,12 @@
|
|||||||
</div>
|
</div>
|
||||||
<CardCover v-if="showCardCover" :card-id="card.id" />
|
<CardCover v-if="showCardCover" :card-id="card.id" />
|
||||||
<div class="card-upper">
|
<div class="card-upper">
|
||||||
<h4 v-if="inlineEditingBlocked" dir="auto">
|
<h4 v-if="!editingTitle" dir="auto">
|
||||||
{{ displayTitle }}
|
<span v-auto-link class="dragDisabled">{{ displayTitle }}</span>
|
||||||
</h4>
|
</h4>
|
||||||
<h4 v-else
|
<h4 v-else
|
||||||
dir="auto"
|
dir="auto"
|
||||||
class="editable"
|
class="editable dragDisabled"
|
||||||
:aria-label="t('deck', 'Edit card title')">
|
:aria-label="t('deck', 'Edit card title')">
|
||||||
<span ref="titleContentEditable"
|
<span ref="titleContentEditable"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
@@ -38,7 +38,10 @@
|
|||||||
</h4>
|
</h4>
|
||||||
|
|
||||||
<DueDate v-if="compactMode" :card="card" />
|
<DueDate v-if="compactMode" :card="card" />
|
||||||
<CardMenu v-if="showMenuAtTitle" :card="card" class="right card-menu" />
|
<CardMenu v-if="showMenuAtTitle"
|
||||||
|
:card="card"
|
||||||
|
class="right card-menu"
|
||||||
|
@edit-title="triggerEditTitle" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="hasLabels" class="card-labels">
|
<div v-if="hasLabels" class="card-labels">
|
||||||
@@ -51,7 +54,10 @@
|
|||||||
<span @click.stop="applyLabelFilter(label)">{{ label.title }}</span>
|
<span @click.stop="applyLabelFilter(label)">{{ label.title }}</span>
|
||||||
</li>
|
</li>
|
||||||
</transition-group>
|
</transition-group>
|
||||||
<CardMenu v-if="showMenuAtLabels" :card="card" class="right" />
|
<CardMenu v-if="showMenuAtLabels"
|
||||||
|
:card="card"
|
||||||
|
class="right"
|
||||||
|
@edit-title="triggerEditTitle" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="hasBadges"
|
<div v-if="hasBadges"
|
||||||
@@ -59,7 +65,10 @@
|
|||||||
class="card-controls compact-item"
|
class="card-controls compact-item"
|
||||||
@click="openCard">
|
@click="openCard">
|
||||||
<CardBadges :card="card">
|
<CardBadges :card="card">
|
||||||
<CardMenu v-if="showMenuAtBadges" :card="card" class="right" />
|
<CardMenu v-if="showMenuAtBadges"
|
||||||
|
:card="card"
|
||||||
|
class="right"
|
||||||
|
@edit-title="triggerEditTitle" />
|
||||||
</CardBadges>
|
</CardBadges>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -78,6 +87,12 @@ import CardCover from './CardCover.vue'
|
|||||||
import DueDate from './badges/DueDate.vue'
|
import DueDate from './badges/DueDate.vue'
|
||||||
import { getCurrentUser } from '@nextcloud/auth'
|
import { getCurrentUser } from '@nextcloud/auth'
|
||||||
|
|
||||||
|
const TITLE_EDITING_STATE = {
|
||||||
|
OFF: 0,
|
||||||
|
PENDING: 1,
|
||||||
|
ON: 2,
|
||||||
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'CardItem',
|
name: 'CardItem',
|
||||||
components: { CardBadges, AttachmentDragAndDrop, CardMenu, CardCover, DueDate },
|
components: { CardBadges, AttachmentDragAndDrop, CardMenu, CardCover, DueDate },
|
||||||
@@ -106,6 +121,7 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
highlight: false,
|
highlight: false,
|
||||||
|
editingTitle: TITLE_EDITING_STATE.OFF,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -132,9 +148,6 @@ export default {
|
|||||||
const board = this.$store.getters.boards.find((item) => item.id === this.card.boardId)
|
const board = this.$store.getters.boards.find((item) => item.id === this.card.boardId)
|
||||||
return board ? !board.archived && board.permissions.PERMISSION_EDIT : false
|
return board ? !board.archived && board.permissions.PERMISSION_EDIT : false
|
||||||
},
|
},
|
||||||
inlineEditingBlocked() {
|
|
||||||
return this.card.referenceData || this.isArchived || this.showArchived || !this.canEdit || this.standalone
|
|
||||||
},
|
|
||||||
card() {
|
card() {
|
||||||
return this.item ? this.item : this.$store.getters.cardById(this.id)
|
return this.item ? this.item : this.$store.getters.cardById(this.id)
|
||||||
},
|
},
|
||||||
@@ -193,15 +206,19 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
hasSelection() {
|
||||||
|
const selection = window.getSelection()
|
||||||
|
return selection.toString() !== ''
|
||||||
|
},
|
||||||
focus(card) {
|
focus(card) {
|
||||||
if (this.shortcutLock) {
|
if (this.shortcutLock || this.hasSelection()) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
card = this.$refs[`card${card}`]
|
card = this.$refs[`card${card}`]
|
||||||
card.focus()
|
card.focus()
|
||||||
},
|
},
|
||||||
openCard() {
|
openCard() {
|
||||||
if (this.dragging) {
|
if (this.dragging || this.hasSelection()) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const boardId = this.card && this.card.boardId ? this.card.boardId : (this.$route?.params.id ?? this.currentBoard.id)
|
const boardId = this.card && this.card.boardId ? this.card.boardId : (this.$route?.params.id ?? this.currentBoard.id)
|
||||||
@@ -213,8 +230,19 @@ export default {
|
|||||||
|
|
||||||
this.$root.$emit('open-card', this.card.id)
|
this.$root.$emit('open-card', this.card.id)
|
||||||
},
|
},
|
||||||
|
triggerEditTitle() {
|
||||||
|
this.editingTitle = TITLE_EDITING_STATE.PENDING
|
||||||
|
this.$store.dispatch('toggleShortcutLock', true)
|
||||||
|
setTimeout(() => {
|
||||||
|
this.$refs.titleContentEditable.focus()
|
||||||
|
this.editingTitle = TITLE_EDITING_STATE.ON
|
||||||
|
}, 0)
|
||||||
|
},
|
||||||
onTitleBlur(e) {
|
onTitleBlur(e) {
|
||||||
// TODO Handle empty title
|
if (this.editingTitle !== TITLE_EDITING_STATE.ON || e.target.innerText === '') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.editingTitle = TITLE_EDITING_STATE.OFF
|
||||||
if (e.target.innerText !== this.card.title) {
|
if (e.target.innerText !== this.card.title) {
|
||||||
this.$store.dispatch('updateCardTitle', {
|
this.$store.dispatch('updateCardTitle', {
|
||||||
...this.card,
|
...this.card,
|
||||||
|
|||||||
@@ -5,13 +5,16 @@
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div v-if="card" class="card-menu" @click.stop.prevent>
|
<div v-if="card" class="card-menu" @click.stop.prevent>
|
||||||
<NcButton v-if="card.referenceData" type="tertiary" @click="openLink">
|
<NcButton v-if="card.referenceData"
|
||||||
|
type="tertiary"
|
||||||
|
:title="t('deck','Open link')"
|
||||||
|
@click="openLink">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<LinkIcon :size="20" />
|
<LinkIcon :size="20" />
|
||||||
</template>
|
</template>
|
||||||
</NcButton>
|
</NcButton>
|
||||||
<NcActions>
|
<NcActions>
|
||||||
<CardMenuEntries :card="card" />
|
<CardMenuEntries :card="card" @edit-title="editTitle" />
|
||||||
</NcActions>
|
</NcActions>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -29,11 +32,15 @@ export default {
|
|||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
emits: ['edit-title'],
|
||||||
methods: {
|
methods: {
|
||||||
openLink() {
|
openLink() {
|
||||||
window.open(this.card?.referenceData?.openGraphObject?.link)
|
window.open(this.card?.referenceData?.openGraphObject?.link)
|
||||||
return false
|
return false
|
||||||
},
|
},
|
||||||
|
editTitle(id) {
|
||||||
|
this.$emit('edit-title', id)
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -9,6 +9,12 @@
|
|||||||
<CardBulletedIcon slot="icon" :size="20" decorative />
|
<CardBulletedIcon slot="icon" :size="20" decorative />
|
||||||
{{ t('deck', 'Card details') }}
|
{{ t('deck', 'Card details') }}
|
||||||
</NcActionButton>
|
</NcActionButton>
|
||||||
|
<NcActionButton v-if="canEdit" :close-after-click="true" @click="editTitle">
|
||||||
|
<template #icon>
|
||||||
|
<PencilIcon :size="20" decorative />
|
||||||
|
</template>
|
||||||
|
{{ t('deck', 'Edit title') }}
|
||||||
|
</NcActionButton>
|
||||||
<NcActionButton v-if="canEdit && !isCurrentUserAssigned"
|
<NcActionButton v-if="canEdit && !isCurrentUserAssigned"
|
||||||
icon="icon-user"
|
icon="icon-user"
|
||||||
:close-after-click="true"
|
:close-after-click="true"
|
||||||
@@ -59,6 +65,7 @@ import { NcActionButton } from '@nextcloud/vue'
|
|||||||
import { mapGetters, mapState } from 'vuex'
|
import { mapGetters, mapState } from 'vuex'
|
||||||
import ArchiveIcon from 'vue-material-design-icons/Archive.vue'
|
import ArchiveIcon from 'vue-material-design-icons/Archive.vue'
|
||||||
import CardBulletedIcon from 'vue-material-design-icons/CardBulleted.vue'
|
import CardBulletedIcon from 'vue-material-design-icons/CardBulleted.vue'
|
||||||
|
import PencilIcon from 'vue-material-design-icons/Pencil.vue'
|
||||||
import { generateUrl } from '@nextcloud/router'
|
import { generateUrl } from '@nextcloud/router'
|
||||||
import { getCurrentUser } from '@nextcloud/auth'
|
import { getCurrentUser } from '@nextcloud/auth'
|
||||||
import { showUndo } from '@nextcloud/dialogs'
|
import { showUndo } from '@nextcloud/dialogs'
|
||||||
@@ -68,7 +75,7 @@ import { emit } from '@nextcloud/event-bus'
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'CardMenuEntries',
|
name: 'CardMenuEntries',
|
||||||
components: { NcActionButton, ArchiveIcon, CardBulletedIcon },
|
components: { NcActionButton, ArchiveIcon, CardBulletedIcon, PencilIcon },
|
||||||
props: {
|
props: {
|
||||||
card: {
|
card: {
|
||||||
type: Object,
|
type: Object,
|
||||||
@@ -79,6 +86,7 @@ export default {
|
|||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
emits: ['edit-title'],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
modalShow: false,
|
modalShow: false,
|
||||||
@@ -136,6 +144,9 @@ export default {
|
|||||||
|
|
||||||
this.$root.$emit('open-card', this.card.id)
|
this.$root.$emit('open-card', this.card.id)
|
||||||
},
|
},
|
||||||
|
editTitle() {
|
||||||
|
this.$emit('edit-title', this.card.id)
|
||||||
|
},
|
||||||
deleteCard() {
|
deleteCard() {
|
||||||
this.$store.dispatch('deleteCard', this.card)
|
this.$store.dispatch('deleteCard', this.card)
|
||||||
const undoCard = { ...this.card, deletedAt: 0 }
|
const undoCard = { ...this.card, deletedAt: 0 }
|
||||||
|
|||||||
Reference in New Issue
Block a user