@parhelia/core 0.1.12772 → 0.1.12775
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/dist/agents-view/AgentsInbox.d.ts +5 -1
- package/dist/agents-view/AgentsInbox.js +5 -3
- package/dist/agents-view/AgentsInbox.js.map +1 -1
- package/dist/agents-view/AgentsView.js +29 -13
- package/dist/agents-view/AgentsView.js.map +1 -1
- package/dist/config/config.js +6 -5
- package/dist/config/config.js.map +1 -1
- package/dist/config/types.d.ts +1 -0
- package/dist/config/types.js.map +1 -1
- package/dist/editor/ai/AgentTerminal.js +85 -12
- package/dist/editor/ai/AgentTerminal.js.map +1 -1
- package/dist/editor/ai/AgentTerminalStatusBar.js +27 -31
- package/dist/editor/ai/AgentTerminalStatusBar.js.map +1 -1
- package/dist/editor/ai/AiResponseMessage.js +2 -2
- package/dist/editor/ai/AiResponseMessage.js.map +1 -1
- package/dist/editor/ai/HeartbeatMessage.js +2 -2
- package/dist/editor/ai/HeartbeatMessage.js.map +1 -1
- package/dist/editor/ai/QueuedPromptsPanel.js +3 -2
- package/dist/editor/ai/QueuedPromptsPanel.js.map +1 -1
- package/dist/editor/ai/SpawnedAgentsPanel.js +2 -2
- package/dist/editor/ai/SpawnedAgentsPanel.js.map +1 -1
- package/dist/editor/ai/TimeWithTooltip.d.ts +9 -0
- package/dist/editor/ai/TimeWithTooltip.js +12 -0
- package/dist/editor/ai/TimeWithTooltip.js.map +1 -0
- package/dist/editor/ai/ToolCallDisplay.js +6 -3
- package/dist/editor/ai/ToolCallDisplay.js.map +1 -1
- package/dist/editor/ai/UserMessage.js +3 -3
- package/dist/editor/ai/UserMessage.js.map +1 -1
- package/dist/editor/ai/agentDiagnostics.js +2 -1
- package/dist/editor/ai/agentDiagnostics.js.map +1 -1
- package/dist/editor/ai/agentDiagnostics.test.js +39 -1
- package/dist/editor/ai/agentDiagnostics.test.js.map +1 -1
- package/dist/editor/ai/agentMessageHelpers.d.ts +1 -0
- package/dist/editor/ai/agentMessageHelpers.js +6 -0
- package/dist/editor/ai/agentMessageHelpers.js.map +1 -1
- package/dist/editor/services/agentService.d.ts +8 -0
- package/dist/editor/services/agentService.js.map +1 -1
- package/dist/editor/services/aiService.d.ts +1 -1
- package/dist/editor/services/aiService.js +3 -2
- package/dist/editor/services/aiService.js.map +1 -1
- package/dist/editor/settings/QuotaInfo.js +29 -60
- package/dist/editor/settings/QuotaInfo.js.map +1 -1
- package/dist/editor/settings/QuotaUserPicker.d.ts +13 -0
- package/dist/editor/settings/QuotaUserPicker.js +58 -0
- package/dist/editor/settings/QuotaUserPicker.js.map +1 -0
- package/dist/editor/settings/SettingsBreadcrumb.d.ts +5 -1
- package/dist/editor/settings/SettingsBreadcrumb.js +3 -3
- package/dist/editor/settings/SettingsBreadcrumb.js.map +1 -1
- package/dist/editor/settings/SettingsHeaderActionsContext.d.ts +3 -0
- package/dist/editor/settings/SettingsHeaderActionsContext.js +11 -0
- package/dist/editor/settings/SettingsHeaderActionsContext.js.map +1 -1
- package/dist/editor/settings/SettingsView.js +5 -3
- package/dist/editor/settings/SettingsView.js.map +1 -1
- package/dist/editor/settings/panels/AgentsPanel.js +2 -4
- package/dist/editor/settings/panels/AgentsPanel.js.map +1 -1
- package/dist/editor/settings/panels/GroupedFieldConfigPanel.js +2 -8
- package/dist/editor/settings/panels/GroupedFieldConfigPanel.js.map +1 -1
- package/dist/editor/settings/panels/ItemConfigPanel.js +1 -1
- package/dist/editor/settings/panels/ItemConfigPanel.js.map +1 -1
- package/dist/editor/settings/panels/ModelsPanel.js +28 -14
- package/dist/editor/settings/panels/ModelsPanel.js.map +1 -1
- package/dist/editor/settings/panels/ProjectTemplateSelector.d.ts +2 -7
- package/dist/editor/settings/panels/ProjectTemplateSelector.js +6 -8
- package/dist/editor/settings/panels/ProjectTemplateSelector.js.map +1 -1
- package/dist/editor/settings/panels/ProjectTemplatesPanel.js +63 -31
- package/dist/editor/settings/panels/ProjectTemplatesPanel.js.map +1 -1
- package/dist/editor/settings/panels/ProviderIcon.d.ts +17 -0
- package/dist/editor/settings/panels/ProviderIcon.js +89 -0
- package/dist/editor/settings/panels/ProviderIcon.js.map +1 -0
- package/dist/editor/settings/panels/ProvidersPanel.js +17 -4
- package/dist/editor/settings/panels/ProvidersPanel.js.map +1 -1
- package/dist/editor/ui/SimpleTabs.js +28 -3
- package/dist/editor/ui/SimpleTabs.js.map +1 -1
- package/dist/revision.d.ts +2 -2
- package/dist/revision.js +2 -2
- package/dist/task-board/TaskBoardWorkspace.js +1 -1
- package/dist/task-board/TaskBoardWorkspace.js.map +1 -1
- package/dist/task-board/components/ProjectDashboard.js +3 -3
- package/dist/task-board/components/ProjectDashboard.js.map +1 -1
- package/dist/task-board/components/ProjectPropertiesPanel.js +1 -1
- package/dist/task-board/components/ProjectPropertiesPanel.js.map +1 -1
- package/dist/task-board/views/DependencyGraphView.js +76 -18
- package/dist/task-board/views/DependencyGraphView.js.map +1 -1
- package/package.json +1 -1
|
@@ -26,7 +26,7 @@ import { cn } from "../../../lib/utils";
|
|
|
26
26
|
import { AgentProfileEditorPanel, } from "./AgentProfileEditorPanel";
|
|
27
27
|
import { ProjectTemplateAgentPanel } from "./ProjectTemplateAgentPanel";
|
|
28
28
|
import { ProjectTemplateSelector } from "./ProjectTemplateSelector";
|
|
29
|
-
import { useRequiredSettingsHeaderActions } from "../SettingsHeaderActionsContext";
|
|
29
|
+
import { useRequiredSettingsBreadcrumbExtra, useRequiredSettingsHeaderActions, } from "../SettingsHeaderActionsContext";
|
|
30
30
|
import { useSearchParams } from "../../client/navigation";
|
|
31
31
|
// Query param for deep-linking the selected project template (settings reload).
|
|
32
32
|
const SELECTED_PROJECT_TEMPLATE_QUERY_PARAM = "projectTemplateId";
|
|
@@ -198,7 +198,7 @@ function buildUpsertTemplateRequest(template) {
|
|
|
198
198
|
disabled: normalizedTask.disabled === true,
|
|
199
199
|
taskType: normalizedTask.taskType ?? "Task",
|
|
200
200
|
decisionMode: normalizedTask.taskType === "DecisionPoint"
|
|
201
|
-
? normalizedTask.decisionMode ?? "MultiSelect"
|
|
201
|
+
? (normalizedTask.decisionMode ?? "MultiSelect")
|
|
202
202
|
: null,
|
|
203
203
|
priority: normalizedTask.priority || null,
|
|
204
204
|
sortOrder: normalizedTask.sortOrder || index * 100,
|
|
@@ -407,6 +407,7 @@ export function ProjectTemplatesPanel() {
|
|
|
407
407
|
const [mobileView, setMobileView] = useState("detail");
|
|
408
408
|
const [editingAgentProfile, setEditingAgentProfile] = useState(null);
|
|
409
409
|
const setSettingsHeaderActions = useRequiredSettingsHeaderActions();
|
|
410
|
+
const setSettingsBreadcrumbExtra = useRequiredSettingsBreadcrumbExtra();
|
|
410
411
|
const autosaveTimeoutRef = useRef(null);
|
|
411
412
|
const lastPersistedSignatureRef = useRef(null);
|
|
412
413
|
const latestDraftSignatureRef = useRef(null);
|
|
@@ -459,8 +460,9 @@ export function ProjectTemplatesPanel() {
|
|
|
459
460
|
return;
|
|
460
461
|
}
|
|
461
462
|
const clonedTemplate = template ? cloneTemplate(template) : null;
|
|
462
|
-
const
|
|
463
|
-
clonedTemplate.id === selectedTemplateIdRef.current
|
|
463
|
+
const isSameTemplate = !!clonedTemplate &&
|
|
464
|
+
clonedTemplate.id === selectedTemplateIdRef.current;
|
|
465
|
+
const preferredTaskId = isSameTemplate
|
|
464
466
|
? selectedTaskIdRef.current
|
|
465
467
|
: null;
|
|
466
468
|
const persistedSignature = clonedTemplate && clonedTemplate.name.trim()
|
|
@@ -472,7 +474,12 @@ export function ProjectTemplatesPanel() {
|
|
|
472
474
|
setDraftTemplate(clonedTemplate);
|
|
473
475
|
setEditingAgentProfile(null);
|
|
474
476
|
setSelectedTaskId(getSelectedTaskIdForTemplate(clonedTemplate, preferredTaskId));
|
|
475
|
-
|
|
477
|
+
// Re-selecting the same template (e.g. via external refresh) must not
|
|
478
|
+
// clobber the user's current tab choice. Only reset the tab when the
|
|
479
|
+
// selected template actually changes.
|
|
480
|
+
if (!isSameTemplate) {
|
|
481
|
+
setActiveDetailTab(clonedTemplate && !clonedTemplate.name.trim() ? "basic" : "tasks");
|
|
482
|
+
}
|
|
476
483
|
setIsDirty(false);
|
|
477
484
|
setSaveError(null);
|
|
478
485
|
lastPersistedSignatureRef.current = persistedSignature;
|
|
@@ -518,7 +525,8 @@ export function ProjectTemplatesPanel() {
|
|
|
518
525
|
? null
|
|
519
526
|
: loadedTemplates[0]?.id || null;
|
|
520
527
|
const nextTemplate = loadedTemplates.find((template) => template.id === nextTemplateId);
|
|
521
|
-
if (options?.preserveDraftIfDirty &&
|
|
528
|
+
if (options?.preserveDraftIfDirty &&
|
|
529
|
+
(savingRef.current || isDirtyRef.current)) {
|
|
522
530
|
return;
|
|
523
531
|
}
|
|
524
532
|
selectTemplate(nextTemplate ?? null);
|
|
@@ -618,12 +626,12 @@ export function ProjectTemplatesPanel() {
|
|
|
618
626
|
}, [dependencyTasks, selectedDependencyId]);
|
|
619
627
|
const headerStatusBadge = useMemo(() => {
|
|
620
628
|
if (saveError) {
|
|
621
|
-
return (_jsx("span", { "data-testid": "project-template-save-status", "data-state": "error", className: "inline-flex min-w-[84px] justify-center rounded bg-red-100 px-1.5
|
|
629
|
+
return (_jsx("span", { "data-testid": "project-template-save-status", "data-state": "error", className: "inline-flex min-w-[84px] justify-center rounded bg-red-100 px-1.5 whitespace-nowrap text-red-700", children: "Save failed" }));
|
|
622
630
|
}
|
|
623
631
|
if (isDirty || saving) {
|
|
624
|
-
return (_jsx("span", { "data-testid": "project-template-save-status", "data-state": "saving", className: "inline-flex min-w-[84px] justify-center rounded bg-amber-100 px-1.5
|
|
632
|
+
return (_jsx("span", { "data-testid": "project-template-save-status", "data-state": "saving", className: "inline-flex min-w-[84px] justify-center rounded bg-amber-100 px-1.5 whitespace-nowrap text-amber-700", children: "Saving..." }));
|
|
625
633
|
}
|
|
626
|
-
return (_jsx("span", { "aria-hidden": "true", "data-testid": "project-template-save-status", "data-state": "saved", className: "pointer-events-none inline-flex min-w-[84px] justify-center rounded px-1.5
|
|
634
|
+
return (_jsx("span", { "aria-hidden": "true", "data-testid": "project-template-save-status", "data-state": "saved", className: "pointer-events-none inline-flex min-w-[84px] justify-center rounded px-1.5 whitespace-nowrap opacity-0 select-none", children: "Saving..." }));
|
|
627
635
|
}, [isDirty, saveError, saving]);
|
|
628
636
|
const graphTasks = useMemo(() => buildTemplateTaskItems(draftTemplate, aiProfilesById), [aiProfilesById, draftTemplate]);
|
|
629
637
|
const graphDependencies = useMemo(() => buildTemplateDependencies(draftTemplate), [draftTemplate]);
|
|
@@ -897,7 +905,9 @@ export function ProjectTemplatesPanel() {
|
|
|
897
905
|
: null;
|
|
898
906
|
draftTemplateRef.current = nextTemplate;
|
|
899
907
|
latestDraftSignatureRef.current = nextSignature;
|
|
900
|
-
setTemplates((existingTemplates) => existingTemplates.map((template) => template.id === nextTemplate.id
|
|
908
|
+
setTemplates((existingTemplates) => existingTemplates.map((template) => template.id === nextTemplate.id
|
|
909
|
+
? cloneTemplate(nextTemplate)
|
|
910
|
+
: template));
|
|
901
911
|
return nextTemplate;
|
|
902
912
|
});
|
|
903
913
|
setIsDirty(true);
|
|
@@ -1549,33 +1559,51 @@ export function ProjectTemplatesPanel() {
|
|
|
1549
1559
|
selectedDependencyId,
|
|
1550
1560
|
selectedTaskId,
|
|
1551
1561
|
]);
|
|
1552
|
-
const templateSelector = useMemo(() => (_jsx(ProjectTemplateSelector, { templates: templates, selectedTemplate: draftTemplate, selectedTemplateId: selectedTemplateId,
|
|
1562
|
+
const templateSelector = useMemo(() => (_jsx(ProjectTemplateSelector, { templates: templates, selectedTemplate: draftTemplate, selectedTemplateId: selectedTemplateId, error: error, deleting: deleting, loading: state === "loading", onSelectTemplate: handleSelectTemplate, onDeleteTemplate: handleDeleteTemplate })), [
|
|
1553
1563
|
deleting,
|
|
1554
1564
|
draftTemplate,
|
|
1555
1565
|
error,
|
|
1556
|
-
handleCreateTemplate,
|
|
1557
1566
|
handleDeleteTemplate,
|
|
1558
|
-
handleRefreshTemplates,
|
|
1559
1567
|
handleSelectTemplate,
|
|
1560
|
-
headerStatusBadge,
|
|
1561
1568
|
selectedTemplateId,
|
|
1562
1569
|
state,
|
|
1563
1570
|
templates,
|
|
1564
1571
|
]);
|
|
1565
|
-
const
|
|
1572
|
+
const desktopBreadcrumbSelector = useMemo(() => !isMobile ? (_jsx("div", { className: "max-w-[32rem] min-w-0", children: templateSelector })) : null, [isMobile, templateSelector]);
|
|
1573
|
+
const desktopHeaderActions = useMemo(() => {
|
|
1574
|
+
if (isMobile)
|
|
1575
|
+
return null;
|
|
1576
|
+
const showDelete = draftTemplate && !draftTemplate.isSystem;
|
|
1577
|
+
return (_jsxs("div", { className: "flex items-center gap-2", children: [headerStatusBadge, _jsxs(Button, { size: "sm", onClick: () => void handleCreateTemplate(), "data-testid": "project-template-create-button", children: [_jsx(Plus, { className: "h-4 w-4", strokeWidth: 1.5 }), "Create new template"] }), showDelete ? (_jsxs(Button, { variant: "outline", size: "sm", onClick: () => handleDeleteTemplate(), disabled: deleting, "data-testid": "project-template-delete-button", children: [_jsx(Trash2, { className: "h-4 w-4", strokeWidth: 1.5 }), deleting ? "Deleting..." : "Delete"] })) : null] }));
|
|
1578
|
+
}, [
|
|
1579
|
+
deleting,
|
|
1580
|
+
draftTemplate,
|
|
1581
|
+
handleCreateTemplate,
|
|
1582
|
+
handleDeleteTemplate,
|
|
1583
|
+
headerStatusBadge,
|
|
1584
|
+
isMobile,
|
|
1585
|
+
]);
|
|
1586
|
+
useEffect(() => {
|
|
1587
|
+
if (!setSettingsBreadcrumbExtra)
|
|
1588
|
+
return;
|
|
1589
|
+
setSettingsBreadcrumbExtra(desktopBreadcrumbSelector);
|
|
1590
|
+
return () => {
|
|
1591
|
+
setSettingsBreadcrumbExtra(null);
|
|
1592
|
+
};
|
|
1593
|
+
}, [desktopBreadcrumbSelector, setSettingsBreadcrumbExtra]);
|
|
1566
1594
|
useEffect(() => {
|
|
1567
1595
|
if (!setSettingsHeaderActions)
|
|
1568
1596
|
return;
|
|
1569
|
-
setSettingsHeaderActions(
|
|
1597
|
+
setSettingsHeaderActions(desktopHeaderActions);
|
|
1570
1598
|
return () => {
|
|
1571
1599
|
setSettingsHeaderActions(null);
|
|
1572
1600
|
};
|
|
1573
|
-
}, [
|
|
1601
|
+
}, [desktopHeaderActions, setSettingsHeaderActions]);
|
|
1574
1602
|
const renderTemplateTaskEditorMain = () => {
|
|
1575
1603
|
if (!draftTemplate) {
|
|
1576
1604
|
return null;
|
|
1577
1605
|
}
|
|
1578
|
-
const graphView = (_jsx("div", { className: "h-full min-h-0 overflow-hidden bg-slate-50/40", "data-testid": "project-template-graph", children: _jsx(DependencyGraphView, { projectId: draftTemplate.id, layoutKey: `project-template:${draftTemplate.id}`, tasks: graphTasks, dependencies: graphDependencies, miniMapWidth:
|
|
1606
|
+
const graphView = (_jsx("div", { className: "h-full min-h-0 overflow-hidden bg-slate-50/40", "data-testid": "project-template-graph", children: _jsx(DependencyGraphView, { projectId: draftTemplate.id, layoutKey: `project-template:${draftTemplate.id}`, tasks: graphTasks, dependencies: graphDependencies, miniMapWidth: 160, miniMapHeight: 120, showMiniMap: !isMobile, orientation: "horizontal", showOrientationToggle: true, autoLayoutStrategy: "hierarchy", savedLayout: draftTemplate.graphLayout, selectedTaskId: selectedTaskId, selectedDependencyId: selectedDependencyId, onSelectTask: handleSelectTask, onSelectDependency: handleSelectDependencyFromGraph, onClearDependencySelection: handleClearDependencySelection, onAddDependentTaskFromNode: (taskId) => {
|
|
1579
1607
|
void handleOpenCreateDependentTaskDialogForTask(taskId);
|
|
1580
1608
|
}, onAddChildTaskFromNode: (taskId) => {
|
|
1581
1609
|
void handleOpenAddChildTaskDialogForTask(taskId);
|
|
@@ -1590,7 +1618,7 @@ export function ProjectTemplatesPanel() {
|
|
|
1590
1618
|
}));
|
|
1591
1619
|
return nextLayout;
|
|
1592
1620
|
} }) }));
|
|
1593
|
-
const taskPane = (_jsx("div", { className: "flex h-full min-h-0 flex-col overflow-hidden", "data-testid": "project-template-task-detail-pane", children: !selectedTask ? (_jsx("div", { className: "min-h-0 flex-1 overflow-y-auto p-4", children: _jsx("div", { className: "rounded-lg border border-dashed border-gray-200 bg-gray-50 p-6 text-center text-xs text-gray-500", children: "Select a task node to edit its details." }) })) : (_jsxs(_Fragment, { children: [_jsx("div", { className: "shrink-0 border-b border-gray-100 bg-white px-4 pt-4 pb-3", children: _jsxs("div", { className: "flex items-center justify-between gap-3", children: [_jsxs("div", { children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "text-xs font-semibold text-gray-900", "data-testid": "project-template-selected-task-title", children: selectedTask.title || "Untitled Task" }), selectedTask.taskType === "DecisionPoint" ? (_jsx(Badge, { variant: "outline", className: "border-violet-200 bg-violet-50 text-[10px]
|
|
1621
|
+
const taskPane = (_jsx("div", { className: "flex h-full min-h-0 flex-col overflow-hidden", "data-testid": "project-template-task-detail-pane", children: !selectedTask ? (_jsx("div", { className: "min-h-0 flex-1 overflow-y-auto p-4", children: _jsx("div", { className: "rounded-lg border border-dashed border-gray-200 bg-gray-50 p-6 text-center text-xs text-gray-500", children: "Select a task node to edit its details." }) })) : (_jsxs(_Fragment, { children: [_jsx("div", { className: "shrink-0 border-b border-gray-100 bg-white px-4 pt-4 pb-3", children: _jsxs("div", { className: "flex items-center justify-between gap-3", children: [_jsxs("div", { children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "text-xs font-semibold text-gray-900", "data-testid": "project-template-selected-task-title", children: selectedTask.title || "Untitled Task" }), selectedTask.taskType === "DecisionPoint" ? (_jsx(Badge, { variant: "outline", className: "border-violet-200 bg-violet-50 text-[10px] text-violet-700 uppercase", children: "Decision Point" })) : null, selectedTask.disabled ? (_jsx(Badge, { variant: "outline", className: "text-[10px] uppercase", children: "Disabled" })) : null] }), _jsx("div", { className: "text-xs text-gray-500", children: "Configure task details, assignment, and dependencies." })] }), _jsxs(Button, { variant: "outline", size: "sm", onClick: handleDeleteSelectedTask, "data-testid": "project-template-remove-task-button", children: [_jsx(Trash2, { className: "h-4 w-4", strokeWidth: 1.5 }), "Remove Task"] })] }) }), _jsx("div", { className: "min-h-0 flex-1 overflow-y-auto px-4 pt-3 pb-4", children: _jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "grid gap-4 md:grid-cols-2", children: [_jsxs("div", { className: "grid gap-1.5 md:col-span-2", children: [_jsx(Label, { className: "text-xs", htmlFor: "project-template-task-title-input", children: "Task title" }), _jsx(Input, { id: "project-template-task-title-input", value: selectedTask.title, onChange: (event) => updateSelectedTask((currentTask) => ({
|
|
1594
1622
|
...currentTask,
|
|
1595
1623
|
title: event.target.value,
|
|
1596
1624
|
})), placeholder: "Task title", className: "text-xs md:text-xs", "data-testid": "project-template-task-title-input" })] }), _jsxs("div", { className: "grid gap-1.5 md:col-span-2", children: [_jsx(Label, { className: "text-xs", children: "Description" }), _jsx(Textarea, { className: "text-xs", value: selectedTask.description ?? "", onChange: (event) => updateSelectedTask((currentTask) => ({
|
|
@@ -1598,9 +1626,11 @@ export function ProjectTemplatesPanel() {
|
|
|
1598
1626
|
description: event.target.value,
|
|
1599
1627
|
})), rows: 4, placeholder: "Describe what this task should accomplish", "data-testid": "project-template-task-description-input" })] }), _jsxs("div", { className: "grid gap-1.5", children: [_jsx(Label, { className: "text-xs", children: "Task type" }), _jsx(Select, { className: "text-xs", value: selectedTask.taskType ?? "Task", onValueChange: (value) => updateSelectedTask((currentTask) => ({
|
|
1600
1628
|
...currentTask,
|
|
1601
|
-
taskType: value === "DecisionPoint"
|
|
1629
|
+
taskType: value === "DecisionPoint"
|
|
1630
|
+
? "DecisionPoint"
|
|
1631
|
+
: "Task",
|
|
1602
1632
|
decisionMode: value === "DecisionPoint"
|
|
1603
|
-
? currentTask.decisionMode ?? "MultiSelect"
|
|
1633
|
+
? (currentTask.decisionMode ?? "MultiSelect")
|
|
1604
1634
|
: null,
|
|
1605
1635
|
})), options: TASK_TYPE_OPTIONS, "data-testid": "project-template-task-type-select" })] }), selectedTask.taskType === "DecisionPoint" ? (_jsxs("div", { className: "grid gap-1.5", children: [_jsx(Label, { className: "text-xs", children: "Decision mode" }), _jsx(Select, { className: "text-xs", value: selectedTask.decisionMode ?? "MultiSelect", onValueChange: (value) => updateSelectedTask((currentTask) => ({
|
|
1606
1636
|
...currentTask,
|
|
@@ -1610,14 +1640,14 @@ export function ProjectTemplatesPanel() {
|
|
|
1610
1640
|
})), options: DECISION_MODE_OPTIONS, "data-testid": "project-template-task-decision-mode-select" })] })) : null, _jsxs("div", { className: "grid gap-1.5", children: [_jsx(Label, { className: "text-xs", children: "Priority" }), _jsx(Select, { className: "text-xs", value: selectedTask.priority ?? "", onValueChange: (value) => updateSelectedTask((currentTask) => ({
|
|
1611
1641
|
...currentTask,
|
|
1612
1642
|
priority: value || null,
|
|
1613
|
-
})), options: PRIORITY_OPTIONS, "data-testid": "project-template-task-priority-select" })] }), selectedTask.taskType === "DecisionPoint" ? (_jsx("div", { className: "grid gap-1.5 md:col-span-2", children: _jsx("div", { className: "rounded-md border border-violet-100 bg-violet-50 px-3 py-2 text-[11px] leading-snug text-violet-800", children: "Direct dependents of this task become selectable option roots when the project is created. Their descendants are materialized only after the Decision Point is resolved at runtime." }) })) : null, _jsxs("div", { className: "grid gap-1.5 md:col-span-2", children: [
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1643
|
+
})), options: PRIORITY_OPTIONS, "data-testid": "project-template-task-priority-select" })] }), selectedTask.taskType === "DecisionPoint" ? (_jsx("div", { className: "grid gap-1.5 md:col-span-2", children: _jsx("div", { className: "rounded-md border border-violet-100 bg-violet-50 px-3 py-2 text-[11px] leading-snug text-violet-800", children: "Direct dependents of this task become selectable option roots when the project is created. Their descendants are materialized only after the Decision Point is resolved at runtime." }) })) : null, _jsxs("div", { className: "grid gap-1.5 md:col-span-2", children: [_jsx(Label, { className: "text-xs", children: "Default assignee" }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "min-w-0 flex-1", children: _jsx(TaskAssigneePicker, { projectTemplateId: draftTemplate.id, assigneeType: selectedTask.assigneeType ?? null, value: selectedTask.assigneeId ?? null, displayValue: selectedTaskAssigneeDisplayValue, onChange: (next) => updateSelectedTask((currentTask) => ({
|
|
1644
|
+
...currentTask,
|
|
1645
|
+
assigneeType: next?.assigneeType ?? null,
|
|
1646
|
+
assigneeId: next?.assigneeId ?? null,
|
|
1647
|
+
agentProfileId: next?.assigneeType === "Agent"
|
|
1648
|
+
? next.assigneeId
|
|
1649
|
+
: null,
|
|
1650
|
+
})), placeholder: "Assign user or agent", buttonClassName: "h-[27px] w-full justify-between rounded-md bg-gray-5 text-xs", buttonTestId: "project-template-task-assignee-picker" }) }), selectedTask.assigneeType === "Agent" ? (_jsxs(Button, { type: "button", size: "sm", variant: "outline", className: "h-[27px] shrink-0 gap-1 px-2 text-xs", onClick: () => void handleEditAssignedAgentProfile(), disabled: !selectedAgentProfileId, "data-testid": "project-template-task-edit-agent-profile-button", children: [_jsx(Settings2, { className: "h-3.5 w-3.5", strokeWidth: 1.5 }), "Edit Profile"] })) : null] }), profilesError ? (_jsx("div", { className: "text-xs text-amber-700", children: profilesError })) : null] })] }), _jsxs("div", { className: "space-y-3", children: [_jsxs("div", { className: "rounded-lg border border-gray-200 bg-gray-50 p-3", "data-testid": "project-template-dependencies-section", children: [_jsxs("div", { className: "mb-2 flex items-center justify-between gap-2", children: [_jsxs("div", { className: "flex items-center gap-2 text-xs font-medium text-gray-800", children: [_jsx(Shield, { className: "h-4 w-4 text-gray-500", strokeWidth: 1.5 }), "Dependencies"] }), _jsxs(Popover, { open: dependencyPickerOpen, onOpenChange: setDependencyPickerOpen, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx(Button, { type: "button", size: "sm", variant: "outline", className: "h-7 gap-1 px-2", disabled: dependencyAddCandidates.length === 0, "aria-label": "Add dependency", "data-testid": "project-template-add-dependency-button", children: _jsx(Plus, { className: "h-3.5 w-3.5", strokeWidth: 1.5 }) }) }), _jsxs(PopoverContent, { align: "end", className: "w-72 p-0", sideOffset: 6, "data-testid": "project-template-dependency-popover", children: [_jsx("div", { className: "border-b border-gray-100 px-3 py-2 text-xs font-medium text-gray-700", children: "Depends on" }), _jsx("div", { className: "max-h-56 overflow-y-auto p-1", children: dependencyAddCandidates.length === 0 ? (_jsx("div", { className: "px-2 py-3 text-center text-xs text-gray-500", children: "All other tasks are already linked." })) : (dependencyAddCandidates.map((task) => (_jsxs("button", { type: "button", className: "flex w-full items-center gap-2 rounded-md px-2 py-2 text-left text-xs hover:bg-gray-100", onClick: () => handleAddDependency(task.id), "data-testid": `project-template-dependency-option-${task.id}`, children: [_jsx(Link2, { className: "h-3.5 w-3.5 shrink-0 text-gray-400", strokeWidth: 1.5 }), _jsx("span", { className: "min-w-0 truncate font-medium text-gray-900", children: task.title || "Untitled Task" })] }, task.id)))) })] })] })] }), _jsx("p", { className: "mb-2 text-[11px] leading-snug text-gray-500", children: "This task must wait for these tasks to finish first." }), dependencyTasks.length === 0 ? (_jsx("div", { className: "text-xs text-gray-500", children: draftTemplate.taskTemplates.filter((t) => t.id !== selectedTask.id).length === 0
|
|
1621
1651
|
? "Add more task templates to create dependencies."
|
|
1622
1652
|
: "No dependencies yet. Use + to add one." })) : (_jsx("ul", { className: "space-y-1.5", children: dependencyTasks.map((task) => (_jsxs("li", { tabIndex: 0, className: cn("flex items-center justify-between gap-2 rounded-md border bg-white px-3 py-2 text-xs transition-colors outline-none", selectedDependencyId === task.id
|
|
1623
1653
|
? "border-amber-300 bg-amber-50 ring-1 ring-amber-200"
|
|
@@ -1693,7 +1723,9 @@ export function ProjectTemplatesPanel() {
|
|
|
1693
1723
|
openInWizardMode: checked,
|
|
1694
1724
|
})), "aria-label": "Open new projects from this template in wizard mode", "data-testid": "project-template-open-in-wizard-mode-switch" })] })] }));
|
|
1695
1725
|
const taskEditorContent = (_jsx("div", { className: "flex h-full min-h-0 flex-1 flex-col overflow-hidden", children: renderTemplateTaskEditorMain() }));
|
|
1696
|
-
return (_jsxs("div", { className: "flex min-h-0 flex-1 flex-col overflow-y-auto overscroll-y-contain p-5 md:overflow-hidden", children: [_jsx("div", { className: "flex shrink-0 flex-col gap-5 md:max-h-[50vh] md:min-h-0 md:overflow-y-auto md:overscroll-y-contain", children: saveError && (_jsx("div", { className: "rounded border border-red-200 bg-red-50 px-4 py-3 text-xs text-red-700", children: saveError })) }), _jsxs("section", { className: "flex min-h-0 flex-1 flex-col rounded-lg border border-gray-200 bg-white shadow-sm md:overflow-hidden", children: [_jsxs("div", { className: "flex shrink-0 items-center justify-between gap-3 border-b border-gray-100 px-
|
|
1726
|
+
return (_jsxs("div", { className: "flex min-h-0 flex-1 flex-col overflow-y-auto overscroll-y-contain p-5 md:overflow-hidden", children: [_jsx("div", { className: "flex shrink-0 flex-col gap-5 md:max-h-[50vh] md:min-h-0 md:overflow-y-auto md:overscroll-y-contain", children: saveError && (_jsx("div", { className: "rounded border border-red-200 bg-red-50 px-4 py-3 text-xs text-red-700", children: saveError })) }), _jsxs("section", { className: "flex min-h-0 flex-1 flex-col rounded-lg border border-gray-200 bg-white shadow-sm md:overflow-hidden", children: [_jsxs("div", { className: "flex shrink-0 items-center justify-between gap-3 border-b border-gray-100 px-2 py-1", children: [_jsx("div", { className: "min-w-0 flex-1", children: _jsx(SimpleTabs, { tabs: detailTabs, activeTab: activeDetailTab === "basic" ? 0 : 1, setActiveTab: (index) => setActiveDetailTab(index === 0 ? "basic" : "tasks"), hideContent: true, variant: "elegant", className: "w-full justify-start gap-6" }) }), _jsxs(Button, { size: "sm", variant: "outline", onClick: () => void handleOpenCreateTaskDialog(), disabled: creatingTask, "data-testid": "project-template-add-task-button", className: activeDetailTab === "tasks"
|
|
1727
|
+
? ""
|
|
1728
|
+
: "pointer-events-none invisible", "aria-hidden": activeDetailTab !== "tasks", tabIndex: activeDetailTab === "tasks" ? undefined : -1, children: [_jsx(Plus, { className: "h-4 w-4", strokeWidth: 1.5 }), "Add Task"] })] }), _jsx("div", { className: "flex min-h-0 flex-1 flex-col overflow-hidden", children: activeDetailTab === "basic"
|
|
1697
1729
|
? basicSettingsContent
|
|
1698
1730
|
: taskEditorContent })] })] }));
|
|
1699
1731
|
})()) : (_jsx("div", { className: "flex min-h-0 flex-1 items-center justify-center p-5", children: _jsxs("div", { className: "max-w-sm rounded-lg border border-dashed border-gray-300 bg-white p-8 text-center", children: [_jsx(GitBranch, { className: "mx-auto mb-3 h-10 w-10 text-gray-300", strokeWidth: 1.2 }), _jsx("h3", { className: "text-xs font-semibold text-gray-900", children: "Select a project template" }), _jsx("p", { className: "mt-1 text-xs text-gray-500", children: "Choose a template from the dropdown or create a new one to start editing." })] }) }))] }));
|
|
@@ -1719,7 +1751,7 @@ export function ProjectTemplatesPanel() {
|
|
|
1719
1751
|
hidden: isMobile && mobileView !== "agent",
|
|
1720
1752
|
},
|
|
1721
1753
|
];
|
|
1722
|
-
return (_jsxs(_Fragment, { children: [_jsx("div", { className: "h-full", "data-testid": "project-template-editor", onKeyDownCapture: handleProjectTemplateEditorKeyDownCapture, children: _jsx(Splitter, { panels: panels, localStorageKey: "settings-project-templates-panel-splitter-v3", direction: "horizontal", className: "h-full" }) }), _jsx(Dialog, { open: isCreateTaskDialogOpen, onOpenChange: (open) => {
|
|
1754
|
+
return (_jsxs(_Fragment, { children: [_jsx("div", { className: "h-full", "data-testid": "project-template-editor", onKeyDownCapture: handleProjectTemplateEditorKeyDownCapture, children: _jsx(Splitter, { panels: panels, localStorageKey: "settings-project-templates-panel-splitter-v3", direction: "horizontal", className: "h-full", forceExpandLastPanelKey: editingAgentProfile?.id ?? null }) }), _jsx(Dialog, { open: isCreateTaskDialogOpen, onOpenChange: (open) => {
|
|
1723
1755
|
setIsCreateTaskDialogOpen(open);
|
|
1724
1756
|
if (!open) {
|
|
1725
1757
|
setNewTaskDependencySourceId(null);
|