Skip to content

Commit 13d98d2

Browse files
committed
Merge branch 'main' of https://github.com/trycompai/comp into chas/show-domain-status
2 parents 03b73ab + e5a74e5 commit 13d98d2

File tree

16 files changed

+212
-60
lines changed

16 files changed

+212
-60
lines changed

apps/app/src/app/(app)/[orgId]/tasks/[taskId]/automation/[automationId]/actions/task-automation-actions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ export async function executeAutomationScript(data: {
193193
body: data,
194194
});
195195

196-
await revalidateCurrentPath();
196+
// Don't revalidate - causes page refresh. Test results are handled via polling/state.
197197
return { success: true, data: result };
198198
} catch (error) {
199199
const typedError = error as EnterpriseApiError;

apps/app/src/app/(app)/[orgId]/tasks/[taskId]/automation/[automationId]/chat.tsx

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,23 +31,29 @@ interface Props {
3131

3232
export function Chat({ className, orgId, taskId, taskName, automationId }: Props) {
3333
const [input, setInput] = useState('');
34-
const { chat, updateAutomationId } = useSharedChatContext();
34+
const { chat, updateAutomationId, automationIdRef } = useSharedChatContext();
3535
const { messages, sendMessage, status } = useChat<ChatUIMessage>({
3636
chat,
3737
});
3838
const { setChatStatus, scriptUrl } = useTaskAutomationStore();
3939
const inputRef = useRef<HTMLInputElement | null>(null);
4040
const { automation } = useTaskAutomation();
4141

42+
// Update shared ref when automation is loaded from hook
43+
if (automation?.id && automationIdRef.current === 'new') {
44+
automationIdRef.current = automation.id;
45+
}
46+
4247
// Ephemeral mode - automation not created yet
43-
const isEphemeral = automationId === 'new';
48+
// Check the shared ref, not the URL param
49+
const isEphemeral = automationIdRef.current === 'new';
4450

4551
const { validateAndSubmitMessage, handleSecretAdded, handleInfoProvided } = useChatHandlers({
4652
sendMessage,
4753
setInput,
4854
orgId,
4955
taskId,
50-
automationId,
56+
automationId: automationIdRef.current,
5157
isEphemeral,
5258
updateAutomationId,
5359
});
@@ -85,7 +91,7 @@ export function Chat({ className, orgId, taskId, taskName, automationId }: Props
8591
orgId={orgId}
8692
taskId={taskId}
8793
taskName={taskName}
88-
automationId={automationId}
94+
automationId={automationIdRef.current}
8995
automationName={automation?.name}
9096
isEphemeral={isEphemeral}
9197
/>

apps/app/src/app/(app)/[orgId]/tasks/[taskId]/automation/[automationId]/components/AutomationSettingsDialogs.tsx

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,25 +21,32 @@ import { useTaskAutomation } from '../hooks/use-task-automation';
2121
interface EditNameDialogProps {
2222
open: boolean;
2323
onOpenChange: (open: boolean) => void;
24+
onSuccess?: () => void;
2425
}
2526

2627
interface EditDescriptionDialogProps {
2728
open: boolean;
2829
onOpenChange: (open: boolean) => void;
30+
onSuccess?: () => void;
2931
}
3032

3133
interface DeleteDialogProps {
3234
open: boolean;
3335
onOpenChange: (open: boolean) => void;
36+
onSuccess?: () => void;
3437
}
3538

36-
export function EditNameDialog({ open, onOpenChange }: EditNameDialogProps) {
37-
const { automation, mutate } = useTaskAutomation();
39+
export function EditNameDialog({ open, onOpenChange, onSuccess }: EditNameDialogProps) {
40+
const { automation, mutate: mutateLocal } = useTaskAutomation();
3841
const { orgId, taskId, automationId } = useParams<{
3942
orgId: string;
4043
taskId: string;
4144
automationId: string;
4245
}>();
46+
47+
// Use real automation ID when available
48+
const realAutomationId = automation?.id || automationId;
49+
4350
const [name, setName] = useState(automation?.name || '');
4451
const [isSaving, setIsSaving] = useState(false);
4552

@@ -57,7 +64,7 @@ export function EditNameDialog({ open, onOpenChange }: EditNameDialogProps) {
5764
setIsSaving(true);
5865
try {
5966
const response = await api.patch(
60-
`/v1/tasks/${taskId}/automations/${automationId}`,
67+
`/v1/tasks/${taskId}/automations/${realAutomationId}`,
6168
{ name: name.trim() },
6269
orgId,
6370
);
@@ -66,7 +73,8 @@ export function EditNameDialog({ open, onOpenChange }: EditNameDialogProps) {
6673
throw new Error(response.error);
6774
}
6875

69-
await mutate(); // Refresh automation data
76+
await mutateLocal(); // Refresh automation data in hook
77+
await onSuccess?.(); // Notify parent to refresh (e.g., overview page)
7078
onOpenChange(false);
7179
toast.success('Automation name updated');
7280
} catch (error) {
@@ -111,8 +119,12 @@ export function EditNameDialog({ open, onOpenChange }: EditNameDialogProps) {
111119
);
112120
}
113121

114-
export function EditDescriptionDialog({ open, onOpenChange }: EditDescriptionDialogProps) {
115-
const { automation, mutate } = useTaskAutomation();
122+
export function EditDescriptionDialog({
123+
open,
124+
onOpenChange,
125+
onSuccess,
126+
}: EditDescriptionDialogProps) {
127+
const { automation, mutate: mutateLocal } = useTaskAutomation();
116128
const { orgId, taskId, automationId } = useParams<{
117129
orgId: string;
118130
taskId: string;
@@ -139,7 +151,8 @@ export function EditDescriptionDialog({ open, onOpenChange }: EditDescriptionDia
139151
throw new Error(response.error);
140152
}
141153

142-
await mutate(); // Refresh automation data
154+
await mutateLocal(); // Refresh automation data in hook
155+
await onSuccess?.(); // Notify parent to refresh (e.g., overview page)
143156
onOpenChange(false);
144157
toast.success('Automation description updated');
145158
} catch (error) {
@@ -185,7 +198,7 @@ export function EditDescriptionDialog({ open, onOpenChange }: EditDescriptionDia
185198
);
186199
}
187200

188-
export function DeleteAutomationDialog({ open, onOpenChange }: DeleteDialogProps) {
201+
export function DeleteAutomationDialog({ open, onOpenChange, onSuccess }: DeleteDialogProps) {
189202
const { automation } = useTaskAutomation();
190203
const { orgId, taskId, automationId } = useParams<{
191204
orgId: string;

apps/app/src/app/(app)/[orgId]/tasks/[taskId]/automation/[automationId]/components/PublishDialog.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,20 @@ import { useState } from 'react';
1717
import { toast } from 'sonner';
1818
import { publishAutomation } from '../actions/task-automation-actions';
1919
import { useAutomationVersions } from '../hooks/use-automation-versions';
20+
import { useSharedChatContext } from '../lib/chat-context';
2021

2122
interface PublishDialogProps {
2223
open: boolean;
2324
onOpenChange: (open: boolean) => void;
2425
}
2526

2627
export function PublishDialog({ open, onOpenChange }: PublishDialogProps) {
27-
const { orgId, taskId, automationId } = useParams<{
28+
const { orgId, taskId } = useParams<{
2829
orgId: string;
2930
taskId: string;
3031
automationId: string;
3132
}>();
33+
const { automationIdRef } = useSharedChatContext();
3234
const [changelog, setChangelog] = useState('');
3335
const [isPublishing, setIsPublishing] = useState(false);
3436
const { mutate } = useAutomationVersions();
@@ -37,7 +39,12 @@ export function PublishDialog({ open, onOpenChange }: PublishDialogProps) {
3739
setIsPublishing(true);
3840

3941
try {
40-
const result = await publishAutomation(orgId, taskId, automationId, changelog || undefined);
42+
const result = await publishAutomation(
43+
orgId,
44+
taskId,
45+
automationIdRef.current,
46+
changelog || undefined,
47+
);
4148

4249
if (!result.success) {
4350
throw new Error(result.error || 'Failed to publish');

apps/app/src/app/(app)/[orgId]/tasks/[taskId]/automation/[automationId]/components/chat/EmptyState.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,15 @@ export function EmptyState({
2020
}: EmptyStateProps) {
2121
return (
2222
<div className="flex-1 min-h-0 overflow-y-auto h-full z-20">
23-
<div className="w-full h-full flex flex-col items-center py-48">
23+
<div className="w-full h-full flex flex-col items-center py-48 px-4">
2424
<div className="w-full max-w-3xl text-center space-y-8 mb-16">
2525
<p className="text-2xl font-medium text-primary tracking-wide z-20">
2626
What evidence do you want to collect?
2727
</p>
2828
<Input
2929
ref={inputRef}
3030
placeholder="Check if GitHub dependabot is enabled and tell me the result"
31-
className="w-full max-w-3xl transition-all duration-200 hover:shadow-md hover:shadow-primary/5 hover:scale-[1.01] focus:shadow-lg focus:shadow-primary/10 focus:scale-[1.02] focus:ring-2 focus:ring-primary/30"
31+
className="w-full max-w-3xl transition-all duration-200 hover:shadow-md hover:shadow-primary/5 focus:shadow-lg focus:shadow-primary/10 focus:ring-2 focus:ring-primary/30"
3232
value={input}
3333
onChange={(e) => onInputChange(e.target.value)}
3434
disabled={status === 'streaming' || status === 'submitted'}

apps/app/src/app/(app)/[orgId]/tasks/[taskId]/automation/[automationId]/components/chat/message-part/reasoning.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,11 @@ export function Reasoning({ part, partIndex }: { part: ReasoningUIPart; partInde
6161
className="text-left w-full flex items-center gap-2.5 transition-all duration-200 group/btn"
6262
onClick={handleClick}
6363
>
64-
<span className="text-xs text-muted-foreground truncate block">{getReasoningLabel()}</span>
64+
<span
65+
className={`text-xs truncate block ${isStreaming ? 'thinking-text' : 'text-muted-foreground'}`}
66+
>
67+
{getReasoningLabel()}
68+
</span>
6569
</button>
6670
</div>
6771
);

apps/app/src/app/(app)/[orgId]/tasks/[taskId]/automation/[automationId]/components/chat/message.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ export const Message = memo(function Message({
113113
if (thisSessionIsThinking) {
114114
result.push(
115115
<div key={`thinking-${sessionId}-active`} className="flex items-center gap-2 py-1">
116-
<span className="text-xs text-muted-foreground">Thinking...</span>
116+
<span className="text-xs thinking-text">Thinking...</span>
117117
</div>,
118118
);
119119
} else {
@@ -191,7 +191,7 @@ export const Message = memo(function Message({
191191
if (finalThinkingIsActive) {
192192
result.push(
193193
<div key={`thinking-${sessionId}-active`} className="flex items-center gap-2 py-1">
194-
<span className="text-xs text-muted-foreground">Thinking...</span>
194+
<span className="text-xs thinking-text">Thinking...</span>
195195
</div>,
196196
);
197197
} else {

apps/app/src/app/(app)/[orgId]/tasks/[taskId]/automation/[automationId]/components/workflow/components/UnifiedWorkflowCard.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,12 @@ export function UnifiedWorkflowCard({ steps, title, onTest, integrationsUsed }:
143143
</div>
144144
) : (
145145
<button
146-
onClick={onTest}
146+
type="button"
147+
onClick={(e) => {
148+
e.preventDefault();
149+
e.stopPropagation();
150+
onTest?.();
151+
}}
147152
className="w-full flex items-center justify-center gap-2 px-4 py-2 rounded-lg bg-primary text-primary-foreground font-medium hover:bg-primary/90 transition-colors animate-in fade-in duration-500"
148153
>
149154
<Play className="w-4 h-4" />

apps/app/src/app/(app)/[orgId]/tasks/[taskId]/automation/[automationId]/components/workflow/workflow-visualizer-simple.tsx

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import { useEffect, useMemo, useState } from 'react';
2626
import { toast } from 'sonner';
2727
import { restoreVersion } from '../../actions/task-automation-actions';
2828
import {
29+
useTaskAutomation,
2930
useTaskAutomationAnalyze,
3031
useTaskAutomationExecution,
3132
useTaskAutomationScript,
@@ -57,29 +58,35 @@ export function WorkflowVisualizerSimple({ className }: Props) {
5758
taskId: string;
5859
automationId: string;
5960
}>();
60-
const { chat } = useSharedChatContext();
61+
const { chat, automationIdRef } = useSharedChatContext();
6162
const { sendMessage } = useChat<ChatUIMessage>({ chat });
6263
const [publishDialogOpen, setPublishDialogOpen] = useState(false);
6364
const [isRestoring, setIsRestoring] = useState(false);
6465
const [confirmRestore, setConfirmRestore] = useState<EvidenceAutomationVersion | null>(null);
66+
const { automation } = useTaskAutomation();
6567
const { versions } = useAutomationVersions();
6668

69+
// Update shared ref when automation is loaded from hook
70+
if (automation?.id && automationIdRef.current === 'new') {
71+
automationIdRef.current = automation.id;
72+
}
73+
6774
const {
6875
script,
6976
isLoading: isLoadingScript,
7077
refresh,
7178
} = useTaskAutomationScript({
7279
orgId: orgId,
7380
taskId: taskId,
74-
automationId: automationId,
75-
enabled: !!orgId && !!taskId && !!automationId,
81+
automationId: automationIdRef.current,
82+
enabled: !!orgId && !!taskId && automationIdRef.current !== 'new',
7683
});
7784

7885
const handleRestoreVersion = async (version: EvidenceAutomationVersion) => {
7986
setIsRestoring(true);
8087

8188
try {
82-
const result = await restoreVersion(orgId, taskId, automationId, version.version);
89+
const result = await restoreVersion(orgId, taskId, automationIdRef.current, version.version);
8390

8491
if (!result.success) {
8592
throw new Error(result.error || 'Failed to restore version');
@@ -155,7 +162,10 @@ export function WorkflowVisualizerSimple({ className }: Props) {
155162
}, [executionResult, executionError]);
156163

157164
const handleTest = async () => {
158-
if (!orgId || !taskId) return;
165+
if (!orgId || !taskId || automationIdRef.current === 'new') {
166+
console.warn('Cannot test ephemeral automation');
167+
return;
168+
}
159169
await execute();
160170
};
161171

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
export { useTaskAutomation } from './use-task-automation';
12
export { useTaskAutomationAnalyze } from './use-task-automation-analyze';
23
export { useTaskAutomationExecution } from './use-task-automation-execution';
34
export { useTaskAutomationScript } from './use-task-automation-script';

0 commit comments

Comments
 (0)