From 11f13e23b48e55b3a8e150512d44d86a4a2f4a97 Mon Sep 17 00:00:00 2001 From: Sebastian Krupinski Date: Sun, 22 Feb 2026 00:38:29 -0500 Subject: [PATCH] feat: improve design Signed-off-by: Sebastian Krupinski --- src/services/moduleService.ts | 3 +- src/types/module.ts | 3 + src/views/ModuleList.vue | 391 +++++++++++++++++++--------------- 3 files changed, 223 insertions(+), 174 deletions(-) diff --git a/src/services/moduleService.ts b/src/services/moduleService.ts index 95ce389..850d99b 100644 --- a/src/services/moduleService.ts +++ b/src/services/moduleService.ts @@ -16,7 +16,8 @@ export async function fetchModules(): Promise { } const data = await response.json() - return data.modules || [] + const raw = data.modules || {} + return Array.isArray(raw) ? raw : Object.values(raw) } export async function manageModule(handle: string, action: ModuleAction): Promise<{ message?: string; error?: string }> { diff --git a/src/types/module.ts b/src/types/module.ts index 153e4bf..a89f51e 100644 --- a/src/types/module.ts +++ b/src/types/module.ts @@ -1,11 +1,14 @@ export interface Module { + id: string | null handle: string label: string author: string description: string version: string + namespace: string | null installed: boolean enabled: boolean + needsUpgrade: boolean } export type ModuleAction = 'install' | 'uninstall' | 'enable' | 'disable' | 'upgrade' diff --git a/src/views/ModuleList.vue b/src/views/ModuleList.vue index 4cbbed4..2bae0ea 100644 --- a/src/views/ModuleList.vue +++ b/src/views/ModuleList.vue @@ -2,15 +2,6 @@ import { ref, computed, onMounted } from 'vue' import { fetchModules, manageModule } from '@/services/moduleService' import type { Module, ModuleAction } from '@/types/module' -import { - mdiPackageVariant, - mdiDownload, - mdiTrashCan, - mdiCheckCircle, - mdiCloseCircle, - mdiUpdate, - mdiLoading, -} from '@mdi/js' const modules = ref([]) const loading = ref(true) @@ -20,31 +11,43 @@ const snackbar = ref(false) const snackbarText = ref('') const snackbarColor = ref('success') const search = ref('') -const filterStatus = ref<'all' | 'installed' | 'not-installed' | 'enabled' | 'disabled'>('all') +const filterStatus = ref('all') + +const upgradeCount = computed(() => modules.value.filter(m => m.needsUpgrade).length) + +const statusFilters = computed(() => [ + { title: 'All', value: 'all' as const, count: modules.value.length }, + { title: 'Installed', value: 'installed' as const, count: modules.value.filter(m => m.installed).length }, + { title: 'Not Installed', value: 'not-installed' as const, count: modules.value.filter(m => !m.installed).length }, + { title: 'Enabled', value: 'enabled' as const, count: modules.value.filter(m => m.enabled).length }, + { title: 'Disabled', value: 'disabled' as const, count: modules.value.filter(m => m.installed && !m.enabled).length }, +]) const filteredModules = computed(() => { let result = modules.value // Filter by status - if (filterStatus.value === 'installed') { + const status = filterStatus.value + if (status === 'installed') { result = result.filter(m => m.installed) - } else if (filterStatus.value === 'not-installed') { + } else if (status === 'not-installed') { result = result.filter(m => !m.installed) - } else if (filterStatus.value === 'enabled') { + } else if (status === 'enabled') { result = result.filter(m => m.enabled) - } else if (filterStatus.value === 'disabled') { + } else if (status === 'disabled') { result = result.filter(m => m.installed && !m.enabled) } // Filter by search - if (search.value) { - const searchLower = search.value.toLowerCase() + const q = (search.value ?? '').trim().toLowerCase() + if (q) { result = result.filter( m => - m.handle.toLowerCase().includes(searchLower) || - m.label.toLowerCase().includes(searchLower) || - m.description.toLowerCase().includes(searchLower) || - m.author.toLowerCase().includes(searchLower) + (m.handle ?? '').toLowerCase().includes(q) || + (m.label ?? '').toLowerCase().includes(q) || + (m.description ?? '').toLowerCase().includes(q) || + (m.author ?? '').toLowerCase().includes(q) || + (m.namespace ?? '').toLowerCase().includes(q) ) } @@ -107,186 +110,221 @@ onMounted(() => {