web/front/pages/kompas.vue

153 lines
6.5 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup lang="ts">
const { sendCommandToPython, isReady } = usePythonBridge()
const {
documents,
selectedTypes,
documentCounts,
filteredDocuments,
documentTypeLabels,
getDocumentLabel,
} = useKompasDocuments()
const {
availableActions,
loadActions
} = useKompasActions()
const selectedAction = ref()
watch(selectedAction, () => {
selectedTypes.value = availableActions.value[selectedAction.value].allowedTypes
})
// Синхронизация с КОМПАС
async function syncKompas() {
try {
const docs = await sendCommandToPython<KompasDocument[]>('open_kompas')
if (!docs || !Array.isArray(docs)) {
console.warn('Неожиданный ответ от Python:', docs)
documents.value = []
} else {
documents.value = docs
loadActions()
}
console.warn('Документы из КОМПАС:', docs)
} catch (err) {
console.error('Ошибка при синхронизации с КОМПАС:', err)
alert('Не удалось получить список документов из КОМПАС')
}
}
const canRunAction = computed(() => {
return selectedAction.value && filteredDocuments.value.length > 0
})
async function runSelectedAction() {
if (!selectedAction.value) {
alert('Выберите действие')
return
}
try {
// Отправляем команду на бэкенд
const result = await sendCommandToPython(selectedAction.value)
console.log('Результат выполнения:', result)
if (result && result.status === 'success') {
alert(`Действие "${selectedAction.value}" выполнено успешно!`)
} else if (result && result.status === 'error') {
alert(`Ошибка при выполнении: ${result.error || 'Неизвестная ошибка'}`)
} else {
alert('Не удалось получить результат от сервера')
}
} catch (err) {
console.error('Ошибка при выполнении действия:', err)
alert('Произошла ошибка при выполнении действия')
}
}
</script>
<template>
<div class="flex flex-col gap-4 p-4">
<h1>Компас прослушка событий от Python</h1>
<!-- Статус -->
<div v-if="!isReady" class="mb-4 p-3 bg-yellow-100 text-yellow-800 rounded flex items-center">
⚠️ <strong class="ml-2">Ещё рано отправлять запросы. Идёт инициализация...</strong>
</div>
<template v-else>
<div>
<!-- Кнопка синхронизации -->
<button @click="syncKompas"
class="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded mb-4 transition">
🔁 Синхронизировать КОМПАС
</button>
</div>
<!-- Сообщение о пустом списке -->
<div v-if="!documents.length" class="text-gray-500 italic mt-2">
Нет данных о документах. Нажмите "Синхронизировать КОМПАС".
</div>
<template v-else>
<!-- Чекбоксы для фильтрации -->
<div class="mb-4 p-3 bg-gray-100 rounded shadow-sm">
<h3 class="font-medium mb-2">Фильтр по типам:</h3>
<div class="flex flex-wrap gap-4">
<label v-for="(label, code) in documentTypeLabels" :key="code" class="flex items-center gap-1">
<input type="checkbox" :value="Number(code)" v-model="selectedTypes"
:disabled="documentCounts[Number(code)] === 0"
class="form-checkbox h-4 w-4 text-blue-600 disabled:opacity-50" />
<span class="text-sm">
{{ label }} ({{ documentCounts[Number(code)] }})
</span>
</label>
</div>
</div>
<!-- Действия -->
<div class="mb-4 p-3 bg-gray-100 rounded shadow-sm">
<h3 class="font-medium mb-2">Действия:</h3>
<div class="flex flex-col gap-2">
<label v-for="(action, key) in availableActions" :key="key" class="flex items-center gap-2">
<input type="radio" :value="key" v-model="selectedAction"
class="form-radio h-4 w-4 text-blue-600" />
<span class="text-sm">{{ action.label }}</span>
</label>
</div>
<!-- Кнопка выполнения действия -->
<button type="button" @click="runSelectedAction" :disabled="!canRunAction" class="mt-4 px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600
disabled:opacity-50 disabled:cursor-not-allowed disabled:pointer-events-none
transition">
✅ Выполнить действие
</button>
</div>
<!-- Грид документов -->
<div v-if="filteredDocuments.length" class="mt-4 grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
<div v-for="(doc, index) in filteredDocuments" :key="index"
class="border rounded shadow-sm p-4 hover:shadow-md transition-shadow bg-white">
<h3 class="font-medium text-lg">{{ doc.name }}</h3>
<div class="mt-2">
<strong>Тип:</strong> {{ getDocumentLabel(doc.type) }}
</div>
<div class="mt-1">
<strong>Активен:</strong>
<span class="ml-2">
{{ doc.active ? '✅' : '❌' }}
</span>
</div>
<div class="mt-2 text-xs text-gray-500 truncate">
{{ doc.path }}
</div>
</div>
</div>
</template>
</template>
</div>
</template>