初始提交:OCI 面板前端(含 GenAI 网关一期)
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
import { useMessage } from 'naive-ui'
|
||||
import { h, ref, type Ref, type VNodeChild } from 'vue'
|
||||
|
||||
type ToastKind = 'error' | 'warning'
|
||||
|
||||
const AUTO_CLOSE_MS = 8000
|
||||
|
||||
function renderDetail(kind: ToastKind, detail: string, copied: Ref<boolean>): VNodeChild {
|
||||
return h('div', { class: 'toast-code' }, [
|
||||
h('div', { class: 'toast-code-head' }, [
|
||||
h('span', { class: `toast-tag toast-tag-${kind}` }, kind === 'error' ? 'ERROR' : 'WARN'),
|
||||
h(
|
||||
'button',
|
||||
{
|
||||
class: 'toast-copy',
|
||||
onClick: () => {
|
||||
void navigator.clipboard.writeText(detail)
|
||||
copied.value = true
|
||||
},
|
||||
},
|
||||
copied.value ? '已复制' : '⎘ 复制',
|
||||
),
|
||||
]),
|
||||
h('pre', { class: 'toast-code-pre' }, detail),
|
||||
])
|
||||
}
|
||||
|
||||
function renderToast(
|
||||
kind: ToastKind,
|
||||
text: string,
|
||||
detail: string,
|
||||
expanded: Ref<boolean>,
|
||||
copied: Ref<boolean>,
|
||||
toggle: () => void,
|
||||
): VNodeChild {
|
||||
const rows: VNodeChild[] = [
|
||||
h('div', { class: 'toast-line' }, [
|
||||
h('span', text),
|
||||
h('a', { class: 'toast-toggle', onClick: toggle }, expanded.value ? '收起 ▴' : '展开详情 ▾'),
|
||||
]),
|
||||
]
|
||||
if (expanded.value) rows.push(renderDetail(kind, detail, copied))
|
||||
return h('div', { class: 'toast-body' }, rows)
|
||||
}
|
||||
|
||||
/**
|
||||
* 带可展开详情的消息封装:error/warning 传 detail 时,toast 内嵌
|
||||
* 「展开详情」代码块(带复制);展开期间暂停 8s 自动关闭,收起后重新计时。
|
||||
*/
|
||||
export function useToast() {
|
||||
const message = useMessage()
|
||||
|
||||
function show(kind: ToastKind, text: string, detail?: string) {
|
||||
if (!detail) {
|
||||
message[kind](text)
|
||||
return
|
||||
}
|
||||
const expanded = ref(false)
|
||||
const copied = ref(false)
|
||||
let timer = 0
|
||||
const inst = message[kind](
|
||||
() => renderToast(kind, text, detail, expanded, copied, toggle),
|
||||
{ duration: 0, closable: true },
|
||||
)
|
||||
const arm = () => {
|
||||
timer = window.setTimeout(() => inst.destroy(), AUTO_CLOSE_MS)
|
||||
}
|
||||
function toggle() {
|
||||
expanded.value = !expanded.value
|
||||
window.clearTimeout(timer)
|
||||
if (!expanded.value) arm()
|
||||
}
|
||||
arm()
|
||||
}
|
||||
|
||||
return {
|
||||
success: (text: string) => message.success(text),
|
||||
info: (text: string) => message.info(text),
|
||||
error: (text: string, detail?: string) => show('error', text, detail),
|
||||
warning: (text: string, detail?: string) => show('warning', text, detail),
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user