--all, --tools
This commit is contained in:
parent
5ea9d5f843
commit
ed46638b50
|
|
@ -21,10 +21,10 @@ export async function configShow() {
|
||||||
const source = process.env.TOES_URL
|
const source = process.env.TOES_URL
|
||||||
? 'TOES_URL'
|
? 'TOES_URL'
|
||||||
: process.env.TOES_HOST
|
: process.env.TOES_HOST
|
||||||
? 'TOES_HOST' + (process.env.PORT ? ' + PORT' : '')
|
? 'TOES_HOST' + (process.env.PORT ? ' + PORT' : '')
|
||||||
: process.env.NODE_ENV === 'production'
|
: process.env.NODE_ENV === 'production'
|
||||||
? 'default (production)'
|
? 'default (production)'
|
||||||
: 'default (development)'
|
: 'default (development)'
|
||||||
|
|
||||||
console.log(`Source: ${color.gray(source)}`)
|
console.log(`Source: ${color.gray(source)}`)
|
||||||
|
|
||||||
|
|
@ -53,7 +53,7 @@ export async function infoApp(arg?: string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const icon = STATE_ICONS[app.state] ?? '◯'
|
const icon = STATE_ICONS[app.state] ?? '◯'
|
||||||
console.log(`${icon} ${color.bold(app.name)}`)
|
console.log(`${icon} ${color.bold(app.name)} ${app.tool && '[tool]'}`)
|
||||||
console.log(` State: ${app.state}`)
|
console.log(` State: ${app.state}`)
|
||||||
if (app.port) {
|
if (app.port) {
|
||||||
console.log(` Port: ${app.port}`)
|
console.log(` Port: ${app.port}`)
|
||||||
|
|
@ -73,11 +73,22 @@ export async function infoApp(arg?: string) {
|
||||||
if (app.error) console.log(` Error: ${color.red(app.error)}`)
|
if (app.error) console.log(` Error: ${color.red(app.error)}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function listApps() {
|
interface ListAppsOptions {
|
||||||
|
tools?: boolean
|
||||||
|
all?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function listApps(options: ListAppsOptions) {
|
||||||
const apps: App[] | undefined = await get('/api/apps')
|
const apps: App[] | undefined = await get('/api/apps')
|
||||||
if (!apps) return
|
if (!apps) return
|
||||||
|
|
||||||
for (const app of apps) {
|
const filtered = apps.filter((app) => {
|
||||||
|
if (options.all) return true
|
||||||
|
if (options.tools) return app.tool
|
||||||
|
return !app.tool
|
||||||
|
})
|
||||||
|
|
||||||
|
for (const app of filtered) {
|
||||||
console.log(`${STATE_ICONS[app.state] ?? '◯'} ${app.name}`)
|
console.log(`${STATE_ICONS[app.state] ?? '◯'} ${app.name}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import { program } from 'commander'
|
import { program } from 'commander'
|
||||||
import { readFileSync } from 'fs'
|
|
||||||
|
|
||||||
import color from 'kleur'
|
import color from 'kleur'
|
||||||
import {
|
import {
|
||||||
|
|
@ -60,6 +59,8 @@ program
|
||||||
program
|
program
|
||||||
.command('list')
|
.command('list')
|
||||||
.description('List all apps')
|
.description('List all apps')
|
||||||
|
.option('-t, --tools', 'show only tools')
|
||||||
|
.option('-a, --all', 'show all apps including tools')
|
||||||
.action(listApps)
|
.action(listApps)
|
||||||
|
|
||||||
program
|
program
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ const render = () => {
|
||||||
// Update tool iframes after DOM settles
|
// Update tool iframes after DOM settles
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
const tools = apps.filter(a => a.tool)
|
const tools = apps.filter(a => a.tool)
|
||||||
updateToolIframes(selectedTab, tools)
|
updateToolIframes(selectedTab, tools, selectedApp)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,9 +24,11 @@ export function initToolIframes() {
|
||||||
const match = iframe.src.match(/localhost:(\d+)/)
|
const match = iframe.src.match(/localhost:(\d+)/)
|
||||||
if (match && match[1]) {
|
if (match && match[1]) {
|
||||||
const port = parseInt(match[1], 10)
|
const port = parseInt(match[1], 10)
|
||||||
const name = iframe.dataset.toolName
|
const toolName = iframe.dataset.toolName
|
||||||
if (name) {
|
const appName = iframe.dataset.appName
|
||||||
iframes.set(name, { iframe, port })
|
if (toolName) {
|
||||||
|
const cacheKey = appName ? `${toolName}:${appName}` : toolName
|
||||||
|
iframes.set(cacheKey, { iframe, port })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -42,7 +44,8 @@ export function initToolIframes() {
|
||||||
// Update which iframe is visible based on selected tab and tool state
|
// Update which iframe is visible based on selected tab and tool state
|
||||||
export function updateToolIframes(
|
export function updateToolIframes(
|
||||||
selectedTab: string,
|
selectedTab: string,
|
||||||
tools: Array<{ name: string; port?: number; state: string }>
|
tools: Array<{ name: string; port?: number; state: string }>,
|
||||||
|
selectedApp: string | null
|
||||||
) {
|
) {
|
||||||
const container = getContainer()
|
const container = getContainer()
|
||||||
if (!container) return
|
if (!container) return
|
||||||
|
|
@ -63,8 +66,11 @@ export function updateToolIframes(
|
||||||
|
|
||||||
const tool = selectedTool!
|
const tool = selectedTool!
|
||||||
|
|
||||||
|
// Build cache key for tool + app combination
|
||||||
|
const cacheKey = selectedApp ? `${tool.name}:${selectedApp}` : tool.name
|
||||||
|
|
||||||
// Skip if nothing changed
|
// Skip if nothing changed
|
||||||
if (currentTool === tool.name) {
|
if (currentTool === cacheKey) {
|
||||||
// Just update position in case of scroll/resize
|
// Just update position in case of scroll/resize
|
||||||
const tabContent = document.querySelector('[data-tool-target]')
|
const tabContent = document.querySelector('[data-tool-target]')
|
||||||
if (tabContent) {
|
if (tabContent) {
|
||||||
|
|
@ -97,34 +103,38 @@ export function updateToolIframes(
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
`
|
`
|
||||||
|
|
||||||
// Get or create the iframe for this tool
|
// Get or create the iframe for this tool + app combination
|
||||||
let cached = iframes.get(tool.name)
|
let cached = iframes.get(cacheKey)
|
||||||
|
|
||||||
if (!cached || cached.port !== tool.port) {
|
if (!cached || cached.port !== tool.port) {
|
||||||
// Create new iframe (first time or port changed)
|
// Create new iframe (first time or port changed)
|
||||||
const iframe = document.createElement('iframe')
|
const iframe = document.createElement('iframe')
|
||||||
iframe.src = `http://localhost:${tool.port}`
|
const url = selectedApp
|
||||||
|
? `http://localhost:${tool.port}?app=${encodeURIComponent(selectedApp)}`
|
||||||
|
: `http://localhost:${tool.port}`
|
||||||
|
iframe.src = url
|
||||||
iframe.dataset.toolName = tool.name // For hot reload recovery
|
iframe.dataset.toolName = tool.name // For hot reload recovery
|
||||||
|
iframe.dataset.appName = selectedApp ?? '' // For hot reload recovery
|
||||||
iframe.style.cssText = `
|
iframe.style.cssText = `
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
border: none;
|
border: none;
|
||||||
`
|
`
|
||||||
cached = { iframe, port: tool.port! }
|
cached = { iframe, port: tool.port! }
|
||||||
iframes.set(tool.name, cached)
|
iframes.set(cacheKey, cached)
|
||||||
// Add to container
|
// Add to container
|
||||||
container.appendChild(iframe)
|
container.appendChild(iframe)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show only the selected iframe, hide others
|
// Show only the selected iframe, hide others
|
||||||
for (const [name, { iframe }] of iframes) {
|
for (const [key, { iframe }] of iframes) {
|
||||||
const shouldShow = name === tool.name
|
const shouldShow = key === cacheKey
|
||||||
if (shouldShow && iframe.parentElement !== container) {
|
if (shouldShow && iframe.parentElement !== container) {
|
||||||
container.appendChild(iframe)
|
container.appendChild(iframe)
|
||||||
}
|
}
|
||||||
iframe.style.display = shouldShow ? 'block' : 'none'
|
iframe.style.display = shouldShow ? 'block' : 'none'
|
||||||
}
|
}
|
||||||
|
|
||||||
currentTool = tool.name
|
currentTool = cacheKey
|
||||||
;(window as any).__currentTool = tool.name
|
;(window as any).__currentTool = cacheKey
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user