Files
windmill/frontend/src/lib/components/instanceSettings/SlackChannelCard.svelte
T
GuilhemandAlexander Petric 210b8285d4 fix(frontend): settings redesign (#7406)
* improve collapsible link

* do not show superadmin ws link when already in it

* improve OAuth UI

* sso/oauth instance settings ui

* refactor instance settings alerts WIP

* Indexer and Oauth to brand guidelines

* refactor ws error handler page

* Create a tab SMTP in the Instance Settings

* Ractivity isssue fix for tabs

* nit

* Add smtp settings status in Error handler

* Add smtp configuration status

* Display teams connection status for instance alerts

* nit

* Add critical alerts description

* nit

* nit

* improve ee display

* nit

* nit

* fix typo

* nit

* restore vit config

---------

Co-authored-by: Alexander Petric <alex@windmill.dev>
2025-12-19 20:33:03 +00:00

129 lines
3.0 KiB
Svelte

<script lang="ts">
import { Slack, X, Plus } from 'lucide-svelte'
import { Button } from '$lib/components/common'
import IntegrationCard from './IntegrationCard.svelte'
import SlackConnectionStatus from '../common/slack/SlackConnectionStatus.svelte'
import TextInput from '../text_input/TextInput.svelte'
interface SlackChannel {
slack_channel: string
}
interface Props {
channels: SlackChannel[]
disabled?: boolean
onAddChannel: () => void
onRemoveChannel: (index: number) => void
onUpdateChannel: (index: number, updatedChannel: SlackChannel) => void
findChannelIndex: (channel: SlackChannel) => number
onDisconnect: () => void
slackTeamName?: string
class?: string
style?: string
}
let {
channels,
disabled = false,
onAddChannel,
onRemoveChannel,
onUpdateChannel,
findChannelIndex,
onDisconnect,
slackTeamName,
class: clazz,
style
}: Props = $props()
function handleSlackChannelInput(channel: SlackChannel, value: string) {
const index = findChannelIndex(channel)
if (index !== -1) {
onUpdateChannel(index, { slack_channel: value })
}
}
function handleRemoveChannel(channel: SlackChannel) {
const index = findChannelIndex(channel)
if (index !== -1) {
onRemoveChannel(index)
}
}
</script>
{#if channels.length > 0}
<!-- Connected Slack Card -->
<IntegrationCard title="Slack" icon={Slack} isPlaceholder={false} class={clazz} {style}>
{#snippet actions()}
<SlackConnectionStatus
isConnected={slackTeamName ? true : false}
{slackTeamName}
mode="instance"
{onDisconnect}
/>
{/snippet}
{#snippet children()}
{#if channels.length > 0}
<span class="text-xs text-secondary"> Channels to send alerts to. </span>
{/if}
<!-- Channel Inputs -->
<div class="space-y-2">
{#each channels as channel}
<div class="flex items-center gap-2 w-full">
<div class="flex-1">
<TextInput
inputProps={{
type: 'text',
placeholder: 'Slack channel (e.g., #general)',
disabled: disabled,
oninput: (e) => {
const target = e.target as HTMLInputElement
handleSlackChannelInput(channel, target.value)
}
}}
value={channel.slack_channel || ''}
/>
</div>
<Button
onclick={() => handleRemoveChannel(channel)}
title="Remove channel"
iconOnly
{disabled}
startIcon={{ icon: X }}
unifiedSize="md"
variant="subtle"
destructive
/>
</div>
{/each}
</div>
<!-- Add Channel Button -->
<div class="flex justify-start">
<Button
variant="default"
size="xs"
onclick={onAddChannel}
btnClasses="text-xs flex items-center gap-2"
{disabled}
>
<Plus size={14} />
Add channel
</Button>
</div>
{/snippet}
</IntegrationCard>
{:else}
<!-- Placeholder Card -->
<IntegrationCard
title="Slack"
icon={Slack}
isPlaceholder={true}
onAdd={onAddChannel}
class={clazz}
{style}
>
{#snippet children()}{/snippet}
</IntegrationCard>
{/if}