зеркало из https://github.com/nextcloud/deck.git
fix: Fix title selection and editing
Signed-off-by: Julius Knorr <jus@bitgrid.net>
This commit is contained in:
Родитель
047fcb6584
Коммит
c5c8a6ef71
|
@ -19,12 +19,12 @@
|
|||
</div>
|
||||
<CardCover v-if="showCardCover" :card-id="card.id" />
|
||||
<div class="card-upper">
|
||||
<h4 v-if="inlineEditingBlocked" dir="auto">
|
||||
{{ displayTitle }}
|
||||
<h4 v-if="!editingTitle" dir="auto">
|
||||
<span v-auto-link class="dragDisabled">{{ displayTitle }}</span>
|
||||
</h4>
|
||||
<h4 v-else
|
||||
dir="auto"
|
||||
class="editable"
|
||||
class="editable dragDisabled"
|
||||
:aria-label="t('deck', 'Edit card title')">
|
||||
<span ref="titleContentEditable"
|
||||
tabindex="0"
|
||||
|
@ -38,7 +38,10 @@
|
|||
</h4>
|
||||
|
||||
<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 v-if="hasLabels" class="card-labels">
|
||||
|
@ -51,7 +54,10 @@
|
|||
<span @click.stop="applyLabelFilter(label)">{{ label.title }}</span>
|
||||
</li>
|
||||
</transition-group>
|
||||
<CardMenu v-if="showMenuAtLabels" :card="card" class="right" />
|
||||
<CardMenu v-if="showMenuAtLabels"
|
||||
:card="card"
|
||||
class="right"
|
||||
@edit-title="triggerEditTitle" />
|
||||
</div>
|
||||
|
||||
<div v-if="hasBadges"
|
||||
|
@ -59,7 +65,10 @@
|
|||
class="card-controls compact-item"
|
||||
@click="openCard">
|
||||
<CardBadges :card="card">
|
||||
<CardMenu v-if="showMenuAtBadges" :card="card" class="right" />
|
||||
<CardMenu v-if="showMenuAtBadges"
|
||||
:card="card"
|
||||
class="right"
|
||||
@edit-title="triggerEditTitle" />
|
||||
</CardBadges>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -78,6 +87,12 @@ import CardCover from './CardCover.vue'
|
|||
import DueDate from './badges/DueDate.vue'
|
||||
import { getCurrentUser } from '@nextcloud/auth'
|
||||
|
||||
const TITLE_EDITING_STATE = {
|
||||
OFF: 0,
|
||||
PENDING: 1,
|
||||
ON: 2,
|
||||
}
|
||||
|
||||
export default {
|
||||
name: 'CardItem',
|
||||
components: { CardBadges, AttachmentDragAndDrop, CardMenu, CardCover, DueDate },
|
||||
|
@ -106,6 +121,7 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
highlight: false,
|
||||
editingTitle: TITLE_EDITING_STATE.OFF,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
@ -132,9 +148,6 @@ export default {
|
|||
const board = this.$store.getters.boards.find((item) => item.id === this.card.boardId)
|
||||
return board ? !board.archived && board.permissions.PERMISSION_EDIT : false
|
||||
},
|
||||
inlineEditingBlocked() {
|
||||
return this.card.referenceData || this.isArchived || this.showArchived || !this.canEdit || this.standalone
|
||||
},
|
||||
card() {
|
||||
return this.item ? this.item : this.$store.getters.cardById(this.id)
|
||||
},
|
||||
|
@ -193,15 +206,19 @@ export default {
|
|||
},
|
||||
},
|
||||
methods: {
|
||||
hasSelection() {
|
||||
const selection = window.getSelection()
|
||||
return selection.toString() !== ''
|
||||
},
|
||||
focus(card) {
|
||||
if (this.shortcutLock) {
|
||||
if (this.shortcutLock || this.hasSelection()) {
|
||||
return
|
||||
}
|
||||
card = this.$refs[`card${card}`]
|
||||
card.focus()
|
||||
},
|
||||
openCard() {
|
||||
if (this.dragging) {
|
||||
if (this.dragging || this.hasSelection()) {
|
||||
return
|
||||
}
|
||||
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)
|
||||
},
|
||||
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) {
|
||||
// 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) {
|
||||
this.$store.dispatch('updateCardTitle', {
|
||||
...this.card,
|
||||
|
|
|
@ -5,13 +5,16 @@
|
|||
|
||||
<template>
|
||||
<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>
|
||||
<LinkIcon :size="20" />
|
||||
</template>
|
||||
</NcButton>
|
||||
<NcActions>
|
||||
<CardMenuEntries :card="card" />
|
||||
<CardMenuEntries :card="card" @edit-title="editTitle" />
|
||||
</NcActions>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -29,11 +32,15 @@ export default {
|
|||
default: null,
|
||||
},
|
||||
},
|
||||
emits: ['edit-title'],
|
||||
methods: {
|
||||
openLink() {
|
||||
window.open(this.card?.referenceData?.openGraphObject?.link)
|
||||
return false
|
||||
},
|
||||
editTitle(id) {
|
||||
this.$emit('edit-title', id)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -9,6 +9,12 @@
|
|||
<CardBulletedIcon slot="icon" :size="20" decorative />
|
||||
{{ t('deck', 'Card details') }}
|
||||
</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"
|
||||
icon="icon-user"
|
||||
:close-after-click="true"
|
||||
|
@ -59,6 +65,7 @@ import { NcActionButton } from '@nextcloud/vue'
|
|||
import { mapGetters, mapState } from 'vuex'
|
||||
import ArchiveIcon from 'vue-material-design-icons/Archive.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 { getCurrentUser } from '@nextcloud/auth'
|
||||
import { showUndo } from '@nextcloud/dialogs'
|
||||
|
@ -68,7 +75,7 @@ import { emit } from '@nextcloud/event-bus'
|
|||
|
||||
export default {
|
||||
name: 'CardMenuEntries',
|
||||
components: { NcActionButton, ArchiveIcon, CardBulletedIcon },
|
||||
components: { NcActionButton, ArchiveIcon, CardBulletedIcon, PencilIcon },
|
||||
props: {
|
||||
card: {
|
||||
type: Object,
|
||||
|
@ -79,6 +86,7 @@ export default {
|
|||
default: false,
|
||||
},
|
||||
},
|
||||
emits: ['edit-title'],
|
||||
data() {
|
||||
return {
|
||||
modalShow: false,
|
||||
|
@ -136,6 +144,9 @@ export default {
|
|||
|
||||
this.$root.$emit('open-card', this.card.id)
|
||||
},
|
||||
editTitle() {
|
||||
this.$emit('edit-title', this.card.id)
|
||||
},
|
||||
deleteCard() {
|
||||
this.$store.dispatch('deleteCard', this.card)
|
||||
const undoCard = { ...this.card, deletedAt: 0 }
|
||||
|
|
Загрузка…
Ссылка в новой задаче