import { nextTick, ref } from 'vue'; /** * Очередь подтверждающих диалогов с поддержкой async-onConfirm и анимаций. * Перенесено из проекта onboard (Composables/useAppDialog.js). * * Использование: * const ok = await useAppDialog({ title: 'Удалить?', content: '...' }) */ export interface AppDialogButtonProps { type?: 'default' | 'primary' | 'info' | 'success' | 'warning' | 'error'; secondary?: boolean; [key: string]: unknown; } export interface AppDialogItem { id: number; show: boolean; title?: string; content?: string; loading: boolean; onConfirm?: () => unknown | Promise; positiveText?: string; negativeText?: string; positiveProps?: AppDialogButtonProps; negativeProps?: AppDialogButtonProps; maskClosable?: boolean; resolve: (confirmed: boolean) => void; } export interface AppDialogOptions { title?: string; content?: string; positiveText?: string; negativeText?: string; positiveProps?: AppDialogButtonProps; negativeProps?: AppDialogButtonProps; maskClosable?: boolean; onConfirm?: () => unknown | Promise; } export const dialogQueue = ref([]); let idCounter = 0; /** Закрытие диалога (кнопка / Esc / клик по маске). */ export function closeDialog(id: number, confirmed = false): void { const dialog = dialogQueue.value.find((d) => d.id === id); if (dialog && dialog.show) { dialog.show = false; dialog.resolve(confirmed); } } /** Удаление из очереди после завершения leave-анимации. */ export function cleanupDialog(id: number): void { dialogQueue.value = dialogQueue.value.filter((d) => d.id !== id); } export function useAppDialog(options: AppDialogOptions = {}): Promise { const { title, content, positiveProps, negativeProps, positiveText = 'Подтвердить', negativeText = 'Отмена', maskClosable = false, onConfirm, } = options; return new Promise((resolve) => { const id = idCounter++; dialogQueue.value.push({ id, show: false, title, content, loading: false, onConfirm, positiveText, negativeText, positiveProps, negativeProps, maskClosable, resolve, }); nextTick(() => { const dialog = dialogQueue.value.find((d) => d.id === id); if (dialog) { dialog.show = true; } }); }); }