feat(vikon): show disabled modules with warning instead of hiding them
This commit is contained in:
@@ -60,11 +60,10 @@ class CheckAccessAction
|
|||||||
}
|
}
|
||||||
$moduleId = (int) $moduleData['id'];
|
$moduleId = (int) $moduleData['id'];
|
||||||
|
|
||||||
// Skip modules disabled by additional_access_flags
|
// Check if entire module is disabled
|
||||||
$moduleFlag = 'no_update_' . config("vikon.modules.{$moduleId}.path", '');
|
$modulePath = config("vikon.modules.{$moduleId}.path", '');
|
||||||
if (in_array($moduleFlag, $flags)) {
|
$moduleFlag = 'no_update_' . $modulePath;
|
||||||
continue;
|
$moduleDisabled = in_array($moduleFlag, $flags);
|
||||||
}
|
|
||||||
|
|
||||||
// Filter out parts disabled by flags
|
// Filter out parts disabled by flags
|
||||||
$parts = array_filter($moduleData['parts'], function ($p) use ($flags) {
|
$parts = array_filter($moduleData['parts'], function ($p) use ($flags) {
|
||||||
@@ -72,10 +71,13 @@ class CheckAccessAction
|
|||||||
return !in_array($partFlag, $flags);
|
return !in_array($partFlag, $flags);
|
||||||
});
|
});
|
||||||
|
|
||||||
$partsByModule[$moduleId] = array_map(
|
$partsByModule[$moduleId] = [
|
||||||
|
'disabled' => $moduleDisabled,
|
||||||
|
'parts' => array_map(
|
||||||
fn($p) => ['id' => $p['id'], 'name' => $p['name'] ?? $p['id'], 'access' => $p['access'] ?? true],
|
fn($p) => ['id' => $p['id'], 'name' => $p['name'] ?? $p['id'], 'access' => $p['access'] ?? true],
|
||||||
array_values($parts)
|
array_values($parts)
|
||||||
);
|
),
|
||||||
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -76,18 +76,21 @@
|
|||||||
<p class="text-xs text-muted-foreground-1">ID: {{ id }}</p>
|
<p class="text-xs text-muted-foreground-1">ID: {{ id }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button @click="updateModule(id)" :disabled="updating || !accessInfo.has_access"
|
<button @click="updateModule(id)" :disabled="updating || !accessInfo.has_access || parts[id]?.disabled"
|
||||||
class="px-4 py-2 bg-primary text-white rounded-lg hover:bg-primary-hover disabled:opacity-50">
|
class="px-4 py-2 bg-primary text-white rounded-lg hover:bg-primary-hover disabled:opacity-50">
|
||||||
{{ updating ? 'Обновление...' : 'Обновить' }}
|
{{ updating ? 'Обновление...' : 'Обновить' }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="parts && parts[id]" class="mt-3 space-y-2">
|
<div v-if="parts && parts[id]?.disabled" class="mt-3 p-3 bg-yellow-50 border border-yellow-200 rounded-lg">
|
||||||
|
<p class="text-sm text-yellow-800">Обновление модуля запрещено сервером VIKON</p>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="parts && parts[id]?.parts?.length" class="mt-3 space-y-2">
|
||||||
<label class="flex items-center gap-2 text-xs font-medium text-muted-foreground-1 cursor-pointer">
|
<label class="flex items-center gap-2 text-xs font-medium text-muted-foreground-1 cursor-pointer">
|
||||||
<input type="checkbox" :checked="isAllPartsSelected(id)" @change="toggleAllParts(id)" class="rounded" />
|
<input type="checkbox" :checked="isAllPartsSelected(id)" @change="toggleAllParts(id)" class="rounded" />
|
||||||
Выбрать все
|
Выбрать все
|
||||||
</label>
|
</label>
|
||||||
<div class="flex flex-wrap gap-x-4 gap-y-1 pl-5">
|
<div class="flex flex-wrap gap-x-4 gap-y-1 pl-5">
|
||||||
<label v-for="p in parts[id]" :key="p.id" class="flex items-center gap-1.5 text-sm" :class="p.access ? 'cursor-pointer' : 'opacity-50 cursor-not-allowed'">
|
<label v-for="p in parts[id]?.parts || []" :key="p.id" class="flex items-center gap-1.5 text-sm" :class="p.access ? 'cursor-pointer' : 'opacity-50 cursor-not-allowed'">
|
||||||
<input type="checkbox" :value="p.id" v-model="selectedParts[id]" :disabled="!p.access" class="rounded" />
|
<input type="checkbox" :value="p.id" v-model="selectedParts[id]" :disabled="!p.access" class="rounded" />
|
||||||
{{ p.name }}
|
{{ p.name }}
|
||||||
</label>
|
</label>
|
||||||
@@ -176,10 +179,12 @@ const versionInfo = ref({ current_version: props.current_version, has_update: fa
|
|||||||
const accessInfo = ref({ has_access: false, error: null });
|
const accessInfo = ref({ has_access: false, error: null });
|
||||||
const selectedParts = ref({});
|
const selectedParts = ref({});
|
||||||
if (props.parts) {
|
if (props.parts) {
|
||||||
for (const [id, moduleParts] of Object.entries(props.parts)) {
|
for (const [id, moduleData] of Object.entries(props.parts)) {
|
||||||
|
if (!moduleData.disabled) {
|
||||||
selectedParts.value[id] = [];
|
selectedParts.value[id] = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
const updatingPart = ref(null);
|
const updatingPart = ref(null);
|
||||||
const partResults = ref([]);
|
const partResults = ref([]);
|
||||||
|
|
||||||
@@ -278,13 +283,13 @@ async function updateModule(moduleId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function isAllPartsSelected(moduleId) {
|
function isAllPartsSelected(moduleId) {
|
||||||
const moduleParts = (props.parts?.[moduleId] || []).filter(p => p.access);
|
const moduleParts = (props.parts?.[moduleId]?.parts || []).filter(p => p.access);
|
||||||
const selected = selectedParts.value[moduleId] || [];
|
const selected = selectedParts.value[moduleId] || [];
|
||||||
return moduleParts.length > 0 && moduleParts.every(p => selected.includes(p.id));
|
return moduleParts.length > 0 && moduleParts.every(p => selected.includes(p.id));
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleAllParts(moduleId) {
|
function toggleAllParts(moduleId) {
|
||||||
const moduleParts = (props.parts?.[moduleId] || []).filter(p => p.access);
|
const moduleParts = (props.parts?.[moduleId]?.parts || []).filter(p => p.access);
|
||||||
if (isAllPartsSelected(moduleId)) {
|
if (isAllPartsSelected(moduleId)) {
|
||||||
selectedParts.value[moduleId] = [];
|
selectedParts.value[moduleId] = [];
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user