@parhelia/core 0.3.12788 → 0.3.12791

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.
Files changed (176) hide show
  1. package/dist/components/ui/LanguageSelector.js +4 -1
  2. package/dist/components/ui/LanguageSelector.js.map +1 -1
  3. package/dist/components/ui/select.js +12 -1
  4. package/dist/components/ui/select.js.map +1 -1
  5. package/dist/editor/FieldHistory.js +2 -2
  6. package/dist/editor/FieldHistory.js.map +1 -1
  7. package/dist/editor/ai/InlineAiDialog.js +35 -8
  8. package/dist/editor/ai/InlineAiDialog.js.map +1 -1
  9. package/dist/editor/ai/terminal/components/AgentProjectProgress.d.ts +4 -3
  10. package/dist/editor/ai/terminal/components/AgentProjectProgress.js +34 -50
  11. package/dist/editor/ai/terminal/components/AgentProjectProgress.js.map +1 -1
  12. package/dist/editor/ai/terminal/components/AgentTerminalView.d.ts +2 -1
  13. package/dist/editor/ai/terminal/components/AgentTerminalView.js +2 -2
  14. package/dist/editor/ai/terminal/components/AgentTerminalView.js.map +1 -1
  15. package/dist/editor/ai/terminal/useAgentTerminalController.js +1 -0
  16. package/dist/editor/ai/terminal/useAgentTerminalController.js.map +1 -1
  17. package/dist/editor/ai/terminal/useAgentTerminalViewProps.d.ts +1 -0
  18. package/dist/editor/ai/terminal/useAgentTerminalViewProps.js +2 -1
  19. package/dist/editor/ai/terminal/useAgentTerminalViewProps.js.map +1 -1
  20. package/dist/editor/bridge/protocol.d.ts +4 -0
  21. package/dist/editor/bridge/protocol.js +1 -0
  22. package/dist/editor/bridge/protocol.js.map +1 -1
  23. package/dist/editor/client/EditorShell.js +174 -65
  24. package/dist/editor/client/EditorShell.js.map +1 -1
  25. package/dist/editor/client/editContext.d.ts +13 -3
  26. package/dist/editor/client/editContext.js.map +1 -1
  27. package/dist/editor/client/hooks/activeSessionSnapshots.d.ts +2 -0
  28. package/dist/editor/client/hooks/activeSessionSnapshots.js +43 -0
  29. package/dist/editor/client/hooks/activeSessionSnapshots.js.map +1 -0
  30. package/dist/editor/client/hooks/feedbackSocketState.js +3 -0
  31. package/dist/editor/client/hooks/feedbackSocketState.js.map +1 -1
  32. package/dist/editor/client/hooks/operationRefreshDeduplication.d.ts +22 -0
  33. package/dist/editor/client/hooks/operationRefreshDeduplication.js +45 -0
  34. package/dist/editor/client/hooks/operationRefreshDeduplication.js.map +1 -0
  35. package/dist/editor/client/hooks/socketMessageRetention.d.ts +7 -0
  36. package/dist/editor/client/hooks/socketMessageRetention.js +11 -0
  37. package/dist/editor/client/hooks/socketMessageRetention.js.map +1 -0
  38. package/dist/editor/client/hooks/useSocketMessageHandler.js +39 -19
  39. package/dist/editor/client/hooks/useSocketMessageHandler.js.map +1 -1
  40. package/dist/editor/client/hooks/useWorkbox.d.ts +4 -0
  41. package/dist/editor/client/hooks/useWorkbox.js +132 -2
  42. package/dist/editor/client/hooks/useWorkbox.js.map +1 -1
  43. package/dist/editor/client/itemsRepository.d.ts +7 -1
  44. package/dist/editor/client/itemsRepository.js +41 -18
  45. package/dist/editor/client/itemsRepository.js.map +1 -1
  46. package/dist/editor/client/operations.d.ts +7 -3
  47. package/dist/editor/client/operations.js +216 -150
  48. package/dist/editor/client/operations.js.map +1 -1
  49. package/dist/editor/client/pageModelBuilder.js +15 -3
  50. package/dist/editor/client/pageModelBuilder.js.map +1 -1
  51. package/dist/editor/client/sidebarAvailability.d.ts +4 -0
  52. package/dist/editor/client/sidebarAvailability.js +15 -0
  53. package/dist/editor/client/sidebarAvailability.js.map +1 -1
  54. package/dist/editor/commands/itemCommands.js +1 -1
  55. package/dist/editor/commands/itemCommands.js.map +1 -1
  56. package/dist/editor/field-types/RichTextEditorComponent.js +6 -1
  57. package/dist/editor/field-types/RichTextEditorComponent.js.map +1 -1
  58. package/dist/editor/field-types/SingleLineText.js +2 -3
  59. package/dist/editor/field-types/SingleLineText.js.map +1 -1
  60. package/dist/editor/field-types/richtext/components/ReactSlate.d.ts +6 -1
  61. package/dist/editor/field-types/richtext/components/ReactSlate.js +91 -5
  62. package/dist/editor/field-types/richtext/components/ReactSlate.js.map +1 -1
  63. package/dist/editor/field-types/singleLineTextValue.d.ts +3 -0
  64. package/dist/editor/field-types/singleLineTextValue.js +9 -0
  65. package/dist/editor/field-types/singleLineTextValue.js.map +1 -0
  66. package/dist/editor/menubar/ItemLanguageVersion.js +1 -1
  67. package/dist/editor/menubar/ItemLanguageVersion.js.map +1 -1
  68. package/dist/editor/menubar/VersionSelector.js +18 -6
  69. package/dist/editor/menubar/VersionSelector.js.map +1 -1
  70. package/dist/editor/menubar/WorkflowButton.js +8 -3
  71. package/dist/editor/menubar/WorkflowButton.js.map +1 -1
  72. package/dist/editor/menubar/toolbar-sections/EditControls.js +1 -1
  73. package/dist/editor/menubar/toolbar-sections/EditControls.js.map +1 -1
  74. package/dist/editor/notifications/NotificationCenter.js +26 -7
  75. package/dist/editor/notifications/NotificationCenter.js.map +1 -1
  76. package/dist/editor/notifications/useNotifications.d.ts +3 -1
  77. package/dist/editor/notifications/useNotifications.js +27 -9
  78. package/dist/editor/notifications/useNotifications.js.map +1 -1
  79. package/dist/editor/page-editor-chrome/BridgeInlineFormatOverlay.js +18 -0
  80. package/dist/editor/page-editor-chrome/BridgeInlineFormatOverlay.js.map +1 -1
  81. package/dist/editor/page-editor-chrome/InlineFieldHistoryButton.js +30 -8
  82. package/dist/editor/page-editor-chrome/InlineFieldHistoryButton.js.map +1 -1
  83. package/dist/editor/page-editor-chrome/VersionDiffHighlightings.js +30 -8
  84. package/dist/editor/page-editor-chrome/VersionDiffHighlightings.js.map +1 -1
  85. package/dist/editor/page-editor-chrome/useBridgeInlineEditing.d.ts +5 -3
  86. package/dist/editor/page-editor-chrome/useBridgeInlineEditing.js +111 -19
  87. package/dist/editor/page-editor-chrome/useBridgeInlineEditing.js.map +1 -1
  88. package/dist/editor/page-viewer/EditorForm.d.ts +2 -1
  89. package/dist/editor/page-viewer/EditorForm.js +41 -12
  90. package/dist/editor/page-viewer/EditorForm.js.map +1 -1
  91. package/dist/editor/page-viewer/PageViewer.d.ts +2 -0
  92. package/dist/editor/page-viewer/PageViewer.js +11 -2
  93. package/dist/editor/page-viewer/PageViewer.js.map +1 -1
  94. package/dist/editor/page-viewer/PageViewerFrame.js +237 -42
  95. package/dist/editor/page-viewer/PageViewerFrame.js.map +1 -1
  96. package/dist/editor/page-viewer/bridgeInlineAiSelection.d.ts +17 -0
  97. package/dist/editor/page-viewer/bridgeInlineAiSelection.js +80 -0
  98. package/dist/editor/page-viewer/bridgeInlineAiSelection.js.map +1 -0
  99. package/dist/editor/page-viewer/bridgeInlineEditCommit.d.ts +18 -0
  100. package/dist/editor/page-viewer/bridgeInlineEditCommit.js +24 -0
  101. package/dist/editor/page-viewer/bridgeInlineEditCommit.js.map +1 -0
  102. package/dist/editor/page-viewer/bridgeInlineEditSession.d.ts +3 -0
  103. package/dist/editor/page-viewer/bridgeInlineEditSession.js +30 -0
  104. package/dist/editor/page-viewer/bridgeInlineEditSession.js.map +1 -1
  105. package/dist/editor/page-viewer/bridgeItemChangeTarget.d.ts +9 -0
  106. package/dist/editor/page-viewer/bridgeItemChangeTarget.js +38 -0
  107. package/dist/editor/page-viewer/bridgeItemChangeTarget.js.map +1 -0
  108. package/dist/editor/page-viewer/bridgePointerDragRelease.d.ts +31 -0
  109. package/dist/editor/page-viewer/bridgePointerDragRelease.js +32 -0
  110. package/dist/editor/page-viewer/bridgePointerDragRelease.js.map +1 -0
  111. package/dist/editor/page-viewer/renderUrl.d.ts +8 -0
  112. package/dist/editor/page-viewer/renderUrl.js +10 -0
  113. package/dist/editor/page-viewer/renderUrl.js.map +1 -1
  114. package/dist/editor/personalization/PersonalizationPanel.js +52 -25
  115. package/dist/editor/personalization/PersonalizationPanel.js.map +1 -1
  116. package/dist/editor/reviews/Comment.js +3 -1
  117. package/dist/editor/reviews/Comment.js.map +1 -1
  118. package/dist/editor/reviews/CommentDisplayPopover.js +2 -0
  119. package/dist/editor/reviews/CommentDisplayPopover.js.map +1 -1
  120. package/dist/editor/reviews/Comments.js +16 -3
  121. package/dist/editor/reviews/Comments.js.map +1 -1
  122. package/dist/editor/reviews/SuggestedEdit.js +25 -2
  123. package/dist/editor/reviews/SuggestedEdit.js.map +1 -1
  124. package/dist/editor/reviews/SuggestionCommentThread.js +2 -0
  125. package/dist/editor/reviews/SuggestionCommentThread.js.map +1 -1
  126. package/dist/editor/reviews/applySuggestedEditActions.js +105 -25
  127. package/dist/editor/reviews/applySuggestedEditActions.js.map +1 -1
  128. package/dist/editor/reviews/commentState.d.ts +4 -0
  129. package/dist/editor/reviews/commentState.js +15 -0
  130. package/dist/editor/reviews/commentState.js.map +1 -0
  131. package/dist/editor/reviews/feedbackOrdering.d.ts +1 -0
  132. package/dist/editor/reviews/feedbackOrdering.js +6 -0
  133. package/dist/editor/reviews/feedbackOrdering.js.map +1 -1
  134. package/dist/editor/reviews/suggestionContentChange.d.ts +7 -0
  135. package/dist/editor/reviews/suggestionContentChange.js +10 -0
  136. package/dist/editor/reviews/suggestionContentChange.js.map +1 -1
  137. package/dist/editor/reviews/suggestionPatch.js +6 -0
  138. package/dist/editor/reviews/suggestionPatch.js.map +1 -1
  139. package/dist/editor/services/personalizationService.js +30 -6
  140. package/dist/editor/services/personalizationService.js.map +1 -1
  141. package/dist/editor/services/suggestedEditsService.d.ts +1 -0
  142. package/dist/editor/services/suggestedEditsService.js +3 -0
  143. package/dist/editor/services/suggestedEditsService.js.map +1 -1
  144. package/dist/editor/settings/SettingsView.js +15 -7
  145. package/dist/editor/settings/SettingsView.js.map +1 -1
  146. package/dist/editor/settings/panels/MemoriesPanel.js +3 -2
  147. package/dist/editor/settings/panels/MemoriesPanel.js.map +1 -1
  148. package/dist/editor/settings/panels/ProjectTemplatesPanel.d.ts +3 -0
  149. package/dist/editor/settings/panels/ProjectTemplatesPanel.js +84 -15
  150. package/dist/editor/settings/panels/ProjectTemplatesPanel.js.map +1 -1
  151. package/dist/editor/settings/panels/projectTemplateDuplication.d.ts +5 -0
  152. package/dist/editor/settings/panels/projectTemplateDuplication.js +52 -0
  153. package/dist/editor/settings/panels/projectTemplateDuplication.js.map +1 -0
  154. package/dist/editor/ui/PerfectTree.js +2 -2
  155. package/dist/editor/ui/PerfectTree.js.map +1 -1
  156. package/dist/editor/ui/PublishRestrictionsDialog.js +9 -1
  157. package/dist/editor/ui/PublishRestrictionsDialog.js.map +1 -1
  158. package/dist/editor/utils.js +5 -2
  159. package/dist/editor/utils.js.map +1 -1
  160. package/dist/editor/views/EditorSlot.js +5 -1
  161. package/dist/editor/views/EditorSlot.js.map +1 -1
  162. package/dist/editor/views/SingleEditView.d.ts +4 -1
  163. package/dist/editor/views/SingleEditView.js +2 -2
  164. package/dist/editor/views/SingleEditView.js.map +1 -1
  165. package/dist/licensing/LicenseContext.js +7 -0
  166. package/dist/licensing/LicenseContext.js.map +1 -1
  167. package/dist/revision.d.ts +2 -2
  168. package/dist/revision.js +2 -2
  169. package/dist/task-board/TaskBoardWorkspace.js +5 -1
  170. package/dist/task-board/TaskBoardWorkspace.js.map +1 -1
  171. package/dist/task-board/taskExecutionRecords.js +7 -0
  172. package/dist/task-board/taskExecutionRecords.js.map +1 -1
  173. package/dist/task-board/views/DependencyGraphView.d.ts +1 -0
  174. package/dist/task-board/views/DependencyGraphView.js +15 -12
  175. package/dist/task-board/views/DependencyGraphView.js.map +1 -1
  176. package/package.json +1 -1
@@ -1,3 +1,6 @@
1
1
  import React from "react";
2
+ export declare function readProjectTemplateIdFromUrl(searchParams: {
3
+ get: (name: string) => string | null;
4
+ }): string | null;
2
5
  export declare function ProjectTemplatesPanel(): React.JSX.Element;
3
6
  export default ProjectTemplatesPanel;
@@ -32,6 +32,7 @@ import { isTypingEventTarget } from "../../utils/keyboardNavigation";
32
32
  import { useRequiredSettingsBreadcrumbItems, useRequiredSettingsHeaderActions, useRequiredSettingsMainContentRef, } from "../SettingsHeaderActionsContext";
33
33
  import { AgentProfileEditorPanel, } from "./AgentProfileEditorPanel";
34
34
  import { ProjectTemplateAgentPanel } from "./ProjectTemplateAgentPanel";
35
+ import { duplicateProjectTemplate, getDuplicateProjectTemplateName, } from "./projectTemplateDuplication";
35
36
  import { ProjectTemplateSelector } from "./ProjectTemplateSelector";
36
37
  import { ProjectTemplateSelectorList } from "./ProjectTemplateSelectorList";
37
38
  // Query param for deep-linking the selected project template (settings reload).
@@ -372,19 +373,15 @@ function isValidGuid(value) {
372
373
  return (!!value &&
373
374
  /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value));
374
375
  }
375
- function readProjectTemplateIdFromUrl(searchParams) {
376
- const raw = searchParams.get(SELECTED_PROJECT_TEMPLATE_QUERY_PARAM) ||
377
- (typeof window !== "undefined"
378
- ? new URLSearchParams(window.location.search).get(SELECTED_PROJECT_TEMPLATE_QUERY_PARAM)
379
- : null);
380
- return raw && isValidGuid(raw) ? raw : null;
381
- }
382
- function readProjectTemplateIdFromWindow() {
376
+ export function readProjectTemplateIdFromUrl(searchParams) {
383
377
  const raw = typeof window !== "undefined"
384
378
  ? new URLSearchParams(window.location.search).get(SELECTED_PROJECT_TEMPLATE_QUERY_PARAM)
385
- : null;
379
+ : searchParams.get(SELECTED_PROJECT_TEMPLATE_QUERY_PARAM);
386
380
  return raw && isValidGuid(raw) ? raw : null;
387
381
  }
382
+ function readProjectTemplateIdFromWindow() {
383
+ return readProjectTemplateIdFromUrl(new URLSearchParams());
384
+ }
388
385
  function getSelectedTaskIdForTemplate(template, preferredTaskId) {
389
386
  const taskTemplates = template?.taskTemplates ?? [];
390
387
  if (!taskTemplates.length) {
@@ -1341,13 +1338,10 @@ export function ProjectTemplatesPanel() {
1341
1338
  }
1342
1339
  setEditingAgentProfile(null);
1343
1340
  selectTemplate(null);
1344
- editContext?.updateUrl({
1345
- [SELECTED_PROJECT_TEMPLATE_QUERY_PARAM]: undefined,
1346
- });
1347
1341
  if (isMobile) {
1348
1342
  setMobileView("detail");
1349
1343
  }
1350
- }, [editContext, flushPendingSave, isMobile, selectTemplate]);
1344
+ }, [flushPendingSave, isMobile, selectTemplate]);
1351
1345
  useEffect(() => {
1352
1346
  if (autosaveTimeoutRef.current !== null) {
1353
1347
  window.clearTimeout(autosaveTimeoutRef.current);
@@ -1532,6 +1526,79 @@ export function ProjectTemplatesPanel() {
1532
1526
  }
1533
1527
  await persistTemplate(request, signature, { showErrorToast: true });
1534
1528
  }, [editContext, flushPendingSave, isMobile, persistTemplate, templates]);
1529
+ const handleDuplicateTemplate = useCallback(async () => {
1530
+ const canContinue = await flushPendingSave({ showErrorToast: true });
1531
+ if (!canContinue) {
1532
+ return;
1533
+ }
1534
+ const sourceTemplate = draftTemplateRef.current ?? draftTemplate;
1535
+ if (!sourceTemplate) {
1536
+ return;
1537
+ }
1538
+ const suggestedName = getDuplicateProjectTemplateName(sourceTemplate.name, templates.map((template) => template.name));
1539
+ let templateName = null;
1540
+ if (editContext) {
1541
+ templateName = await editContext.openDialog(ItemNameDialog, {
1542
+ name: suggestedName,
1543
+ title: "Duplicate Project Template",
1544
+ message: "Enter a name for the duplicated template:",
1545
+ headerIcon: _jsx(CopyPlus, { strokeWidth: 1 }),
1546
+ });
1547
+ }
1548
+ else {
1549
+ templateName = window.prompt("Enter a name for the duplicated template:", suggestedName);
1550
+ }
1551
+ if (templateName == null) {
1552
+ return;
1553
+ }
1554
+ const trimmedName = templateName.trim();
1555
+ if (!trimmedName) {
1556
+ return;
1557
+ }
1558
+ const nameLower = trimmedName.toLowerCase();
1559
+ if (templates.some((t) => t.name.trim().toLowerCase() === nameLower)) {
1560
+ toast.error("A project template with this name already exists");
1561
+ return;
1562
+ }
1563
+ const nextTemplate = duplicateProjectTemplate(sourceTemplate, trimmedName);
1564
+ const request = buildUpsertTemplateRequest(nextTemplate);
1565
+ const signature = JSON.stringify(request);
1566
+ if (autosaveTimeoutRef.current !== null) {
1567
+ window.clearTimeout(autosaveTimeoutRef.current);
1568
+ autosaveTimeoutRef.current = null;
1569
+ }
1570
+ selectedTemplateIdRef.current = nextTemplate.id;
1571
+ draftTemplateRef.current = nextTemplate;
1572
+ latestDraftSignatureRef.current = signature;
1573
+ setTemplates((current) => sortTemplates([nextTemplate, ...current]));
1574
+ setSelectedTemplateId(nextTemplate.id);
1575
+ setDraftTemplate(cloneTemplate(nextTemplate));
1576
+ setSelectedTaskId(getSelectedTaskIdForTemplate(nextTemplate, null));
1577
+ setSelectedGoalId(null);
1578
+ setIsDirty(true);
1579
+ setSaveError(null);
1580
+ lastPersistedSignatureRef.current = null;
1581
+ latestDraftSignatureRef.current = null;
1582
+ editContext?.updateUrl({
1583
+ [SELECTED_PROJECT_TEMPLATE_QUERY_PARAM]: nextTemplate.id,
1584
+ });
1585
+ if (isMobile) {
1586
+ setMobileView("detail");
1587
+ }
1588
+ const didPersist = await persistTemplate(request, signature, {
1589
+ showErrorToast: true,
1590
+ });
1591
+ if (didPersist) {
1592
+ toast.success("Project template duplicated");
1593
+ }
1594
+ }, [
1595
+ draftTemplate,
1596
+ editContext,
1597
+ flushPendingSave,
1598
+ isMobile,
1599
+ persistTemplate,
1600
+ templates,
1601
+ ]);
1535
1602
  const handleDeleteTemplate = useCallback((templateToDelete) => {
1536
1603
  const template = templateToDelete ?? draftTemplate;
1537
1604
  if (!template || template.isSystem)
@@ -2112,17 +2179,19 @@ export function ProjectTemplatesPanel() {
2112
2179
  : 0;
2113
2180
  return (_jsxs("div", { className: "mt-2 flex items-center gap-2", style: agentPanelHeaderOffset > 0
2114
2181
  ? { marginRight: agentPanelHeaderOffset }
2115
- : undefined, children: [headerStatusBadge, showCreate ? (_jsxs(Button, { size: "sm", onClick: () => void handleCreateTemplate(), "data-testid": "project-template-create-button", children: [_jsx(Plus, { className: "h-4 w-4", strokeWidth: 1 }), "Create template"] })) : null, showDelete ? (_jsxs(Button, { variant: "outline", size: "sm", onClick: () => handleDeleteTemplate(), disabled: deleting, "data-testid": "project-template-delete-button", children: [_jsx(DeleteIcon, { size: "lg" }), deleting ? "Deleting..." : "Delete"] })) : null] }));
2182
+ : undefined, children: [headerStatusBadge, showCreate ? (_jsxs(Button, { size: "sm", onClick: () => void handleCreateTemplate(), "data-testid": "project-template-create-button", children: [_jsx(Plus, { className: "h-4 w-4", strokeWidth: 1 }), "Create template"] })) : null, draftTemplate ? (_jsxs(Button, { variant: "outline", size: "sm", onClick: () => void handleDuplicateTemplate(), disabled: saving || deleting, "data-testid": "project-template-duplicate-button", children: [_jsx(CopyPlus, { className: "h-4 w-4", strokeWidth: 1 }), "Duplicate"] })) : null, showDelete ? (_jsxs(Button, { variant: "outline", size: "sm", onClick: () => handleDeleteTemplate(), disabled: deleting, "data-testid": "project-template-delete-button", children: [_jsx(DeleteIcon, { size: "lg" }), deleting ? "Deleting..." : "Delete"] })) : null] }));
2116
2183
  }, [
2117
2184
  agentPanelBounds,
2118
2185
  deleting,
2119
2186
  draftTemplate,
2120
2187
  handleCreateTemplate,
2121
2188
  handleDeleteTemplate,
2189
+ handleDuplicateTemplate,
2122
2190
  headerStatusBadge,
2123
2191
  isAgentPanelCollapsed,
2124
2192
  isTaskEditorMaximized,
2125
2193
  isMobile,
2194
+ saving,
2126
2195
  ]);
2127
2196
  useEffect(() => {
2128
2197
  if (!setSettingsBreadcrumbItems)
@@ -2228,7 +2297,7 @@ export function ProjectTemplatesPanel() {
2228
2297
  : []),
2229
2298
  ] }) }));
2230
2299
  };
2231
- const detailContent = (_jsxs("div", { className: "bg-neutral-grey-5/40 flex h-full flex-col", "data-testid": "project-template-detail-pane", children: [isMobile && draftTemplate && !draftTemplate.isSystem ? (_jsxs("div", { className: "border-border-default flex min-w-0 items-center gap-3 border-b bg-white px-5 py-2", "data-testid": "project-template-detail-pane-header", children: [_jsx("div", { className: "min-w-0 flex-1", children: templateSelector }), _jsx("div", { className: "flex shrink-0 items-center gap-1.5 self-center", children: _jsx(Button, { variant: "outline", size: "icon", className: "h-9 w-9 shrink-0", onClick: () => handleDeleteTemplate(), disabled: deleting, "aria-label": deleting ? "Deleting template" : "Delete template", title: deleting ? "Deleting…" : "Delete template", "data-testid": "project-template-delete-button", children: deleting ? (_jsx(RefreshCw, { className: "h-4 w-4 animate-spin", strokeWidth: 1 })) : (_jsx(DeleteIcon, { size: "lg" })) }) })] })) : null, draftTemplate ? ((() => {
2300
+ const detailContent = (_jsxs("div", { className: "bg-neutral-grey-5/40 flex h-full flex-col", "data-testid": "project-template-detail-pane", children: [isMobile && draftTemplate ? (_jsxs("div", { className: "border-border-default flex min-w-0 items-center gap-3 border-b bg-white px-5 py-2", "data-testid": "project-template-detail-pane-header", children: [_jsx("div", { className: "min-w-0 flex-1", children: templateSelector }), _jsxs("div", { className: "flex shrink-0 items-center gap-1.5 self-center", children: [_jsx(Button, { variant: "outline", size: "icon", className: "h-9 w-9 shrink-0", onClick: () => void handleDuplicateTemplate(), disabled: saving || deleting, "aria-label": "Duplicate template", title: "Duplicate template", "data-testid": "project-template-duplicate-button", children: _jsx(CopyPlus, { className: "h-4 w-4", strokeWidth: 1 }) }), !draftTemplate.isSystem ? (_jsx(Button, { variant: "outline", size: "icon", className: "h-9 w-9 shrink-0", onClick: () => handleDeleteTemplate(), disabled: deleting, "aria-label": deleting ? "Deleting template" : "Delete template", title: deleting ? "Deleting…" : "Delete template", "data-testid": "project-template-delete-button", children: deleting ? (_jsx(RefreshCw, { className: "h-4 w-4 animate-spin", strokeWidth: 1 })) : (_jsx(DeleteIcon, { size: "lg" })) })) : null] })] })) : null, draftTemplate ? ((() => {
2232
2301
  const detailTabs = [
2233
2302
  {
2234
2303
  id: "project-template-tab-basic-settings",