fix(frontend): polish integration channel card actions
Align add-card height with channel cards, show actions on hover, and replace delete dialogs with in-place popconfirm like model settings.
This commit is contained in:
@@ -45,12 +45,32 @@
|
||||
variant="text"
|
||||
shape="square"
|
||||
size="small"
|
||||
class="channel-card__more"
|
||||
class="channel-card__action-btn channel-card__more"
|
||||
@click.stop
|
||||
>
|
||||
<template #icon><t-icon name="ellipsis" /></template>
|
||||
</t-button>
|
||||
</t-dropdown>
|
||||
<t-popconfirm
|
||||
:content="$t('embedPublish.deleteConfirm')"
|
||||
:confirm-btn="{ content: $t('common.delete'), theme: 'danger' }"
|
||||
:cancel-btn="{ content: $t('common.cancel') }"
|
||||
placement="bottom-right"
|
||||
@confirm="() => removeChannel(ch.id)"
|
||||
>
|
||||
<t-tooltip :content="$t('common.delete')" placement="top">
|
||||
<t-button
|
||||
theme="danger"
|
||||
shape="square"
|
||||
variant="text"
|
||||
size="small"
|
||||
class="channel-card__action-btn channel-card__delete"
|
||||
@click.stop
|
||||
>
|
||||
<template #icon><t-icon name="delete" /></template>
|
||||
</t-button>
|
||||
</t-tooltip>
|
||||
</t-popconfirm>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
@@ -524,7 +544,7 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, nextTick, reactive, ref, watch } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { DialogPlugin, MessagePlugin } from 'tdesign-vue-next'
|
||||
import { MessagePlugin } from 'tdesign-vue-next'
|
||||
import { useAuthStore } from '@/stores/auth'
|
||||
import SettingDrawer from '@/components/settings/SettingDrawer.vue'
|
||||
import EmbedChannelPreview from '@/components/EmbedChannelPreview.vue'
|
||||
@@ -680,7 +700,7 @@ const defaultLocaleOptions = computed(() => ([
|
||||
]))
|
||||
|
||||
const channelMenuOptions = (ch: EmbedChannel) => {
|
||||
const items: Array<{ content: string; value: string; theme?: 'error' }> = []
|
||||
const items: Array<{ content: string; value: string }> = []
|
||||
if (isAdmin.value) {
|
||||
items.push({ content: t('embedPublish.preview'), value: 'preview' })
|
||||
}
|
||||
@@ -688,9 +708,6 @@ const channelMenuOptions = (ch: EmbedChannel) => {
|
||||
content: ch.enabled ? t('common.off') : t('common.on'),
|
||||
value: 'toggle',
|
||||
})
|
||||
if (isAdmin.value) {
|
||||
items.push({ content: t('common.delete'), value: 'delete', theme: 'error' })
|
||||
}
|
||||
return items
|
||||
}
|
||||
|
||||
@@ -701,10 +718,6 @@ function handleChannelMenuClick(data: { value?: string }, ch: EmbedChannel) {
|
||||
}
|
||||
if (data.value === 'toggle') {
|
||||
void toggleEnabled(ch, !ch.enabled)
|
||||
return
|
||||
}
|
||||
if (data.value === 'delete') {
|
||||
confirmRemoveChannel(ch.id)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1216,20 +1229,6 @@ const performRotate = async (id: string) => {
|
||||
}
|
||||
}
|
||||
|
||||
const confirmRemoveChannel = (id: string) => {
|
||||
const dialog = DialogPlugin.confirm({
|
||||
header: t('common.delete'),
|
||||
body: t('embedPublish.deleteConfirm'),
|
||||
confirmBtn: { content: t('common.delete'), theme: 'danger' },
|
||||
cancelBtn: t('common.cancel'),
|
||||
onConfirm: async () => {
|
||||
dialog.destroy()
|
||||
await removeChannel(id)
|
||||
},
|
||||
onClose: () => dialog.destroy(),
|
||||
})
|
||||
}
|
||||
|
||||
const removeChannel = async (id: string) => {
|
||||
await deleteEmbedChannel(id)
|
||||
const map = loadStoredTokens()
|
||||
|
||||
@@ -51,12 +51,32 @@
|
||||
variant="text"
|
||||
shape="square"
|
||||
size="small"
|
||||
class="channel-card__more"
|
||||
class="channel-card__action-btn channel-card__more"
|
||||
@click.stop
|
||||
>
|
||||
<template #icon><t-icon name="ellipsis" /></template>
|
||||
</t-button>
|
||||
</t-dropdown>
|
||||
<t-popconfirm
|
||||
:content="$t('agentEditor.im.deleteConfirm')"
|
||||
:confirm-btn="{ content: $t('common.delete'), theme: 'danger' }"
|
||||
:cancel-btn="{ content: $t('common.cancel') }"
|
||||
placement="bottom-right"
|
||||
@confirm="() => handleDelete(channel.id)"
|
||||
>
|
||||
<t-tooltip :content="$t('common.delete')" placement="top">
|
||||
<t-button
|
||||
theme="danger"
|
||||
shape="square"
|
||||
variant="text"
|
||||
size="small"
|
||||
class="channel-card__action-btn channel-card__delete"
|
||||
@click.stop
|
||||
>
|
||||
<template #icon><t-icon name="delete" /></template>
|
||||
</t-button>
|
||||
</t-tooltip>
|
||||
</t-popconfirm>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
@@ -565,7 +585,7 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, watch, onUnmounted, computed } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { DialogPlugin, MessagePlugin } from 'tdesign-vue-next';
|
||||
import { MessagePlugin } from 'tdesign-vue-next';
|
||||
import {
|
||||
listIMChannels, createIMChannel, updateIMChannel, deleteIMChannel, toggleIMChannel,
|
||||
getWeChatQRCode, pollWeChatQRCodeStatus, listAllIMChannels, listAgents,
|
||||
@@ -703,7 +723,6 @@ const channelMenuOptions = (channel: IMChannel | IMChannelOverview) => ([
|
||||
content: channel.enabled ? t('common.off') : t('common.on'),
|
||||
value: 'toggle',
|
||||
},
|
||||
{ content: t('common.delete'), value: 'delete', theme: 'error' as const },
|
||||
]);
|
||||
|
||||
function handleChannelMenuClick(
|
||||
@@ -712,10 +731,6 @@ function handleChannelMenuClick(
|
||||
) {
|
||||
if (data.value === 'toggle') {
|
||||
void handleToggle(channel);
|
||||
return;
|
||||
}
|
||||
if (data.value === 'delete') {
|
||||
confirmDelete(channel.id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -935,20 +950,6 @@ function openDrawer(channel: IMChannel | IMChannelOverview) {
|
||||
void editChannel(channel);
|
||||
}
|
||||
|
||||
function confirmDelete(id: string) {
|
||||
const dialog = DialogPlugin.confirm({
|
||||
header: t('common.delete'),
|
||||
body: t('agentEditor.im.deleteConfirm'),
|
||||
confirmBtn: { content: t('common.delete'), theme: 'danger' },
|
||||
cancelBtn: t('common.cancel'),
|
||||
onConfirm: async () => {
|
||||
dialog.destroy();
|
||||
await handleDelete(id);
|
||||
},
|
||||
onClose: () => dialog.destroy(),
|
||||
});
|
||||
}
|
||||
|
||||
async function editChannel(channel: IMChannel | IMChannelOverview) {
|
||||
wizardStep.value = 0;
|
||||
let fullChannel: IMChannel | null = null;
|
||||
|
||||
@@ -41,6 +41,8 @@
|
||||
gap: 12px;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
// Match two-line body (title + agent name) so the add card aligns with existing channels.
|
||||
min-height: calc(20px + 14px * 1.4 + 4px + 12px * 1.4);
|
||||
padding: 10px 12px;
|
||||
border: 1px solid var(--td-component-stroke);
|
||||
border-radius: 10px;
|
||||
@@ -54,6 +56,12 @@
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
|
||||
.channel-card__actions:not(.channel-card__actions--spacer) {
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
transition: opacity 0.15s ease;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:focus-visible {
|
||||
border-color: var(--td-brand-color-3, var(--td-brand-color));
|
||||
@@ -61,12 +69,25 @@
|
||||
outline: none;
|
||||
}
|
||||
|
||||
&:hover .channel-card__actions:not(.channel-card__actions--spacer),
|
||||
&:focus-within .channel-card__actions:not(.channel-card__actions--spacer) {
|
||||
opacity: 1;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
outline: 2px solid var(--td-brand-color);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (hover: none) {
|
||||
&--clickable .channel-card__actions:not(.channel-card__actions--spacer) {
|
||||
opacity: 1;
|
||||
pointer-events: auto;
|
||||
}
|
||||
}
|
||||
|
||||
&--add {
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
@@ -160,16 +181,18 @@
|
||||
margin-left: auto;
|
||||
|
||||
&--spacer {
|
||||
width: 24px;
|
||||
width: 52px;
|
||||
height: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
&__more {
|
||||
&__action-btn {
|
||||
flex-shrink: 0;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
&__more {
|
||||
color: var(--td-text-color-placeholder);
|
||||
transition: color 0.15s ease, background 0.15s ease;
|
||||
|
||||
&:hover,
|
||||
&:focus-visible {
|
||||
@@ -177,6 +200,16 @@
|
||||
color: var(--td-text-color-primary);
|
||||
}
|
||||
}
|
||||
|
||||
&__delete {
|
||||
color: var(--td-error-color);
|
||||
|
||||
&:hover,
|
||||
&:focus-visible {
|
||||
background: color-mix(in srgb, var(--td-error-color) 12%, transparent);
|
||||
color: var(--td-error-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.agent-field-row {
|
||||
|
||||
Reference in New Issue
Block a user