@taskforcehq/taskforce 0.3.306 → 0.3.308
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 +0 -2
- package/dist/Taskforce.module.css +317 -27
- package/dist/TaskforceCore.js +1 -0
- package/dist/TaskforceCore.test.js +178 -0
- package/dist/components/activity/EntityActivityTimeline.d.ts +34 -0
- package/dist/components/activity/EntityActivityTimeline.js +81 -0
- package/dist/components/context/ContextAttachmentManager.js +15 -3
- package/dist/components/features/AgentsModule.d.ts +5 -1
- package/dist/components/features/AgentsModule.js +142 -39
- package/dist/components/features/AgentsModule.test.js +260 -11
- package/dist/components/features/AnnotatedAttachmentWorkspace.d.ts +3 -1
- package/dist/components/features/AnnotatedAttachmentWorkspace.js +118 -4
- package/dist/components/features/AnnotatedAttachmentWorkspace.test.js +52 -0
- package/dist/components/features/DocumentIndex.d.ts +2 -2
- package/dist/components/features/DocumentIndex.js +3 -4
- package/dist/components/features/DocumentViewer.d.ts +3 -1
- package/dist/components/features/DocumentViewer.js +6 -5
- package/dist/components/features/DocumentWorkspace.d.ts +10 -2
- package/dist/components/features/DocumentWorkspace.js +15 -4
- package/dist/components/features/DocumentWorkspace.test.js +20 -3
- package/dist/components/features/TaskSettings.d.ts +2 -0
- package/dist/components/features/TaskSettings.js +83 -78
- package/dist/components/features/TaskSettings.test.js +171 -82
- package/dist/components/task/TaskActionHeader.js +11 -5
- package/dist/components/task/TaskActionHeader.test.js +10 -0
- package/dist/components/task/TaskCard.js +6 -2
- package/dist/components/task/TaskContextUpload.test.js +3 -3
- package/dist/components/task/TaskForm.js +14 -64
- package/dist/components/task/TaskKanban.js +0 -8
- package/dist/components/task/TaskList.js +5 -1
- package/dist/components/task/TaskList.test.js +4 -0
- package/dist/components/ui/HierarchyActionBadge.d.ts +10 -0
- package/dist/components/ui/HierarchyActionBadge.js +5 -0
- package/dist/components/views/AppShellHeader.d.ts +3 -1
- package/dist/components/views/AppShellHeader.js +27 -11
- package/dist/components/views/AppShellHeader.test.js +18 -1
- package/dist/components/views/PlanComparisonPage.d.ts +20 -15
- package/dist/components/views/PlanComparisonPage.js +221 -82
- package/dist/components/views/PlanComparisonPage.test.js +268 -14
- package/dist/components/views/PlansPage.js +16 -10
- package/dist/components/views/PlansPage.test.js +4 -2
- package/dist/components/views/StandaloneLayout.js +256 -69
- package/dist/components/views/WidgetView.js +10 -8
- package/dist/components/views/panels/PlanningDrawer.d.ts +19 -6
- package/dist/components/views/panels/PlanningDrawer.js +259 -51
- package/dist/components/views/panels/PlanningDrawer.test.js +392 -4
- package/dist/config/envSchema.js +1 -0
- package/dist/core/AiProfileService.d.ts +7 -0
- package/dist/core/AiProfileService.js +460 -35
- package/dist/core/AiProfiles.test.js +648 -2
- package/dist/core/AttachmentLinkService.d.ts +3 -0
- package/dist/core/AttachmentLinkService.js +58 -13
- package/dist/core/GlobalSettingsService.js +30 -0
- package/dist/core/GlobalSettingsService.test.d.ts +1 -0
- package/dist/core/GlobalSettingsService.test.js +45 -0
- package/dist/core/McpTokenService.d.ts +12 -0
- package/dist/core/McpTokenService.js +44 -1
- package/dist/core/PlanEntitlementService.d.ts +20 -0
- package/dist/core/PlanEntitlementService.js +215 -19
- package/dist/core/PlanFeatureCatalog.test.js +55 -0
- package/dist/core/PlanningEntities.test.js +366 -4
- package/dist/core/TaskActivityService.d.ts +28 -1
- package/dist/core/TaskActivityService.js +227 -46
- package/dist/core/TaskActivitySync.test.d.ts +1 -0
- package/dist/core/TaskActivitySync.test.js +90 -0
- package/dist/core/TaskAuditTimeline.test.js +96 -0
- package/dist/core/Taskforce.d.ts +204 -26
- package/dist/core/Taskforce.ids.test.js +58 -0
- package/dist/core/Taskforce.js +781 -71
- package/dist/core/Taskforce.mcpAuth.test.js +109 -0
- package/dist/core/types.d.ts +10 -0
- package/dist/hooks/auth/useTaskforceAuthBootstrap.js +2 -1
- package/dist/hooks/bootstrapTimeouts.d.ts +4 -0
- package/dist/hooks/bootstrapTimeouts.js +8 -0
- package/dist/hooks/bootstrapTimeouts.test.d.ts +1 -0
- package/dist/hooks/bootstrapTimeouts.test.js +12 -0
- package/dist/hooks/sync/orchestratorShared.d.ts +3 -3
- package/dist/hooks/sync/orchestratorShared.js +61 -1
- package/dist/hooks/sync/recovery.js +8 -0
- package/dist/hooks/sync/recovery.test.js +5 -5
- package/dist/hooks/sync/transfers.d.ts +2 -1
- package/dist/hooks/sync/transfers.js +36 -9
- package/dist/hooks/sync/transfers.test.js +534 -2
- package/dist/hooks/useFilterSort.js +13 -13
- package/dist/hooks/useFilterSort.test.js +87 -1
- package/dist/hooks/useSyncOrchestrator.js +50 -5
- package/dist/hooks/useTaskforce.d.ts +85 -50
- package/dist/hooks/useTaskforce.js +44 -14
- package/dist/hooks/useTaskforce.runtime-routing.test.js +94 -0
- package/dist/hooks/useTaskforce.sync-behavior.test.js +99 -0
- package/dist/hooks/useWorkspaceSyncController.js +7 -1
- package/dist/hooks/useWorkspaceSyncController.test.js +48 -0
- package/dist/hooks/workspace/useTaskforceWorkspaceBootstrap.js +14 -7
- package/dist/mcp/canonicalAssetHelpers.d.ts +16 -4
- package/dist/mcp/canonicalAssetHelpers.js +18 -10
- package/dist/mcp/canonicalAssetHelpers.test.d.ts +1 -0
- package/dist/mcp/canonicalAssetHelpers.test.js +67 -0
- package/dist/mcp/clientIntegrations.d.ts +1 -0
- package/dist/mcp/clientIntegrations.js +25 -0
- package/dist/mcp/clientIntegrations.test.js +14 -3
- package/dist/mcp/clientProfileDefaults.js +3 -3
- package/dist/mcp/collaborationRegistrar.js +7 -7
- package/dist/mcp/documentAssetRegistrar.js +113 -7
- package/dist/mcp/runtime.d.ts +1 -0
- package/dist/mcp/runtime.js +969 -122
- package/dist/mcp/runtime.test.js +1083 -11
- package/dist/mcp/taskAttachmentTypes.d.ts +1 -1
- package/dist/mcp/taskPlanningRegistrar.js +48 -0
- package/dist/mcp/toolRegistry.d.ts +56 -0
- package/dist/mcp/toolRegistry.js +8 -0
- package/dist/mcp/toolRegistry.test.js +4 -0
- package/dist/migrations/taskSchemaMigrations.js +58 -15
- package/dist/server/aiProfileAvatarAssets.d.ts +49 -0
- package/dist/server/aiProfileAvatarAssets.js +319 -0
- package/dist/server/aiProfileAvatarAssets.test.d.ts +1 -0
- package/dist/server/aiProfileAvatarAssets.test.js +213 -0
- package/dist/server/annotatedAttachmentsRoutes.test.js +66 -7
- package/dist/server/index.js +4 -0
- package/dist/server/index.test.js +6 -1
- package/dist/server/routes/admin.js +328 -9
- package/dist/server/routes/annotatedAttachments.js +51 -0
- package/dist/server/routes/auth.d.ts +11 -0
- package/dist/server/routes/auth.js +189 -27
- package/dist/server/routes/authSupport.d.ts +5 -0
- package/dist/server/routes/authSupport.js +13 -1
- package/dist/server/routes/billing.d.ts +1 -0
- package/dist/server/routes/billing.js +116 -63
- package/dist/server/routes/billing.test.js +162 -11
- package/dist/server/routes/documents.js +10 -0
- package/dist/server/routes/shared.js +0 -10
- package/dist/server/routes/sync.integration.test.js +221 -0
- package/dist/server/routes/sync.js +13 -3
- package/dist/server/routes/syncSnapshotRoutes.js +2 -0
- package/dist/server/routes/tasks.js +12 -9
- package/dist/server/routes.js +87 -8
- package/dist/server/routes.test.js +972 -23
- package/dist/shared/aiProfileSurfaceType.d.ts +1 -1
- package/dist/shared/aiProfileSurfaceType.js +10 -8
- package/dist/storage/objectStorage.d.ts +1 -0
- package/dist/storage/objectStorage.js +2 -1
- package/dist/storage/objectStorageClient.d.ts +1 -0
- package/dist/storage/objectStorageClient.js +41 -8
- package/dist/storage/objectStorageClient.test.js +26 -1
- package/dist/storage/objectStorageConfig.js +3 -1
- package/dist/storage/objectStorageConfig.test.js +13 -1
- package/dist/sync/collaborationSyncPayload.js +2 -0
- package/dist/sync/collaborationSyncPayload.test.js +1 -0
- package/dist/sync/collaborationSyncState.d.ts +3 -3
- package/dist/sync/collaborationSyncState.js +19 -12
- package/dist/sync/contentSyncPayload.d.ts +5 -1
- package/dist/sync/contentSyncPayload.js +9 -0
- package/dist/sync/contentSyncPayload.test.js +39 -0
- package/dist/sync/contentSyncState.d.ts +5 -1
- package/dist/sync/contentSyncState.js +231 -37
- package/dist/sync/planningSyncPayload.js +5 -0
- package/dist/sync/planningSyncPayload.test.js +24 -0
- package/dist/sync/syncApplyHandlers.d.ts +4 -4
- package/dist/sync/syncApplyHandlers.js +89 -31
- package/dist/sync/syncApplyHandlers.test.js +184 -4
- package/dist/sync/syncResourceAdapters.d.ts +2 -0
- package/dist/sync/syncResourceAdapters.js +2 -0
- package/dist/sync/syncService.d.ts +1 -0
- package/dist/sync/syncService.js +13 -1
- package/dist/sync/syncService.test.js +39 -0
- package/dist/sync/workspacePullFeed.d.ts +4 -0
- package/dist/sync/workspacePullFeed.js +129 -70
- package/dist/sync/workspacePullFeed.test.js +49 -0
- package/dist/sync/workspaceSyncModel.d.ts +28 -6
- package/dist/sync/workspaceSyncModel.js +159 -45
- package/dist/sync/workspaceSyncModel.test.js +269 -3
- package/dist/types.d.ts +33 -2
- package/dist/ui/agent-logos/ChatGPT.png +0 -0
- package/dist/ui/agent-logos/Gemini CLI.jpeg +0 -0
- package/dist/ui/agent-logos/antigravity.jpeg +0 -0
- package/dist/ui/agent-logos/claude-code.jpeg +0 -0
- package/dist/ui/agent-logos/codex.jpeg +0 -0
- package/dist/ui/agent-logos/cursor.png +0 -0
- package/dist/ui/agent-logos/openclaw.jpeg +0 -0
- package/dist/ui/agent-logos/windsurf.png +0 -0
- package/dist/ui/assets/AgentsModule-BS4Pi_nC.js +1 -0
- package/dist/ui/assets/AnnotatedAttachmentWorkspace-BVKew-mH.css +1 -0
- package/dist/ui/assets/AnnotatedAttachmentWorkspace-CCckzWYZ.js +3 -0
- package/dist/ui/assets/ContextAttachmentManager-CfG_ER7C.js +3 -0
- package/dist/ui/assets/DocumentWorkspace-BVaWPA25.js +252 -0
- package/dist/ui/assets/DocumentWorkspace-D4rJKXzd.css +1 -0
- package/dist/ui/assets/EntityActivityTimeline-DSj0ThaK.js +1 -0
- package/dist/ui/assets/EntityActivityTimeline-DyqvvhuF.css +1 -0
- package/dist/ui/assets/{InitiativesModule-9E6ParrY.js → InitiativesModule-AxMkWtxH.js} +1 -1
- package/dist/ui/assets/PlansPage-B_z-D6Nh.css +1 -0
- package/dist/ui/assets/PlansPage-Ndt7mYfo.js +1 -0
- package/dist/ui/assets/TaskContextUpload-Dw4rTF4i.js +1 -0
- package/dist/ui/assets/TaskSettings-f2ga42_V.js +9 -0
- package/dist/ui/assets/{WorkflowsModule-BA7jcEpH.js → WorkflowsModule-E4UL3mov.js} +4 -4
- package/dist/ui/assets/documentReferences-BOUcJm6-.js +1 -0
- package/dist/ui/assets/index-BvAbqx5Q.css +1 -0
- package/dist/ui/assets/index-MAHKvFqp.js +4 -0
- package/dist/ui/assets/{vendor-icons-DuEd_65c.js → vendor-icons-B32hGuF2.js} +1 -1
- package/dist/ui/index.html +3 -3
- package/dist/ui/og-image.png +0 -0
- package/dist/ui/product/agent manager.png +0 -0
- package/dist/ui/product/agent_manager_02.png +0 -0
- package/dist/utils/aiProfileEvents.d.ts +7 -0
- package/dist/utils/aiProfileEvents.js +6 -0
- package/dist/utils/assignees.d.ts +6 -0
- package/dist/utils/assignees.js +8 -1
- package/dist/utils/assignees.test.d.ts +1 -0
- package/dist/utils/assignees.test.js +25 -0
- package/dist/utils/avatarDisplay.d.ts +1 -0
- package/dist/utils/avatarDisplay.js +15 -0
- package/dist/utils/contextFiles.d.ts +3 -1
- package/dist/utils/contextFiles.js +2 -1
- package/dist/utils/taskActivity.d.ts +7 -1
- package/dist/utils/taskActivity.js +63 -1
- package/dist/utils/taskActivity.test.js +23 -1
- package/dist/utils/taskSearch.d.ts +22 -0
- package/dist/utils/taskSearch.js +87 -0
- package/dist/utils/taskSearch.test.d.ts +1 -0
- package/dist/utils/taskSearch.test.js +69 -0
- package/dist/utils/taskUtils.js +10 -3
- package/dist/utils/taskUtils.test.d.ts +1 -0
- package/dist/utils/taskUtils.test.js +19 -0
- package/package.json +1 -1
- package/dist/ui/assets/AgentsModule-DrLawwNl.js +0 -1
- package/dist/ui/assets/AnnotatedAttachmentWorkspace-BaS2VwIr.css +0 -1
- package/dist/ui/assets/AnnotatedAttachmentWorkspace-Z9_whf7F.js +0 -3
- package/dist/ui/assets/DocumentWorkspace-B03MaSkw.js +0 -252
- package/dist/ui/assets/DocumentWorkspace-Dhdso07p.css +0 -1
- package/dist/ui/assets/PlansPage-CvfnMiWq.css +0 -1
- package/dist/ui/assets/PlansPage-DRXscYxH.js +0 -1
- package/dist/ui/assets/TaskSettings-DZX4jk7e.js +0 -9
- package/dist/ui/assets/index-9eT8e0Lu.css +0 -1
- package/dist/ui/assets/index-C6k75jr8.js +0 -6
|
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
2
2
|
import React, { useMemo, useCallback, useState, useEffect, useRef, Suspense } from 'react';
|
|
3
3
|
import { createPortal } from 'react-dom';
|
|
4
4
|
import { useLocation, useNavigate } from 'react-router-dom';
|
|
5
|
-
import { Settings, Plus, Filter, Layers, User, Maximize2, Minimize2, Check, ChevronLeft, ArrowUp, ArrowDown, ArrowUpDown, AlertTriangle, Save, Loader2, Folder, FileText, LogOut, NotebookTabs, ClipboardCheck, Cloud, CloudOff, Users, ClockAlert, ChevronsUp, ChevronsDown, EyeOff, Zap, HelpCircle, Bot, Image, Workflow } from 'lucide-react';
|
|
5
|
+
import { Settings, Plus, Filter, Layers, User, Maximize2, Minimize2, Check, ChevronLeft, ArrowUp, ArrowDown, ArrowUpDown, AlertTriangle, Save, Loader2, Folder, FileText, LogOut, NotebookTabs, ClipboardCheck, Cloud, CloudOff, Users, ClockAlert, ChevronsUp, ChevronsDown, EyeOff, Zap, HelpCircle, Bot, Image, Workflow, Plug } from 'lucide-react';
|
|
6
6
|
import { STATUS_OPTIONS, getStatusDefinition } from '../../utils/constants';
|
|
7
7
|
import styles from '../../Taskforce.module.css';
|
|
8
8
|
import shellStyles from './WorkspaceShell.module.css';
|
|
@@ -29,6 +29,7 @@ import { resolveDraftDefaultsForGrouping } from '../../utils/taskDraftDefaults';
|
|
|
29
29
|
import { formatDate } from '../../utils/formatting';
|
|
30
30
|
import { resolveHeaderWorkspaceSyncPresentation } from '../../utils/workspaceSyncPresentation';
|
|
31
31
|
import { getTaskReferenceLabel, parseTaskReference } from '../../utils/taskReferences';
|
|
32
|
+
import { normalizeTaskSearchQuery, taskMatchesSearch } from '../../utils/taskSearch';
|
|
32
33
|
import { formatInitiativeReference, formatWorkstreamReference, parseWorkstreamReference, resolveInitiativeReference } from '../../utils/planningReferences';
|
|
33
34
|
import { DEFAULT_TYPE_VALUE } from '../../shared/taxonomyDefaults.js';
|
|
34
35
|
import { getImageReferenceLabel } from '../../utils/imageReferences';
|
|
@@ -211,6 +212,9 @@ export function StandaloneLayout(props) {
|
|
|
211
212
|
const [showFilters, setShowFilters] = useState(false);
|
|
212
213
|
const [taskModalFullscreen, setTaskModalFullscreen] = useState(false);
|
|
213
214
|
const [planningDrawerOpen, setPlanningDrawerOpen] = useState(false);
|
|
215
|
+
const [documentTrayOpen, setDocumentTrayOpen] = useState(true);
|
|
216
|
+
const [imageTrayOpen, setImageTrayOpen] = useState(true);
|
|
217
|
+
const [agentTrayOpen, setAgentTrayOpen] = useState(true);
|
|
214
218
|
const [planningTreeCollapsed, setPlanningTreeCollapsed] = useState(false);
|
|
215
219
|
const [planningPrimaryCollapsed, setPlanningPrimaryCollapsed] = useState(false);
|
|
216
220
|
const [planningSecondaryCollapsed, setPlanningSecondaryCollapsed] = useState(false);
|
|
@@ -226,6 +230,10 @@ export function StandaloneLayout(props) {
|
|
|
226
230
|
const [planningDraftOwner, setPlanningDraftOwner] = useState('');
|
|
227
231
|
const [planningDraftInitiativeId, setPlanningDraftInitiativeId] = useState('');
|
|
228
232
|
const [isSubmittingPlanningEditor, setIsSubmittingPlanningEditor] = useState(false);
|
|
233
|
+
const taskContextAttachmentDraftRef = useRef({
|
|
234
|
+
taskId: null,
|
|
235
|
+
attachments: [],
|
|
236
|
+
});
|
|
229
237
|
const planningContextAttachmentDraftsRef = useRef(new Map());
|
|
230
238
|
const planningContextAttachmentUpdateQueueRef = useRef(new Map());
|
|
231
239
|
const [documentTypeFilters, setDocumentTypeFilters] = useState(() => DOCUMENT_TYPE_FILTER_OPTIONS.map((option) => option.value));
|
|
@@ -242,6 +250,27 @@ export function StandaloneLayout(props) {
|
|
|
242
250
|
const requestedAnnotatedTargetRef = useRef(null);
|
|
243
251
|
const requestedAnnotatedSessionIdRef = useRef(null);
|
|
244
252
|
const annotatedImageReferenceFetchesRef = useRef(new Set());
|
|
253
|
+
useEffect(() => {
|
|
254
|
+
taskContextAttachmentDraftRef.current = {
|
|
255
|
+
taskId: editingTaskId || null,
|
|
256
|
+
attachments,
|
|
257
|
+
};
|
|
258
|
+
}, [editingTaskId, attachments]);
|
|
259
|
+
const updateTaskContextAttachments = useCallback((getNextAttachments) => {
|
|
260
|
+
const taskId = editingTaskId || null;
|
|
261
|
+
const draft = taskContextAttachmentDraftRef.current;
|
|
262
|
+
const currentAttachments = draft.taskId === taskId ? draft.attachments : attachments;
|
|
263
|
+
const nextAttachments = getNextAttachments(currentAttachments);
|
|
264
|
+
taskContextAttachmentDraftRef.current = {
|
|
265
|
+
taskId,
|
|
266
|
+
attachments: nextAttachments,
|
|
267
|
+
};
|
|
268
|
+
setAttachments(nextAttachments);
|
|
269
|
+
setAttachmentsDirty(true);
|
|
270
|
+
if (taskId) {
|
|
271
|
+
void handleUpdateTask(taskId, { attachments: nextAttachments });
|
|
272
|
+
}
|
|
273
|
+
}, [attachments, editingTaskId, handleUpdateTask, setAttachments, setAttachmentsDirty]);
|
|
245
274
|
const workspaceUiStateHeaders = useMemo(() => {
|
|
246
275
|
const headers = {};
|
|
247
276
|
const workspaceIdHeader = String(currentWorkspaceId || '').trim();
|
|
@@ -252,7 +281,33 @@ export function StandaloneLayout(props) {
|
|
|
252
281
|
}, [runtimeMode, currentWorkspaceId]);
|
|
253
282
|
const layoutStateWorkspaceKey = useMemo(() => `${runtimeMode}:${String(currentWorkspaceId || 'default').trim() || 'default'}`, [runtimeMode, currentWorkspaceId]);
|
|
254
283
|
const annotatedLayoutCacheKey = useMemo(() => `taskforce:annotate-layout:${layoutStateWorkspaceKey}`, [layoutStateWorkspaceKey]);
|
|
284
|
+
const taskOriginWorkspaceModuleKey = useMemo(() => `taskforce:task-origin-workspace-module:${layoutStateWorkspaceKey}`, [layoutStateWorkspaceKey]);
|
|
255
285
|
const annotatedWorkspaceReady = useMemo(() => (runtimeMode === 'cloud' ? authSessionResolved : configLoaded), [authSessionResolved, configLoaded, runtimeMode]);
|
|
286
|
+
const openedTaskOriginWorkspaceModuleRef = useRef(false);
|
|
287
|
+
const taskOriginWorkspaceModuleRestoreHandledRef = useRef(false);
|
|
288
|
+
const rememberTaskOriginWorkspaceModule = useCallback((taskId) => {
|
|
289
|
+
const normalizedTaskId = String(taskId || '').trim();
|
|
290
|
+
if (!normalizedTaskId || typeof window === 'undefined')
|
|
291
|
+
return;
|
|
292
|
+
openedTaskOriginWorkspaceModuleRef.current = true;
|
|
293
|
+
try {
|
|
294
|
+
window.sessionStorage.setItem(taskOriginWorkspaceModuleKey, normalizedTaskId);
|
|
295
|
+
}
|
|
296
|
+
catch {
|
|
297
|
+
// ignore cache write failure
|
|
298
|
+
}
|
|
299
|
+
}, [taskOriginWorkspaceModuleKey]);
|
|
300
|
+
const clearTaskOriginWorkspaceModule = useCallback(() => {
|
|
301
|
+
openedTaskOriginWorkspaceModuleRef.current = false;
|
|
302
|
+
if (typeof window === 'undefined')
|
|
303
|
+
return;
|
|
304
|
+
try {
|
|
305
|
+
window.sessionStorage.removeItem(taskOriginWorkspaceModuleKey);
|
|
306
|
+
}
|
|
307
|
+
catch {
|
|
308
|
+
// ignore cache clear failure
|
|
309
|
+
}
|
|
310
|
+
}, [taskOriginWorkspaceModuleKey]);
|
|
256
311
|
useEffect(() => {
|
|
257
312
|
requestedAnnotatedTargetRef.current = requestedAnnotatedTarget;
|
|
258
313
|
}, [requestedAnnotatedTarget]);
|
|
@@ -299,6 +354,7 @@ export function StandaloneLayout(props) {
|
|
|
299
354
|
pushNotice(documentsWorkspaceUnavailableMessage, 'error');
|
|
300
355
|
return;
|
|
301
356
|
}
|
|
357
|
+
rememberTaskOriginWorkspaceModule(customEvent.detail?.taskId);
|
|
302
358
|
setRequestedDocPath(fsPath || null);
|
|
303
359
|
setRequestedDocAssetId(assetId);
|
|
304
360
|
setActiveWorkspaceModule('docs');
|
|
@@ -307,7 +363,7 @@ export function StandaloneLayout(props) {
|
|
|
307
363
|
return () => {
|
|
308
364
|
window.removeEventListener('taskforce:open-markdown-document', handleOpenMarkdownDocument);
|
|
309
365
|
};
|
|
310
|
-
}, [documentsWorkspaceEnabled, documentsWorkspaceUnavailableMessage, pushNotice, setActiveWorkspaceModule]);
|
|
366
|
+
}, [documentsWorkspaceEnabled, documentsWorkspaceUnavailableMessage, pushNotice, rememberTaskOriginWorkspaceModule, setActiveWorkspaceModule]);
|
|
311
367
|
useEffect(() => {
|
|
312
368
|
if (resolvedWorkspaceModule !== activeWorkspaceModule) {
|
|
313
369
|
setActiveWorkspaceModule(resolvedWorkspaceModule);
|
|
@@ -338,6 +394,29 @@ export function StandaloneLayout(props) {
|
|
|
338
394
|
// ignore cache read failure
|
|
339
395
|
}
|
|
340
396
|
}, [annotatedLayoutCacheKey]);
|
|
397
|
+
useEffect(() => {
|
|
398
|
+
if (taskOriginWorkspaceModuleRestoreHandledRef.current)
|
|
399
|
+
return;
|
|
400
|
+
if (resolvedWorkspaceModule !== 'docs' && resolvedWorkspaceModule !== 'annotate')
|
|
401
|
+
return;
|
|
402
|
+
taskOriginWorkspaceModuleRestoreHandledRef.current = true;
|
|
403
|
+
if (openedTaskOriginWorkspaceModuleRef.current || typeof window === 'undefined')
|
|
404
|
+
return;
|
|
405
|
+
try {
|
|
406
|
+
const taskId = String(window.sessionStorage.getItem(taskOriginWorkspaceModuleKey) || '').trim();
|
|
407
|
+
if (!taskId)
|
|
408
|
+
return;
|
|
409
|
+
window.sessionStorage.removeItem(taskOriginWorkspaceModuleKey);
|
|
410
|
+
setActiveWorkspaceModule('tasks');
|
|
411
|
+
}
|
|
412
|
+
catch {
|
|
413
|
+
// ignore cache read failure
|
|
414
|
+
}
|
|
415
|
+
}, [resolvedWorkspaceModule, setActiveWorkspaceModule, taskOriginWorkspaceModuleKey]);
|
|
416
|
+
useEffect(() => {
|
|
417
|
+
taskOriginWorkspaceModuleRestoreHandledRef.current = false;
|
|
418
|
+
openedTaskOriginWorkspaceModuleRef.current = false;
|
|
419
|
+
}, [taskOriginWorkspaceModuleKey]);
|
|
341
420
|
useEffect(() => {
|
|
342
421
|
if (loadedLayoutStateWorkspaceRef.current === layoutStateWorkspaceKey)
|
|
343
422
|
return;
|
|
@@ -387,6 +466,15 @@ export function StandaloneLayout(props) {
|
|
|
387
466
|
if (typeof state.planningDrawerOpen === 'boolean') {
|
|
388
467
|
setPlanningDrawerOpen(state.planningDrawerOpen);
|
|
389
468
|
}
|
|
469
|
+
if (typeof state.documentTrayOpen === 'boolean') {
|
|
470
|
+
setDocumentTrayOpen(state.documentTrayOpen);
|
|
471
|
+
}
|
|
472
|
+
if (typeof state.imageTrayOpen === 'boolean') {
|
|
473
|
+
setImageTrayOpen(state.imageTrayOpen);
|
|
474
|
+
}
|
|
475
|
+
if (typeof state.agentTrayOpen === 'boolean') {
|
|
476
|
+
setAgentTrayOpen(state.agentTrayOpen);
|
|
477
|
+
}
|
|
390
478
|
if (typeof state.planningTreeCollapsed === 'boolean') {
|
|
391
479
|
setPlanningTreeCollapsed(state.planningTreeCollapsed);
|
|
392
480
|
}
|
|
@@ -462,6 +550,9 @@ export function StandaloneLayout(props) {
|
|
|
462
550
|
showFilters,
|
|
463
551
|
documentTypeFilters,
|
|
464
552
|
documentAttachmentFilters,
|
|
553
|
+
documentTrayOpen,
|
|
554
|
+
imageTrayOpen,
|
|
555
|
+
agentTrayOpen,
|
|
465
556
|
planningDrawerOpen,
|
|
466
557
|
planningTreeCollapsed,
|
|
467
558
|
planningPrimaryCollapsed,
|
|
@@ -491,6 +582,9 @@ export function StandaloneLayout(props) {
|
|
|
491
582
|
showFilters,
|
|
492
583
|
documentTypeFilters,
|
|
493
584
|
documentAttachmentFilters,
|
|
585
|
+
documentTrayOpen,
|
|
586
|
+
imageTrayOpen,
|
|
587
|
+
agentTrayOpen,
|
|
494
588
|
planningDrawerOpen,
|
|
495
589
|
planningTreeCollapsed,
|
|
496
590
|
planningPrimaryCollapsed,
|
|
@@ -568,6 +662,7 @@ export function StandaloneLayout(props) {
|
|
|
568
662
|
setRequestedAnnotatedTarget(detail);
|
|
569
663
|
setRequestedAnnotatedSessionId(null);
|
|
570
664
|
setRequestedAnnotatedOpenVersion((current) => current + 1);
|
|
665
|
+
rememberTaskOriginWorkspaceModule(detail.taskId);
|
|
571
666
|
setActiveWorkspaceModule('annotate');
|
|
572
667
|
};
|
|
573
668
|
window.addEventListener('taskforce:open-annotated-attachment', handleOpenAnnotatedAttachment);
|
|
@@ -579,6 +674,7 @@ export function StandaloneLayout(props) {
|
|
|
579
674
|
annotatedAttachmentsWorkspaceEnabled,
|
|
580
675
|
annotatedAttachmentsWorkspaceUnavailableMessage,
|
|
581
676
|
pushNotice,
|
|
677
|
+
rememberTaskOriginWorkspaceModule,
|
|
582
678
|
setActiveWorkspaceModule
|
|
583
679
|
]);
|
|
584
680
|
useEffect(() => {
|
|
@@ -674,7 +770,14 @@ export function StandaloneLayout(props) {
|
|
|
674
770
|
}, [props.deletedTasks]);
|
|
675
771
|
const filteredDeletedTasks = useMemo(() => {
|
|
676
772
|
const deletedTasks = deletedScopeAllTasks;
|
|
677
|
-
const
|
|
773
|
+
const normalizedSearch = normalizeTaskSearchQuery(searchQuery);
|
|
774
|
+
const searchContext = {
|
|
775
|
+
categories: activeCategories,
|
|
776
|
+
types: activeTypes,
|
|
777
|
+
priorities,
|
|
778
|
+
assigneeOptions: props.assigneeOptions,
|
|
779
|
+
taxonomies
|
|
780
|
+
};
|
|
678
781
|
const allCategoriesSelected = activeCategories.every((taskCategory) => filterCategories.includes(taskCategory.value));
|
|
679
782
|
const allTypesSelected = activeTypes.every((taskType) => filterTypes.includes(taskType.value));
|
|
680
783
|
const selectedPriorities = new Set(filterPriorities.map((value) => String(value)));
|
|
@@ -682,12 +785,7 @@ export function StandaloneLayout(props) {
|
|
|
682
785
|
const selectedStatuses = new Set(filterStatus.map((value) => String(value)));
|
|
683
786
|
const allStatusesSelected = STATUS_OPTIONS.every((statusOption) => selectedStatuses.has(String(statusOption.value)));
|
|
684
787
|
return deletedTasks.filter((task) => {
|
|
685
|
-
const
|
|
686
|
-
const matchesSearch = !searchNeedle
|
|
687
|
-
|| task.title.toLowerCase().includes(searchNeedle)
|
|
688
|
-
|| String(task.description || '').toLowerCase().includes(searchNeedle)
|
|
689
|
-
|| task.id.toLowerCase().includes(searchNeedle)
|
|
690
|
-
|| referenceLabel.includes(searchNeedle);
|
|
788
|
+
const matchesSearch = taskMatchesSearch(task, normalizedSearch, searchContext);
|
|
691
789
|
const matchesCategory = allCategoriesSelected || filterCategories.includes(task.category);
|
|
692
790
|
const matchesType = allTypesSelected || filterTypes.includes(task.type || DEFAULT_TYPE_VALUE);
|
|
693
791
|
const matchesPriority = allPrioritiesSelected || selectedPriorities.has(String(task.priority));
|
|
@@ -781,6 +879,11 @@ export function StandaloneLayout(props) {
|
|
|
781
879
|
: taskScope === 'deleted'
|
|
782
880
|
? deletedScopeAllTasks
|
|
783
881
|
: props.tasks.filter((task) => !task.isArchived);
|
|
882
|
+
const planningPreviewTasks = taskScope === 'deleted'
|
|
883
|
+
? deletedScopeAllTasks
|
|
884
|
+
: Array.from([...props.tasks, ...archivedScopeAllTasks]
|
|
885
|
+
.reduce((map, task) => map.set(task.id, task), new Map())
|
|
886
|
+
.values());
|
|
784
887
|
const summarizeTaskCounts = (taskCount, completedTaskCount) => {
|
|
785
888
|
return {
|
|
786
889
|
progressPercent: taskCount > 0 ? Math.round((completedTaskCount / taskCount) * 100) : 0,
|
|
@@ -792,9 +895,11 @@ export function StandaloneLayout(props) {
|
|
|
792
895
|
&& props.planningBootstrapTaskSummaries.length > 0
|
|
793
896
|
&& (props.loadingTasks || props.tasks.length === 0);
|
|
794
897
|
const workstreamTaskSummaryById = new Map();
|
|
898
|
+
const workstreamTaskPreviewsById = new Map();
|
|
795
899
|
if (useBootstrapTaskSummaries) {
|
|
796
900
|
props.planningBootstrapTaskSummaries.forEach((summary) => {
|
|
797
901
|
workstreamTaskSummaryById.set(summary.workstreamId, summary);
|
|
902
|
+
workstreamTaskPreviewsById.set(summary.workstreamId, summary.tasks || []);
|
|
798
903
|
});
|
|
799
904
|
}
|
|
800
905
|
else {
|
|
@@ -812,13 +917,21 @@ export function StandaloneLayout(props) {
|
|
|
812
917
|
if (task.isArchived || task.status === 'done' || task.status === 'cancelled') {
|
|
813
918
|
current.completedTaskCount += 1;
|
|
814
919
|
}
|
|
815
|
-
|
|
920
|
+
workstreamTaskSummaryById.set(workstreamId, current);
|
|
921
|
+
});
|
|
922
|
+
planningPreviewTasks.forEach((task) => {
|
|
923
|
+
const workstreamId = String(task.workstreamId || '').trim();
|
|
924
|
+
if (!workstreamId)
|
|
925
|
+
return;
|
|
926
|
+
const current = workstreamTaskPreviewsById.get(workstreamId) || [];
|
|
927
|
+
current.push({
|
|
816
928
|
id: task.id,
|
|
817
929
|
referenceNumber: task.referenceNumber ?? null,
|
|
818
930
|
title: task.title,
|
|
819
931
|
status: task.status || null,
|
|
932
|
+
isArchived: Boolean(task.isArchived),
|
|
820
933
|
});
|
|
821
|
-
|
|
934
|
+
workstreamTaskPreviewsById.set(workstreamId, current);
|
|
822
935
|
});
|
|
823
936
|
}
|
|
824
937
|
const workstreamTaskIds = new Map();
|
|
@@ -827,12 +940,13 @@ export function StandaloneLayout(props) {
|
|
|
827
940
|
const workstreamsByInitiativeId = new Map();
|
|
828
941
|
const buildWorkstreamSummary = (workstream) => {
|
|
829
942
|
const taskSummary = workstreamTaskSummaryById.get(workstream.id);
|
|
830
|
-
const taskPreviews = taskSummary?.tasks || [];
|
|
943
|
+
const taskPreviews = workstreamTaskPreviewsById.get(workstream.id) || taskSummary?.tasks || [];
|
|
831
944
|
const summary = {
|
|
832
945
|
id: workstream.id,
|
|
833
946
|
referenceNumber: workstream.referenceNumber ?? null,
|
|
834
947
|
title: workstream.title,
|
|
835
948
|
description: String(workstream.description || '').trim() || undefined,
|
|
949
|
+
ownerId: workstream.ownerId ? String(workstream.ownerId) : null,
|
|
836
950
|
ownerLabel: workstream.ownerId ? assigneeLabelByValue.get(String(workstream.ownerId)) || String(workstream.ownerId) : null,
|
|
837
951
|
...summarizeTaskCounts(taskSummary?.taskCount || 0, taskSummary?.completedTaskCount || 0),
|
|
838
952
|
initiativeId: workstream.initiativeId || null,
|
|
@@ -854,7 +968,8 @@ export function StandaloneLayout(props) {
|
|
|
854
968
|
const allWorkstreamSummaries = props.workstreams.map(buildWorkstreamSummary);
|
|
855
969
|
const scopedWorkstreamSummaries = allWorkstreamSummaries.filter((workstream) => (isPlanningEntityVisibleForScope(taskScope, Boolean(workstream.isArchived))));
|
|
856
970
|
const allInitiatives = props.initiatives.map((initiative) => {
|
|
857
|
-
const
|
|
971
|
+
const allWorkstreamsForInitiative = workstreamsByInitiativeId.get(initiative.id) || [];
|
|
972
|
+
const workstreams = allWorkstreamsForInitiative
|
|
858
973
|
.filter((workstream) => isPlanningEntityVisibleForScope(taskScope, Boolean(workstream.isArchived)));
|
|
859
974
|
const taskCount = workstreams.reduce((sum, workstream) => sum + workstream.taskCount, 0);
|
|
860
975
|
const completedTaskCount = workstreams.reduce((sum, workstream) => sum + workstream.completedTaskCount, 0);
|
|
@@ -863,10 +978,12 @@ export function StandaloneLayout(props) {
|
|
|
863
978
|
referenceNumber: initiative.referenceNumber ?? null,
|
|
864
979
|
title: initiative.title,
|
|
865
980
|
description: String(initiative.description || '').trim() || undefined,
|
|
981
|
+
ownerId: initiative.ownerId ? String(initiative.ownerId) : null,
|
|
866
982
|
ownerLabel: initiative.ownerId ? assigneeLabelByValue.get(String(initiative.ownerId)) || String(initiative.ownerId) : null,
|
|
867
983
|
...summarizeTaskCounts(taskCount, completedTaskCount),
|
|
868
984
|
workstreamCount: workstreams.length,
|
|
869
985
|
workstreams,
|
|
986
|
+
allWorkstreams: allWorkstreamsForInitiative,
|
|
870
987
|
commentCount: Array.isArray(initiative.comments) ? initiative.comments.length : 0,
|
|
871
988
|
attachmentCount: Array.isArray(initiative.attachments) ? initiative.attachments.length : 0,
|
|
872
989
|
attachments: Array.isArray(initiative.attachments) ? initiative.attachments : [],
|
|
@@ -875,12 +992,14 @@ export function StandaloneLayout(props) {
|
|
|
875
992
|
return initiativeSummary;
|
|
876
993
|
});
|
|
877
994
|
const { initiatives, standaloneWorkstreams, visibleWorkstreams, initiativeById, workstreamById, } = scopePlanningSummaries(allInitiatives, scopedWorkstreamSummaries, taskScope);
|
|
995
|
+
const allStandaloneWorkstreams = allWorkstreamSummaries.filter((workstream) => !workstream.initiativeId);
|
|
878
996
|
initiatives.forEach((initiative) => {
|
|
879
997
|
initiativeTaskIds.set(initiative.id, initiative.workstreams.flatMap((workstream) => (workstream.tasks || []).map((task) => task.id)));
|
|
880
998
|
});
|
|
881
999
|
return {
|
|
882
1000
|
initiatives,
|
|
883
1001
|
standaloneWorkstreams,
|
|
1002
|
+
allStandaloneWorkstreams,
|
|
884
1003
|
workstreamTaskIds,
|
|
885
1004
|
workstreamInitiativeIds,
|
|
886
1005
|
initiativeTaskIds,
|
|
@@ -1829,6 +1948,39 @@ export function StandaloneLayout(props) {
|
|
|
1829
1948
|
props,
|
|
1830
1949
|
pushNotice
|
|
1831
1950
|
]);
|
|
1951
|
+
const handleOpenKanbanFromBrand = useCallback(() => {
|
|
1952
|
+
if (isPlansScreen) {
|
|
1953
|
+
void handlePlansBack();
|
|
1954
|
+
return;
|
|
1955
|
+
}
|
|
1956
|
+
handleNavigation(() => {
|
|
1957
|
+
clearTaskOriginWorkspaceModule();
|
|
1958
|
+
setActiveWorkspaceModule('tasks');
|
|
1959
|
+
setPlanningDrawerOpen(false);
|
|
1960
|
+
setPlanningDrawerDetail(null);
|
|
1961
|
+
setPlanningNestedWorkstreamDetailId(null);
|
|
1962
|
+
setPlanningEditor(null);
|
|
1963
|
+
setTaskModalFullscreen(false);
|
|
1964
|
+
if (activeTab === 'add')
|
|
1965
|
+
resetForm();
|
|
1966
|
+
setActiveTab('tasks');
|
|
1967
|
+
if (location.pathname !== '/' || location.search) {
|
|
1968
|
+
navigate('/');
|
|
1969
|
+
}
|
|
1970
|
+
});
|
|
1971
|
+
}, [
|
|
1972
|
+
activeTab,
|
|
1973
|
+
clearTaskOriginWorkspaceModule,
|
|
1974
|
+
handleNavigation,
|
|
1975
|
+
handlePlansBack,
|
|
1976
|
+
isPlansScreen,
|
|
1977
|
+
location.pathname,
|
|
1978
|
+
location.search,
|
|
1979
|
+
navigate,
|
|
1980
|
+
resetForm,
|
|
1981
|
+
setActiveTab,
|
|
1982
|
+
setActiveWorkspaceModule,
|
|
1983
|
+
]);
|
|
1832
1984
|
const handleSwitchWorkspace = useCallback(async (workspaceId) => {
|
|
1833
1985
|
if (!workspaceId || workspaceActionBusy)
|
|
1834
1986
|
return;
|
|
@@ -2495,13 +2647,6 @@ export function StandaloneLayout(props) {
|
|
|
2495
2647
|
setPlanningSecondaryCollapsed(false);
|
|
2496
2648
|
setPlanningNestedWorkstreamDetailId(workstreamId);
|
|
2497
2649
|
}, []);
|
|
2498
|
-
const ownerValueByLabel = useMemo(() => {
|
|
2499
|
-
const map = new Map();
|
|
2500
|
-
assigneeOptions.forEach((option) => {
|
|
2501
|
-
map.set(option.label, String(option.value));
|
|
2502
|
-
});
|
|
2503
|
-
return map;
|
|
2504
|
-
}, [assigneeOptions]);
|
|
2505
2650
|
const openPlanningCreateEditor = useCallback((type, initiativeId) => {
|
|
2506
2651
|
if (type === 'workstream' && initiativeId) {
|
|
2507
2652
|
openPlanningSecondaryEditor({ mode: 'create', entityType: 'workstream' }, initiativeId);
|
|
@@ -2523,7 +2668,7 @@ export function StandaloneLayout(props) {
|
|
|
2523
2668
|
setPlanningEditor({ mode: 'edit', entityType: 'initiative', targetId: id });
|
|
2524
2669
|
setPlanningDraftTitle(item.title);
|
|
2525
2670
|
setPlanningDraftDescription(item.description || '');
|
|
2526
|
-
setPlanningDraftOwner(item.
|
|
2671
|
+
setPlanningDraftOwner(item.ownerId ? String(item.ownerId) : '');
|
|
2527
2672
|
setPlanningDraftInitiativeId('');
|
|
2528
2673
|
}
|
|
2529
2674
|
else {
|
|
@@ -2534,12 +2679,12 @@ export function StandaloneLayout(props) {
|
|
|
2534
2679
|
setPlanningEditor({ mode: 'edit', entityType: 'workstream', targetId: id });
|
|
2535
2680
|
setPlanningDraftTitle(item.title);
|
|
2536
2681
|
setPlanningDraftDescription(item.description || '');
|
|
2537
|
-
setPlanningDraftOwner(item.
|
|
2682
|
+
setPlanningDraftOwner(item.ownerId ? String(item.ownerId) : '');
|
|
2538
2683
|
const initiative = item.initiativeId ? planningStructure.initiativeById.get(item.initiativeId) || null : null;
|
|
2539
2684
|
setPlanningDraftInitiativeId(initiative ? formatInitiativeReference(initiative) : '');
|
|
2540
2685
|
}
|
|
2541
2686
|
setPlanningNestedWorkstreamDetailId(null);
|
|
2542
|
-
}, [
|
|
2687
|
+
}, [planningStructure.initiativeById, planningStructure.standaloneWorkstreams, planningStructure.workstreamById]);
|
|
2543
2688
|
const handleAssignInitiativeToWorkstream = useCallback(async (workstreamId, initiativeReferenceOverride) => {
|
|
2544
2689
|
const workstream = props.workstreams.find((item) => item.id === workstreamId);
|
|
2545
2690
|
if (!workstream) {
|
|
@@ -2710,8 +2855,10 @@ export function StandaloneLayout(props) {
|
|
|
2710
2855
|
pushNotice(`${unavailableLabel} is not available in this build yet.`, 'error');
|
|
2711
2856
|
return;
|
|
2712
2857
|
}
|
|
2858
|
+
clearTaskOriginWorkspaceModule();
|
|
2713
2859
|
setActiveWorkspaceModule(nextModule);
|
|
2714
2860
|
}, [
|
|
2861
|
+
clearTaskOriginWorkspaceModule,
|
|
2715
2862
|
pushNotice,
|
|
2716
2863
|
setActiveWorkspaceModule,
|
|
2717
2864
|
workspaceModules,
|
|
@@ -2731,10 +2878,40 @@ export function StandaloneLayout(props) {
|
|
|
2731
2878
|
}
|
|
2732
2879
|
setPlanningDrawerOpen((current) => !current);
|
|
2733
2880
|
}, [planningDrawerOpen, resolvedWorkspaceModule, setActiveWorkspaceModule]);
|
|
2881
|
+
const handleDocumentTrayToggle = useCallback(() => {
|
|
2882
|
+
if (resolvedWorkspaceModule !== 'docs') {
|
|
2883
|
+
setActiveWorkspaceModule('docs');
|
|
2884
|
+
setDocumentTrayOpen(true);
|
|
2885
|
+
return;
|
|
2886
|
+
}
|
|
2887
|
+
setDocumentTrayOpen((current) => !current);
|
|
2888
|
+
}, [resolvedWorkspaceModule, setActiveWorkspaceModule]);
|
|
2889
|
+
const handleImageTrayToggle = useCallback(() => {
|
|
2890
|
+
if (resolvedWorkspaceModule !== 'annotate') {
|
|
2891
|
+
setActiveWorkspaceModule('annotate');
|
|
2892
|
+
setImageTrayOpen(true);
|
|
2893
|
+
return;
|
|
2894
|
+
}
|
|
2895
|
+
setImageTrayOpen((current) => !current);
|
|
2896
|
+
}, [resolvedWorkspaceModule, setActiveWorkspaceModule]);
|
|
2897
|
+
const handleAgentTrayToggle = useCallback(() => {
|
|
2898
|
+
if (resolvedWorkspaceModule !== 'agents') {
|
|
2899
|
+
setActiveWorkspaceModule('agents');
|
|
2900
|
+
setAgentTrayOpen(true);
|
|
2901
|
+
return;
|
|
2902
|
+
}
|
|
2903
|
+
setAgentTrayOpen((current) => !current);
|
|
2904
|
+
}, [resolvedWorkspaceModule, setActiveWorkspaceModule]);
|
|
2734
2905
|
const handleBackToTaskFromAnnotatedAttachment = useCallback((taskId) => {
|
|
2906
|
+
clearTaskOriginWorkspaceModule();
|
|
2907
|
+
setActiveWorkspaceModule('tasks');
|
|
2908
|
+
handleOpenTaskById(taskId);
|
|
2909
|
+
}, [clearTaskOriginWorkspaceModule, handleOpenTaskById, setActiveWorkspaceModule]);
|
|
2910
|
+
const handleBackToTaskFromDocument = useCallback((taskId) => {
|
|
2911
|
+
clearTaskOriginWorkspaceModule();
|
|
2735
2912
|
setActiveWorkspaceModule('tasks');
|
|
2736
2913
|
handleOpenTaskById(taskId);
|
|
2737
|
-
}, [handleOpenTaskById, setActiveWorkspaceModule]);
|
|
2914
|
+
}, [clearTaskOriginWorkspaceModule, handleOpenTaskById, setActiveWorkspaceModule]);
|
|
2738
2915
|
const handleAnnotatedAttachmentOpenTarget = useCallback((target, options) => {
|
|
2739
2916
|
setRequestedAnnotatedTarget(target);
|
|
2740
2917
|
setRequestedAnnotatedSessionId(options?.sessionId ?? null);
|
|
@@ -2925,18 +3102,45 @@ export function StandaloneLayout(props) {
|
|
|
2925
3102
|
workflows: _jsx(Workflow, { size: 18 }),
|
|
2926
3103
|
agents: _jsx(Bot, { size: 18 }),
|
|
2927
3104
|
};
|
|
2928
|
-
|
|
3105
|
+
const trayButtonDisabledClass = shellStyles.workspaceToolButtonDisabled || '';
|
|
3106
|
+
const workspaceTrayButton = (() => {
|
|
3107
|
+
if (resolvedWorkspaceModule === 'docs') {
|
|
3108
|
+
return (_jsx("button", { type: "button", className: `${shellStyles.workspaceToolButton} ${documentTrayOpen ? shellStyles.workspaceToolButtonActive : ''}`.trim(), onClick: handleDocumentTrayToggle, title: documentTrayOpen ? 'Collapse document tray' : 'Document tray', "aria-label": documentTrayOpen ? 'Collapse document tray' : 'Document tray', children: documentTrayOpen ? _jsx(ChevronLeft, { size: 18 }) : _jsx(Folder, { size: 18 }) }));
|
|
3109
|
+
}
|
|
3110
|
+
if (resolvedWorkspaceModule === 'annotate') {
|
|
3111
|
+
return (_jsx("button", { type: "button", className: `${shellStyles.workspaceToolButton} ${imageTrayOpen ? shellStyles.workspaceToolButtonActive : ''}`.trim(), onClick: handleImageTrayToggle, title: imageTrayOpen ? 'Collapse image tray' : 'Image tray', "aria-label": imageTrayOpen ? 'Collapse image tray' : 'Image tray', children: imageTrayOpen ? _jsx(ChevronLeft, { size: 18 }) : _jsx(Folder, { size: 18 }) }));
|
|
3112
|
+
}
|
|
3113
|
+
if (resolvedWorkspaceModule === 'agents') {
|
|
3114
|
+
return (_jsx("button", { type: "button", className: `${shellStyles.workspaceToolButton} ${agentTrayOpen ? shellStyles.workspaceToolButtonActive : ''}`.trim(), onClick: handleAgentTrayToggle, title: agentTrayOpen ? 'Collapse agent tray' : 'MCP settings tray', "aria-label": agentTrayOpen ? 'Collapse agent tray' : 'MCP settings tray', children: agentTrayOpen ? _jsx(ChevronLeft, { size: 18 }) : _jsx(Plug, { size: 18 }) }));
|
|
3115
|
+
}
|
|
3116
|
+
if (resolvedWorkspaceModule === 'workflows') {
|
|
3117
|
+
return (_jsx("button", { type: "button", className: `${shellStyles.workspaceToolButton} ${trayButtonDisabledClass}`.trim(), title: "Workflow tray coming soon", "aria-label": "Workflow tray coming soon", disabled: true, children: _jsx(Workflow, { size: 18 }) }));
|
|
3118
|
+
}
|
|
3119
|
+
return (_jsx("button", { type: "button", className: `${shellStyles.workspaceToolButton} ${(resolvedWorkspaceModule === 'tasks' && planningDrawerOpen) ? shellStyles.workspaceToolButtonActive : ''}`.trim(), onClick: handlePlanningToolToggle, title: resolvedWorkspaceModule === 'tasks' && planningDrawerOpen ? 'Collapse planning trays' : 'Planning', "aria-label": resolvedWorkspaceModule === 'tasks' && planningDrawerOpen ? 'Collapse planning trays' : 'Planning', children: resolvedWorkspaceModule === 'tasks' && planningDrawerOpen ? _jsx(ChevronLeft, { size: 18 }) : _jsx(NotebookTabs, { size: 18 }) }));
|
|
3120
|
+
})();
|
|
3121
|
+
return (_jsxs("aside", { className: shellStyles.workspaceToolRail, "aria-label": "Workspace tools", children: [_jsxs("div", { className: shellStyles.workspaceToolRailMain, children: [workspaceTrayButton, _jsx("div", { className: shellStyles.workspaceToolRailDivider }), workspaceToolModules.map((module) => (_jsx("button", { type: "button", className: `${shellStyles.workspaceToolButton} ${resolvedWorkspaceModule === module.id ? shellStyles.workspaceToolButtonActive : ''}`.trim(), onClick: () => handleModuleChange(module.id), title: module.label, "aria-label": module.label, children: moduleIcons[module.id] }, module.id)))] }), _jsxs("div", { className: shellStyles.workspaceToolRailBottom, children: [_jsx("div", { className: shellStyles.workspaceToolRailDivider }), _jsx("button", { type: "button", className: `${shellStyles.workspaceToolButton} ${activeTab === 'settings' ? shellStyles.workspaceToolButtonActive : ''}`.trim(), onClick: () => {
|
|
2929
3122
|
setSettingsSection('general');
|
|
2930
3123
|
setActiveTab('settings');
|
|
2931
3124
|
}, title: "Workspace Settings", "aria-label": "Workspace Settings", children: _jsx(Settings, { size: 18 }) })] })] }));
|
|
2932
|
-
}, [activeTab, handleModuleChange, handlePlanningToolToggle, planningDrawerOpen, resolvedWorkspaceModule, setSettingsSection, setActiveTab, workspaceToolModules]);
|
|
2933
|
-
const
|
|
2934
|
-
const
|
|
3125
|
+
}, [activeTab, agentTrayOpen, documentTrayOpen, handleAgentTrayToggle, handleDocumentTrayToggle, handleImageTrayToggle, handleModuleChange, handlePlanningToolToggle, imageTrayOpen, planningDrawerOpen, resolvedWorkspaceModule, setSettingsSection, setActiveTab, workspaceToolModules]);
|
|
3126
|
+
const [planningDrawerPortalElement, setPlanningDrawerPortalElement] = useState(null);
|
|
3127
|
+
const setPlanningDrawerPortalRef = useCallback((node) => {
|
|
3128
|
+
setPlanningDrawerPortalElement(node);
|
|
3129
|
+
}, []);
|
|
3130
|
+
const planningDrawerNode = (_jsx(PlanningDrawer, { open: planningDrawerOpen, leftOffset: WORKSPACE_TOOL_RAIL_WIDTH, initiatives: planningStructure.initiatives, standaloneWorkstreams: planningStructure.standaloneWorkstreams, allStandaloneWorkstreams: planningStructure.allStandaloneWorkstreams, activeInitiativeId: selectedPlanningInitiativeId, activeWorkstreamId: selectedPlanningWorkstreamId, expandedInitiativeIds: expandedPlanningInitiativeIds, detail: planningDrawerItem, editor: planningEditor, secondaryPane: planningSecondaryPane, currentWorkspaceId: currentWorkspaceId, assigneeOptions: assigneeOptions.map((option) => ({
|
|
3131
|
+
value: String(option.value),
|
|
3132
|
+
label: option.label,
|
|
3133
|
+
kind: option.kind,
|
|
3134
|
+
username: option.username ?? null,
|
|
3135
|
+
archivedAt: option.archivedAt ?? null
|
|
3136
|
+
})), draftInitiativeSummary: planningDraftInitiativeSummary, draftTitle: planningDraftTitle, draftDescription: planningDraftDescription, draftOwner: planningDraftOwner, draftInitiativeId: planningDraftInitiativeId, onChangeDraftTitle: setPlanningDraftTitle, onChangeDraftDescription: setPlanningDraftDescription, onChangeDraftOwner: setPlanningDraftOwner, onChangeDraftInitiativeId: setPlanningDraftInitiativeId, onCollapseTreePane: () => setPlanningTreeCollapsed(true), onExpandTreePane: () => setPlanningTreeCollapsed(false), onCollapsePrimaryPane: () => setPlanningPrimaryCollapsed(true), onExpandPrimaryPane: () => setPlanningPrimaryCollapsed(false), onCollapseSecondaryPane: () => setPlanningSecondaryCollapsed(true), onExpandSecondaryPane: () => setPlanningSecondaryCollapsed(false), onBackFromSecondary: () => {
|
|
2935
3137
|
planningEditorSubmitInFlightRef.current = false;
|
|
2936
3138
|
setIsSubmittingPlanningEditor(false);
|
|
2937
3139
|
setPlanningSecondaryEditor(null);
|
|
2938
3140
|
setPlanningNestedWorkstreamDetailId(null);
|
|
2939
|
-
}, treeCollapsed: planningTreeCollapsed, primaryCollapsed: planningPrimaryCollapsed, secondaryCollapsed: planningSecondaryCollapsed, onCancelEditor: closePlanningEditor, onSubmitEditor: submitPlanningEditor, isSubmittingEditor: isSubmittingPlanningEditor, onCreateInitiative: () => openPlanningCreateEditor('initiative'), onCreateWorkstream: () => openPlanningCreateEditor('workstream'), onCreateTaskInWorkstream: openAddTaskModalForWorkstream, onCreateWorkstreamInInitiative: (initiativeId) => openPlanningCreateEditor('workstream', initiativeId), onAssignInitiativeToWorkstream: handleAssignInitiativeToWorkstream, onOpenTaskById: handleOpenTaskById,
|
|
3141
|
+
}, treeCollapsed: planningTreeCollapsed, primaryCollapsed: planningPrimaryCollapsed, secondaryCollapsed: planningSecondaryCollapsed, onCancelEditor: closePlanningEditor, onSubmitEditor: submitPlanningEditor, isSubmittingEditor: isSubmittingPlanningEditor, onCreateInitiative: () => openPlanningCreateEditor('initiative'), onCreateWorkstream: () => openPlanningCreateEditor('workstream'), onCreateTaskInWorkstream: openAddTaskModalForWorkstream, onCreateWorkstreamInInitiative: (initiativeId) => openPlanningCreateEditor('workstream', initiativeId), onAssignInitiativeToWorkstream: handleAssignInitiativeToWorkstream, onOpenTaskById: handleOpenTaskById, onRemoveTaskFromWorkstream: (taskId) => {
|
|
3142
|
+
void handleAssignTaskToWorkstream(taskId, null);
|
|
3143
|
+
}, onAttachTaskToWorkstreamByReference: handleAttachTaskToWorkstreamByReference, onAttachWorkstreamToInitiativeByReference: handleAttachWorkstreamToInitiativeByReference, onAddPlanningContextFile: handleAddPlanningContextFile, onRemovePlanningContextFile: handleRemovePlanningContextFile, onUpdatePlanningContextCaption: handleUpdatePlanningContextCaption, onToggleInitiative: togglePlanningInitiative, onSelectInitiative: selectPlanningInitiative, onSelectWorkstream: selectPlanningWorkstream, onOpenInitiativeDetails: openInitiativeDetails, onOpenWorkstreamDetails: openWorkstreamDetails, onOpenNestedWorkstreamDetails: openNestedWorkstreamDetails, onEditInitiative: (initiativeId) => openPlanningEditDialog('initiative', initiativeId), onEditWorkstream: (workstreamId) => openPlanningEditDialog('workstream', workstreamId), onArchiveInitiative: (initiativeId) => {
|
|
2940
3144
|
void props.archiveInitiative(initiativeId).then(() => {
|
|
2941
3145
|
pushNotice('Initiative archived', 'success');
|
|
2942
3146
|
}).catch((error) => {
|
|
@@ -2971,7 +3175,7 @@ export function StandaloneLayout(props) {
|
|
|
2971
3175
|
const workspacePrimaryAction = workspaceChromeDefinition.primaryAction
|
|
2972
3176
|
? primaryActionRegistry[workspaceChromeDefinition.primaryAction]
|
|
2973
3177
|
: null;
|
|
2974
|
-
return (_jsxs("div", { className: `${shellStyles.standaloneWrapper} ${zenMode ? styles.zenModeEnabled : ''}`, "data-theme": currentTheme, children: [_jsx(AppShellHeader, { projectName: projectName, currentWorkspaceId: currentWorkspaceId, runtimeMode: runtimeMode, theme: currentTheme, meta: (_jsxs(_Fragment, { children: [_jsx("span", { className: styles.taskCountBadge, title: activeCountTitle, children: activeCountLabel }), normalizedAuthUserId && normalizedAuthUserId !== 'anonymous' && (_jsxs(_Fragment, { children: [_jsxs("span", { className: styles.taskCountBadge, title: "Tasks assigned to me", children: [_jsx(User, { size: 13, className: styles.taskCountBadgeIcon, "aria-hidden": "true" }), assignedTaskCount] }), _jsxs("span", { className: `${styles.taskCountBadge} ${assignedOverdueTaskCount > 0 ? styles.taskCountBadgeAlert : ''}`.trim(), title: "Tasks overdue", children: [_jsx(ClockAlert, { size: 13, className: styles.taskCountBadgeIcon, "aria-hidden": "true" }), assignedOverdueTaskCount] })] })), shouldShowSyncStatus && (_jsx("button", { className: "tf-control-icon", onClick: openSyncStatusModal, title: `Sync manager: ${syncStatusMeta.label} | Last success: ${formattedLastSyncTime}`, style: {
|
|
3178
|
+
return (_jsxs("div", { className: `${shellStyles.standaloneWrapper} ${zenMode ? styles.zenModeEnabled : ''}`, "data-theme": currentTheme, children: [_jsx(AppShellHeader, { projectName: projectName, currentWorkspaceId: currentWorkspaceId, runtimeMode: runtimeMode, theme: currentTheme, onBrandClick: handleOpenKanbanFromBrand, meta: (_jsxs(_Fragment, { children: [_jsx("span", { className: styles.taskCountBadge, title: activeCountTitle, children: activeCountLabel }), normalizedAuthUserId && normalizedAuthUserId !== 'anonymous' && (_jsxs(_Fragment, { children: [_jsxs("span", { className: styles.taskCountBadge, title: "Tasks assigned to me", children: [_jsx(User, { size: 13, className: styles.taskCountBadgeIcon, "aria-hidden": "true" }), assignedTaskCount] }), _jsxs("span", { className: `${styles.taskCountBadge} ${assignedOverdueTaskCount > 0 ? styles.taskCountBadgeAlert : ''}`.trim(), title: "Tasks overdue", children: [_jsx(ClockAlert, { size: 13, className: styles.taskCountBadgeIcon, "aria-hidden": "true" }), assignedOverdueTaskCount] })] })), shouldShowSyncStatus && (_jsx("button", { className: "tf-control-icon", onClick: openSyncStatusModal, title: `Sync manager: ${syncStatusMeta.label} | Last success: ${formattedLastSyncTime}`, style: {
|
|
2975
3179
|
marginLeft: '6px',
|
|
2976
3180
|
height: '24px',
|
|
2977
3181
|
width: '24px',
|
|
@@ -2998,10 +3202,14 @@ export function StandaloneLayout(props) {
|
|
|
2998
3202
|
overflowX: 'hidden',
|
|
2999
3203
|
scrollbarGutter: 'stable',
|
|
3000
3204
|
background: 'var(--surface-page)'
|
|
3001
|
-
}, children: _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(PlansPage, { ...props, currentTheme: currentTheme, projectName: projectName, currentWorkspaceId: currentWorkspaceId, authUserId: authUserId, apiBaseUrl: apiBaseUrl, connectedEnvironmentSource: props.config?.cloudAuthBaseUrl || props.config?.apiBaseUrl || '', resolveCloudAuthUrl: resolveCloudAuthUrl, embedded: true, shellOwnsScroll: true, onAccountProfileSummaryChange: applyPlansAccountProfileSummary, onContinueToTaskforce: handlePlansBack, continueBusy: plansNavigationBusy }) }) })) : resolvedWorkspaceModule === 'docs' && documentsWorkspaceEnabled ? (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent}`, style: { position: 'relative', display: 'flex', flex: 1, minHeight: 0, overflow: 'hidden', paddingLeft: `${WORKSPACE_TOOL_RAIL_WIDTH}px` }, children: [workspaceToolRail, _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(DocumentWorkspaceShell, { tasks: tasks, runtimeMode: runtimeMode, apiBaseUrl: props.config?.apiBaseUrl || '', cloudAuthBaseUrl: props.config?.cloudAuthBaseUrl || '', typeFilters: documentTypeFilters, attachmentFilters: documentAttachmentFilters, onTypeFiltersChange: setDocumentTypeFilters, onAttachmentFiltersChange: setDocumentAttachmentFilters, requestedDocPath: requestedDocPath, requestedDocAssetId: requestedDocAssetId, onRequestedDocHandled: () => {
|
|
3205
|
+
}, children: _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(PlansPage, { ...props, currentTheme: currentTheme, projectName: projectName, currentWorkspaceId: currentWorkspaceId, authUserId: authUserId, apiBaseUrl: apiBaseUrl, connectedEnvironmentSource: props.config?.cloudAuthBaseUrl || props.config?.apiBaseUrl || '', resolveCloudAuthUrl: resolveCloudAuthUrl, embedded: true, shellOwnsScroll: true, onAccountProfileSummaryChange: applyPlansAccountProfileSummary, onContinueToTaskforce: handlePlansBack, continueBusy: plansNavigationBusy }) }) })) : resolvedWorkspaceModule === 'docs' && documentsWorkspaceEnabled ? (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent}`, style: { position: 'relative', display: 'flex', flex: 1, minHeight: 0, overflow: 'hidden', paddingLeft: `${WORKSPACE_TOOL_RAIL_WIDTH}px` }, children: [workspaceToolRail, _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(DocumentWorkspaceShell, { tasks: tasks, runtimeMode: runtimeMode, apiBaseUrl: props.config?.apiBaseUrl || '', cloudAuthBaseUrl: props.config?.cloudAuthBaseUrl || '', typeFilters: documentTypeFilters, attachmentFilters: documentAttachmentFilters, onTypeFiltersChange: setDocumentTypeFilters, onAttachmentFiltersChange: setDocumentAttachmentFilters, documentTrayOpen: documentTrayOpen, onCloseDocumentTray: () => setDocumentTrayOpen(false), requestedDocPath: requestedDocPath, requestedDocAssetId: requestedDocAssetId, onRequestedDocHandled: () => {
|
|
3002
3206
|
setRequestedDocPath(null);
|
|
3003
3207
|
setRequestedDocAssetId(null);
|
|
3004
|
-
}, enableTaskGeneration: true }) })] })) : resolvedWorkspaceModule === 'annotate' && annotatedAttachmentsWorkspaceEnabled ? (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent}`, style: { position: 'relative', display: 'flex', flex: 1, minHeight: 0, overflow: 'hidden', paddingLeft: `${WORKSPACE_TOOL_RAIL_WIDTH}px` }, children: [workspaceToolRail, _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(AnnotatedAttachmentWorkspaceShell, { runtimeMode: runtimeMode, apiBaseUrl: props.config?.apiBaseUrl || '', cloudAuthBaseUrl: props.config?.cloudAuthBaseUrl || '', workspaceId: currentWorkspaceId, sessionLoadReady: annotatedWorkspaceReady, requestedTarget: requestedAnnotatedTarget, requestedSessionId: requestedAnnotatedSessionId, requestedOpenVersion: requestedAnnotatedOpenVersion, resolveTaskReferenceLabel: resolveAnnotatedTaskReferenceLabel, resolveImageReferenceLabel: resolveAnnotatedImageReferenceLabel, onOpenTarget: handleAnnotatedAttachmentOpenTarget, onContextChange: handleAnnotatedAttachmentContextChange, onBackToTask: handleBackToTaskFromAnnotatedAttachment }) })] })) : resolvedWorkspaceModule === 'workflows' ? (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent}`, style: { position: 'relative', display: 'flex', flex: 1, minHeight: 0, overflow: 'hidden', paddingLeft: `${WORKSPACE_TOOL_RAIL_WIDTH}px` }, children: [workspaceToolRail, _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(WorkflowsModule, { availableWorkflows: availableWorkflows, availableEnvironments: availableEnvironments, exportEnvironment: exportEnvironment, exportWorkflowsPath: props.exportWorkflowsPath, exportingResource: exportingResource, exportResult: exportResult, onExportEnvironmentChange: props.setExportEnvironment, onExportWorkflows: onExportWorkflows, onRefreshWorkflows: fetchWorkflows, onFetchWorkflowTemplate: props.fetchWorkflowTemplate, onFetchWorkflowOverrideNames: props.fetchWorkflowOverrideNames, onSaveWorkflowTemplateDraft: props.saveWorkflowTemplateDraft, onResetWorkflowTemplateDraft: props.resetWorkflowTemplateDraft }) })] })) : resolvedWorkspaceModule === 'agents' ? (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent}`, style: { position: 'relative', display: 'flex', flex: 1, minHeight: 0, overflow: 'hidden', paddingLeft: `${WORKSPACE_TOOL_RAIL_WIDTH}px` }, children: [workspaceToolRail, _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(AgentsModule, { workspaceId: currentWorkspaceId, cloudAuthConfigured: cloudAuthConfigured, authSessionResolved: authSessionResolved, isAuthenticated: isAuthenticated, cloudAiProfileSeatUsage: accountProfileSummary?.aiProfileSeatUsage ?? null
|
|
3208
|
+
}, onBackToTask: handleBackToTaskFromDocument, enableTaskGeneration: true }) })] })) : resolvedWorkspaceModule === 'annotate' && annotatedAttachmentsWorkspaceEnabled ? (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent}`, style: { position: 'relative', display: 'flex', flex: 1, minHeight: 0, overflow: 'hidden', paddingLeft: `${WORKSPACE_TOOL_RAIL_WIDTH}px` }, children: [workspaceToolRail, _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(AnnotatedAttachmentWorkspaceShell, { runtimeMode: runtimeMode, apiBaseUrl: props.config?.apiBaseUrl || '', cloudAuthBaseUrl: props.config?.cloudAuthBaseUrl || '', workspaceId: currentWorkspaceId, sessionLoadReady: annotatedWorkspaceReady, requestedTarget: requestedAnnotatedTarget, requestedSessionId: requestedAnnotatedSessionId, requestedOpenVersion: requestedAnnotatedOpenVersion, imageTrayOpen: imageTrayOpen, onCloseImageTray: () => setImageTrayOpen(false), resolveTaskReferenceLabel: resolveAnnotatedTaskReferenceLabel, resolveImageReferenceLabel: resolveAnnotatedImageReferenceLabel, onOpenTarget: handleAnnotatedAttachmentOpenTarget, onContextChange: handleAnnotatedAttachmentContextChange, onBackToTask: handleBackToTaskFromAnnotatedAttachment }) })] })) : resolvedWorkspaceModule === 'workflows' ? (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent}`, style: { position: 'relative', display: 'flex', flex: 1, minHeight: 0, overflow: 'hidden', paddingLeft: `${WORKSPACE_TOOL_RAIL_WIDTH}px` }, children: [workspaceToolRail, _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(WorkflowsModule, { availableWorkflows: availableWorkflows, availableEnvironments: availableEnvironments, exportEnvironment: exportEnvironment, exportWorkflowsPath: props.exportWorkflowsPath, exportingResource: exportingResource, exportResult: exportResult, onExportEnvironmentChange: props.setExportEnvironment, onExportWorkflows: onExportWorkflows, onRefreshWorkflows: fetchWorkflows, onFetchWorkflowTemplate: props.fetchWorkflowTemplate, onFetchWorkflowOverrideNames: props.fetchWorkflowOverrideNames, onSaveWorkflowTemplateDraft: props.saveWorkflowTemplateDraft, onResetWorkflowTemplateDraft: props.resetWorkflowTemplateDraft }) })] })) : resolvedWorkspaceModule === 'agents' ? (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent}`, style: { position: 'relative', display: 'flex', flex: 1, minHeight: 0, overflow: 'hidden', paddingLeft: `${WORKSPACE_TOOL_RAIL_WIDTH}px` }, children: [workspaceToolRail, _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(AgentsModule, { workspaceId: currentWorkspaceId, cloudAuthConfigured: cloudAuthConfigured, authSessionResolved: authSessionResolved, isAuthenticated: isAuthenticated, cloudAiProfileSeatUsage: accountProfileSummary?.aiProfileSeatUsage ?? null, agentTrayOpen: agentTrayOpen, onCloseAgentTray: () => setAgentTrayOpen(false), mcpSettingsNode: _jsx(TaskSettings, { settingsModel: {
|
|
3209
|
+
...settingsModel,
|
|
3210
|
+
initialSection: 'mcp',
|
|
3211
|
+
onOpenCloudAuth: openSharedLoginRoute
|
|
3212
|
+
}, renderMode: "mcp-only" }) }) })] })) : (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent} `, style: {
|
|
3005
3213
|
position: 'relative',
|
|
3006
3214
|
opacity: props.loadingTasks ? 0.7 : 1,
|
|
3007
3215
|
transition: 'opacity 0.2s ease, padding 220ms cubic-bezier(0.4, 0, 0.2, 1)',
|
|
@@ -3012,7 +3220,7 @@ export function StandaloneLayout(props) {
|
|
|
3012
3220
|
? `${WORKSPACE_TOOL_RAIL_WIDTH + planningDrawerWidthPx + WORKSPACE_CONTENT_GUTTER}px`
|
|
3013
3221
|
: `${WORKSPACE_TOOL_RAIL_WIDTH + WORKSPACE_CONTENT_GUTTER}px`,
|
|
3014
3222
|
paddingRight: (groupBy === 'schedule' && scheduleSidebarOpen) ? `${SCHEDULE_SIDEBAR_WIDTH_PX}px` : 0
|
|
3015
|
-
}, children: [workspaceToolRail, _jsx("div", { ref:
|
|
3223
|
+
}, children: [workspaceToolRail, _jsx("div", { ref: setPlanningDrawerPortalRef, style: {
|
|
3016
3224
|
position: 'absolute',
|
|
3017
3225
|
inset: 0,
|
|
3018
3226
|
zIndex: 35,
|
|
@@ -3027,8 +3235,8 @@ export function StandaloneLayout(props) {
|
|
|
3027
3235
|
if (groupBy !== 'schedule')
|
|
3028
3236
|
return;
|
|
3029
3237
|
setScheduleScrollLeft(scrollLeft);
|
|
3030
|
-
}, emptyColumnMode: emptyColumnMode, categories: activeCategories, compressed: compressedCards, readOnlyMode: taskScope === 'deleted' ? 'deleted' : taskScope === 'archived' ? 'archived' : null, recentlyChangedTaskIds: props.recentlyChangedTaskIds, sortBy: sortBy, sortOrder: props.sortOrder, planningDropTargets:
|
|
3031
|
-
? createPortal(planningDrawerNode,
|
|
3238
|
+
}, emptyColumnMode: emptyColumnMode, categories: activeCategories, compressed: compressedCards, readOnlyMode: taskScope === 'deleted' ? 'deleted' : taskScope === 'archived' ? 'archived' : null, recentlyChangedTaskIds: props.recentlyChangedTaskIds, sortBy: sortBy, sortOrder: props.sortOrder, planningDropTargets: planningDrawerPortalElement
|
|
3239
|
+
? createPortal(planningDrawerNode, planningDrawerPortalElement)
|
|
3032
3240
|
: null, onAssignTaskToWorkstream: handleAssignTaskToWorkstream, onAssignWorkstreamToInitiative: handleAssignInitiativeToWorkstream, workstreams: props.workstreams, initiatives: props.initiatives, onUnarchive: (taskId) => {
|
|
3033
3241
|
if (taskScope === 'deleted') {
|
|
3034
3242
|
const deletedRecord = deletedTaskRecordByTaskId.get(taskId);
|
|
@@ -3084,41 +3292,17 @@ export function StandaloneLayout(props) {
|
|
|
3084
3292
|
setSettingsSection(section);
|
|
3085
3293
|
setActiveTab('settings');
|
|
3086
3294
|
}, onSubmit: handleSubmit, commentsEndRef: commentsEndRef, onAddComment: () => handleAddComment(newCommentText), onOpenTaskById: handleOpenTaskById, onAddContextFile: (file) => {
|
|
3087
|
-
|
|
3088
|
-
setAttachments((prev) => {
|
|
3089
|
-
nextAttachments = [...prev, file];
|
|
3090
|
-
return nextAttachments;
|
|
3091
|
-
});
|
|
3092
|
-
setAttachmentsDirty(true);
|
|
3093
|
-
if (editingTaskId) {
|
|
3094
|
-
void handleUpdateTask(editingTaskId, { attachments: nextAttachments });
|
|
3095
|
-
}
|
|
3295
|
+
updateTaskContextAttachments((current) => [...current, file]);
|
|
3096
3296
|
}, onRemoveContextFile: async (index) => {
|
|
3097
|
-
|
|
3098
|
-
setAttachments((prev) => {
|
|
3099
|
-
nextAttachments = prev.filter((_, i) => i !== index);
|
|
3100
|
-
return nextAttachments;
|
|
3101
|
-
});
|
|
3102
|
-
setAttachmentsDirty(true);
|
|
3103
|
-
if (editingTaskId) {
|
|
3104
|
-
void handleUpdateTask(editingTaskId, { attachments: nextAttachments });
|
|
3105
|
-
}
|
|
3297
|
+
updateTaskContextAttachments((current) => current.filter((_, i) => i !== index));
|
|
3106
3298
|
}, onUpdateContextCaption: (index, caption) => {
|
|
3107
|
-
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
return { ...s, caption };
|
|
3115
|
-
});
|
|
3116
|
-
return nextAttachments;
|
|
3117
|
-
});
|
|
3118
|
-
setAttachmentsDirty(true);
|
|
3119
|
-
if (editingTaskId) {
|
|
3120
|
-
void handleUpdateTask(editingTaskId, { attachments: nextAttachments });
|
|
3121
|
-
}
|
|
3299
|
+
updateTaskContextAttachments((current) => current.map((s, i) => {
|
|
3300
|
+
if (i !== index)
|
|
3301
|
+
return s;
|
|
3302
|
+
if (typeof s === 'string')
|
|
3303
|
+
return { path: s, caption, timestamp: new Date().toISOString() };
|
|
3304
|
+
return { ...s, caption };
|
|
3305
|
+
}));
|
|
3122
3306
|
}, onCopyId: handleCopyId, onToggleInProgress: handleToggleInProgress, onToggleReview: handleToggleReview, onToggleComplete: handleToggleComplete, onToggleCancel: handleToggleCancel, onSetStatus: handleSetStatus, onArchiveTask: handleArchiveTask, onUnarchive: (taskId) => {
|
|
3123
3307
|
if (currentTask?.isDeleted) {
|
|
3124
3308
|
const deletedRecord = deletedTaskRecordByTaskId.get(taskId);
|
|
@@ -3128,7 +3312,10 @@ export function StandaloneLayout(props) {
|
|
|
3128
3312
|
return;
|
|
3129
3313
|
}
|
|
3130
3314
|
void handleUnarchive(taskId);
|
|
3131
|
-
}, currentTask: currentTask })] }), _jsx(Modal, { isOpen: activeTab === 'settings', onClose: handleCloseModal, title: "Settings", size: "xl", theme: currentTheme, draggable: true, isSettings: true, closeOnOverlayClick: false, children: _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', padding: '2rem' }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(TaskSettings, { settingsModel:
|
|
3315
|
+
}, currentTask: currentTask })] }), _jsx(Modal, { isOpen: activeTab === 'settings', onClose: handleCloseModal, title: "Settings", size: "xl", theme: currentTheme, draggable: true, isSettings: true, closeOnOverlayClick: false, children: _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', padding: '2rem' }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(TaskSettings, { settingsModel: {
|
|
3316
|
+
...settingsModel,
|
|
3317
|
+
onOpenCloudAuth: openSharedLoginRoute
|
|
3318
|
+
}, onSectionChange: setSettingsSection }) }) }), _jsx(ScheduleWarningModal, { prompt: scheduleWarningPrompt, theme: currentTheme, onClose: cancelScheduleWarning, onConfirm: confirmScheduleWarning }), _jsx(SyncEnableWarningModal, { isOpen: showSyncEnableWarning, theme: currentTheme, onClose: cancelSyncEnableWarning, onConfirm: confirmSyncEnableWarning }), _jsx(HelpModal, { isOpen: showHelpModal, theme: currentTheme, onClose: () => setShowHelpModal(false), onOpenSettings: () => {
|
|
3132
3319
|
setShowHelpModal(false);
|
|
3133
3320
|
setActiveTab('settings');
|
|
3134
3321
|
setSettingsSection('general');
|