176 lines
4.6 KiB
TypeScript
176 lines
4.6 KiB
TypeScript
// Composable for Git synchronization functionality
|
|
interface GitRepository {
|
|
id: string
|
|
name: string
|
|
owner: string
|
|
url: string
|
|
cloneUrl: string
|
|
isPrivate: boolean
|
|
type: 'personal' | 'group'
|
|
ownerId: string
|
|
createdAt: string
|
|
updatedAt: string
|
|
}
|
|
|
|
export const useGitSync = () => {
|
|
const auth = useAuth()
|
|
const user = computed(() => auth.user)
|
|
|
|
const apiFetch = (url: string, opts: any = {}) => $fetch(url, {
|
|
...opts,
|
|
headers: { Authorization: `Bearer ${auth.token.value}`, ...opts.headers }
|
|
})
|
|
|
|
const isSyncing = ref(false)
|
|
const lastSyncTime = ref<string | null>(null)
|
|
const syncStatus = ref<'idle' | 'syncing' | 'success' | 'error'>('idle')
|
|
const repository = ref<GitRepository | null>(null)
|
|
|
|
// Auto-sync canvas changes
|
|
const autoSyncCanvas = async (canvasId: string, canvasData: any) => {
|
|
if (!auth.user || !canvasId) return
|
|
|
|
try {
|
|
syncStatus.value = 'syncing'
|
|
isSyncing.value = true
|
|
|
|
const response = await apiFetch('/api/git/real-sync', {
|
|
method: 'POST',
|
|
body: {
|
|
canvasId,
|
|
action: 'sync',
|
|
commitMessage: `Auto-sync: ${new Date().toLocaleString('ru-RU')}`
|
|
}
|
|
}) as any
|
|
|
|
if (response.success) {
|
|
syncStatus.value = 'success'
|
|
lastSyncTime.value = new Date().toISOString()
|
|
|
|
// Show success notification
|
|
console.log('Canvas synchronized with Git:', response.message)
|
|
} else {
|
|
syncStatus.value = 'error'
|
|
console.error('Git sync failed:', response.message)
|
|
}
|
|
} catch (error) {
|
|
syncStatus.value = 'error'
|
|
console.error('Auto-sync failed:', error)
|
|
} finally {
|
|
isSyncing.value = false
|
|
// Reset status after delay
|
|
setTimeout(() => {
|
|
if (syncStatus.value === 'success') {
|
|
syncStatus.value = 'idle'
|
|
}
|
|
}, 3000)
|
|
}
|
|
}
|
|
|
|
// Create Git repository for canvas
|
|
const createRepository = async (canvasId: string, type: 'personal' | 'group' = 'personal') => {
|
|
if (!auth.user || !canvasId) return
|
|
|
|
try {
|
|
const response = await apiFetch('/api/git/real-sync', {
|
|
method: 'POST',
|
|
body: {
|
|
canvasId,
|
|
action: 'init'
|
|
}
|
|
}) as any
|
|
|
|
if (response.success) {
|
|
repository.value = response.repository
|
|
console.log('Git repository created:', response.message)
|
|
return response.repository
|
|
}
|
|
} catch (error) {
|
|
console.error('Failed to create repository:', error)
|
|
throw error
|
|
}
|
|
}
|
|
|
|
// Manual sync
|
|
const manualSync = async (canvasId: string, commitMessage?: string) => {
|
|
if (!auth.user || !canvasId) return
|
|
|
|
try {
|
|
syncStatus.value = 'syncing'
|
|
isSyncing.value = true
|
|
|
|
const response = await apiFetch('/api/git/real-sync', {
|
|
method: 'POST',
|
|
body: {
|
|
canvasId,
|
|
action: 'sync',
|
|
commitMessage: commitMessage || `Ручная синхронизация: ${new Date().toLocaleString('ru-RU')}`
|
|
}
|
|
}) as any
|
|
|
|
if (response.success) {
|
|
syncStatus.value = 'success'
|
|
lastSyncTime.value = new Date().toISOString()
|
|
console.log('Manual sync completed:', response.message)
|
|
}
|
|
} catch (error) {
|
|
syncStatus.value = 'error'
|
|
console.error('Manual sync failed:', error)
|
|
} finally {
|
|
isSyncing.value = false
|
|
setTimeout(() => {
|
|
if (syncStatus.value === 'success') {
|
|
syncStatus.value = 'idle'
|
|
}
|
|
}, 3000)
|
|
}
|
|
}
|
|
|
|
// Check if canvas has repository
|
|
const checkRepository = async (canvasId: string) => {
|
|
if (!canvasId) return null
|
|
|
|
try {
|
|
const response = await apiFetch(`/api/git/repository/${canvasId}`) as any
|
|
repository.value = response.repository
|
|
return response.repository
|
|
} catch (error) {
|
|
repository.value = null
|
|
return null
|
|
}
|
|
}
|
|
|
|
// Get sync status color
|
|
const syncStatusColor = computed(() => {
|
|
switch (syncStatus.value) {
|
|
case 'syncing': return 'text-yellow-400'
|
|
case 'success': return 'text-green-400'
|
|
case 'error': return 'text-red-400'
|
|
default: return 'text-slate-400'
|
|
}
|
|
})
|
|
|
|
// Get sync status icon
|
|
const syncStatusIcon = computed(() => {
|
|
switch (syncStatus.value) {
|
|
case 'syncing': return '⟳'
|
|
case 'success': return '✓'
|
|
case 'error': return '✗'
|
|
default: return '⚡'
|
|
}
|
|
})
|
|
|
|
return {
|
|
isSyncing: readonly(isSyncing),
|
|
lastSyncTime: readonly(lastSyncTime),
|
|
syncStatus: readonly(syncStatus),
|
|
repository: readonly(repository),
|
|
syncStatusColor,
|
|
syncStatusIcon,
|
|
autoSyncCanvas,
|
|
createRepository,
|
|
manualSync,
|
|
checkRepository
|
|
}
|
|
}
|