From 79a09717a24fb61f6a29655756b4e95d996ea52c Mon Sep 17 00:00:00 2001 From: 1dabread Date: Wed, 12 Aug 2026 14:43:29 -0500 Subject: [PATCH] updated home grid to display all custom and existing apps before "easy setup" --- admin/app/controllers/system_controller.ts | 31 +++++++++++++++++++++- admin/app/services/system_service.ts | 26 +++++++++--------- admin/inertia/pages/home.tsx | 5 +++- install/management_compose_new.yaml | 2 +- 4 files changed, 48 insertions(+), 16 deletions(-) diff --git a/admin/app/controllers/system_controller.ts b/admin/app/controllers/system_controller.ts index a06cdd1..dea0cee 100644 --- a/admin/app/controllers/system_controller.ts +++ b/admin/app/controllers/system_controller.ts @@ -36,6 +36,8 @@ import type { HttpContext } from '@adonisjs/core/http' import logger from '@adonisjs/core/services/logger' import Service from '#models/service' +const CUSTOM_APP_HOME_DISPLAY_ORDER = 49 + @inject() export default class SystemController { constructor( @@ -441,6 +443,7 @@ export default class SystemController { is_dependency_service: false, is_custom: true, category: payload.category ?? 'custom', + display_order: uiLocation ? CUSTOM_APP_HOME_DISPLAY_ORDER : null, depends_on: null, }) @@ -486,7 +489,7 @@ export default class SystemController { is_dependency_service: false, is_custom: true, category: payload.category ?? 'custom', - display_order: publishedHostPort ? 49 : null, + display_order: publishedHostPort ? CUSTOM_APP_HOME_DISPLAY_ORDER : null, depends_on: null, }) @@ -569,6 +572,19 @@ export default class SystemController { } service.custom_url = normalized + if ( + normalized && + (service.display_order === null || service.display_order >= 50) + ) { + service.display_order = CUSTOM_APP_HOME_DISPLAY_ORDER + } + if ( + !normalized && + !service.ui_location && + service.display_order === CUSTOM_APP_HOME_DISPLAY_ORDER + ) { + service.display_order = null + } await service.save() return response.send({ success: true, custom_url: service.custom_url }) @@ -704,6 +720,19 @@ export default class SystemController { ? `${prevScheme}:${uiLocation}` : uiLocation service.category = payload.category ?? service.category ?? 'custom' + if ( + (service.ui_location || service.custom_url) && + (service.display_order === null || service.display_order >= 50) + ) { + service.display_order = CUSTOM_APP_HOME_DISPLAY_ORDER + } + if ( + !service.ui_location && + !service.custom_url && + service.display_order === CUSTOM_APP_HOME_DISPLAY_ORDER + ) { + service.display_order = null + } if (payload.icon) service.icon = payload.icon // Flag as user-modified so the seeder stops overwriting this app's config on future runs. service.is_user_modified = true diff --git a/admin/app/services/system_service.ts b/admin/app/services/system_service.ts index d01f27a..92798e7 100644 --- a/admin/app/services/system_service.ts +++ b/admin/app/services/system_service.ts @@ -24,6 +24,8 @@ import { isNewerVersion } from '../utils/version.js' import { invalidateAssistantNameCache } from '../../config/inertia.js' import { KiwixLibraryService } from '#services/kiwix_library_service' +const CUSTOM_APP_HOME_DISPLAY_ORDER = 49 + @inject() export class SystemService { private static appVersion: string | null = null @@ -319,7 +321,7 @@ export class SystemService { async getServices({ installedOnly = true }: { installedOnly?: boolean }): Promise { const statuses = await this._syncContainersWithDatabase() // Sync and reuse the fetched status list - await this._syncExistingPublishedAppLinks() + await this._syncCustomAppHomeLinks() const query = Service.query() .orderBy('display_order', 'asc') @@ -390,23 +392,21 @@ export class SystemService { } /** - * Backfill launch metadata for existing Docker containers added before published ports were - * detected. A published existing app gets a Command Center link and a pre-system sort order; - * unpublished containers stay manageable in Supply Depot without a dead dashboard tile. + * Backfill launch metadata for custom app records. Launchable apps get the same pre-system + * Command Center sort order whether they were created by NOMAD or registered from an existing + * Docker container. */ - private async _syncExistingPublishedAppLinks(): Promise { + private async _syncCustomAppHomeLinks(): Promise { try { - const existingApps = await Service.query() + const customApps = await Service.query() .where('installed', true) .where('is_custom', true) .where('is_dependency_service', false) - .whereNull('container_config') - for (const service of existingApps) { + for (const service of customApps) { const inspect = await this.dockerService.inspectContainerByName(service.service_name) - if (!inspect) continue + const publishedHostPort = inspect ? DockerService.getFirstPublishedHostPort(inspect) : null - const publishedHostPort = DockerService.getFirstPublishedHostPort(inspect) let changed = false if (publishedHostPort && service.ui_location !== publishedHostPort) { @@ -414,10 +414,10 @@ export class SystemService { changed = true } if ( - publishedHostPort && + (publishedHostPort || service.ui_location || service.custom_url) && (service.display_order === null || service.display_order >= 50) ) { - service.display_order = 49 + service.display_order = CUSTOM_APP_HOME_DISPLAY_ORDER changed = true } if (!publishedHostPort && service.ui_location === service.service_name) { @@ -431,7 +431,7 @@ export class SystemService { } } catch (error) { logger.warn( - `[SystemService] Existing app launch metadata sync failed: ${ + `[SystemService] Custom app launch metadata sync failed: ${ error instanceof Error ? error.message : error }` ) diff --git a/admin/inertia/pages/home.tsx b/admin/inertia/pages/home.tsx index cf3f158..99b4002 100644 --- a/admin/inertia/pages/home.tsx +++ b/admin/inertia/pages/home.tsx @@ -24,6 +24,8 @@ import Alert from '~/components/Alert' import WhatsNewBanner from '~/components/WhatsNewBanner' import { SERVICE_NAMES } from '../../constants/service_names' +const APP_FALLBACK_DISPLAY_ORDER = 49 + // Maps is a Core Capability (display_order: 4) const MAPS_ITEM = { label: 'Maps', @@ -153,7 +155,8 @@ export default function Home(props: { ), installed: service.installed, - displayOrder: service.display_order ?? 100, + // Launchable apps without an explicit order still belong before system tiles. + displayOrder: service.display_order ?? APP_FALLBACK_DISPLAY_ORDER, poweredBy: service.powered_by ?? null, }) }) diff --git a/install/management_compose_new.yaml b/install/management_compose_new.yaml index 51288a0..cab6f16 100644 --- a/install/management_compose_new.yaml +++ b/install/management_compose_new.yaml @@ -9,7 +9,7 @@ name: project-nomad services: admin: - image: nomad:1.0 + image: nomad:app-button container_name: nomad_admin restart: unless-stopped extra_hosts: