WP-11: package and OS updates from the UI
package_upgrade job streams apt-get output into the job log (streaming CommandRunner, DebianUpdater with dist-upgrade or --only-upgrade), refreshes the inventory afterwards and flags reboot-required. POST /api/system/upgrade (admin), package name validation, selectable package table with confirm dialog and live log on the Updates page. Fake updater for dev. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@ -2,8 +2,16 @@
|
||||
import { computed, ref } from 'vue'
|
||||
import type { Package } from '../api/types'
|
||||
|
||||
const props = defineProps<{ packages: Package[] }>()
|
||||
const props = defineProps<{ packages: Package[]; selectable?: boolean }>()
|
||||
const emit = defineEmits<{ 'update:selected': [names: string[]] }>()
|
||||
const selected = ref<Set<string>>(new Set())
|
||||
const search = ref('')
|
||||
|
||||
function toggle(name: string, on: boolean) {
|
||||
if (on) selected.value.add(name)
|
||||
else selected.value.delete(name)
|
||||
emit('update:selected', [...selected.value])
|
||||
}
|
||||
const upgradableOnly = ref(false)
|
||||
const source = ref<'all' | 'apt' | 'snap'>('all')
|
||||
|
||||
@ -52,6 +60,7 @@ const filtered = computed(() =>
|
||||
<table class="mt-4 w-full text-left text-sm">
|
||||
<thead class="border-b border-gray-200 text-gray-500">
|
||||
<tr>
|
||||
<th v-if="selectable" class="w-8"></th>
|
||||
<th class="py-2">Package</th>
|
||||
<th>Source</th>
|
||||
<th>Installed</th>
|
||||
@ -66,6 +75,16 @@ const filtered = computed(() =>
|
||||
class="border-b border-gray-100"
|
||||
:class="p.candidate ? 'bg-amber-50' : ''"
|
||||
>
|
||||
<td v-if="selectable">
|
||||
<input
|
||||
v-if="p.candidate"
|
||||
name="select"
|
||||
type="checkbox"
|
||||
:aria-label="`Select ${p.name}`"
|
||||
:checked="selected.has(p.name)"
|
||||
@change="toggle(p.name, ($event.target as HTMLInputElement).checked)"
|
||||
/>
|
||||
</td>
|
||||
<td class="py-1.5 font-mono">{{ p.name }}</td>
|
||||
<td>{{ p.source }}</td>
|
||||
<td class="font-mono text-gray-600">{{ p.installed }}</td>
|
||||
@ -79,7 +98,9 @@ const filtered = computed(() =>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-if="filtered.length === 0">
|
||||
<td colspan="5" class="py-6 text-center text-gray-500">No packages match.</td>
|
||||
<td :colspan="selectable ? 6 : 5" class="py-6 text-center text-gray-500">
|
||||
No packages match.
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
Reference in New Issue
Block a user