@sentry/junior-dashboard 0.263.0 → 0.265.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +2 -5
- package/dist/app.js +119 -35
- package/dist/client.js +148 -135
- package/dist/index.d.ts +0 -1
- package/dist/index.js +119 -35
- package/dist/tailwind.css +1 -1
- package/package.json +9 -4
- package/src/api/schema.ts +0 -1
- package/src/app.ts +5 -20
- package/src/client/App.tsx +29 -31
- package/src/client/api.ts +7 -0
- package/src/client/components/BottomSheet.tsx +26 -18
- package/src/client/components/CopyButton.tsx +83 -0
- package/src/client/components/DetailsPanel.tsx +133 -0
- package/src/client/components/Drawer.tsx +34 -33
- package/src/client/components/FilterBar.tsx +16 -31
- package/src/client/components/Metric.tsx +33 -23
- package/src/client/components/PageContentSkeleton.tsx +1 -1
- package/src/client/components/Pagination.tsx +1 -1
- package/src/client/components/ParticipantAvatarStack.tsx +40 -36
- package/src/client/components/ProfileMenu.tsx +27 -93
- package/src/client/components/README.md +101 -64
- package/src/client/components/SegmentedNav.tsx +1 -1
- package/src/client/components/ShimmerText.tsx +2 -6
- package/src/client/components/ThemeSwitcher.tsx +19 -15
- package/src/client/components/charts/ActivityChart.tsx +173 -288
- package/src/client/components/charts/CacheWrites.tsx +63 -50
- package/src/client/components/charts/InputCacheChart.tsx +137 -131
- package/src/client/components/charts/README.md +4 -4
- package/src/client/components/charts/SystemMetricCharts.tsx +68 -95
- package/src/client/components/charts/WorkspaceUsageChart.tsx +42 -62
- package/src/client/components/controls/DirectorySortSelect.tsx +3 -3
- package/src/client/components/controls/TimeRangeSelector.tsx +10 -15
- package/src/client/components/layout/DashboardHeader.tsx +44 -90
- package/src/client/components/layout/SecondaryNavigation.tsx +2 -1
- package/src/client/components/layout/VisualViewportShell.tsx +2 -2
- package/src/client/components/ui/accordion.tsx +77 -0
- package/src/client/components/ui/alert-dialog.tsx +89 -0
- package/src/client/components/ui/button.tsx +85 -0
- package/src/client/components/ui/chart.tsx +74 -0
- package/src/client/components/ui/checkbox.tsx +26 -0
- package/src/client/components/ui/collapsible.tsx +22 -0
- package/src/client/components/ui/field.tsx +49 -0
- package/src/client/components/ui/input.tsx +35 -0
- package/src/client/components/ui/native-select.tsx +57 -0
- package/src/client/components/ui/popover.tsx +67 -0
- package/src/client/components/ui/radio-group.tsx +32 -0
- package/src/client/components/ui/sheet.tsx +151 -0
- package/src/client/components/ui/skeleton.tsx +19 -0
- package/src/client/components/ui/table.tsx +80 -0
- package/src/client/components/ui/tabs.tsx +75 -0
- package/src/client/components/ui/textarea.tsx +17 -0
- package/src/client/components/ui/toast.tsx +215 -0
- package/src/client/components/ui/toggle-group.tsx +36 -0
- package/src/client/components/ui/toggle.tsx +37 -0
- package/src/client/components/ui/tooltip.tsx +168 -0
- package/src/client/components/ui/trace.tsx +96 -0
- package/src/client/components/ui/useSheet.ts +74 -0
- package/src/client/conversations/ChatLayout.tsx +7 -3
- package/src/client/conversations/ConversationBrief.tsx +17 -6
- package/src/client/conversations/ConversationChildAgents.tsx +87 -58
- package/src/client/conversations/ConversationComposer.tsx +26 -12
- package/src/client/conversations/ConversationDetails.tsx +198 -95
- package/src/client/conversations/ConversationEventDetails.tsx +141 -0
- package/src/client/conversations/ConversationEventLog.tsx +150 -129
- package/src/client/conversations/ConversationHeader.tsx +8 -3
- package/src/client/conversations/ConversationHeaderActions.tsx +90 -82
- package/src/client/conversations/ConversationHomeList.tsx +1 -1
- package/src/client/conversations/ConversationLinkedWork.tsx +118 -0
- package/src/client/conversations/ConversationMeta.tsx +111 -92
- package/src/client/conversations/ConversationPage.tsx +241 -110
- package/src/client/conversations/ConversationSidebar.tsx +48 -29
- package/src/client/conversations/ConversationUsageBreakdown.tsx +16 -3
- package/src/client/conversations/ConversationWatches.tsx +165 -0
- package/src/client/conversations/ConversationWorkspace.tsx +12 -22
- package/src/client/conversations/ConversationWorkspaceLoading.tsx +1 -1
- package/src/client/conversations/DetailsList.tsx +124 -0
- package/src/client/conversations/EventDetails.tsx +42 -8
- package/src/client/conversations/ForkConversationButton.tsx +27 -16
- package/src/client/conversations/ObjectCard.tsx +20 -8
- package/src/client/conversations/PendingMailboxStack.tsx +52 -33
- package/src/client/conversations/README.md +93 -19
- package/src/client/conversations/ShareConversationButton.tsx +28 -3
- package/src/client/conversations/SubagentTranscriptDrawer.tsx +21 -15
- package/src/client/conversations/ToolFrame.tsx +36 -52
- package/src/client/conversations/TranscriptActivityGroup.tsx +13 -4
- package/src/client/conversations/TranscriptAutomationTriggerView.tsx +5 -4
- package/src/client/conversations/TranscriptContextEventView.tsx +25 -11
- package/src/client/conversations/TranscriptHeadingRow.tsx +7 -7
- package/src/client/conversations/TranscriptLoading.tsx +1 -1
- package/src/client/conversations/TranscriptMarkdown.tsx +25 -20
- package/src/client/conversations/TranscriptMessageContextView.tsx +8 -2
- package/src/client/conversations/TranscriptMessageView.tsx +6 -1
- package/src/client/conversations/TranscriptReasoningView.tsx +54 -68
- package/src/client/conversations/TranscriptSubagentView.tsx +3 -3
- package/src/client/conversations/TranscriptTimestamp.tsx +9 -7
- package/src/client/conversations/TranscriptToolView.tsx +1 -1
- package/src/client/conversations/TranscriptTurnContextView.tsx +99 -27
- package/src/client/conversations/TranscriptView.tsx +63 -27
- package/src/client/conversations/eventLog.ts +57 -0
- package/src/client/conversations/eventTime.ts +60 -0
- package/src/client/conversations/queries.ts +29 -0
- package/src/client/conversations/transcriptBottomPinning.ts +34 -0
- package/src/client/format.ts +5 -0
- package/src/client/lib/utils.ts +1 -0
- package/src/client/pages/ConnectionsPage.tsx +2 -2
- package/src/client/pages/PersonalTokensPage.tsx +4 -4
- package/src/client/pages/SettingsPage.tsx +9 -10
- package/src/client/pages/admin/ServiceAccountsSection.tsx +2 -2
- package/src/client/pages/automations/AutomationCostChart.tsx +50 -71
- package/src/client/pages/automations/AutomationDeleteDialog.tsx +87 -0
- package/src/client/pages/automations/AutomationDetails.tsx +193 -0
- package/src/client/pages/automations/AutomationEditPage.tsx +7 -8
- package/src/client/pages/automations/AutomationEditor.tsx +41 -29
- package/src/client/pages/automations/AutomationEditorLoading.tsx +1 -1
- package/src/client/pages/automations/AutomationEventFields.tsx +202 -119
- package/src/client/pages/automations/AutomationExecutionChart.tsx +51 -64
- package/src/client/pages/automations/AutomationExecutionStatusChart.tsx +47 -70
- package/src/client/pages/automations/AutomationExecutionsPage.tsx +150 -126
- package/src/client/pages/automations/AutomationFilters.tsx +189 -74
- package/src/client/pages/automations/AutomationLifecycle.tsx +109 -78
- package/src/client/pages/automations/AutomationOutcomeFields.tsx +26 -24
- package/src/client/pages/automations/AutomationRecentRuns.tsx +143 -0
- package/src/client/pages/automations/AutomationRow.tsx +12 -138
- package/src/client/pages/automations/AutomationRunDetails.tsx +307 -0
- package/src/client/pages/automations/AutomationRunsPage.tsx +119 -94
- package/src/client/pages/automations/AutomationScheduleFields.tsx +51 -51
- package/src/client/pages/automations/AutomationStatus.tsx +201 -0
- package/src/client/pages/automations/AutomationVersionsPage.tsx +65 -28
- package/src/client/pages/automations/AutomationsPage.tsx +80 -68
- package/src/client/pages/automations/AutomationsPageLayout.tsx +46 -14
- package/src/client/pages/automations/README.md +57 -0
- package/src/client/pages/automations/TriggerFilters.tsx +22 -0
- package/src/client/pages/automations/automationFormat.ts +37 -23
- package/src/client/pages/code/CodeActivityChart.tsx +59 -101
- package/src/client/pages/code/CodePage.tsx +52 -55
- package/src/client/pages/code/RepositoryPage.tsx +6 -8
- package/src/client/pages/locations/LocationActivityChart.tsx +53 -70
- package/src/client/pages/locations/LocationDirectoryActivityChart.tsx +60 -80
- package/src/client/pages/memory/MemoryCostChart.tsx +79 -103
- package/src/client/pages/memory/MemoryDetails.tsx +218 -0
- package/src/client/pages/memory/MemoryPage.tsx +168 -112
- package/src/client/pages/memory/MemoryPageLayout.tsx +33 -9
- package/src/client/pages/memory/MemoryTimeline.tsx +46 -69
- package/src/client/pages/memory/memoryRecord.ts +1 -1
- package/src/client/pages/people/ContributionGrid.tsx +23 -16
- package/src/client/pages/people/PeopleActivityChart.tsx +68 -107
- package/src/client/pages/people/ProfileCodeChanges.tsx +5 -5
- package/src/client/pages/system/BaseSandboxCard.tsx +1 -1
- package/src/client/pages/system/ConversationActivityChart.tsx +49 -67
- package/src/client/pages/system/GuardianActivity.tsx +1 -2
- package/src/client/pages/system/PluginBarChart.tsx +106 -87
- package/src/client/pages/system/PluginReportRecordSet.tsx +25 -24
- package/src/client/pages/system/README.md +23 -0
- package/src/client/pages/system/SystemNavigation.tsx +5 -1
- package/src/client/pages/system/WorkspaceDeleteDialog.tsx +111 -0
- package/src/client/pages/system/WorkspaceDetails.tsx +200 -43
- package/src/client/pages/system/WorkspaceEditor.tsx +59 -61
- package/src/client/pages/system/WorkspaceFormPage.tsx +23 -47
- package/src/client/pages/system/WorkspaceList.tsx +20 -30
- package/src/client/pages/system/WorkspacesPage.tsx +117 -119
- package/src/client/pages/system/sandboxSize.ts +8 -0
- package/src/client/pages/system/workspaceQueries.ts +53 -0
- package/src/client/pages/user/PluginUserPage.tsx +51 -2
- package/src/client/pages/user/pluginUserPageData.ts +1 -6
- package/src/client/styles.ts +4 -0
- package/src/client.tsx +7 -1
- package/src/mock-reporting/automation-collection.ts +4 -2
- package/src/mock-reporting/fixtures.ts +23 -7
- package/src/mock-reporting/routes.ts +12 -0
- package/src/mock-reporting/watches.ts +94 -0
- package/src/shell.ts +4 -9
- package/src/tailwind.css +77 -10
- package/src/client/components/Button.tsx +0 -118
- package/src/client/components/Field.tsx +0 -53
- package/src/client/components/SegmentedTabs.tsx +0 -119
- package/src/client/components/Select.tsx +0 -52
- package/src/client/components/Sheet.LICENSE +0 -21
- package/src/client/components/Sheet.tsx +0 -141
- package/src/client/components/Skeleton.tsx +0 -17
- package/src/client/components/TextInput.tsx +0 -58
- package/src/client/components/Tooltip.tsx +0 -216
- package/src/client/components/charts/useChartLayout.ts +0 -27
- package/src/client/conversations/ConversationDetailsFrame.tsx +0 -91
- package/src/client/conversations/CopyMarkdownButton.tsx +0 -65
- package/src/client/pages/automations/AutomationDetailsDrawer.tsx +0 -219
- package/src/client/pages/dev/ChartFixtures.tsx +0 -325
- package/src/client/pages/dev/ComponentsPage.tsx +0 -899
- package/src/client/pages/dev/ConversationFixture.tsx +0 -231
- package/src/client/pages/dev/ObjectFixtures.tsx +0 -138
- package/src/client/pages/dev/SegmentedFixtures.tsx +0 -59
- package/src/client/pages/dev/SelectFixtures.tsx +0 -62
- package/src/client/pages/dev/TranscriptActivityFixtures.tsx +0 -206
- package/src/client/pages/memory/MemoryDetailsDrawer.tsx +0 -167
- package/src/client/pages/system/SandboxSizeSummary.tsx +0 -47
- package/src/client/pages/system/SnapshotSummary.tsx +0 -78
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import type { AutomationSummary } from "@sentry/junior/api/schema";
|
|
2
|
+
import type { ReactNode } from "react";
|
|
3
|
+
import { Link, useLocation } from "react-router";
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
Accordion,
|
|
7
|
+
AccordionContent,
|
|
8
|
+
AccordionItem,
|
|
9
|
+
AccordionTrigger,
|
|
10
|
+
} from "../../components/ui/accordion";
|
|
11
|
+
import { Button } from "../../components/ui/button";
|
|
12
|
+
import { DetailsPanel } from "../../components/DetailsPanel";
|
|
13
|
+
import { InlineError } from "../../components/InlineError";
|
|
14
|
+
import { PageContentSkeleton } from "../../components/PageContentSkeleton";
|
|
15
|
+
import {
|
|
16
|
+
timeRangeLabel,
|
|
17
|
+
type TimeRangeDays,
|
|
18
|
+
} from "../../components/controls/TimeRangeSelector";
|
|
19
|
+
import { TranscriptText } from "../../conversations/TranscriptText";
|
|
20
|
+
import { peoplePath } from "../../format";
|
|
21
|
+
import { dashboardInlineLinkClass } from "../../styles";
|
|
22
|
+
import { TriggerFilters } from "./TriggerFilters";
|
|
23
|
+
import { AutomationLifecycle } from "./AutomationLifecycle";
|
|
24
|
+
import { AutomationRecentRuns } from "./AutomationRecentRuns";
|
|
25
|
+
import { AutomationStatus } from "./AutomationStatus";
|
|
26
|
+
import {
|
|
27
|
+
automationScheduleLabel,
|
|
28
|
+
formatAutomationRunTime,
|
|
29
|
+
} from "./automationFormat";
|
|
30
|
+
import { automationOutcomeLabel } from "./automationOutcomes";
|
|
31
|
+
|
|
32
|
+
/** Keep Automation context scrollable above persistent, permission-aware actions. */
|
|
33
|
+
export function AutomationDetails(props: {
|
|
34
|
+
onClose(): void;
|
|
35
|
+
onDelete(source: HTMLButtonElement): void;
|
|
36
|
+
onRetry(): void;
|
|
37
|
+
error: boolean;
|
|
38
|
+
range: TimeRangeDays;
|
|
39
|
+
automation: AutomationSummary | undefined;
|
|
40
|
+
}) {
|
|
41
|
+
const location = useLocation();
|
|
42
|
+
const { automation } = props;
|
|
43
|
+
return (
|
|
44
|
+
<DetailsPanel
|
|
45
|
+
label="Automation details"
|
|
46
|
+
sheetTitle={automation?.title}
|
|
47
|
+
onClose={props.onClose}
|
|
48
|
+
title={
|
|
49
|
+
<h2 className="m-0 break-words font-display text-base font-medium text-dashboard-text">
|
|
50
|
+
{automation?.title ?? "Automation details"}
|
|
51
|
+
</h2>
|
|
52
|
+
}
|
|
53
|
+
>
|
|
54
|
+
<div className="grid h-full min-h-0 grid-rows-[minmax(0,1fr)_auto]">
|
|
55
|
+
<div
|
|
56
|
+
aria-label="Automation content"
|
|
57
|
+
role="region"
|
|
58
|
+
tabIndex={0}
|
|
59
|
+
className="min-h-0 overflow-y-auto overscroll-contain p-4 outline-none focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-dashboard-focus [overflow-wrap:anywhere]"
|
|
60
|
+
>
|
|
61
|
+
{automation ? (
|
|
62
|
+
<AutomationDetailsContent
|
|
63
|
+
automation={automation}
|
|
64
|
+
range={props.range}
|
|
65
|
+
/>
|
|
66
|
+
) : null}
|
|
67
|
+
{props.error ? (
|
|
68
|
+
<InlineError>
|
|
69
|
+
Automation details could not be loaded. It may be unavailable or
|
|
70
|
+
you may not have access.{" "}
|
|
71
|
+
<Button onClick={props.onRetry}>Try again</Button>
|
|
72
|
+
</InlineError>
|
|
73
|
+
) : !automation ? (
|
|
74
|
+
<PageContentSkeleton
|
|
75
|
+
label="Loading automation details"
|
|
76
|
+
variant="panel"
|
|
77
|
+
/>
|
|
78
|
+
) : null}
|
|
79
|
+
</div>
|
|
80
|
+
{automation ? (
|
|
81
|
+
<AutomationLifecycle
|
|
82
|
+
automation={automation}
|
|
83
|
+
onDelete={props.onDelete}
|
|
84
|
+
editPath={`/automations/${encodeURIComponent(automation.id)}/edit${location.search}`}
|
|
85
|
+
/>
|
|
86
|
+
) : null}
|
|
87
|
+
</div>
|
|
88
|
+
</DetailsPanel>
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function AutomationDetailsContent({
|
|
93
|
+
automation,
|
|
94
|
+
range,
|
|
95
|
+
}: {
|
|
96
|
+
automation: AutomationSummary;
|
|
97
|
+
range: TimeRangeDays;
|
|
98
|
+
}) {
|
|
99
|
+
const location = useLocation();
|
|
100
|
+
return (
|
|
101
|
+
<div className="grid min-w-0 gap-5">
|
|
102
|
+
<AutomationStatus automation={automation} />
|
|
103
|
+
<section aria-label="Instructions" className="text-sm leading-relaxed">
|
|
104
|
+
<TranscriptText
|
|
105
|
+
mentions={automation.mentions ?? []}
|
|
106
|
+
text={automation.instruction}
|
|
107
|
+
/>
|
|
108
|
+
</section>
|
|
109
|
+
<dl className="m-0 grid gap-3 text-xs leading-relaxed">
|
|
110
|
+
<AutomationFact label="Trigger">
|
|
111
|
+
{automation.kind === "scheduled" ? (
|
|
112
|
+
<p className="m-0">{automationScheduleLabel(automation)}</p>
|
|
113
|
+
) : (
|
|
114
|
+
<>
|
|
115
|
+
<p className="m-0 break-words">{automation.resource}</p>
|
|
116
|
+
<p className="m-0 mt-1 text-dashboard-text-muted">
|
|
117
|
+
{automation.trigger.events.join(", ")}
|
|
118
|
+
</p>
|
|
119
|
+
<TriggerFilters filters={automation.trigger.filters} />
|
|
120
|
+
</>
|
|
121
|
+
)}
|
|
122
|
+
</AutomationFact>
|
|
123
|
+
<AutomationFact label="On success">
|
|
124
|
+
{automation.outcomes.length === 0 ? (
|
|
125
|
+
<span className="text-dashboard-text-muted">No message</span>
|
|
126
|
+
) : (
|
|
127
|
+
<ol className="m-0 grid list-none gap-2 p-0">
|
|
128
|
+
{automation.outcomes.map((outcome, index) => (
|
|
129
|
+
<li key={index}>
|
|
130
|
+
Message{" "}
|
|
131
|
+
{automationOutcomeLabel(outcome, automation.destination)}
|
|
132
|
+
</li>
|
|
133
|
+
))}
|
|
134
|
+
</ol>
|
|
135
|
+
)}
|
|
136
|
+
</AutomationFact>
|
|
137
|
+
</dl>
|
|
138
|
+
<AutomationRecentRuns automation={automation} />
|
|
139
|
+
<Accordion className="border-t border-dashboard-border pt-1">
|
|
140
|
+
<AccordionItem value="about">
|
|
141
|
+
<AccordionTrigger className="min-h-11 text-xs text-dashboard-text-muted">
|
|
142
|
+
About this Automation
|
|
143
|
+
</AccordionTrigger>
|
|
144
|
+
<AccordionContent>
|
|
145
|
+
<dl className="m-0 grid gap-3 text-xs leading-relaxed">
|
|
146
|
+
<AutomationFact label="Created by">
|
|
147
|
+
{automation.createdByEmail ? (
|
|
148
|
+
<Link
|
|
149
|
+
className={dashboardInlineLinkClass}
|
|
150
|
+
to={peoplePath(automation.createdByEmail)}
|
|
151
|
+
>
|
|
152
|
+
{automation.ownedByViewer ? "you" : automation.createdBy}
|
|
153
|
+
</Link>
|
|
154
|
+
) : automation.ownedByViewer ? (
|
|
155
|
+
"you"
|
|
156
|
+
) : (
|
|
157
|
+
automation.createdBy
|
|
158
|
+
)}
|
|
159
|
+
</AutomationFact>
|
|
160
|
+
<AutomationFact label="Created">
|
|
161
|
+
{formatAutomationRunTime(automation.createdAt)}
|
|
162
|
+
</AutomationFact>
|
|
163
|
+
<AutomationFact label="Accounts">
|
|
164
|
+
{automation.credentialMode === "creator"
|
|
165
|
+
? `Uses accounts connected by ${automation.ownedByViewer ? "you" : automation.createdBy}.`
|
|
166
|
+
: "Junior’s accounts only"}
|
|
167
|
+
</AutomationFact>
|
|
168
|
+
<AutomationFact label="Runs">
|
|
169
|
+
{automation.runs[range]} runs / {timeRangeLabel(range)} ·{" "}
|
|
170
|
+
{automation.totalRuns} total
|
|
171
|
+
</AutomationFact>
|
|
172
|
+
</dl>
|
|
173
|
+
<Link
|
|
174
|
+
className={`${dashboardInlineLinkClass} mt-3 inline-block py-2 text-xs`}
|
|
175
|
+
to={`/automations/${encodeURIComponent(automation.id)}/versions${location.search}`}
|
|
176
|
+
>
|
|
177
|
+
Version history
|
|
178
|
+
</Link>
|
|
179
|
+
</AccordionContent>
|
|
180
|
+
</AccordionItem>
|
|
181
|
+
</Accordion>
|
|
182
|
+
</div>
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function AutomationFact(props: { label: string; children: ReactNode }) {
|
|
187
|
+
return (
|
|
188
|
+
<div className="grid min-w-0 grid-cols-[5.25rem_minmax(0,1fr)] gap-3">
|
|
189
|
+
<dt className="text-dashboard-text-muted">{props.label}</dt>
|
|
190
|
+
<dd className="m-0 min-w-0">{props.children}</dd>
|
|
191
|
+
</div>
|
|
192
|
+
);
|
|
193
|
+
}
|
|
@@ -8,10 +8,11 @@ import {
|
|
|
8
8
|
import { useAutomationData } from "../../api";
|
|
9
9
|
import { useDocumentTitle } from "../../documentTitle";
|
|
10
10
|
import { fetchDashboardJson } from "../../http";
|
|
11
|
-
import { Button } from "../../components/
|
|
11
|
+
import { Button } from "../../components/ui/button";
|
|
12
12
|
import { FormNotice } from "../../components/FormNotice";
|
|
13
13
|
import { StatusChip } from "../../components/StatusChip";
|
|
14
14
|
import { AutomationsNavigation } from "./AutomationsPageLayout";
|
|
15
|
+
import { TriggerFilters } from "./TriggerFilters";
|
|
15
16
|
import { AutomationEditor } from "./AutomationEditor";
|
|
16
17
|
import { AutomationEditorLoading } from "./AutomationEditorLoading";
|
|
17
18
|
import { AutomationFormSection } from "./AutomationFormSection";
|
|
@@ -49,7 +50,7 @@ export function AutomationEditPage(props: { enabled: boolean }) {
|
|
|
49
50
|
value?.kind === "event"
|
|
50
51
|
? value.status !== "active"
|
|
51
52
|
? value.status
|
|
52
|
-
: value.
|
|
53
|
+
: value.trigger.problems.length === 0
|
|
53
54
|
? "active"
|
|
54
55
|
: "unavailable"
|
|
55
56
|
: value?.status;
|
|
@@ -144,12 +145,10 @@ function AutomationReadOnly({ automation }: { automation: AutomationSummary }) {
|
|
|
144
145
|
) : (
|
|
145
146
|
<div className="grid gap-3 text-sm">
|
|
146
147
|
<p className="m-0 break-words">{automation.resource}</p>
|
|
147
|
-
<p className="m-0 break-words">
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
</pre>
|
|
152
|
-
) : null}
|
|
148
|
+
<p className="m-0 break-words">
|
|
149
|
+
{automation.trigger.events.join(", ")}
|
|
150
|
+
</p>
|
|
151
|
+
<TriggerFilters filters={automation.trigger.filters} />
|
|
153
152
|
</div>
|
|
154
153
|
)}
|
|
155
154
|
</AutomationFormSection>
|
|
@@ -8,10 +8,13 @@ import {
|
|
|
8
8
|
type AutomationEdit,
|
|
9
9
|
type AutomationSummary,
|
|
10
10
|
} from "@sentry/junior/api/schema";
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
11
|
+
import { Button } from "../../components/ui/button";
|
|
12
|
+
import { Input } from "../../components/ui/input";
|
|
13
|
+
import { Textarea } from "../../components/ui/textarea";
|
|
14
|
+
import { Field, FieldError, FieldLabel } from "../../components/ui/field";
|
|
15
|
+
import { useToastManager } from "../../components/ui/toast";
|
|
14
16
|
import { FormNotice } from "../../components/FormNotice";
|
|
17
|
+
import { RadioGroup, RadioGroupItem } from "../../components/ui/radio-group";
|
|
15
18
|
import { DashboardApiError, fetchDashboardJson, patch } from "../../http";
|
|
16
19
|
import { AutomationFormSection } from "./AutomationFormSection";
|
|
17
20
|
import { AutomationScheduleFields } from "./AutomationScheduleFields";
|
|
@@ -33,6 +36,7 @@ export function AutomationEditor(props: {
|
|
|
33
36
|
summary: AutomationSummary;
|
|
34
37
|
returnPath: string;
|
|
35
38
|
}) {
|
|
39
|
+
const toast = useToastManager();
|
|
36
40
|
const [original, setOriginal] = useState(props.automation);
|
|
37
41
|
const [draft, setDraft] = useState(() =>
|
|
38
42
|
createAutomationDraft(props.automation),
|
|
@@ -80,7 +84,12 @@ export function AutomationEditor(props: {
|
|
|
80
84
|
await queryClient.invalidateQueries({
|
|
81
85
|
queryKey: ["dashboard", "automations"],
|
|
82
86
|
});
|
|
83
|
-
|
|
87
|
+
toast.add({
|
|
88
|
+
title: "Automation saved",
|
|
89
|
+
description: "Changes apply to future work.",
|
|
90
|
+
type: "success",
|
|
91
|
+
});
|
|
92
|
+
navigate(props.returnPath);
|
|
84
93
|
},
|
|
85
94
|
onError: (error) => {
|
|
86
95
|
setFields(error instanceof DashboardApiError ? (error.fields ?? {}) : {});
|
|
@@ -246,8 +255,9 @@ export function AutomationEditor(props: {
|
|
|
246
255
|
title="What to do"
|
|
247
256
|
detail="Give Junior a clear instruction and a name you can find later."
|
|
248
257
|
>
|
|
249
|
-
<Field
|
|
250
|
-
<
|
|
258
|
+
<Field>
|
|
259
|
+
<FieldLabel htmlFor="title">Title</FieldLabel>
|
|
260
|
+
<Input
|
|
251
261
|
size="comfortable"
|
|
252
262
|
id="title"
|
|
253
263
|
value={draft.title}
|
|
@@ -255,24 +265,24 @@ export function AutomationEditor(props: {
|
|
|
255
265
|
onChange={(e) => change({ title: e.target.value })}
|
|
256
266
|
{...inputState("title")}
|
|
257
267
|
/>
|
|
268
|
+
<FieldError id="title-error">{fieldError("title")}</FieldError>
|
|
258
269
|
</Field>
|
|
259
|
-
<Field
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
error={fieldError("instruction")}
|
|
263
|
-
>
|
|
264
|
-
<TextArea
|
|
265
|
-
prose
|
|
270
|
+
<Field>
|
|
271
|
+
<FieldLabel htmlFor="instruction">Instruction</FieldLabel>
|
|
272
|
+
<Textarea
|
|
266
273
|
id="instruction"
|
|
267
274
|
rows={8}
|
|
268
275
|
value={draft.instruction}
|
|
269
276
|
onChange={(e) => change({ instruction: e.target.value })}
|
|
270
277
|
{...inputState("instruction")}
|
|
271
|
-
className="resize-y text-base sm:text-sm"
|
|
278
|
+
className="resize-y text-base leading-relaxed sm:text-sm"
|
|
272
279
|
/>
|
|
273
280
|
<p className="m-0 text-right text-xs text-dashboard-text-muted">
|
|
274
281
|
{draft.instruction.length.toLocaleString()} / 4,000
|
|
275
282
|
</p>
|
|
283
|
+
<FieldError id="instruction-error">
|
|
284
|
+
{fieldError("instruction")}
|
|
285
|
+
</FieldError>
|
|
276
286
|
</Field>
|
|
277
287
|
</AutomationFormSection>
|
|
278
288
|
<AutomationFormSection
|
|
@@ -304,6 +314,7 @@ export function AutomationEditor(props: {
|
|
|
304
314
|
<AutomationEventFields
|
|
305
315
|
value={draft.trigger ?? original.trigger}
|
|
306
316
|
original={original.trigger}
|
|
317
|
+
disabled={save.isPending}
|
|
307
318
|
onChange={(trigger) => change({ trigger })}
|
|
308
319
|
/>
|
|
309
320
|
)}
|
|
@@ -323,6 +334,7 @@ export function AutomationEditor(props: {
|
|
|
323
334
|
value={draft.outcomes}
|
|
324
335
|
original={original.outcomes}
|
|
325
336
|
destination={props.summary.destination}
|
|
337
|
+
disabled={save.isPending}
|
|
326
338
|
onChange={(outcomes) => change({ outcomes })}
|
|
327
339
|
/>
|
|
328
340
|
) : (
|
|
@@ -341,8 +353,15 @@ export function AutomationEditor(props: {
|
|
|
341
353
|
title="Credentials"
|
|
342
354
|
detail="Choose which connected accounts Junior can use."
|
|
343
355
|
>
|
|
344
|
-
<
|
|
345
|
-
|
|
356
|
+
<RadioGroup
|
|
357
|
+
aria-label="Credential mode"
|
|
358
|
+
disabled={save.isPending}
|
|
359
|
+
className="divide-y divide-dashboard-border-subtle rounded-md border border-dashboard-border-emphasis"
|
|
360
|
+
onValueChange={(credentialMode: "creator" | "system") =>
|
|
361
|
+
change({ credentialMode })
|
|
362
|
+
}
|
|
363
|
+
value={dropsCreatorCredentials ? "system" : draft.credentialMode}
|
|
364
|
+
>
|
|
346
365
|
{(
|
|
347
366
|
[
|
|
348
367
|
[
|
|
@@ -365,24 +384,17 @@ export function AutomationEditor(props: {
|
|
|
365
384
|
).map(([value, label, detail]) => (
|
|
366
385
|
<label
|
|
367
386
|
key={value}
|
|
368
|
-
className="flex cursor-pointer items-start gap-3 px-4 py-4 has-checked:bg-dashboard-fill-soft has-disabled:cursor-not-allowed has-disabled:opacity-60"
|
|
387
|
+
className="flex cursor-pointer items-start gap-3 px-4 py-4 has-data-checked:bg-dashboard-fill-soft has-data-disabled:cursor-not-allowed has-data-disabled:opacity-60"
|
|
369
388
|
>
|
|
370
|
-
<
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
className="mt-0.5 size-4 shrink-0 accent-dashboard-focus"
|
|
374
|
-
checked={
|
|
375
|
-
dropsCreatorCredentials
|
|
376
|
-
? value === "system"
|
|
377
|
-
: draft.credentialMode === value
|
|
378
|
-
}
|
|
389
|
+
<RadioGroupItem
|
|
390
|
+
className="mt-0.5"
|
|
391
|
+
value={value}
|
|
379
392
|
disabled={
|
|
380
393
|
value === "creator" &&
|
|
381
394
|
!owned &&
|
|
382
395
|
(original.credentialMode !== "creator" ||
|
|
383
396
|
dropsCreatorCredentials)
|
|
384
397
|
}
|
|
385
|
-
onChange={() => change({ credentialMode: value })}
|
|
386
398
|
/>
|
|
387
399
|
<span>
|
|
388
400
|
<span className="block text-sm font-medium">{label}</span>
|
|
@@ -392,7 +404,7 @@ export function AutomationEditor(props: {
|
|
|
392
404
|
</span>
|
|
393
405
|
</label>
|
|
394
406
|
))}
|
|
395
|
-
</
|
|
407
|
+
</RadioGroup>
|
|
396
408
|
{dropsCreatorCredentials ? (
|
|
397
409
|
<FormNotice title="Saving switches this automation to system credentials.">
|
|
398
410
|
Only {creator} can let a changed instruction
|
|
@@ -431,7 +443,7 @@ export function AutomationEditor(props: {
|
|
|
431
443
|
</Link>
|
|
432
444
|
<Button
|
|
433
445
|
type="submit"
|
|
434
|
-
|
|
446
|
+
variant="primary"
|
|
435
447
|
className="min-h-11 sm:min-h-9"
|
|
436
448
|
disabled={!dirty || save.isPending || conflict}
|
|
437
449
|
>
|