Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 91 additions & 0 deletions apps/showcase-bot/src/listeners/commands/showcase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,97 @@ export function register(app: App) {
],
},
},
{
type: 'input',
label: { type: 'plain_text', text: 'Department' },
element: {
type: 'static_select',
action_id: 'showcase_modal_department',
placeholder: {
type: 'plain_text',
text: 'Select a department',
},
options: [
{
text: { type: 'plain_text', text: 'Engineering' },
value: 'engineering',
},
{
text: { type: 'plain_text', text: 'Design' },
value: 'design',
},
{
text: { type: 'plain_text', text: 'Marketing' },
value: 'marketing',
},
{
text: { type: 'plain_text', text: 'Sales' },
value: 'sales',
},
],
},
},
{
type: 'input',
label: { type: 'plain_text', text: 'Skills' },
element: {
type: 'multi_static_select',
action_id: 'showcase_modal_skills',
placeholder: {
type: 'plain_text',
text: 'Select your skills',
},
options: [
{
text: { type: 'plain_text', text: 'JavaScript' },
value: 'javascript',
},
{
text: { type: 'plain_text', text: 'TypeScript' },
value: 'typescript',
},
{
text: { type: 'plain_text', text: 'Python' },
value: 'python',
},
{
text: { type: 'plain_text', text: 'Rust' },
value: 'rust',
},
{
text: { type: 'plain_text', text: 'Go' },
value: 'go',
},
],
},
},
{
type: 'input',
label: { type: 'plain_text', text: 'Attachments' },
element: {
type: 'file_input',
action_id: 'showcase_modal_attachments',
max_files: 3,
},
},
{
type: 'input',
label: { type: 'plain_text', text: 'Additional Notes' },
hint: {
type: 'plain_text',
text: 'Any extra details or comments',
},
optional: true,
element: {
type: 'plain_text_input',
action_id: 'showcase_modal_notes',
multiline: true,
placeholder: {
type: 'plain_text',
text: 'Enter any additional notes here...',
},
},
},
],
},
})
Expand Down
157 changes: 157 additions & 0 deletions apps/showcase-bot/src/messages/blocks/16-search-results.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
{
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "We found *205 Hotels* in New Orleans, LA from *12/14 to 12/17*"
},
"accessory": {
"type": "overflow",
"action_id": "showcase_search_results_filter",
"options": [
{
"text": {
"type": "plain_text",
"emoji": true,
"text": "Option One"
},
"value": "value-0"
},
{
"text": {
"type": "plain_text",
"emoji": true,
"text": "Option Two"
},
"value": "value-1"
},
{
"text": {
"type": "plain_text",
"emoji": true,
"text": "Option Three"
},
"value": "value-2"
},
{
"text": {
"type": "plain_text",
"emoji": true,
"text": "Option Four"
},
"value": "value-3"
}
]
}
},
{
"type": "divider"
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*<fakeLink.toHotelPage.com|Windsor Court Hotel>*\n★★★★★\n$340 per night\nRated: 9.4 - Excellent"
},
"accessory": {
"type": "image",
"image_url": "https://api.slack.com/img/blocks/bkb_template_images/tripAgent_1.png",
"alt_text": "Windsor Court Hotel thumbnail"
}
},
{
"type": "context",
"elements": [
{
"type": "image",
"image_url": "https://api.slack.com/img/blocks/bkb_template_images/tripAgentLocationMarker.png",
"alt_text": "Location Pin Icon"
},
{
"type": "plain_text",
"emoji": true,
"text": "Location: Central Business District"
}
]
},
{
"type": "divider"
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*<fakeLink.toHotelPage.com|The Ritz-Carlton New Orleans>*\n★★★★★\n$340 per night\nRated: 9.1 - Excellent"
},
"accessory": {
"type": "image",
"image_url": "https://api.slack.com/img/blocks/bkb_template_images/tripAgent_2.png",
"alt_text": "Ritz-Carlton New Orleans thumbnail"
}
},
{
"type": "context",
"elements": [
{
"type": "image",
"image_url": "https://api.slack.com/img/blocks/bkb_template_images/tripAgentLocationMarker.png",
"alt_text": "Location Pin Icon"
},
{
"type": "plain_text",
"emoji": true,
"text": "Location: French Quarter"
}
]
},
{
"type": "divider"
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*<fakeLink.toHotelPage.com|Omni Royal Orleans Hotel>*\n★★★★★\n$419 per night\nRated: 8.8 - Excellent"
},
"accessory": {
"type": "image",
"image_url": "https://api.slack.com/img/blocks/bkb_template_images/tripAgent_3.png",
"alt_text": "Omni Royal Orleans Hotel thumbnail"
}
},
{
"type": "context",
"elements": [
{
"type": "image",
"image_url": "https://api.slack.com/img/blocks/bkb_template_images/tripAgentLocationMarker.png",
"alt_text": "Location Pin Icon"
},
{
"type": "plain_text",
"emoji": true,
"text": "Location: French Quarter"
}
]
},
{
"type": "divider"
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {
"type": "plain_text",
"emoji": true,
"text": "Next 2 Results"
},
"action_id": "showcase_search_results_next",
"value": "click_me_123"
}
]
}
]
}
4 changes: 4 additions & 0 deletions apps/ui/src/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@

@custom-variant dark (&:where(.dark, .dark *));

button {
cursor: pointer;
}

@theme inline {
/* Typography */
--font-sans:
Expand Down
4 changes: 1 addition & 3 deletions apps/ui/src/components/Message.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -354,9 +354,7 @@
<ContextMenu.Root>
<ContextMenu.Trigger class="block">
<div
class="group flex flex-col px-5 transition-colors duration-100 relative hover:bg-slack-hover {isGrouped
? 'py-0.5'
: 'py-2'}"
class="group flex flex-col px-5 transition-colors duration-100 relative hover:bg-slack-hover py-2"
>
{#if isEphemeral}
<div
Expand Down
56 changes: 50 additions & 6 deletions apps/ui/src/components/ModalOverlay.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
import { X } from '@lucide/svelte'
import { X, Sparkles } from '@lucide/svelte'
import { simulatorState } from '../lib/state.svelte'
import {
submitView,
Expand Down Expand Up @@ -41,6 +41,16 @@
// Track whether the user has attempted to submit (enables live revalidation)
let hasSubmitted = $state(false)

// Track whether modal content is scrolled
let contentScrolled = $state(false)

// Look up the bot that opened the modal
const modalBot = $derived.by(() => {
const botId = simulatorState.activeModal?.botId
if (!botId) return undefined
return simulatorState.connectedBots.get(botId)
})

/**
* Extract initial values from modal blocks to pre-populate formValues
*/
Expand Down Expand Up @@ -148,6 +158,7 @@
fileFormValues = {}
validationErrors = {}
hasSubmitted = false
contentScrolled = false
}
})

Expand Down Expand Up @@ -324,9 +335,31 @@
>
<!-- Header -->
<div
class="flex items-center justify-between px-5 py-4 border-b border-white/10 shrink-0"
class="flex items-center gap-3 px-5 py-4 shrink-0 border-b transition-colors {contentScrolled
? 'border-white/10'
: 'border-transparent'}"
>
<h2 id="modal-title" class="text-lg font-semibold text-slack-text">
{#if modalBot}
<div
class="size-9 rounded-lg flex items-center justify-center shrink-0 {modalBot.iconUrl
? ''
: 'bg-slack-bot-avatar text-white'}"
>
{#if modalBot.iconUrl}
<img
src={modalBot.iconUrl}
alt={modalBot.name}
class="size-9 rounded-lg object-cover"
/>
{:else}
<Sparkles size={20} />
{/if}
</div>
{/if}
<h2
id="modal-title"
class="text-lg font-semibold text-slack-text flex-1"
>
{modal.view.title?.text ?? 'Modal'}
</h2>
<button
Expand All @@ -339,7 +372,12 @@
</div>

<!-- Content -->
<div class="flex-1 overflow-y-auto p-5">
<div
class="modal-content flex-1 overflow-y-auto p-5"
onscroll={(e) => {
contentScrolled = e.currentTarget.scrollTop > 0
}}
>
<BlockKitRenderer
blocks={modal.view.blocks}
values={formValues}
Expand All @@ -362,15 +400,15 @@
{#if modal.view.close}
<button
onclick={handleClose}
class="px-4 py-2 rounded-lg bg-transparent border border-white/20 text-slack-text hover:bg-white/10 transition-colors"
class="px-4 py-2 rounded-lg bg-transparent border border-white/30 text-slack-text font-bold hover:border-white/50 hover:bg-white/5 transition-colors"
>
{modal.view.close.text}
</button>
{/if}
{#if modal.view.submit}
<button
onclick={handleSubmit}
class="px-4 py-2 rounded-lg bg-slack-accent text-white hover:bg-slack-accent-hover transition-colors font-medium"
class="px-4 py-2 rounded-lg bg-slack-accent text-white hover:bg-slack-accent-hover transition-colors font-bold"
>
{modal.view.submit.text}
</button>
Expand All @@ -380,3 +418,9 @@
</div>
</div>
{/if}

<style>
.modal-content :global(.p-block_kit_renderer) {
gap: 1rem;
}
</style>
Loading