优化pagetype添加标签的实现

This commit is contained in:
jingrow 2026-06-26 00:02:08 +08:00
parent fef84333fa
commit 1c284bf18f
2 changed files with 60 additions and 17 deletions

View File

@ -15,15 +15,26 @@
{{ tag }}
</n-tag>
<!-- 编辑态 按钮输入框收起时 -->
<button
v-if="canEdit && !inputVisible"
class="tag-add-btn"
@click="inputVisible = true"
:title="t('Add tag...')"
>
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
</button>
<!-- 编辑态 按钮或幽灵文字输入框收起时 -->
<template v-if="canEdit && !inputVisible">
<!-- 有标签时 按钮 -->
<button
v-if="tags.length > 0"
class="tag-add-btn"
@click="handleShowInput"
:title="t('Add tag...')"
>
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
</button>
<!-- 无标签时幽灵文字入口 -->
<span
v-else
class="tag-ghost"
@click="handleShowInput"
>
+ {{ t('Add tag') }}
</span>
</template>
<!-- 编辑态输入框展开时 -->
<div v-if="canEdit && inputVisible" class="tag-compact-input" ref="inputContainerRef">
@ -144,21 +155,24 @@ async function handleAddTag(tag: string) {
const trimmed = (tag || '').trim()
if (!trimmed) return
// _user_tags
if (tags.value.includes(trimmed)) {
tagInput.value = ''
return
}
// _user_tags @select + @keyup.enter
const currentTags = props.record._user_tags || ''
const newTags = currentTags ? `${currentTags},${trimmed}` : `,${trimmed}`
props.record._user_tags = newTags
tagInput.value = ''
try {
await api.call('jingrow.desk.pagetype.tag.tag.add_tag', {
tag: trimmed,
dt: props.entity,
dn: props.id
})
const currentTags = props.record._user_tags || ''
const newTags = currentTags ? `${currentTags},${trimmed}` : `,${trimmed}`
props.record._user_tags = newTags
tagInput.value = ''
// compact
if (props.compact) {
@ -167,6 +181,11 @@ async function handleAddTag(tag: string) {
input?.focus()
}
} catch (e: any) {
//
const tagList = (props.record._user_tags || '').split(',').filter(
(t: string) => t.trim() && t.trim() !== trimmed
)
props.record._user_tags = tagList.length > 0 ? ',' + tagList.join(',') : ''
message.error(e.message || t('Failed to add tag'))
}
}
@ -219,16 +238,25 @@ function handleTagClick(tag: string) {
})
}
// compact
async function handleShowInput() {
inputVisible.value = true
await nextTick()
inputContainerRef.value?.querySelector('input')?.focus()
}
// compact
function handleInputBlur(e: FocusEvent) {
// select
// select / click
setTimeout(() => {
const relatedTarget = e.relatedTarget as HTMLElement | null
const container = inputContainerRef.value
if (container && !container.contains(relatedTarget)) {
inputVisible.value = false
tagInput.value = ''
// relatedTarget null
if (!container || (relatedTarget && container.contains(relatedTarget))) {
return
}
inputVisible.value = false
tagInput.value = ''
}, 200)
}
</script>
@ -320,6 +348,18 @@ function handleInputBlur(e: FocusEvent) {
background: #f3f4f6;
}
.tag-ghost {
color: #d1d5db;
font-size: 12px;
cursor: pointer;
user-select: none;
transition: color 0.15s ease;
line-height: 22px;
}
.tag-ghost:hover {
color: #6b7280;
}
.tag-compact-input {
width: 180px;
}

View File

@ -23106,6 +23106,9 @@ msgstr "暂无标签"
msgid "Add tag..."
msgstr "添加标签..."
msgid "Add tag"
msgstr "添加标签"
msgid "Failed to add tag"
msgstr "添加标签失败"