@@ -9,7 +9,10 @@ import type { CloudProviderType } from '@/lib/api/types';
99
1010// ============================================================================
1111// MessageFAB - Enhanced Floating Action Button with multiple actions
12- // Master control for all Service Bus testing operations
12+ // Master control for messaging test operations across all providers:
13+ // Azure Service Bus, AWS SQS/SNS, and GCP Pub/Sub. Rendered only for DEV
14+ // namespaces with Manage permission (gated in MainLayout); production
15+ // namespaces additionally disable all destructive actions here.
1316// Handles both Queues and Topic Subscriptions
1417// ============================================================================
1518
@@ -39,8 +42,11 @@ export function MessageFAB({
3942 onMessagesGenerated,
4043} : MessageFABProps ) {
4144 const isProd = environment ?. toLowerCase ( ) === 'prod' ;
42- const isNonAzure = cloudProvider === 'aws' || cloudProvider === 'gcp' ;
43- const providerLabel = cloudProvider === 'aws' ? 'AWS SQS' : cloudProvider === 'gcp' ? 'GCP Pub/Sub' : 'Azure Service Bus' ;
45+ // Test actions are supported for all providers: Azure (native), AWS (SQS send /
46+ // SNS publish / manual DLQ via the queue's redrive target), and GCP (publish /
47+ // manual DLQ by republishing to the subscription's dead-letter topic). AWS and
48+ // GCP require a DLQ/dead-letter policy on the entity — a clear error explains
49+ // this when it is missing.
4450 const fabBgColor = cloudProvider === 'aws'
4551 ? 'bg-gradient-to-br from-orange-500 to-orange-600 hover:from-orange-600 hover:to-orange-700 ring-orange-200'
4652 : cloudProvider === 'gcp'
@@ -229,12 +235,6 @@ export function MessageFAB({
229235 </ div >
230236 </ button >
231237
232- { isNonAzure && (
233- < div className = "px-3 py-1.5 text-[11px] font-medium text-purple-700 bg-purple-50 border border-purple-200 rounded-lg mb-2 flex items-center gap-1.5" >
234- < span > ⚡</ span > { providerLabel } — write operations in Phase 2
235- </ div >
236- ) }
237-
238238 { isProd && (
239239 < div className = "px-3 py-1.5 text-[11px] font-medium text-amber-700 bg-amber-50 border border-amber-200 rounded-lg mb-2 flex items-center gap-1.5" >
240240 < span > ⚠</ span > Production — destructive actions disabled
@@ -244,29 +244,29 @@ export function MessageFAB({
244244 { /* Dead-Letter Messages Option */ }
245245 < button
246246 onClick = { isProd ? undefined : handleDeadLetter }
247- disabled = { ! hasValidEntity || isDeadLettering || isProd || isNonAzure }
247+ disabled = { ! hasValidEntity || isDeadLettering || isProd }
248248 className = { `
249249 flex items-center gap-3
250250 px-4 py-3
251251 border rounded-xl shadow-lg
252252 transition-all duration-150
253253 group
254- ${ ! hasValidEntity || isProd || isNonAzure
254+ ${ ! hasValidEntity || isProd
255255 ? 'bg-gray-100 border-gray-200 cursor-not-allowed opacity-50'
256256 : 'bg-white hover:bg-red-50 border-gray-200 hover:border-red-300 hover:shadow-xl'
257257 }
258258 ` }
259- title = { isProd ? 'Quick Actions are disabled for Production namespaces' : isNonAzure ? `Write operations for ${ providerLabel } coming in Phase 2` : 'For testing: moves up to 3 messages from the active queue to the dead-letter queue' }
259+ title = { isProd ? 'Quick Actions are disabled for Production namespaces' : 'For testing: moves up to 3 messages from the active queue to the dead-letter queue' }
260260 >
261261 < div className = { `p-2 rounded-lg transition-colors ${
262- ! hasValidEntity || isProd || isNonAzure
262+ ! hasValidEntity || isProd
263263 ? 'bg-gray-200'
264264 : 'bg-red-100 group-hover:bg-red-200'
265265 } `} >
266- < Skull className = { `w-5 h-5 ${ ! hasValidEntity || isProd || isNonAzure ? 'text-gray-400' : 'text-red-600' } ` } />
266+ < Skull className = { `w-5 h-5 ${ ! hasValidEntity || isProd ? 'text-gray-400' : 'text-red-600' } ` } />
267267 </ div >
268268 < div className = "text-left" >
269- < div className = { `text-sm font-semibold ${ ! hasValidEntity || isProd || isNonAzure ? 'text-gray-400' : 'text-gray-800' } ` } >
269+ < div className = { `text-sm font-semibold ${ ! hasValidEntity || isProd ? 'text-gray-400' : 'text-gray-800' } ` } >
270270 { isDeadLettering ? 'Moving...' : 'Test DLQ' }
271271 </ div >
272272 < div className = "text-xs text-gray-500 max-w-[180px]" >
@@ -278,19 +278,19 @@ export function MessageFAB({
278278 { /* Generate Messages Option */ }
279279 < button
280280 onClick = { handleOpenGenerate }
281- disabled = { isProd || isNonAzure }
281+ disabled = { isProd }
282282 className = { `
283283 flex items-center gap-3
284284 px-4 py-3
285285 border rounded-xl shadow-lg
286286 transition-all duration-150
287287 group
288- ${ isProd || isNonAzure
288+ ${ isProd
289289 ? 'bg-gray-100 border-gray-200 cursor-not-allowed opacity-50'
290290 : 'bg-white hover:bg-amber-50 border-gray-200 hover:border-amber-300 hover:shadow-xl'
291291 }
292292 ` }
293- title = { isProd ? 'Quick Actions are disabled for Production namespaces' : isNonAzure ? `Write operations for ${ providerLabel } coming in Phase 2` : undefined }
293+ title = { isProd ? 'Quick Actions are disabled for Production namespaces' : undefined }
294294 >
295295 < div className = "p-2 bg-amber-100 rounded-lg group-hover:bg-amber-200 transition-colors" >
296296 < Wand2 className = "w-5 h-5 text-amber-600" />
@@ -304,19 +304,19 @@ export function MessageFAB({
304304 { /* Send Message Option */ }
305305 < button
306306 onClick = { handleOpenSend }
307- disabled = { isProd || isNonAzure }
307+ disabled = { isProd }
308308 className = { `
309309 flex items-center gap-3
310310 px-4 py-3
311311 border rounded-xl shadow-lg
312312 transition-all duration-150
313313 group
314- ${ isProd || isNonAzure
314+ ${ isProd
315315 ? 'bg-gray-100 border-gray-200 cursor-not-allowed opacity-50'
316316 : 'bg-white hover:bg-sky-50 border-gray-200 hover:border-sky-300 hover:shadow-xl'
317317 }
318318 ` }
319- title = { isProd ? 'Quick Actions are disabled for Production namespaces' : isNonAzure ? `Write operations for ${ providerLabel } coming in Phase 2` : undefined }
319+ title = { isProd ? 'Quick Actions are disabled for Production namespaces' : undefined }
320320 >
321321 < div className = "p-2 bg-sky-100 rounded-lg group-hover:bg-sky-200 transition-colors" >
322322 < Send className = "w-5 h-5 text-sky-600" />
@@ -357,7 +357,8 @@ export function MessageFAB({
357357 onClose = { ( ) => setActiveModal ( null ) }
358358 onSend = { handleSend }
359359 defaultNamespaceId = { namespaceId }
360- defaultQueueName = { queueName }
360+ defaultEntityName = { entityType === 'topic' ? topicName : queueName }
361+ defaultEntityType = { entityType }
361362 />
362363
363364 { /* Message Generator Modal */ }
@@ -366,6 +367,7 @@ export function MessageFAB({
366367 onClose = { ( ) => setActiveModal ( null ) }
367368 defaultNamespaceId = { namespaceId }
368369 defaultEntityName = { entityType === 'topic' ? topicName : queueName }
370+ defaultTargetType = { entityType }
369371 onGenerated = { handleGenerated }
370372 />
371373 </ >
0 commit comments