feat(vikon): add part selection UI to Vue dashboard

This commit is contained in:
F4ilji
2026-07-05 02:52:50 +05:00
parent b259809960
commit 1d423adc12
2 changed files with 65 additions and 10 deletions
@@ -41,6 +41,7 @@ class VikonController extends Controller
'is_authenticated' => $isAuth,
'current_version' => config('vikon.current_version'),
'modules' => config('vikon.modules'),
'parts' => config('vikon.parts'),
'vikon_api_domain' => config('vikon.api_domain'),
'vikon_client_id' => config('vikon.client_id'),
]);
@@ -74,6 +75,7 @@ class VikonController extends Controller
'is_authenticated' => $isAuth,
'current_version' => config('vikon.current_version'),
'modules' => config('vikon.modules'),
'parts' => config('vikon.parts'),
'vikon_api_domain' => config('vikon.api_domain'),
'vikon_client_id' => config('vikon.client_id'),
]);
@@ -67,18 +67,34 @@
<h3 class="text-sm font-medium">Модули для обновления</h3>
</div>
<div class="divide-y divide-line-2">
<div v-for="(mod, id) in modules" :key="id" class="px-6 py-4 flex items-center justify-between">
<div class="flex items-center gap-3">
<DashboardIcon name="cube" size="6" class="text-primary" />
<div>
<p class="text-sm font-medium">{{ mod.name }}</p>
<p class="text-xs text-muted-foreground-1">ID: {{ id }}</p>
<div v-for="(mod, id) in modules" :key="id" class="px-6 py-4">
<div class="flex items-center justify-between">
<div class="flex items-center gap-3">
<DashboardIcon name="cube" size="6" class="text-primary" />
<div>
<p class="text-sm font-medium">{{ mod.name }}</p>
<p class="text-xs text-muted-foreground-1">ID: {{ id }}</p>
</div>
</div>
<button @click="updateModule(id)" :disabled="updating || !accessInfo.has_access"
class="px-4 py-2 bg-primary text-white rounded-lg hover:bg-primary-hover disabled:opacity-50">
{{ updating ? 'Обновление...' : 'Обновить' }}
</button>
</div>
<div v-if="parts && parts[id]" class="mt-3 flex items-center gap-2">
<select v-model="selectedPart[id]" class="text-sm bg-layer border border-layer-line rounded-md px-2 py-1.5">
<option value="">Выберите часть...</option>
<option v-for="p in parts[id]" :key="p" :value="p">{{ p }}</option>
</select>
<button
@click="updatePart(id, selectedPart[id])"
:disabled="!selectedPart[id] || updatingPart"
class="text-sm bg-surface border border-layer-line px-3 py-1.5 rounded-md hover:bg-muted-hover disabled:opacity-50"
>
<span v-if="updatingPart === `${id}-${selectedPart[id]}`">Обновление...</span>
<span v-else>Обновить часть</span>
</button>
</div>
<button @click="updateModule(id)" :disabled="updating || !accessInfo.has_access"
class="px-4 py-2 bg-primary text-white rounded-lg hover:bg-primary-hover disabled:opacity-50">
{{ updating ? 'Обновление...' : 'Обновить' }}
</button>
</div>
</div>
</div>
@@ -95,6 +111,13 @@
<p class="text-xs text-muted-foreground-1 mt-2">{{ progress }}%</p>
</div>
<!-- Результат обновления части -->
<div v-if="partResult" class="bg-layer border border-layer-line rounded-lg p-4">
<p class="text-sm" :class="partResult.success ? 'text-green-600' : 'text-red-600'">
{{ partResult.message }}
</p>
</div>
<!-- Ошибка -->
<div v-if="updateError" class="bg-layer border border-red-200 rounded-lg p-6">
<div class="flex items-start gap-3">
@@ -126,6 +149,7 @@ const props = defineProps({
is_authenticated: Boolean,
current_version: String,
modules: Object,
parts: Object,
vikon_api_domain: String,
vikon_client_id: String,
});
@@ -139,6 +163,9 @@ const progress = ref(0);
const updateError = ref(null);
const versionInfo = ref({ current_version: props.current_version, has_update: false, latest_version: null });
const accessInfo = ref({ has_access: false, error: null });
const selectedPart = ref({});
const updatingPart = ref(null);
const partResult = ref(null);
const authUrl = computed(() => {
const redirect = encodeURIComponent(`${window.location.origin}/vikon_core/update/index.php`);
@@ -234,6 +261,32 @@ async function updateModule(moduleId) {
}
}
async function updatePart(moduleId, part) {
if (!part) return;
updatingPart.value = `${moduleId}-${part}`;
partResult.value = null;
try {
const res = await fetch('/dashboard/vikon-updates/update-part', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]')?.content,
'Accept': 'application/json',
},
body: JSON.stringify({ module_id: moduleId, part }),
});
const data = await res.json();
partResult.value = data;
} catch (e) {
partResult.value = { success: false, message: e.message };
} finally {
updatingPart.value = null;
}
}
async function logout() {
try {
await axios.post(route('dashboard.vikon-updates.logout'));