first commit

This commit is contained in:
brusnitsyn
2026-06-24 17:20:43 +09:00
commit 43499acf1c
165 changed files with 25929 additions and 0 deletions

View File

@@ -0,0 +1,98 @@
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<unknown>;
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<unknown>;
}
export const dialogQueue = ref<AppDialogItem[]>([]);
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<boolean> {
const {
title,
content,
positiveProps,
negativeProps,
positiveText = 'Подтвердить',
negativeText = 'Отмена',
maskClosable = false,
onConfirm,
} = options;
return new Promise<boolean>((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;
}
});
});
}