kin: KIN-049 Кнопка Deploy на странице задачи после approve. Для каждого проекта настраивается deploy-команда (git push, scp, ssh restart). В Settings проекта.

This commit is contained in:
Gros Frumos 2026-03-16 08:21:13 +02:00
parent 860ef3f6c9
commit d50bd703ae
11 changed files with 517 additions and 61 deletions

View file

@ -4,9 +4,12 @@ import { api, type Project, type ObsidianSyncResult } from '../api'
const projects = ref<Project[]>([])
const vaultPaths = ref<Record<string, string>>({})
const deployCommands = ref<Record<string, string>>({})
const saving = ref<Record<string, boolean>>({})
const savingDeploy = ref<Record<string, boolean>>({})
const syncing = ref<Record<string, boolean>>({})
const saveStatus = ref<Record<string, string>>({})
const saveDeployStatus = ref<Record<string, string>>({})
const syncResults = ref<Record<string, ObsidianSyncResult | null>>({})
const error = ref<string | null>(null)
@ -15,6 +18,7 @@ onMounted(async () => {
projects.value = await api.projects()
for (const p of projects.value) {
vaultPaths.value[p.id] = p.obsidian_vault_path ?? ''
deployCommands.value[p.id] = p.deploy_command ?? ''
}
} catch (e) {
error.value = String(e)
@ -34,6 +38,19 @@ async function saveVaultPath(projectId: string) {
}
}
async function saveDeployCommand(projectId: string) {
savingDeploy.value[projectId] = true
saveDeployStatus.value[projectId] = ''
try {
await api.patchProject(projectId, { deploy_command: deployCommands.value[projectId] })
saveDeployStatus.value[projectId] = 'Saved'
} catch (e) {
saveDeployStatus.value[projectId] = `Error: ${e}`
} finally {
savingDeploy.value[projectId] = false
}
}
async function runSync(projectId: string) {
syncing.value[projectId] = true
syncResults.value[projectId] = null
@ -70,13 +87,37 @@ async function runSync(projectId: string) {
/>
</div>
<div class="mb-3">
<label class="block text-xs text-gray-400 mb-1">Deploy Command</label>
<input
v-model="deployCommands[project.id]"
type="text"
placeholder="git push origin main"
class="w-full bg-gray-900 border border-gray-700 rounded px-3 py-2 text-sm text-gray-200 font-mono focus:outline-none focus:border-gray-500"
/>
<p class="text-xs text-gray-600 mt-1">Команда выполняется через shell в директории проекта. Настраивается только администратором.</p>
</div>
<div class="flex items-center gap-3 flex-wrap mb-3">
<button
@click="saveDeployCommand(project.id)"
:disabled="savingDeploy[project.id]"
class="px-3 py-1.5 text-sm bg-gray-700 hover:bg-gray-600 text-gray-200 rounded disabled:opacity-50"
>
{{ savingDeploy[project.id] ? 'Saving…' : 'Save Deploy' }}
</button>
<span v-if="saveDeployStatus[project.id]" class="text-xs" :class="saveDeployStatus[project.id].startsWith('Error') ? 'text-red-400' : 'text-green-400'">
{{ saveDeployStatus[project.id] }}
</span>
</div>
<div class="flex items-center gap-3 flex-wrap">
<button
@click="saveVaultPath(project.id)"
:disabled="saving[project.id]"
class="px-3 py-1.5 text-sm bg-gray-700 hover:bg-gray-600 text-gray-200 rounded disabled:opacity-50"
>
{{ saving[project.id] ? 'Saving…' : 'Save' }}
{{ saving[project.id] ? 'Saving…' : 'Save Vault' }}
</button>
<button