@taskforcehq/taskforce 0.3.303 → 0.3.305
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/README.md +140 -247
- package/dist/Taskforce.module.css +102 -5
- package/dist/TaskforceCore.js +635 -238
- package/dist/TaskforceCore.test.js +2243 -495
- package/dist/annotatedAttachments/service.d.ts +1 -1
- package/dist/annotatedAttachments/types.d.ts +1 -1
- package/dist/compat/workspaceSyncCompat.js +6 -0
- package/dist/components/features/AgentsModule.js +1 -1
- package/dist/components/features/AgentsModule.test.js +1 -1
- package/dist/components/features/DocumentIndex.d.ts +1 -1
- package/dist/components/features/DocumentIndex.js +1 -1
- package/dist/components/features/DocumentViewer.d.ts +1 -1
- package/dist/components/features/DocumentViewer.js +32 -9
- package/dist/components/features/DocumentWorkspace.d.ts +5 -22
- package/dist/components/features/DocumentWorkspace.js +12 -155
- package/dist/components/features/DocumentWorkspace.test.js +193 -6
- package/dist/components/features/TaskSettings.js +87 -41
- package/dist/components/features/TaskSettings.test.js +180 -40
- package/dist/components/features/documentWorkspaceModel.d.ts +24 -0
- package/dist/components/features/documentWorkspaceModel.js +57 -0
- package/dist/components/features/useDocumentWorkspaceController.d.ts +34 -0
- package/dist/components/features/useDocumentWorkspaceController.js +113 -0
- package/dist/components/task/TaskActionHeader.d.ts +2 -1
- package/dist/components/task/TaskActionHeader.js +3 -3
- package/dist/components/task/TaskActionHeader.test.js +8 -0
- package/dist/components/task/TaskCard.js +16 -1
- package/dist/components/task/TaskCard.test.js +31 -0
- package/dist/components/task/TaskForm.d.ts +9 -8
- package/dist/components/task/TaskForm.js +374 -219
- package/dist/components/task/TaskForm.test.js +482 -361
- package/dist/components/task/TaskKanban.d.ts +1 -1
- package/dist/components/task/TaskKanban.js +33 -161
- package/dist/components/task/TaskStatusActions.d.ts +6 -1
- package/dist/components/task/TaskStatusActions.js +8 -3
- package/dist/components/task/TaskStatusActions.test.js +9 -0
- package/dist/components/task/taskKanbanDropRules.d.ts +58 -0
- package/dist/components/task/taskKanbanDropRules.js +187 -0
- package/dist/components/task/taskKanbanDropRules.test.d.ts +1 -0
- package/dist/components/task/taskKanbanDropRules.test.js +114 -0
- package/dist/components/ui/Modal.d.ts +1 -1
- package/dist/components/ui/Modal.js +1 -0
- package/dist/components/views/AppShellHeader.js +5 -1
- package/dist/components/views/AppShellHeader.test.js +4 -0
- package/dist/components/views/PlanComparisonPage.d.ts +3 -2
- package/dist/components/views/PlanComparisonPage.js +9 -10
- package/dist/components/views/PlanComparisonPage.test.js +55 -41
- package/dist/components/views/PlansPage.d.ts +5 -1
- package/dist/components/views/PlansPage.js +150 -81
- package/dist/components/views/PlansPage.test.js +367 -41
- package/dist/components/views/StandaloneLayout.js +135 -54
- package/dist/components/views/WidgetView.js +11 -2
- package/dist/components/views/panels/FilterToolbar.test.js +6 -4
- package/dist/components/views/standalone/modals/AccountHubModal.d.ts +2 -14
- package/dist/components/views/standalone/modals/AccountHubModal.js +12 -14
- package/dist/components/views/standalone/modals/AccountHubModal.test.js +24 -1
- package/dist/components/views/standalone/modals/SyncStatusModal.js +1 -1
- package/dist/config/envSchema.js +1 -1
- package/dist/core/AiProfileService.d.ts +6 -1
- package/dist/core/AiProfileService.js +161 -16
- package/dist/core/AiProfileService.test.js +3 -1
- package/dist/core/AiProfiles.test.js +200 -0
- package/dist/core/AuthTokenService.test.d.ts +1 -0
- package/dist/core/AuthTokenService.test.js +78 -0
- package/dist/core/DeletedTaskLifecycleService.d.ts +2 -1
- package/dist/core/EntitlementsPolicy.test.js +75 -13
- package/dist/core/PlanEntitlementService.d.ts +9 -1
- package/dist/core/PlanEntitlementService.js +144 -19
- package/dist/core/PlanVersionPolicy.test.js +19 -26
- package/dist/core/SignupMonetizationSettings.test.js +75 -15
- package/dist/core/SystemAdmin.test.js +212 -56
- package/dist/core/TaskActivityService.d.ts +4 -1
- package/dist/core/TaskActivityService.js +45 -0
- package/dist/core/TaskAuditTimeline.test.js +52 -1
- package/dist/core/TaskTaxonomyValidation.test.js +53 -0
- package/dist/core/Taskforce.d.ts +18 -11
- package/dist/core/Taskforce.js +93 -12
- package/dist/core/WorkspacePlanMode.test.js +73 -8
- package/dist/core/shared.d.ts +2 -0
- package/dist/core/shared.js +11 -0
- package/dist/documentReviews/service.d.ts +1 -1
- package/dist/documentReviews/types.d.ts +1 -1
- package/dist/hooks/auth/useTaskforceAuthBootstrap.d.ts +48 -0
- package/dist/hooks/auth/useTaskforceAuthBootstrap.js +219 -0
- package/dist/hooks/sync/auth.d.ts +37 -0
- package/dist/hooks/sync/auth.js +63 -0
- package/dist/hooks/sync/bootstrap.d.ts +34 -0
- package/dist/hooks/sync/bootstrap.js +52 -0
- package/dist/hooks/sync/orchestratorShared.d.ts +36 -0
- package/dist/hooks/sync/orchestratorShared.js +209 -0
- package/dist/hooks/sync/orchestratorShared.test.d.ts +1 -0
- package/dist/hooks/sync/orchestratorShared.test.js +49 -0
- package/dist/hooks/sync/realtime.d.ts +25 -0
- package/dist/hooks/sync/realtime.js +60 -0
- package/dist/hooks/sync/recovery.d.ts +69 -0
- package/dist/hooks/sync/recovery.js +118 -0
- package/dist/hooks/sync/transfers.d.ts +123 -0
- package/dist/hooks/sync/transfers.js +435 -0
- package/dist/hooks/sync/useDataVersionRefresh.d.ts +16 -0
- package/dist/hooks/sync/useDataVersionRefresh.js +73 -0
- package/dist/hooks/ui/useResourceExport.d.ts +3 -1
- package/dist/hooks/ui/useResourceExport.js +5 -2
- package/dist/hooks/ui/useWorkflowTemplates.js +11 -6
- package/dist/hooks/useRealtimeSync.js +2 -1
- package/dist/hooks/useSyncOrchestrator.aiProfiles.test.js +8 -0
- package/dist/hooks/useSyncOrchestrator.context-assets.test.d.ts +1 -0
- package/dist/hooks/useSyncOrchestrator.context-assets.test.js +228 -0
- package/dist/hooks/useSyncOrchestrator.d.ts +12 -8
- package/dist/hooks/useSyncOrchestrator.js +388 -879
- package/dist/hooks/useSyncOrchestrator.retry-closure.test.js +641 -6
- package/dist/hooks/useTaskMutations.d.ts +2 -1
- package/dist/hooks/useTaskMutations.js +57 -7
- package/dist/hooks/useTaskMutations.test.js +176 -0
- package/dist/hooks/useTaskforce.d.ts +13 -4
- package/dist/hooks/useTaskforce.js +302 -817
- package/dist/hooks/useTaskforce.sync-behavior.test.js +78 -0
- package/dist/hooks/useWorkspaceSyncController.d.ts +4 -1
- package/dist/hooks/useWorkspaceSyncController.js +33 -11
- package/dist/hooks/useWorkspaceSyncController.test.js +1 -0
- package/dist/hooks/workspace/useTaskforceApiRouting.test.js +17 -0
- package/dist/hooks/workspace/useTaskforceWorkspaceBootstrap.d.ts +166 -0
- package/dist/hooks/workspace/useTaskforceWorkspaceBootstrap.js +434 -0
- package/dist/hooks/workspace/workspaceLocalState.d.ts +19 -0
- package/dist/hooks/workspace/workspaceLocalState.js +100 -0
- package/dist/hooks/workspace/workspaceLocalState.test.d.ts +1 -0
- package/dist/hooks/workspace/workspaceLocalState.test.js +59 -0
- package/dist/localization/locales/en-US.js +2 -2
- package/dist/mcp/adminWorkspaceRegistrar.d.ts +2 -0
- package/dist/mcp/adminWorkspaceRegistrar.js +154 -0
- package/dist/mcp/canonicalAssetHelpers.d.ts +70 -0
- package/dist/mcp/canonicalAssetHelpers.js +259 -0
- package/dist/mcp/clientIntegrations.d.ts +12 -1
- package/dist/mcp/clientIntegrations.js +161 -6
- package/dist/mcp/clientIntegrations.test.js +76 -4
- package/dist/mcp/collaborationRegistrar.d.ts +2 -0
- package/dist/mcp/collaborationRegistrar.js +71 -0
- package/dist/mcp/documentAssetRegistrar.d.ts +2 -0
- package/dist/mcp/documentAssetRegistrar.js +346 -0
- package/dist/mcp/documentHelpers.d.ts +100 -0
- package/dist/mcp/documentHelpers.js +161 -0
- package/dist/mcp/runtime.js +2455 -3925
- package/dist/mcp/runtime.test.js +240 -8
- package/dist/mcp/taskAttachmentHelpers.d.ts +41 -0
- package/dist/mcp/taskAttachmentHelpers.js +60 -0
- package/dist/mcp/taskAttachmentTypes.d.ts +37 -0
- package/dist/mcp/taskAttachmentTypes.js +1 -0
- package/dist/mcp/taskPlanningRegistrar.d.ts +2 -0
- package/dist/mcp/taskPlanningRegistrar.js +418 -0
- package/dist/mcp/toolCatalog.d.ts +35 -0
- package/dist/mcp/toolCatalog.js +3 -0
- package/dist/plugins/vite.js +1 -1
- package/dist/runtime/appGateDefinitions.d.ts +1 -1
- package/dist/runtime/appGateDefinitions.js +1 -1
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.js +46 -3
- package/dist/server/index.test.js +12 -1
- package/dist/server/routes/admin.d.ts +1 -5
- package/dist/server/routes/admin.js +151 -80
- package/dist/server/routes/annotatedAttachments.d.ts +1 -1
- package/dist/server/routes/annotatedAttachments.js +1 -1
- package/dist/server/routes/auth.d.ts +1 -4
- package/dist/server/routes/auth.js +59 -64
- package/dist/server/routes/authSupport.d.ts +30 -0
- package/dist/server/routes/authSupport.js +81 -0
- package/dist/server/routes/billing.d.ts +1 -1
- package/dist/server/routes/billing.js +122 -255
- package/dist/server/routes/billing.test.js +257 -86
- package/dist/server/routes/documentReviews.d.ts +1 -1
- package/dist/server/routes/documentReviews.js +1 -1
- package/dist/server/routes/documents.d.ts +4 -2
- package/dist/server/routes/documents.js +73 -7
- package/dist/server/routes/primitives.d.ts +11 -0
- package/dist/server/routes/primitives.js +73 -0
- package/dist/server/routes/resources.d.ts +1 -1
- package/dist/server/routes/resources.js +1 -1
- package/dist/server/routes/shared.d.ts +31 -1
- package/dist/server/routes/shared.js +26 -0
- package/dist/server/routes/sync.d.ts +1 -1
- package/dist/server/routes/sync.integration.test.js +20 -0
- package/dist/server/routes/sync.js +111 -238
- package/dist/server/routes/tasks.d.ts +1 -1
- package/dist/server/routes/tasks.js +50 -8
- package/dist/server/routes/workspaces.d.ts +1 -1
- package/dist/server/routes/workspaces.js +1 -1
- package/dist/server/routes.d.ts +2 -9
- package/dist/server/routes.js +84 -181
- package/dist/server/routes.test.js +912 -32
- package/dist/shared/taskActor.d.ts +10 -0
- package/dist/shared/taskActor.js +1 -0
- package/dist/sync/collaborationSyncPayload.js +4 -0
- package/dist/sync/collaborationSyncPayload.test.js +8 -0
- package/dist/sync/collaborationSyncState.d.ts +3 -1
- package/dist/sync/collaborationSyncState.js +19 -0
- package/dist/sync/contentSyncState.js +28 -17
- package/dist/sync/syncApplyHandlers.d.ts +87 -1
- package/dist/sync/syncApplyHandlers.js +370 -8
- package/dist/sync/syncApplyHandlers.test.d.ts +1 -0
- package/dist/sync/syncApplyHandlers.test.js +379 -0
- package/dist/sync/syncService.d.ts +9 -1
- package/dist/sync/syncService.js +44 -2
- package/dist/sync/syncService.test.js +62 -0
- package/dist/sync/workspacePullFeed.d.ts +1 -0
- package/dist/sync/workspacePullFeed.js +66 -59
- package/dist/sync/workspacePullFeed.test.js +72 -4
- package/dist/sync/workspaceSyncModel.d.ts +25 -1
- package/dist/sync/workspaceSyncModel.js +77 -3
- package/dist/sync/workspaceSyncModel.test.js +153 -0
- package/dist/sync/workspaceSyncState.d.ts +2 -0
- package/dist/sync/workspaceSyncState.js +1 -0
- package/dist/types.d.ts +2 -10
- package/dist/ui/assets/AgentsModule-N2MnQBZk.js +1 -0
- package/dist/ui/assets/{AnnotatedAttachmentWorkspace-C_TmXZwA.js → AnnotatedAttachmentWorkspace-BG6P_GVW.js} +1 -1
- package/dist/ui/assets/DocumentWorkspace-B3nV_Gc5.css +1 -0
- package/dist/ui/assets/DocumentWorkspace-DRbDMwh8.js +252 -0
- package/dist/ui/assets/{InitiativesModule-4-Rh2K2n.js → InitiativesModule-Dhm7M8e7.js} +1 -1
- package/dist/ui/assets/{PlansPage-BlVC_lRq.css → PlansPage-C2dd2n1X.css} +1 -1
- package/dist/ui/assets/PlansPage-Cq0zXj3I.js +1 -0
- package/dist/ui/assets/TaskSettings-ln0aF7xc.js +9 -0
- package/dist/ui/assets/{WorkflowsModule-CGk9s3NJ.js → WorkflowsModule-BcS4afRn.js} +1 -1
- package/dist/ui/assets/index-C2-OXZV7.css +1 -0
- package/dist/ui/assets/index-DcSI5F86.js +6 -0
- package/dist/ui/assets/{vendor-icons-pWocEipT.js → vendor-icons-BSUaRwF8.js} +1 -1
- package/dist/ui/index.html +4 -4
- package/dist/utils/commercialLifecyclePresentation.d.ts +19 -0
- package/dist/utils/commercialLifecyclePresentation.js +196 -0
- package/dist/utils/taskActivity.js +4 -0
- package/dist/utils/taskActivity.test.js +25 -1
- package/package.json +10 -1
- package/scripts/check-cloud-mcp.mjs +83 -0
- package/scripts/playwright-auth.sh +9 -1
- package/scripts/run-billing-performance-smoke.sh +24 -0
- package/dist/ui/assets/AgentsModule-CpsTmrIW.js +0 -1
- package/dist/ui/assets/DocumentWorkspace-C3GyzrWm.js +0 -250
- package/dist/ui/assets/DocumentWorkspace-C_8T8oz-.css +0 -1
- package/dist/ui/assets/PlansPage-BP7AYOqr.js +0 -1
- package/dist/ui/assets/TaskSettings-BOC5F6Ag.js +0 -8
- package/dist/ui/assets/index-CLIMgR6g.js +0 -6
- package/dist/ui/assets/index-DneETxcu.css +0 -1
|
@@ -23,8 +23,9 @@ interface TaskActionHeaderProps {
|
|
|
23
23
|
handleToggleCancel: (task: TaskItem) => void;
|
|
24
24
|
handleSetStatus?: (task: TaskItem, status: TaskStatus) => void;
|
|
25
25
|
handleArchiveTask: (task: TaskItem) => void;
|
|
26
|
+
handleUnarchiveTask?: (taskId: string) => void;
|
|
26
27
|
handleRestoreDeletedTask?: (deletedRecordId: string) => void;
|
|
27
28
|
handlePermanentlyDeleteDeletedTask?: (deletedRecordId: string) => void;
|
|
28
29
|
}
|
|
29
|
-
export declare function TaskActionHeader({ editingTaskId, loading, autoSaveState, title, handleSubmit, resetForm, handleCopyId, copiedId, tasks, currentTask: currentTaskProp, currentTaskWorkstream, currentTaskInitiative, workstreamInput, onWorkstreamInputChange, onSetWorkstreamForCurrentTask, handleToggleInProgress, handleToggleReview, handleToggleComplete, handleToggleCancel, handleSetStatus, handleArchiveTask, handleRestoreDeletedTask, handlePermanentlyDeleteDeletedTask }: TaskActionHeaderProps): import("react/jsx-runtime").JSX.Element;
|
|
30
|
+
export declare function TaskActionHeader({ editingTaskId, loading, autoSaveState, title, handleSubmit, resetForm, handleCopyId, copiedId, tasks, currentTask: currentTaskProp, currentTaskWorkstream, currentTaskInitiative, workstreamInput, onWorkstreamInputChange, onSetWorkstreamForCurrentTask, handleToggleInProgress, handleToggleReview, handleToggleComplete, handleToggleCancel, handleSetStatus, handleArchiveTask, handleUnarchiveTask, handleRestoreDeletedTask, handlePermanentlyDeleteDeletedTask }: TaskActionHeaderProps): import("react/jsx-runtime").JSX.Element;
|
|
30
31
|
export {};
|
|
@@ -7,7 +7,7 @@ import { TaskStatusActions } from './TaskStatusActions';
|
|
|
7
7
|
import { getTaskReferenceDisplayState } from '../../utils/taskReferences';
|
|
8
8
|
import { TaskReferenceBadge } from './TaskReferenceBadge';
|
|
9
9
|
import { formatInitiativeReference, getWorkstreamReferenceLabel } from '../../utils/planningReferences';
|
|
10
|
-
export function TaskActionHeader({ editingTaskId, loading, autoSaveState = 'idle', title, handleSubmit, resetForm, handleCopyId, copiedId, tasks, currentTask: currentTaskProp, currentTaskWorkstream, currentTaskInitiative, workstreamInput = '', onWorkstreamInputChange, onSetWorkstreamForCurrentTask, handleToggleInProgress, handleToggleReview, handleToggleComplete, handleToggleCancel, handleSetStatus, handleArchiveTask, handleRestoreDeletedTask, handlePermanentlyDeleteDeletedTask }) {
|
|
10
|
+
export function TaskActionHeader({ editingTaskId, loading, autoSaveState = 'idle', title, handleSubmit, resetForm, handleCopyId, copiedId, tasks, currentTask: currentTaskProp, currentTaskWorkstream, currentTaskInitiative, workstreamInput = '', onWorkstreamInputChange, onSetWorkstreamForCurrentTask, handleToggleInProgress, handleToggleReview, handleToggleComplete, handleToggleCancel, handleSetStatus, handleArchiveTask, handleUnarchiveTask, handleRestoreDeletedTask, handlePermanentlyDeleteDeletedTask }) {
|
|
11
11
|
const [showWorkstreamEditor, setShowWorkstreamEditor] = React.useState(false);
|
|
12
12
|
const currentTask = currentTaskProp ?? (editingTaskId ? tasks.find(t => t.id === editingTaskId) || null : null);
|
|
13
13
|
const isArchivedReadOnly = Boolean(currentTask?.isArchived);
|
|
@@ -48,7 +48,7 @@ export function TaskActionHeader({ editingTaskId, loading, autoSaveState = 'idle
|
|
|
48
48
|
} }), _jsx("button", { type: "button", className: "tf-control-icon tf-control-icon-compact", onClick: handleWorkstreamConfirm, disabled: !workstreamInput.trim() || loading, title: "Attach workstream", "aria-label": "Attach workstream", children: _jsx(Check, { size: 14 }) }), _jsx("button", { type: "button", className: "tf-control-icon tf-control-icon-compact", onClick: () => {
|
|
49
49
|
onWorkstreamInputChange?.('');
|
|
50
50
|
setShowWorkstreamEditor(false);
|
|
51
|
-
}, disabled: loading, title: "Cancel workstream attach", "aria-label": "Cancel workstream attach", children: _jsx(X, { size: 14 }) })] })) : null] }), _jsx("div", { className: styles.taskSaveStatusCenter, children: _jsx("div", { className: `${styles.taskSaveStatus} ${autoSaveState === 'error' ? styles.taskSaveStatusError : ''}`, "aria-live": "polite", children: autoSaveState === 'saving' ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { size: 14, className: styles.spinner }), _jsx("span", { children: "Saving\u2026" })] })) : autoSaveState === 'saved' ? (_jsx("span", { children: "Saved" })) : autoSaveState === 'error' ? (_jsx("span", { children: "Save failed" })) : null }) }), _jsx("div", { className: styles.editActionsGroup, children: isDeletedReadOnly && currentTask?.deletedRecordId ? (_jsxs(_Fragment, { children: [handleRestoreDeletedTask && (_jsx("button", { type: "button", className: styles.actionBtn, onClick: () => handleRestoreDeletedTask(currentTask.deletedRecordId || ''), disabled: loading, title: "Restore deleted task", children: _jsx(RotateCcw, { size: 16 }) })), handlePermanentlyDeleteDeletedTask && (_jsx("button", { type: "button", className: `${styles.actionBtn} ${styles.deleteBtn}`, onClick: () => handlePermanentlyDeleteDeletedTask(currentTask.deletedRecordId || ''), disabled: loading, title: "Permanently delete deleted task", children: _jsx(Trash2, { size: 16 }) }))] })) : (_jsx(TaskStatusActions, { task: currentTask, disabled: loading || isArchivedReadOnly, onSetStatus: (task, status) => {
|
|
51
|
+
}, disabled: loading, title: "Cancel workstream attach", "aria-label": "Cancel workstream attach", children: _jsx(X, { size: 14 }) })] })) : null] }), _jsx("div", { className: styles.taskSaveStatusCenter, children: _jsx("div", { className: `${styles.taskSaveStatus} ${autoSaveState === 'error' ? styles.taskSaveStatusError : ''}`, "aria-live": "polite", children: autoSaveState === 'saving' ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { size: 14, className: styles.spinner }), _jsx("span", { children: "Saving\u2026" })] })) : autoSaveState === 'saved' ? (_jsx("span", { children: "Saved" })) : autoSaveState === 'error' ? (_jsx("span", { children: "Save failed" })) : null }) }), _jsx("div", { className: styles.editActionsGroup, children: isDeletedReadOnly && currentTask?.deletedRecordId ? (_jsxs(_Fragment, { children: [handleRestoreDeletedTask && (_jsx("button", { type: "button", className: styles.actionBtn, onClick: () => handleRestoreDeletedTask(currentTask.deletedRecordId || ''), disabled: loading, title: "Restore deleted task", children: _jsx(RotateCcw, { size: 16 }) })), handlePermanentlyDeleteDeletedTask && (_jsx("button", { type: "button", className: `${styles.actionBtn} ${styles.deleteBtn}`, onClick: () => handlePermanentlyDeleteDeletedTask(currentTask.deletedRecordId || ''), disabled: loading, title: "Permanently delete deleted task", children: _jsx(Trash2, { size: 16 }) }))] })) : (_jsx(TaskStatusActions, { task: currentTask, disabled: loading, statusDisabled: loading || isArchivedReadOnly, archiveActionMode: isArchivedReadOnly ? 'unarchive' : 'auto', onSetStatus: (task, status) => {
|
|
52
52
|
if (handleSetStatus) {
|
|
53
53
|
handleSetStatus(task, status);
|
|
54
54
|
return;
|
|
@@ -68,5 +68,5 @@ export function TaskActionHeader({ editingTaskId, loading, autoSaveState = 'idle
|
|
|
68
68
|
if (status === 'cancelled') {
|
|
69
69
|
handleToggleCancel(task);
|
|
70
70
|
}
|
|
71
|
-
}, onArchiveTask: handleArchiveTask })) })] })) : (_jsxs(_Fragment, { children: [_jsxs("button", { type: "button", onClick: resetForm, disabled: loading, className: styles.secondaryHeaderBtn, title: t('actionHeader.clearFormTitle'), children: [_jsx(RotateCcw, { size: 16 }), t('actionHeader.clear')] }), _jsxs("button", { type: "button", onClick: (e) => handleSubmit(e), disabled: loading || !title.trim(), className: styles.primaryUpdateBtn, title: t('actionHeader.addTaskTitle'), children: [loading ? _jsx(Loader2, { size: 16, className: styles.spinner }) : _jsx(Plus, { size: 16 }), t('actionHeader.addTask')] })] })) }));
|
|
71
|
+
}, onArchiveTask: handleArchiveTask, onUnarchiveTask: (task) => handleUnarchiveTask?.(task.id) })) })] })) : (_jsxs(_Fragment, { children: [_jsxs("button", { type: "button", onClick: resetForm, disabled: loading, className: styles.secondaryHeaderBtn, title: t('actionHeader.clearFormTitle'), children: [_jsx(RotateCcw, { size: 16 }), t('actionHeader.clear')] }), _jsxs("button", { type: "button", onClick: (e) => handleSubmit(e), disabled: loading || !title.trim(), className: styles.primaryUpdateBtn, title: t('actionHeader.addTaskTitle'), children: [loading ? _jsx(Loader2, { size: 16, className: styles.spinner }) : _jsx(Plus, { size: 16 }), t('actionHeader.addTask')] })] })) }));
|
|
72
72
|
}
|
|
@@ -70,4 +70,12 @@ describe('TaskActionHeader', () => {
|
|
|
70
70
|
await user.click(screen.getByRole('button', { name: /cancel workstream attach/i }));
|
|
71
71
|
expect(onWorkstreamInputChange).toHaveBeenCalledWith('');
|
|
72
72
|
});
|
|
73
|
+
it('shows an unarchive action for archived tasks and wires it to the task id', async () => {
|
|
74
|
+
const user = userEvent.setup();
|
|
75
|
+
const handleUnarchiveTask = vi.fn();
|
|
76
|
+
render(_jsx(TaskActionHeader, { ...baseProps, editingTaskId: "task-1", title: "Polish task modal", currentTask: { ...baseTask, status: 'done', isArchived: true }, handleUnarchiveTask: handleUnarchiveTask }));
|
|
77
|
+
expect(screen.queryByRole('button', { name: /^Archive task$/i })).not.toBeInTheDocument();
|
|
78
|
+
await user.click(screen.getByRole('button', { name: /unarchive task/i }));
|
|
79
|
+
expect(handleUnarchiveTask).toHaveBeenCalledWith('task-1');
|
|
80
|
+
});
|
|
73
81
|
});
|
|
@@ -54,7 +54,22 @@ const TaskCardInner = ({ task, searchQuery = '', copiedId = null, taxonomies = [
|
|
|
54
54
|
const latestActivity = React.useMemo(() => getLatestTaskActivity(task), [task]);
|
|
55
55
|
const resolvedReadOnlyMode = readOnlyMode || (task.isDeleted ? 'deleted' : (isArchived ? 'archived' : null));
|
|
56
56
|
const isReadOnly = resolvedReadOnlyMode !== null;
|
|
57
|
-
const
|
|
57
|
+
const formatActivityFieldValue = React.useCallback((field, value) => {
|
|
58
|
+
const normalizedValue = String(value || '').trim();
|
|
59
|
+
if (!normalizedValue)
|
|
60
|
+
return undefined;
|
|
61
|
+
if (field === 'assignee') {
|
|
62
|
+
return getAssigneeLabel(normalizedValue, assigneeOptions);
|
|
63
|
+
}
|
|
64
|
+
if (field === 'workstreamId' && normalizedValue === taskWorkstream?.id) {
|
|
65
|
+
return workstreamReferenceLabel || taskWorkstream.id;
|
|
66
|
+
}
|
|
67
|
+
if (field === 'initiativeId' && normalizedValue === taskInitiative?.id) {
|
|
68
|
+
return initiativeReferenceLabel || taskInitiative.id;
|
|
69
|
+
}
|
|
70
|
+
return undefined;
|
|
71
|
+
}, [assigneeOptions, initiativeReferenceLabel, taskInitiative, taskWorkstream, workstreamReferenceLabel]);
|
|
72
|
+
const latestActivityText = React.useMemo(() => summarizeTaskActivity(latestActivity, formatActivityFieldValue), [formatActivityFieldValue, latestActivity]);
|
|
58
73
|
const activityCount = Array.isArray(task.activity) && task.activity.length > 0
|
|
59
74
|
? task.activity.length
|
|
60
75
|
: (task.comments?.length || 0);
|
|
@@ -108,6 +108,37 @@ describe('TaskCard parent/child progress', () => {
|
|
|
108
108
|
expect(screen.getByText(/Status: task -> review/)).toBeInTheDocument();
|
|
109
109
|
expect(screen.getByTitle('2 activity items')).toBeInTheDocument();
|
|
110
110
|
});
|
|
111
|
+
it('uses the current workstream reference in latest activity summaries', () => {
|
|
112
|
+
const task = baseTask({
|
|
113
|
+
id: 'task-relationship-summary',
|
|
114
|
+
title: 'Relationship summary task',
|
|
115
|
+
workstreamId: 'workstream-1',
|
|
116
|
+
activity: [
|
|
117
|
+
{
|
|
118
|
+
id: 'event:event-relationship-1',
|
|
119
|
+
type: 'event',
|
|
120
|
+
timestamp: '2026-03-22T10:00:00.000Z',
|
|
121
|
+
event: {
|
|
122
|
+
id: 'event-relationship-1',
|
|
123
|
+
taskId: 'task-relationship-summary',
|
|
124
|
+
workspaceId: 'default',
|
|
125
|
+
action: 'task-relationship-changed',
|
|
126
|
+
actor: 'user',
|
|
127
|
+
actorType: 'human',
|
|
128
|
+
createdAt: '2026-03-22T10:00:00.000Z',
|
|
129
|
+
details: {
|
|
130
|
+
changes: {
|
|
131
|
+
workstreamId: { from: null, to: 'workstream-1' }
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
]
|
|
137
|
+
});
|
|
138
|
+
render(_jsx(TaskCard, { task: task, taskWorkstream: baseWorkstream({ id: 'workstream-1', referenceNumber: 12 }), onClick: () => { }, onCopyId: () => { } }));
|
|
139
|
+
expect(screen.getByText(/Workstream: none -> WS-12/)).toBeInTheDocument();
|
|
140
|
+
expect(screen.queryByText(/workstream-1/i)).not.toBeInTheDocument();
|
|
141
|
+
});
|
|
111
142
|
it('renders named AI assignee labels from assignee options', () => {
|
|
112
143
|
const task = baseTask({
|
|
113
144
|
id: 'task-ai-assignee',
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import React from
|
|
2
|
-
import type { TaskItem, CategoryConfig, Comment, AttachmentItem, TaskAssignee, ChecklistItem } from
|
|
3
|
-
import type { TaxonomyDefinition } from
|
|
4
|
-
import { type TaskAssigneeOption } from
|
|
5
|
-
import type { WorkstreamItem } from
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { TaskItem, CategoryConfig, Comment, AttachmentItem, TaskAssignee, ChecklistItem, InitiativeItem } from "../../types";
|
|
3
|
+
import type { TaxonomyDefinition } from "../../types";
|
|
4
|
+
import { type TaskAssigneeOption } from "../../utils/assignees";
|
|
5
|
+
import type { WorkstreamItem } from "../../types";
|
|
6
6
|
interface TaskFormProps {
|
|
7
7
|
editingTaskId: string | null;
|
|
8
8
|
error: string;
|
|
@@ -36,7 +36,7 @@ interface TaskFormProps {
|
|
|
36
36
|
label: string;
|
|
37
37
|
color?: string;
|
|
38
38
|
icon?: string;
|
|
39
|
-
status?:
|
|
39
|
+
status?: "active" | "retired";
|
|
40
40
|
}[];
|
|
41
41
|
priorities: Array<{
|
|
42
42
|
value: number;
|
|
@@ -58,6 +58,7 @@ interface TaskFormProps {
|
|
|
58
58
|
assigneeOptions: TaskAssigneeOption[];
|
|
59
59
|
taxonomies: TaxonomyDefinition[];
|
|
60
60
|
workstreams?: WorkstreamItem[];
|
|
61
|
+
initiatives?: InitiativeItem[];
|
|
61
62
|
copiedId: string | null;
|
|
62
63
|
onTitleChange: (value: string) => void;
|
|
63
64
|
onDescriptionChange: (value: string) => void;
|
|
@@ -77,7 +78,7 @@ interface TaskFormProps {
|
|
|
77
78
|
onShowMarkdownHelpChange: (value: boolean) => void;
|
|
78
79
|
onShowChecklistChange?: (value: boolean) => void;
|
|
79
80
|
onShowCommentsChange: (value: boolean) => void;
|
|
80
|
-
onOpenSettings?: (section:
|
|
81
|
+
onOpenSettings?: (section: "categories" | "types") => void;
|
|
81
82
|
onSubmit: (e: React.FormEvent) => void;
|
|
82
83
|
onAddComment: () => void;
|
|
83
84
|
onAddContextFile: (file: AttachmentItem) => void;
|
|
@@ -88,7 +89,7 @@ interface TaskFormProps {
|
|
|
88
89
|
onToggleReview?: (task: TaskItem) => void;
|
|
89
90
|
onToggleComplete?: (task: TaskItem) => void;
|
|
90
91
|
onToggleCancel?: (task: TaskItem) => void;
|
|
91
|
-
onSetStatus?: (task: TaskItem, status: TaskItem[
|
|
92
|
+
onSetStatus?: (task: TaskItem, status: TaskItem["status"]) => void;
|
|
92
93
|
onArchiveTask?: (task: TaskItem) => void;
|
|
93
94
|
onUnarchive?: (taskId: string) => void;
|
|
94
95
|
onOpenTaskById?: (taskId: string) => void;
|