mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-21 16:02:28 +00:00
feat: replace hub error toasts with warning alerts and add disable hub setting (#8225)
* feat: replace hub error toasts with warning alerts and add disable hub setting Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: guard hub script cache refresh when hub is disabled Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -43,8 +43,8 @@ use windmill_common::{
|
||||
get_database_url,
|
||||
global_settings::{
|
||||
APP_WORKSPACED_ROUTE_SETTING, AUTOMATE_USERNAME_CREATION_SETTING,
|
||||
CRITICAL_ALERT_MUTE_UI_SETTING, DEFAULT_TAGS_WORKSPACES_SETTING, EMAIL_DOMAIN_SETTING,
|
||||
ENV_SETTINGS, HUB_ACCESSIBLE_URL_SETTING, HUB_BASE_URL_SETTING,
|
||||
CRITICAL_ALERT_MUTE_UI_SETTING, DEFAULT_TAGS_WORKSPACES_SETTING, DISABLE_HUB_SETTING,
|
||||
EMAIL_DOMAIN_SETTING, ENV_SETTINGS, HUB_ACCESSIBLE_URL_SETTING, HUB_BASE_URL_SETTING,
|
||||
},
|
||||
instance_config::{self, ApplyMode, InstanceConfig},
|
||||
server::Smtp,
|
||||
@@ -519,6 +519,7 @@ pub async fn get_global_setting(
|
||||
&& key != DEFAULT_TAGS_WORKSPACES_SETTING
|
||||
&& key != HUB_BASE_URL_SETTING
|
||||
&& key != HUB_ACCESSIBLE_URL_SETTING
|
||||
&& key != DISABLE_HUB_SETTING
|
||||
&& key != EMAIL_DOMAIN_SETTING
|
||||
&& key != APP_WORKSPACED_ROUTE_SETTING
|
||||
{
|
||||
|
||||
@@ -44,6 +44,7 @@ pub const HUB_API_SECRET_SETTING: &str = "hub_api_secret";
|
||||
pub const AUTOMATE_USERNAME_CREATION_SETTING: &str = "automate_username_creation";
|
||||
pub const HUB_BASE_URL_SETTING: &str = "hub_base_url";
|
||||
pub const HUB_ACCESSIBLE_URL_SETTING: &str = "hub_accessible_url";
|
||||
pub const DISABLE_HUB_SETTING: &str = "disable_hub";
|
||||
pub const CRITICAL_ERROR_CHANNELS_SETTING: &str = "critical_error_channels";
|
||||
pub const CRITICAL_ALERT_MUTE_UI_SETTING: &str = "critical_alert_mute_ui";
|
||||
pub const CRITICAL_ALERTS_ON_DB_OVERSIZE_SETTING: &str = "critical_alerts_on_db_oversize";
|
||||
|
||||
@@ -230,6 +230,8 @@ pub struct GlobalSettings {
|
||||
pub no_default_maven: Option<bool>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub default_tags_per_workspace: Option<bool>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub disable_hub: Option<bool>,
|
||||
|
||||
// String settings
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
import RowIcon from '$lib/components/common/table/RowIcon.svelte'
|
||||
import { loadHubApps } from '$lib/hub'
|
||||
import TextInput from '$lib/components/text_input/TextInput.svelte'
|
||||
import { Alert } from '$lib/components/common'
|
||||
import { disableHubStore } from '$lib/stores'
|
||||
|
||||
interface Props {
|
||||
filter?: string
|
||||
@@ -30,11 +32,22 @@
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
let hubNotAvailable = $state(false)
|
||||
|
||||
onMount(async () => {
|
||||
hubApps = await loadHubApps()
|
||||
if ($disableHubStore) return
|
||||
const result = await loadHubApps()
|
||||
if (result === undefined) {
|
||||
hubNotAvailable = true
|
||||
} else {
|
||||
hubApps = result
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
{#if $disableHubStore}
|
||||
<!-- Hub disabled, show nothing -->
|
||||
{:else}
|
||||
<SearchItems
|
||||
{filter}
|
||||
items={prefilteredItems}
|
||||
@@ -54,7 +67,11 @@
|
||||
</div>
|
||||
<ListFilters {syncQuery} filters={apps} bind:selectedFilter={appFilter} resourceType />
|
||||
|
||||
{#if hubApps}
|
||||
{#if hubNotAvailable}
|
||||
<Alert type="warning" title="Hub not available">
|
||||
Could not connect to the Windmill Hub. If you are in a closed environment, you can disable the Hub in the <a href="/#superadmin-settings?tab=private_hub">instance settings</a>.
|
||||
</Alert>
|
||||
{:else if hubApps}
|
||||
{#if filteredItems.length == 0}
|
||||
<NoItemFound />
|
||||
{:else}
|
||||
@@ -93,3 +110,4 @@
|
||||
<Skeleton layout={[[4], 0.5]} />
|
||||
{/each}
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
import RowIcon from '$lib/components/common/table/RowIcon.svelte'
|
||||
import { loadHubFlows } from '$lib/hub'
|
||||
import TextInput from '$lib/components/text_input/TextInput.svelte'
|
||||
import { Alert } from '$lib/components/common'
|
||||
import { disableHubStore } from '$lib/stores'
|
||||
|
||||
interface Props {
|
||||
filter?: string
|
||||
@@ -30,11 +32,22 @@
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
let hubNotAvailable = $state(false)
|
||||
|
||||
onMount(async () => {
|
||||
hubFlows = await loadHubFlows()
|
||||
if ($disableHubStore) return
|
||||
const result = await loadHubFlows()
|
||||
if (result === undefined) {
|
||||
hubNotAvailable = true
|
||||
} else {
|
||||
hubFlows = result
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
{#if $disableHubStore}
|
||||
<!-- Hub disabled, show nothing -->
|
||||
{:else}
|
||||
<SearchItems
|
||||
{filter}
|
||||
items={prefilteredItems}
|
||||
@@ -54,7 +67,11 @@
|
||||
</div>
|
||||
<ListFilters {syncQuery} filters={apps} bind:selectedFilter={appFilter} resourceType />
|
||||
|
||||
{#if hubFlows}
|
||||
{#if hubNotAvailable}
|
||||
<Alert type="warning" title="Hub not available">
|
||||
Could not connect to the Windmill Hub. If you are in a closed environment, you can disable the Hub in the <a href="/#superadmin-settings?tab=private_hub">instance settings</a>.
|
||||
</Alert>
|
||||
{:else if hubFlows}
|
||||
{#if filteredItems.length == 0}
|
||||
<NoItemFound />
|
||||
{:else}
|
||||
@@ -95,3 +112,4 @@
|
||||
<Skeleton layout={[[4], 0.5]} />
|
||||
{/each}
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
import { IntegrationService, ScriptService, type HubScriptKind } from '$lib/gen'
|
||||
import { Loader2 } from 'lucide-svelte'
|
||||
import TextInput from '$lib/components/text_input/TextInput.svelte'
|
||||
import { disableHubStore } from '$lib/stores'
|
||||
|
||||
interface Props {
|
||||
kind?: HubScriptKind & string
|
||||
@@ -47,6 +48,7 @@
|
||||
)
|
||||
|
||||
async function getAllApps(filterKind: typeof kind) {
|
||||
if ($disableHubStore) return
|
||||
try {
|
||||
hubNotAvailable = false
|
||||
allApps = (
|
||||
@@ -67,6 +69,7 @@
|
||||
filterKind: typeof kind,
|
||||
appFilter: string | undefined
|
||||
) {
|
||||
if ($disableHubStore) return
|
||||
try {
|
||||
loading = true
|
||||
hubNotAvailable = false
|
||||
@@ -138,6 +141,9 @@
|
||||
})
|
||||
</script>
|
||||
|
||||
{#if $disableHubStore}
|
||||
<!-- Hub disabled, show nothing -->
|
||||
{:else}
|
||||
<div class="w-full flex items-center gap-2">
|
||||
{@render children?.()}
|
||||
<div class="relative w-full">
|
||||
@@ -156,7 +162,9 @@
|
||||
</div>
|
||||
|
||||
{#if hubNotAvailable}
|
||||
<Alert type="error" title="Hub not available" />
|
||||
<Alert type="warning" title="Hub not available">
|
||||
Could not connect to the Windmill Hub. If you are in a closed environment, you can disable the Hub in the <a href="/#superadmin-settings?tab=private_hub">instance settings</a>.
|
||||
</Alert>
|
||||
{:else if (items.length > 0 && apps.length > 0) || !loading}
|
||||
<ListFilters {syncQuery} filters={apps} bind:selectedFilter={appFilter} resourceType />
|
||||
{#if items.length == 0}
|
||||
@@ -204,3 +212,4 @@
|
||||
<Skeleton layout={[0.5, [4]]} />
|
||||
{/each}
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
[])
|
||||
: undefined
|
||||
} catch (err) {
|
||||
sendUserToast('Failed to fetch hub scripts: ' + err, 'error')
|
||||
console.error('Failed to fetch hub scripts:', err)
|
||||
return undefined
|
||||
}
|
||||
},
|
||||
@@ -44,9 +44,10 @@
|
||||
import { Circle, ExternalLink } from 'lucide-svelte'
|
||||
import Popover from '$lib/components/Popover.svelte'
|
||||
import { usePromise } from '$lib/svelte5Utils.svelte'
|
||||
import { hubBaseUrlStore, userStore } from '$lib/stores'
|
||||
import { disableHubStore, hubBaseUrlStore, userStore } from '$lib/stores'
|
||||
import { get } from 'svelte/store'
|
||||
import Button from '$lib/components/common/button/Button.svelte'
|
||||
import { Alert } from '$lib/components/common'
|
||||
|
||||
let hubNotAvailable = $state(false)
|
||||
|
||||
@@ -94,13 +95,14 @@
|
||||
})
|
||||
|
||||
async function getAllApps(filterKind: typeof kind) {
|
||||
if ($disableHubStore) return
|
||||
try {
|
||||
hubNotAvailable = false
|
||||
allApps = (await listHubIntegrationsCached({ kind: filterKind, refreshCount })).map(
|
||||
(x) => x.name
|
||||
)
|
||||
} catch (err) {
|
||||
sendUserToast('Failed to fetch hub integrations: ' + err, 'error')
|
||||
console.error('Failed to fetch hub integrations:', err)
|
||||
allApps = []
|
||||
hubNotAvailable = true
|
||||
}
|
||||
@@ -112,7 +114,9 @@
|
||||
)
|
||||
$effect(() => {
|
||||
;[filter, kind, appFilter, refreshCount]
|
||||
hubScriptsFilteredPromise.refresh()
|
||||
if (!$disableHubStore) {
|
||||
hubScriptsFilteredPromise.refresh()
|
||||
}
|
||||
})
|
||||
$effect(() => {
|
||||
loading = hubScriptsFilteredPromise.status === 'loading'
|
||||
@@ -175,9 +179,13 @@
|
||||
</script>
|
||||
|
||||
<svelte:window onkeydown={onKeyDown} />
|
||||
{#if hubNotAvailable}
|
||||
<div class="text-2xs text-red-400 font-normal text-center py-2 px-3 items-center">
|
||||
Hub not available
|
||||
{#if $disableHubStore}
|
||||
<!-- Hub disabled, show nothing -->
|
||||
{:else if hubNotAvailable}
|
||||
<div class="px-3 py-2 mt-2">
|
||||
<Alert type="warning" title="Hub not available" size="xs">
|
||||
Could not connect to the Windmill Hub. If you are in a closed environment, you can disable the Hub in the <a href="/#superadmin-settings?tab=private_hub">instance settings</a>.
|
||||
</Alert>
|
||||
</div>
|
||||
{:else if loading}
|
||||
{#each Array(15).fill(0) as _}
|
||||
|
||||
@@ -331,6 +331,16 @@ export const settings: Record<string, Setting[]> = {
|
||||
storage: 'setting',
|
||||
ee_only: '',
|
||||
hiddenIfEmpty: true
|
||||
},
|
||||
{
|
||||
label: 'Disable Hub',
|
||||
description:
|
||||
'Disable the Windmill Hub integration entirely. Enable this if your instance runs in a closed environment without internet access and you do not have a private hub setup.',
|
||||
key: 'disable_hub',
|
||||
fieldType: 'boolean',
|
||||
storage: 'setting',
|
||||
ee_only: '',
|
||||
requiresReloadOnChange: true
|
||||
}
|
||||
],
|
||||
SMTP: [
|
||||
|
||||
@@ -83,6 +83,7 @@ export const superadmin = writable<string | false | undefined>(undefined)
|
||||
export const devopsRole = writable<string | false | undefined>(undefined)
|
||||
export const lspTokenStore = writable<string | undefined>(undefined)
|
||||
export const hubBaseUrlStore = writable<string>(DEFAULT_HUB_BASE_URL)
|
||||
export const disableHubStore = writable<boolean>(false)
|
||||
export const userWorkspaces: Readable<Array<UserWorkspace>> = derived(
|
||||
[usersWorkspaceStore, superadmin],
|
||||
([store, superadmin]) => {
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
type UserExt,
|
||||
defaultScripts,
|
||||
hubBaseUrlStore,
|
||||
disableHubStore,
|
||||
usedTriggerKinds,
|
||||
devopsRole,
|
||||
whitelabelNameStore,
|
||||
@@ -157,6 +158,7 @@
|
||||
loadUsage()
|
||||
syncTutorialsTodos()
|
||||
loadHubBaseUrl()
|
||||
loadDisableHub()
|
||||
loadUsedTriggerKinds()
|
||||
}
|
||||
|
||||
@@ -176,6 +178,11 @@
|
||||
DEFAULT_HUB_BASE_URL
|
||||
}
|
||||
|
||||
async function loadDisableHub() {
|
||||
$disableHubStore =
|
||||
((await SettingService.getGlobal({ key: 'disable_hub' })) as boolean) ?? false
|
||||
}
|
||||
|
||||
async function loadFavorites() {
|
||||
const scripts = await ScriptService.listScripts({
|
||||
workspace: $workspaceStore ?? '',
|
||||
|
||||
Reference in New Issue
Block a user