mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-21 00:02:30 +00:00
* feat: label resource types and integrations with hub display names Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: load hub integration names in the app and flow pickers Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: load hub resource type names where drawers title a type Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * feat: store resource type display names and drop the hardcoded list Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: leave display_name out of the fork comparison Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: ignore over-long synced display names, move name loaders Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: share the hub integration list cache, backfill admins only Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: keep a name over a nameless duplicate, retry failed hub reads Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
72 lines
2.7 KiB
TypeScript
72 lines
2.7 KiB
TypeScript
import { get } from 'svelte/store'
|
|
import { IntegrationService, ResourceService } from '$lib/gen'
|
|
import { disableHubStore } from '$lib/stores'
|
|
import { createCache } from '$lib/utils'
|
|
import { addResourceTypeDisplayName, setHubIntegrationDisplayNames } from './resourceTypeDisplay'
|
|
|
|
/**
|
|
* Loads what `resourceTypeDisplayName` and `integrationDisplayName` read: a type's stored name for a
|
|
* surface that holds no row for it, and the hub's integration list, which every picker that needs
|
|
* it shares. Apart from `resourceTypeDisplay`, which makes no API calls so it can be unit-tested
|
|
* alone. Cached briefly: drawers and pickers reopen often, and a name rarely changes.
|
|
*/
|
|
const CACHE_MS = 60_000
|
|
|
|
const resourceTypeRowCached = createCache(
|
|
({ workspace, name }: { workspace: string; name: string }) =>
|
|
ResourceService.getResourceType({ workspace, path: name }).then(
|
|
(rt) => addResourceTypeDisplayName(rt),
|
|
() => {}
|
|
),
|
|
{ invalidateMs: CACHE_MS, maxSize: 50 }
|
|
)
|
|
|
|
/**
|
|
* Fill `resourceTypeDisplayName` for one type, for a surface titled with a type it holds no row
|
|
* for. The name is stored with the type, so this reads the row rather than the hub.
|
|
*/
|
|
export function loadResourceTypeDisplayName(workspace: string, name: string): Promise<void> {
|
|
return resourceTypeRowCached({ workspace, name })
|
|
}
|
|
|
|
/** Bumped by every failed read, so the next caller keys a fresh read rather than the rejection. */
|
|
let failedReads = 0
|
|
|
|
const hubIntegrationsCached = createCache(
|
|
({ kind }: { kind?: string; refresh: number; attempt: number }) =>
|
|
IntegrationService.listHubIntegrations({ kind }).then(
|
|
(integrations) => {
|
|
setHubIntegrationDisplayNames(integrations)
|
|
return integrations
|
|
},
|
|
(error) => {
|
|
failedReads += 1
|
|
throw error
|
|
}
|
|
),
|
|
{ invalidateMs: CACHE_MS }
|
|
)
|
|
|
|
/**
|
|
* The hub's integration list, read once a minute per `kind` however many pickers ask, recording
|
|
* each integration's name on the way. A failed read rejects, so a picker can say the hub is
|
|
* unavailable, but is not kept: the next caller reads again. `refresh` is a picker's refresh
|
|
* count, and a new value reads again too.
|
|
*/
|
|
export function listHubIntegrationsShared(kind?: string, refresh = 0) {
|
|
return hubIntegrationsCached({ kind, refresh, attempt: failedReads })
|
|
}
|
|
|
|
/**
|
|
* Fill `integrationDisplayName` for a picker whose integrations come from its own items rather
|
|
* than the hub's integration list, as the hub app and flow pickers do. Unfiltered: `kind`
|
|
* narrows by script kind, so asking for an app or a flow would name nothing.
|
|
*/
|
|
export function loadHubIntegrationDisplayNames(): Promise<void> {
|
|
if (get(disableHubStore)) return Promise.resolve()
|
|
return listHubIntegrationsShared().then(
|
|
() => {},
|
|
() => {}
|
|
)
|
|
}
|