@taskforcehq/taskforce 0.3.327 → 0.3.328
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Taskforce.module.css +24 -53
- package/dist/components/activity/EntityActivityTimeline.js +15 -5
- package/dist/components/context/AttachmentPreviewHost.js +1 -1
- package/dist/components/context/ContextAttachmentManager.d.ts +3 -0
- package/dist/components/context/ContextAttachmentManager.js +116 -20
- package/dist/components/features/planning/PlanningEntitySummary.d.ts +3 -1
- package/dist/components/features/planning/PlanningEntitySummary.js +3 -2
- package/dist/components/features/planning/PlanningLinkPicker.d.ts +3 -1
- package/dist/components/features/planning/PlanningLinkPicker.js +5 -3
- package/dist/components/features/planning/PlanningModule.js +26 -9
- package/dist/components/features/planning/PlanningVisualIdentity.d.ts +14 -0
- package/dist/components/features/planning/PlanningVisualIdentity.js +106 -0
- package/dist/components/features/planning/planningWorkspaceModel.d.ts +11 -0
- package/dist/components/task/TaskActionHeader.d.ts +2 -1
- package/dist/components/task/TaskActionHeader.js +2 -2
- package/dist/components/task/TaskCard.js +37 -4
- package/dist/components/task/TaskContextUpload.d.ts +3 -0
- package/dist/components/task/TaskContextUpload.js +2 -2
- package/dist/components/task/TaskForm.d.ts +4 -0
- package/dist/components/task/TaskForm.js +32 -7
- package/dist/components/task/TaskImageReviews.js +16 -16
- package/dist/components/task/TaskStatusActions.js +11 -2
- package/dist/components/task/TaskWorkstreamPicker.js +2 -1
- package/dist/components/ui/DocumentTypeIcon.d.ts +7 -0
- package/dist/components/ui/DocumentTypeIcon.js +8 -0
- package/dist/components/ui/TaxonomyDropdown.d.ts +9 -1
- package/dist/components/ui/TaxonomyDropdown.js +30 -3
- package/dist/components/views/StandaloneLayout.js +62 -9
- package/dist/components/views/WidgetView.js +8 -5
- package/dist/components/views/panels/PlanningDrawer.d.ts +7 -1
- package/dist/components/views/panels/PlanningDrawer.js +48 -44
- package/dist/config/envSchema.js +1 -0
- package/dist/config/localServiceCloudTarget.d.ts +10 -0
- package/dist/config/localServiceCloudTarget.js +76 -0
- package/dist/core/AiProfileService.d.ts +1 -0
- package/dist/core/AiProfileService.js +2 -1
- package/dist/core/AttachmentLinkService.js +7 -4
- package/dist/core/DeletedTaskLifecycleService.d.ts +4 -0
- package/dist/core/DeletedTaskLifecycleService.js +21 -0
- package/dist/core/McpTokenService.d.ts +4 -0
- package/dist/core/McpTokenService.js +52 -0
- package/dist/core/TaskAttachmentLinksDurableMutationService.d.ts +5 -0
- package/dist/core/TaskAttachmentLinksDurableMutationService.js +20 -11
- package/dist/core/Taskforce.d.ts +63 -1
- package/dist/core/Taskforce.js +558 -73
- package/dist/core/types.d.ts +2 -1
- package/dist/documentReviews/DocumentReviewCommentStore.d.ts +11 -0
- package/dist/documentReviews/DocumentReviewCommentStore.js +35 -2
- package/dist/documentReviews/service.d.ts +4 -0
- package/dist/documentReviews/service.js +141 -46
- package/dist/hooks/tasks/useTaskFormActions.d.ts +3 -0
- package/dist/hooks/tasks/useTaskFormActions.js +33 -7
- package/dist/hooks/useTaskforce.d.ts +59 -50
- package/dist/hooks/useTaskforce.js +103 -1
- package/dist/mcp/canonicalAssetHelpers.d.ts +13 -0
- package/dist/mcp/canonicalAssetHelpers.js +39 -5
- package/dist/mcp/collaborationRegistrar.js +15 -13
- package/dist/mcp/documentAssetRegistrar.js +16 -9
- package/dist/mcp/localServiceProxy.js +4 -1
- package/dist/mcp/runtime.d.ts +16 -0
- package/dist/mcp/runtime.js +566 -171
- package/dist/mcp/taskAttachmentCommandAdapter.d.ts +2 -0
- package/dist/mcp/taskAttachmentCommandAdapter.js +14 -8
- package/dist/mcp/taskPlanningRegistrar.js +42 -34
- package/dist/mcp/toolRegistry.js +2 -2
- package/dist/migrations/taskSchemaMigrations.js +35 -0
- package/dist/runtime/appGateDefinitions.d.ts +2 -2
- package/dist/runtime/appGateDefinitions.js +2 -2
- package/dist/server/appAccess.d.ts +12 -0
- package/dist/server/appAccess.js +21 -0
- package/dist/server/authorizedWorkspaceAccess.d.ts +12 -0
- package/dist/server/authorizedWorkspaceAccess.js +40 -0
- package/dist/server/cloudCollectionRead.d.ts +25 -0
- package/dist/server/cloudCollectionRead.js +120 -0
- package/dist/server/cloudCollectionReadPool.d.ts +52 -0
- package/dist/server/cloudCollectionReadPool.js +140 -0
- package/dist/server/cloudCollectionReadWorker.d.ts +1 -0
- package/dist/server/cloudCollectionReadWorker.js +36 -0
- package/dist/server/index.d.ts +3 -11
- package/dist/server/index.js +53 -40
- package/dist/server/localServiceLease.d.ts +3 -0
- package/dist/server/localServiceLease.js +9 -1
- package/dist/server/routes/documents.d.ts +5 -2
- package/dist/server/routes/documents.js +160 -13
- package/dist/server/routes/durableTaskHttpRouters.d.ts +2 -0
- package/dist/server/routes/durableTaskHttpRouters.js +2 -2
- package/dist/server/routes/localService.js +2 -0
- package/dist/server/routes/primitives.d.ts +2 -0
- package/dist/server/routes/shared.d.ts +24 -0
- package/dist/server/routes/shared.js +114 -18
- package/dist/server/routes/sync.js +22 -0
- package/dist/server/routes/syncV3FeedRoutes.js +4 -2
- package/dist/server/routes/syncV3LocalCaptureRoutes.js +20 -2
- package/dist/server/routes/syncV3OperationRoutes.js +17 -2
- package/dist/server/routes/tasks.js +199 -89
- package/dist/server/routes.js +35 -7
- package/dist/service/localServiceCli.js +36 -25
- package/dist/service/localServiceClientLifecycle.js +67 -6
- package/dist/shared/planningIdentity.d.ts +20 -0
- package/dist/shared/planningIdentity.js +79 -0
- package/dist/storage/postgresAdapter.js +4 -0
- package/dist/storage/postgresRequestDiagnostics.d.ts +8 -0
- package/dist/storage/postgresRequestDiagnostics.js +24 -0
- package/dist/storage/workspaceAssetStore.d.ts +32 -0
- package/dist/storage/workspaceAssetStore.js +70 -0
- package/dist/sync/coordinator/localSyncExecutionPermitStore.d.ts +16 -0
- package/dist/sync/coordinator/localSyncExecutionPermitStore.js +70 -22
- package/dist/sync/coordinator/workspaceSyncTransportGateway.js +4 -2
- package/dist/sync/engine/workspaceSyncEngineRemoteServices.d.ts +5 -0
- package/dist/sync/engine/workspaceSyncEngineServerRemoteServices.d.ts +1 -1
- package/dist/sync/engine/workspaceSyncEngineServerRemoteServices.js +15 -0
- package/dist/sync/engine/workspaceSyncEngineServerRunnerOperations.js +26 -3
- package/dist/sync/engine/workspaceSyncV2ChangeDispatcher.js +2 -0
- package/dist/sync/syncApplyHandlers.d.ts +3 -1
- package/dist/sync/syncApplyHandlers.js +29 -0
- package/dist/sync/syncService.js +9 -0
- package/dist/sync/taskSyncPayload.d.ts +1 -0
- package/dist/sync/taskSyncPayload.js +6 -0
- package/dist/sync/v3/durableTaskAttachmentLinksMutationRouter.d.ts +1 -0
- package/dist/sync/v3/durableTaskAttachmentLinksMutationRouter.js +21 -3
- package/dist/sync/v3/durableTaskHttpBulkMutationRouter.js +17 -4
- package/dist/sync/v3/localInitiativeOutboxService.js +4 -2
- package/dist/sync/v3/localOutboxDispatcher.js +5 -1
- package/dist/sync/v3/localTaskAttachmentLinksOutboxHandler.js +12 -2
- package/dist/sync/v3/localTaskAttachmentLinksOutboxService.d.ts +1 -0
- package/dist/sync/v3/localTaskAttachmentLinksOutboxService.js +15 -3
- package/dist/sync/v3/localWorkstreamOutboxService.js +4 -2
- package/dist/sync/v3/syncDurabilityStore.d.ts +8 -0
- package/dist/sync/v3/syncDurabilityStore.js +171 -33
- package/dist/sync/v3/taskAttachmentLinksMutationService.d.ts +1 -0
- package/dist/sync/v3/taskAttachmentLinksMutationService.js +18 -2
- package/dist/sync/v3/taskMetadataCoexistence.js +4 -0
- package/dist/sync/v3/workspaceSyncV2ProjectionExclusions.js +1 -9
- package/dist/sync/v3/workspaceSyncV3CloudOperationHandler.js +1 -0
- package/dist/sync/v3/workspaceSyncV3CombinedFeedOrchestrator.js +7 -1
- package/dist/sync/v3/workspaceSyncV3CombinedLocalApply.js +15 -3
- package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.d.ts +4 -0
- package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.js +29 -6
- package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.d.ts +1 -0
- package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.js +29 -7
- package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.js +62 -7
- package/dist/sync/v3/workspaceSyncV3OperationProtocol.d.ts +1 -0
- package/dist/sync/v3/workspaceSyncV3RepairSqlBatching.d.ts +2 -0
- package/dist/sync/v3/workspaceSyncV3RepairSqlBatching.js +10 -0
- package/dist/sync/v3/workspaceSyncV3TaskRootProjection.d.ts +1 -1
- package/dist/sync/v3/workspaceSyncV3TaskRootProjection.js +1 -1
- package/dist/sync/workspacePullFeed.d.ts +6 -1
- package/dist/sync/workspacePullFeed.js +172 -161
- package/dist/sync/workspaceSyncModel.d.ts +11 -0
- package/dist/sync/workspaceSyncModel.js +27 -2
- package/dist/types.d.ts +8 -0
- package/dist/ui/assets/{AiIdentityRosterCard-DB1BLO_j.js → AiIdentityRosterCard-MZs7lVED.js} +1 -1
- package/dist/ui/assets/{AiProfilesModule-DPxQeF9N.js → AiProfilesModule-C3i0LOxe.js} +1 -1
- package/dist/ui/assets/{AnnotatedAttachmentWorkspace-DHNYaNg6.js → AnnotatedAttachmentWorkspace-DVZk5Tln.js} +1 -1
- package/dist/ui/assets/AssetTraySortControl-Kf1pelSy.js +1 -0
- package/dist/ui/assets/ContextAttachmentManager-B8boOs6Q.js +3 -0
- package/dist/ui/assets/{DocumentWorkspace-BC7sy5TG.js → DocumentWorkspace-DXH4XUsB.js} +4 -4
- package/dist/ui/assets/EntityActivityTimeline-BtSTq0ON.js +1 -0
- package/dist/ui/assets/PlanningModule-BPVyEa-f.js +1 -0
- package/dist/ui/assets/PlanningModule-CoIR9hbV.css +1 -0
- package/dist/ui/assets/{PlansPage-BVH_NfgT.js → PlansPage-ChqgxALc.js} +1 -1
- package/dist/ui/assets/TaskContextUpload-CB3ol0sN.js +1 -0
- package/dist/ui/assets/TaskContextUpload-qmBeUw3u.css +1 -0
- package/dist/ui/assets/{TaskSettings-xVsxSa0g.js → TaskSettings-g4ECKNOz.js} +1 -1
- package/dist/ui/assets/{TaskforceAgentsModule-CkAxW19K.js → TaskforceAgentsModule-BazdUwxZ.js} +1 -1
- package/dist/ui/assets/WorkflowManagerModule-DWFspC-o.js +1 -0
- package/dist/ui/assets/index-BUplSsv_.js +7 -0
- package/dist/ui/assets/index-gz2EXuoK.css +1 -0
- package/dist/ui/assets/{vendor-icons-B8ZNsH1g.js → vendor-icons-BkFLXavV.js} +1 -1
- package/dist/ui/index.html +3 -3
- package/dist/utils/constants.d.ts +2 -2
- package/dist/utils/constants.js +1 -1
- package/dist/utils/contextAttachmentUpload.d.ts +2 -0
- package/dist/utils/contextAttachmentUpload.js +7 -0
- package/dist/utils/contextFiles.d.ts +1 -1
- package/dist/utils/contextFiles.js +4 -4
- package/package.json +6 -1
- package/dist/ui/assets/AssetTraySortControl-DphbyHVc.js +0 -1
- package/dist/ui/assets/ContextAttachmentManager-CMxSzHqc.js +0 -3
- package/dist/ui/assets/EntityActivityTimeline-pJ2ZjZ-k.js +0 -1
- package/dist/ui/assets/PlanningModule-CeTqXMMz.css +0 -1
- package/dist/ui/assets/PlanningModule-t5GbvVR9.js +0 -1
- package/dist/ui/assets/TaskContextUpload-Ds4LnDzV.css +0 -1
- package/dist/ui/assets/TaskContextUpload-bl4fOOUz.js +0 -1
- package/dist/ui/assets/WorkflowManagerModule-BKqIGVnF.js +0 -1
- package/dist/ui/assets/index-BzJlVnNS.css +0 -1
- package/dist/ui/assets/index-Cx7vZJHL.js +0 -7
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect, useState } from 'react';
|
|
3
3
|
import { Image, Loader2, MessageSquareText } from 'lucide-react';
|
|
4
4
|
import { fetchTaskforceApi } from '../../utils/taskforceApiClient';
|
|
@@ -29,19 +29,19 @@ export function TaskImageReviews({ taskId, taskReferenceLabel, workspaceId, apiB
|
|
|
29
29
|
}, [apiBaseUrl, taskId, workspaceId]);
|
|
30
30
|
if (reviews !== null && reviews.length === 0)
|
|
31
31
|
return null;
|
|
32
|
-
return (
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
32
|
+
return (_jsx("section", { className: styles.group, "aria-label": "Image reviews", children: reviews === null ? (_jsxs("div", { className: styles.loading, "aria-live": "polite", children: [_jsx(Loader2, { size: 14 }), " Loading image reviews"] })) : (_jsx("div", { className: styles.list, children: reviews.map((review) => {
|
|
33
|
+
const image = review.image;
|
|
34
|
+
const markerCount = review.annotations.length;
|
|
35
|
+
const canOpen = Boolean(image?.assetId && image.apiUrl);
|
|
36
|
+
return (_jsxs("button", { type: "button", className: styles.review, disabled: !canOpen, onClick: () => {
|
|
37
|
+
if (!image)
|
|
38
|
+
return;
|
|
39
|
+
dispatchOpenAnnotatedAttachment({
|
|
40
|
+
assetId: image.assetId,
|
|
41
|
+
path: image.apiUrl,
|
|
42
|
+
displayName: image.displayName,
|
|
43
|
+
referenceLabel: image.referenceLabel || undefined,
|
|
44
|
+
}, { taskId, taskReferenceLabel, sessionId: review.id });
|
|
45
|
+
}, children: [_jsx("span", { className: styles.icon, children: _jsx(Image, { size: 14 }) }), _jsxs("span", { className: styles.copy, children: [_jsx("span", { className: styles.kindLabel, children: "Image review session" }), _jsx("span", { className: `${styles.title} tf-heading-card`, children: reviewTitle(review) }), _jsxs("span", { className: "tf-text-meta", children: [markerCount, " ", markerCount === 1 ? 'marker' : 'markers'] })] }), _jsx(MessageSquareText, { className: styles.openIcon, size: 14, "aria-hidden": "true" })] }, review.id));
|
|
46
|
+
}) })) }));
|
|
47
47
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { RotateCcw } from 'lucide-react';
|
|
3
3
|
import styles from '../../Taskforce.module.css';
|
|
4
4
|
import { resolveColor, STATUS_DEFINITIONS } from '../../utils/constants';
|
|
5
5
|
import { TaxonomyDropdown } from '../ui/TaxonomyDropdown';
|
|
@@ -23,7 +23,16 @@ export function TaskStatusActions({ task, status, disabled = false, actionDisabl
|
|
|
23
23
|
'--field-focus-border': statusAccent,
|
|
24
24
|
'--field-focus-ring': `color-mix(in srgb, ${statusAccent} 18%, transparent)`
|
|
25
25
|
};
|
|
26
|
-
|
|
26
|
+
const statusPanelActions = resolvedArchiveActionMode === 'archive' && task
|
|
27
|
+
? [{
|
|
28
|
+
id: 'archive-task',
|
|
29
|
+
label: 'Archive task',
|
|
30
|
+
icon: 'Archive',
|
|
31
|
+
disabled: resolvedActionDisabled || !onArchiveTask,
|
|
32
|
+
onSelect: () => onArchiveTask?.(task),
|
|
33
|
+
}]
|
|
34
|
+
: [];
|
|
35
|
+
return (_jsxs("div", { className: `${styles.statusActionsGroup} ${compressed ? styles.statusActionsGroupCompact : ''}`, children: [resolvedArchiveActionMode === 'unarchive' && (_jsx("button", { type: "button", className: `${styles.actionBtn} ${styles.restoreTaskBtn}`, onClick: () => task && !resolvedActionDisabled && onUnarchiveTask?.(task), disabled: resolvedActionDisabled, title: "Unarchive task", "aria-label": "Unarchive task", children: _jsx(RotateCcw, { size: compressed ? 12 : 16 }) })), _jsx("div", { className: `${styles.statusSelectWrap} ${styles.statusTaxonomyDropdownWrap}`, style: statusAccentStyle, children: _jsx(TaxonomyDropdown, { value: currentStatus, options: statusOptions, disabled: resolvedStatusDisabled || (!task && !onStatusChange), ariaLabel: "Status", optionLabelColor: "var(--text-primary)", hideSelectedLabel: !showLabel, hideChevron: !showLabel, className: `${styles.statusTaxonomyDropdown} ${compressed ? styles.statusTaxonomyDropdownCompact : ''} ${!showLabel ? styles.statusTaxonomyDropdownIconOnly : ''}`, panelClassName: !showLabel ? styles.statusTaxonomyDropdownIconOnlyPanel : '', portalPanel: !showLabel, panelMinWidth: !showLabel ? 144 : undefined, panelActions: statusPanelActions, onChange: (value) => {
|
|
27
36
|
const nextStatus = value;
|
|
28
37
|
if (task) {
|
|
29
38
|
onSetStatus?.(task, nextStatus);
|
|
@@ -4,6 +4,7 @@ import { Link2 } from 'lucide-react';
|
|
|
4
4
|
import { getWorkstreamReferenceLabel } from '../../utils/planningReferences';
|
|
5
5
|
import { TaxonomyDropdown } from '../ui/TaxonomyDropdown';
|
|
6
6
|
import styles from '../../Taskforce.module.css';
|
|
7
|
+
import { PlanningVisualIdentity } from '../features/planning/PlanningVisualIdentity';
|
|
7
8
|
export function TaskWorkstreamPicker({ workstreams, onSelect, disabled = false, }) {
|
|
8
9
|
const availableWorkstreams = React.useMemo(() => workstreams.filter((workstream) => !workstream.isArchived), [workstreams]);
|
|
9
10
|
const workstreamById = React.useMemo(() => new Map(availableWorkstreams.map((workstream) => [workstream.id, workstream])), [availableWorkstreams]);
|
|
@@ -19,6 +20,6 @@ export function TaskWorkstreamPicker({ workstreams, onSelect, disabled = false,
|
|
|
19
20
|
const workstream = workstreamById.get(String(option.value));
|
|
20
21
|
if (!workstream)
|
|
21
22
|
return option.label;
|
|
22
|
-
return (_jsxs("span", { className: styles.taskWorkstreamPickerOption, children: [_jsx("span", { children: getWorkstreamReferenceLabel(workstream) || workstream.id }), _jsx("span", { children: workstream.title })] }));
|
|
23
|
+
return (_jsxs("span", { className: styles.taskWorkstreamPickerOption, children: [_jsx(PlanningVisualIdentity, { entityType: "workstream", entityId: workstream.id, icon: workstream.icon, color: workstream.color, size: "inline", disabled: true }), _jsx("span", { children: getWorkstreamReferenceLabel(workstream) || workstream.id }), _jsx("span", { children: workstream.title })] }));
|
|
23
24
|
} }));
|
|
24
25
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import styles from './DocumentTypeIcon.module.css';
|
|
3
|
+
export function DocumentTypeIcon({ label, compact = false, accentColor, }) {
|
|
4
|
+
const style = accentColor
|
|
5
|
+
? { '--document-type-accent': accentColor }
|
|
6
|
+
: undefined;
|
|
7
|
+
return (_jsxs("span", { className: `${styles.root} ${compact ? styles.compact : ''}`.trim(), style: style, "aria-hidden": "true", children: [_jsxs("svg", { className: styles.outline, viewBox: "0 0 28 28", focusable: "false", children: [_jsx("path", { d: "M2 0.75h18.25l7 7V26q0 1.25-1.25 1.25H2Q0.75 27.25 0.75 26V2Q0.75 0.75 2 0.75Z" }), _jsx("path", { className: styles.foldFill, d: "M20.25 0.75v7h7Z" }), _jsx("path", { className: styles.foldLine, d: "M20.25 0.75v7h7" })] }), _jsx("span", { className: styles.label, children: label })] }));
|
|
8
|
+
}
|
|
@@ -5,6 +5,13 @@ export interface TaxonomyOption {
|
|
|
5
5
|
icon?: string;
|
|
6
6
|
color?: string;
|
|
7
7
|
}
|
|
8
|
+
export interface TaxonomyDropdownAction {
|
|
9
|
+
id: string;
|
|
10
|
+
label: string;
|
|
11
|
+
icon?: string;
|
|
12
|
+
disabled?: boolean;
|
|
13
|
+
onSelect: () => void;
|
|
14
|
+
}
|
|
8
15
|
export interface TaxonomyDropdownProps {
|
|
9
16
|
value: string | number;
|
|
10
17
|
options: TaxonomyOption[];
|
|
@@ -28,5 +35,6 @@ export interface TaxonomyDropdownProps {
|
|
|
28
35
|
searchable?: boolean;
|
|
29
36
|
searchPlaceholder?: string;
|
|
30
37
|
noResultsText?: string;
|
|
38
|
+
panelActions?: TaxonomyDropdownAction[];
|
|
31
39
|
}
|
|
32
|
-
export declare function TaxonomyDropdown({ value, options, onChange, placeholder, required, disabled, className, ariaLabelledBy, ariaLabel, title, hideSelectedLabel, hideChevron, panelClassName, portalPanel, panelMinWidth, panelAlign, renderOptionContent: customRenderOptionContent, triggerContent, optionLabelColor, searchable, searchPlaceholder, noResultsText, }: TaxonomyDropdownProps): import("react/jsx-runtime").JSX.Element;
|
|
40
|
+
export declare function TaxonomyDropdown({ value, options, onChange, placeholder, required, disabled, className, ariaLabelledBy, ariaLabel, title, hideSelectedLabel, hideChevron, panelClassName, portalPanel, panelMinWidth, panelAlign, renderOptionContent: customRenderOptionContent, triggerContent, optionLabelColor, searchable, searchPlaceholder, noResultsText, panelActions, }: TaxonomyDropdownProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -12,7 +12,7 @@ function resolveTint(color, opacity) {
|
|
|
12
12
|
}
|
|
13
13
|
return `color-mix(in srgb, ${resolved} ${Math.round(opacity * 100)}%, transparent)`;
|
|
14
14
|
}
|
|
15
|
-
export function TaxonomyDropdown({ value, options, onChange, placeholder = 'Select...', required = false, disabled = false, className = '', ariaLabelledBy, ariaLabel, title, hideSelectedLabel = false, hideChevron = false, panelClassName = '', portalPanel = false, panelMinWidth, panelAlign = 'end', renderOptionContent: customRenderOptionContent, triggerContent, optionLabelColor, searchable = false, searchPlaceholder = 'Search options...', noResultsText = 'No matching options.', }) {
|
|
15
|
+
export function TaxonomyDropdown({ value, options, onChange, placeholder = 'Select...', required = false, disabled = false, className = '', ariaLabelledBy, ariaLabel, title, hideSelectedLabel = false, hideChevron = false, panelClassName = '', portalPanel = false, panelMinWidth, panelAlign = 'end', renderOptionContent: customRenderOptionContent, triggerContent, optionLabelColor, searchable = false, searchPlaceholder = 'Search options...', noResultsText = 'No matching options.', panelActions = [], }) {
|
|
16
16
|
const [isOpen, setIsOpen] = useState(false);
|
|
17
17
|
const [highlightedIndex, setHighlightedIndex] = useState(-1);
|
|
18
18
|
const [panelPosition, setPanelPosition] = useState({});
|
|
@@ -23,6 +23,7 @@ export function TaxonomyDropdown({ value, options, onChange, placeholder = 'Sele
|
|
|
23
23
|
const panelRef = useRef(null);
|
|
24
24
|
const portalPanelWidthRef = useRef(null);
|
|
25
25
|
const optionRefs = useRef([]);
|
|
26
|
+
const panelActionRefs = useRef([]);
|
|
26
27
|
const searchInputRef = useRef(null);
|
|
27
28
|
const listboxId = `taxonomy-listbox-${React.useId().replace(/:/g, '')}`;
|
|
28
29
|
// Find the currently selected option
|
|
@@ -147,6 +148,14 @@ export function TaxonomyDropdown({ value, options, onChange, placeholder = 'Sele
|
|
|
147
148
|
setIsOpen(false);
|
|
148
149
|
buttonRef.current?.focus();
|
|
149
150
|
};
|
|
151
|
+
const handlePanelAction = (action) => {
|
|
152
|
+
if (action.disabled)
|
|
153
|
+
return;
|
|
154
|
+
action.onSelect();
|
|
155
|
+
setSearchQuery('');
|
|
156
|
+
setIsOpen(false);
|
|
157
|
+
buttonRef.current?.focus();
|
|
158
|
+
};
|
|
150
159
|
const handleKeyDown = (e) => {
|
|
151
160
|
if (disabled)
|
|
152
161
|
return;
|
|
@@ -222,7 +231,11 @@ export function TaxonomyDropdown({ value, options, onChange, placeholder = 'Sele
|
|
|
222
231
|
}
|
|
223
232
|
break;
|
|
224
233
|
case 'Tab':
|
|
225
|
-
|
|
234
|
+
if (isOpen && !e.shiftKey && panelActions.length > 0) {
|
|
235
|
+
e.preventDefault();
|
|
236
|
+
panelActionRefs.current[0]?.focus();
|
|
237
|
+
break;
|
|
238
|
+
}
|
|
226
239
|
setIsOpen(false);
|
|
227
240
|
break;
|
|
228
241
|
default:
|
|
@@ -256,7 +269,21 @@ export function TaxonomyDropdown({ value, options, onChange, placeholder = 'Sele
|
|
|
256
269
|
'--option-bg': resolveTint(accent, 0.06)
|
|
257
270
|
};
|
|
258
271
|
})(), children: renderOptionContent(option, { labelColor: optionLabelColor }) }, String(option.value)));
|
|
259
|
-
}) }), visibleOptions.length === 0 ? (_jsx("div", { className: styles.taxonomyDropdownEmpty, role: "status", children: noResultsText })) : null
|
|
272
|
+
}) }), visibleOptions.length === 0 ? (_jsx("div", { className: styles.taxonomyDropdownEmpty, role: "status", children: noResultsText })) : null, panelActions.length > 0 ? (_jsx("div", { className: styles.taxonomyDropdownActions, role: "group", "aria-label": "Actions", children: panelActions.map((action, index) => {
|
|
273
|
+
const ActionIcon = action.icon && Icons[action.icon]
|
|
274
|
+
? Icons[action.icon]
|
|
275
|
+
: null;
|
|
276
|
+
return (_jsxs("button", { ref: (node) => { panelActionRefs.current[index] = node; }, type: "button", className: styles.taxonomyDropdownAction, disabled: action.disabled, onClick: () => handlePanelAction(action), onKeyDown: (event) => {
|
|
277
|
+
if (event.key === 'Escape') {
|
|
278
|
+
event.preventDefault();
|
|
279
|
+
setIsOpen(false);
|
|
280
|
+
buttonRef.current?.focus();
|
|
281
|
+
}
|
|
282
|
+
else if (event.key === 'Tab' && !event.shiftKey) {
|
|
283
|
+
setIsOpen(false);
|
|
284
|
+
}
|
|
285
|
+
}, children: [ActionIcon ? _jsx(ActionIcon, { size: 16, "aria-hidden": "true" }) : null, _jsx("span", { children: action.label })] }, action.id));
|
|
286
|
+
}) })) : null] })) : null;
|
|
260
287
|
return (_jsxs("div", { ref: dropdownRef, className: `taxonomyDropdown ${styles.taxonomyDropdown} ${isOpen ? `taxonomyDropdownActive ${styles.taxonomyDropdownActive}` : ''} ${className}`, children: [_jsxs("button", { ref: buttonRef, type: "button", className: `taxonomyDropdownButton ${styles.taxonomyDropdownButton} ${isOpen ? `taxonomyDropdownOpen ${styles.taxonomyDropdownOpen}` : ''}`, onClick: handleToggle, onKeyDown: handleKeyDown, disabled: disabled, role: "combobox", "aria-haspopup": "listbox", "aria-expanded": isOpen, "aria-controls": listboxId, "aria-activedescendant": isOpen && highlightedIndex >= 0 ? `${listboxId}-option-${highlightedIndex}` : undefined, "aria-labelledby": ariaLabelledBy, "aria-label": ariaLabel, title: title, style: (() => {
|
|
261
288
|
if (!selectedOption)
|
|
262
289
|
return {};
|
|
@@ -169,9 +169,9 @@ export function StandaloneLayout(props) {
|
|
|
169
169
|
// State
|
|
170
170
|
activeTab, setActiveTab, activeCategories, groupBy, setGroupBy, activeWorkspaceModule, setActiveWorkspaceModule, emptyColumnMode, setEmptyColumnMode, zenMode, setZenMode, filterStatus, setFilterStatus,
|
|
171
171
|
// Data & Actions
|
|
172
|
-
tasks, handleEdit, handleSubmit, resetForm, handleUpdateTask, handleSetStatus: handleSetStatusDurably,
|
|
172
|
+
tasks, handleEdit, handleSubmit, resetForm, discardDescriptionImageDraft, handleUpdateTask, handleSetStatus: handleSetStatusDurably,
|
|
173
173
|
// Form State (destructure all needed for TaskForm)
|
|
174
|
-
editingTaskId, loading, error, title, setTitle, setTitleDraft, description, setDescription, setDescriptionDraft, checklistItems, setChecklistItems, category, setCategory, type, setType, priority, setPriority, complexity, setComplexity, status, setStatus, assignee, setAssignee, scheduledDate, setScheduledDate, dueDate, setDueDate, workstreamInput, setWorkstreamInput, manualComplexityEnabled, checklistDropdownEnabled, showTaskCardStatusLabel, formTaxonomies, setFormTaxonomies, comments, newCommentText, setNewCommentText, attachments, setAttachments, setAttachmentsDirty, descriptionFocused, setDescriptionFocused, showMarkdownHelp, setShowMarkdownHelp,
|
|
174
|
+
editingTaskId, loading, error, title, setTitle, setTitleDraft, description, setDescription, setDescriptionDraft, checklistItems, setChecklistItems, category, setCategory, type, setType, priority, setPriority, complexity, setComplexity, status, setStatus, assignee, setAssignee, scheduledDate, setScheduledDate, dueDate, setDueDate, workstreamInput, setWorkstreamInput, manualComplexityEnabled, checklistDropdownEnabled, showTaskCardStatusLabel, formTaxonomies, setFormTaxonomies, comments, newCommentText, setNewCommentText, attachments, setAttachments, attachmentsDirty, setAttachmentsDirty, descriptionImageUploadPending, descriptionImageDraftId, registerDescriptionImageUpload, descriptionFocused, setDescriptionFocused, showMarkdownHelp, setShowMarkdownHelp,
|
|
175
175
|
// Form Actions
|
|
176
176
|
handleAddComment, handleSetWorkstreamForCurrentTask, handleOpenTaskById,
|
|
177
177
|
// Other Props for Form
|
|
@@ -206,6 +206,9 @@ export function StandaloneLayout(props) {
|
|
|
206
206
|
// Handlers
|
|
207
207
|
const handleDiscard = () => {
|
|
208
208
|
setUnsavedModalOpen(false);
|
|
209
|
+
if (activeTab === 'add' && !editingTaskId) {
|
|
210
|
+
void discardDescriptionImageDraft();
|
|
211
|
+
}
|
|
209
212
|
if (pendingNavigation) {
|
|
210
213
|
if (activeTab === 'add')
|
|
211
214
|
resetForm();
|
|
@@ -271,6 +274,8 @@ export function StandaloneLayout(props) {
|
|
|
271
274
|
const [planningDraftDescription, setPlanningDraftDescription] = useState('');
|
|
272
275
|
const [planningDraftOwner, setPlanningDraftOwner] = useState('');
|
|
273
276
|
const [planningDraftInitiativeId, setPlanningDraftInitiativeId] = useState('');
|
|
277
|
+
const [planningDraftIcon, setPlanningDraftIcon] = useState(null);
|
|
278
|
+
const [planningDraftColor, setPlanningDraftColor] = useState(null);
|
|
274
279
|
const [isSubmittingPlanningEditor, setIsSubmittingPlanningEditor] = useState(false);
|
|
275
280
|
const taskContextAttachmentDraftRef = useRef({
|
|
276
281
|
taskId: null,
|
|
@@ -1173,6 +1178,8 @@ export function StandaloneLayout(props) {
|
|
|
1173
1178
|
description: String(workstream.description || '').trim() || undefined,
|
|
1174
1179
|
ownerId: workstream.ownerId ? String(workstream.ownerId) : null,
|
|
1175
1180
|
ownerLabel: workstream.ownerId ? assigneeLabelByValue.get(String(workstream.ownerId)) || String(workstream.ownerId) : null,
|
|
1181
|
+
icon: workstream.icon ?? null,
|
|
1182
|
+
color: workstream.color ?? null,
|
|
1176
1183
|
...taskCounts,
|
|
1177
1184
|
statusCounts: workstreamStatusCountsById.get(workstream.id) || summarizeTaskStatuses([]),
|
|
1178
1185
|
initiativeId: workstream.initiativeId || null,
|
|
@@ -1217,6 +1224,8 @@ export function StandaloneLayout(props) {
|
|
|
1217
1224
|
description: String(initiative.description || '').trim() || undefined,
|
|
1218
1225
|
ownerId: initiative.ownerId ? String(initiative.ownerId) : null,
|
|
1219
1226
|
ownerLabel: initiative.ownerId ? assigneeLabelByValue.get(String(initiative.ownerId)) || String(initiative.ownerId) : null,
|
|
1227
|
+
icon: initiative.icon ?? null,
|
|
1228
|
+
color: initiative.color ?? null,
|
|
1220
1229
|
...initiativeTaskCounts,
|
|
1221
1230
|
statusCounts: combineTaskStatuses(allWorkstreamsForInitiative),
|
|
1222
1231
|
workstreamCount: workstreams.length,
|
|
@@ -1281,6 +1290,8 @@ export function StandaloneLayout(props) {
|
|
|
1281
1290
|
id: initiative.id,
|
|
1282
1291
|
referenceLabel: formatInitiativeReference(initiative) || initiative.id,
|
|
1283
1292
|
title: initiative.title,
|
|
1293
|
+
icon: initiative.icon,
|
|
1294
|
+
color: initiative.color,
|
|
1284
1295
|
meta: `${initiative.workstreamCount || 0} workstream${initiative.workstreamCount === 1 ? '' : 's'}`,
|
|
1285
1296
|
}))
|
|
1286
1297
|
.sort(sortByTitle);
|
|
@@ -1290,6 +1301,8 @@ export function StandaloneLayout(props) {
|
|
|
1290
1301
|
id: workstream.id,
|
|
1291
1302
|
referenceLabel: formatWorkstreamReference(workstream) || workstream.id,
|
|
1292
1303
|
title: workstream.title,
|
|
1304
|
+
icon: workstream.icon,
|
|
1305
|
+
color: workstream.color,
|
|
1293
1306
|
meta: workstream.initiativeId
|
|
1294
1307
|
? `In ${planningStructure.allInitiativeById.get(workstream.initiativeId)?.title || 'another initiative'}`
|
|
1295
1308
|
: 'Standalone workstream',
|
|
@@ -3034,6 +3047,8 @@ export function StandaloneLayout(props) {
|
|
|
3034
3047
|
setPlanningDraftTitle('');
|
|
3035
3048
|
setPlanningDraftDescription('');
|
|
3036
3049
|
setPlanningDraftOwner('');
|
|
3050
|
+
setPlanningDraftIcon(null);
|
|
3051
|
+
setPlanningDraftColor(null);
|
|
3037
3052
|
const selectedInitiative = editor.entityType === 'workstream' && selectedPlanningInitiativeId
|
|
3038
3053
|
? planningStructure.initiativeById.get(selectedPlanningInitiativeId) || null
|
|
3039
3054
|
: null;
|
|
@@ -3048,6 +3063,8 @@ export function StandaloneLayout(props) {
|
|
|
3048
3063
|
setPlanningDraftTitle('');
|
|
3049
3064
|
setPlanningDraftDescription('');
|
|
3050
3065
|
setPlanningDraftOwner('');
|
|
3066
|
+
setPlanningDraftIcon(null);
|
|
3067
|
+
setPlanningDraftColor(null);
|
|
3051
3068
|
const selectedInitiative = editor.entityType === 'workstream'
|
|
3052
3069
|
? ((initiativeId ? planningStructure.initiativeById.get(initiativeId) : null)
|
|
3053
3070
|
|| (selectedPlanningInitiativeId ? planningStructure.initiativeById.get(selectedPlanningInitiativeId) || null : null))
|
|
@@ -3062,6 +3079,8 @@ export function StandaloneLayout(props) {
|
|
|
3062
3079
|
setPlanningDraftTitle('');
|
|
3063
3080
|
setPlanningDraftDescription('');
|
|
3064
3081
|
setPlanningDraftOwner('');
|
|
3082
|
+
setPlanningDraftIcon(null);
|
|
3083
|
+
setPlanningDraftColor(null);
|
|
3065
3084
|
setPlanningDraftInitiativeId('');
|
|
3066
3085
|
}, []);
|
|
3067
3086
|
const closePlanningSecondaryEditor = useCallback(() => {
|
|
@@ -3071,6 +3090,8 @@ export function StandaloneLayout(props) {
|
|
|
3071
3090
|
setPlanningDraftTitle('');
|
|
3072
3091
|
setPlanningDraftDescription('');
|
|
3073
3092
|
setPlanningDraftOwner('');
|
|
3093
|
+
setPlanningDraftIcon(null);
|
|
3094
|
+
setPlanningDraftColor(null);
|
|
3074
3095
|
setPlanningDraftInitiativeId('');
|
|
3075
3096
|
}, []);
|
|
3076
3097
|
const submitPlanningEditor = useCallback(async () => {
|
|
@@ -3099,6 +3120,10 @@ export function StandaloneLayout(props) {
|
|
|
3099
3120
|
title,
|
|
3100
3121
|
description: planningDraftDescription.trim() || null,
|
|
3101
3122
|
ownerId,
|
|
3123
|
+
...(planningDraftIcon || planningDraftColor ? {
|
|
3124
|
+
icon: planningDraftIcon,
|
|
3125
|
+
color: planningDraftColor,
|
|
3126
|
+
} : {}),
|
|
3102
3127
|
});
|
|
3103
3128
|
setPlanningDrawerDetail({ type: 'initiative', id: created.id });
|
|
3104
3129
|
setPlanningNestedWorkstreamDetailId(null);
|
|
@@ -3129,7 +3154,13 @@ export function StandaloneLayout(props) {
|
|
|
3129
3154
|
pushNotice('Workstream updated', 'success');
|
|
3130
3155
|
}
|
|
3131
3156
|
else {
|
|
3132
|
-
const created = await props.createWorkstream(
|
|
3157
|
+
const created = await props.createWorkstream({
|
|
3158
|
+
...patch,
|
|
3159
|
+
...(planningDraftIcon || planningDraftColor ? {
|
|
3160
|
+
icon: planningDraftIcon,
|
|
3161
|
+
color: planningDraftColor,
|
|
3162
|
+
} : {}),
|
|
3163
|
+
});
|
|
3133
3164
|
if (isSecondaryEditor) {
|
|
3134
3165
|
setPlanningNestedWorkstreamDetailId(created.id);
|
|
3135
3166
|
}
|
|
@@ -3159,6 +3190,8 @@ export function StandaloneLayout(props) {
|
|
|
3159
3190
|
closePlanningSecondaryEditor,
|
|
3160
3191
|
planningDraftDescription,
|
|
3161
3192
|
planningDraftInitiativeId,
|
|
3193
|
+
planningDraftIcon,
|
|
3194
|
+
planningDraftColor,
|
|
3162
3195
|
planningDraftOwner,
|
|
3163
3196
|
planningDraftTitle,
|
|
3164
3197
|
planningEditor,
|
|
@@ -3462,6 +3495,15 @@ export function StandaloneLayout(props) {
|
|
|
3462
3495
|
throw error;
|
|
3463
3496
|
}
|
|
3464
3497
|
}, [props, pushNotice]);
|
|
3498
|
+
const handleChangePlanningIdentity = useCallback(async (entityType, entityId, patch) => {
|
|
3499
|
+
try {
|
|
3500
|
+
await props.updatePlanningIdentity(entityType, entityId, patch);
|
|
3501
|
+
}
|
|
3502
|
+
catch (error) {
|
|
3503
|
+
pushNotice(error instanceof Error ? error.message : 'Failed to update visual identity.', 'error');
|
|
3504
|
+
throw error;
|
|
3505
|
+
}
|
|
3506
|
+
}, [props.updatePlanningIdentity, pushNotice]);
|
|
3465
3507
|
const handleAssignInitiativeToWorkstream = useCallback(async (workstreamId, initiativeReferenceOverride) => {
|
|
3466
3508
|
const workstream = props.workstreams.find((item) => item.id === workstreamId);
|
|
3467
3509
|
if (!workstream) {
|
|
@@ -4069,6 +4111,7 @@ export function StandaloneLayout(props) {
|
|
|
4069
4111
|
title,
|
|
4070
4112
|
description: input.description?.trim() || null,
|
|
4071
4113
|
ownerId: input.ownerId?.trim() || null,
|
|
4114
|
+
...(input.icon || input.color ? { icon: input.icon ?? null, color: input.color ?? null } : {}),
|
|
4072
4115
|
});
|
|
4073
4116
|
pushNotice('Initiative created', 'success');
|
|
4074
4117
|
return { id: created.id };
|
|
@@ -4078,6 +4121,7 @@ export function StandaloneLayout(props) {
|
|
|
4078
4121
|
description: input.description?.trim() || null,
|
|
4079
4122
|
ownerId: input.ownerId?.trim() || null,
|
|
4080
4123
|
initiativeId: input.initiativeId?.trim() || null,
|
|
4124
|
+
...(input.icon || input.color ? { icon: input.icon ?? null, color: input.color ?? null } : {}),
|
|
4081
4125
|
});
|
|
4082
4126
|
pushNotice('Workstream created', 'success');
|
|
4083
4127
|
return { id: created.id };
|
|
@@ -4138,6 +4182,7 @@ export function StandaloneLayout(props) {
|
|
|
4138
4182
|
archiveEntity: handleArchivePlanningEntity,
|
|
4139
4183
|
unarchiveEntity: handleUnarchivePlanningEntity,
|
|
4140
4184
|
changeOwner: handleChangePlanningOwner,
|
|
4185
|
+
changeIdentity: handleChangePlanningIdentity,
|
|
4141
4186
|
createEntity: createPlanningWorkspaceEntity,
|
|
4142
4187
|
updateEntity: updatePlanningWorkspaceEntity,
|
|
4143
4188
|
addContextFile: handleAddPlanningContextFile,
|
|
@@ -4151,6 +4196,7 @@ export function StandaloneLayout(props) {
|
|
|
4151
4196
|
currentWorkspaceId,
|
|
4152
4197
|
currentTheme,
|
|
4153
4198
|
handleChangePlanningOwner,
|
|
4199
|
+
handleChangePlanningIdentity,
|
|
4154
4200
|
handleAssignInitiativeToWorkstream,
|
|
4155
4201
|
handleAssignTaskToWorkstream,
|
|
4156
4202
|
handleAttachTaskToWorkstreamByReference,
|
|
@@ -4198,12 +4244,12 @@ export function StandaloneLayout(props) {
|
|
|
4198
4244
|
surfaceType: option.surfaceType ?? null,
|
|
4199
4245
|
providerMetadata: option.providerMetadata ?? null,
|
|
4200
4246
|
archivedAt: option.archivedAt ?? null
|
|
4201
|
-
})), 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: () => {
|
|
4247
|
+
})), draftInitiativeSummary: planningDraftInitiativeSummary, draftTitle: planningDraftTitle, draftDescription: planningDraftDescription, draftOwner: planningDraftOwner, draftInitiativeId: planningDraftInitiativeId, draftIcon: planningDraftIcon, draftColor: planningDraftColor, onChangeDraftTitle: setPlanningDraftTitle, onChangeDraftDescription: setPlanningDraftDescription, onChangeDraftOwner: setPlanningDraftOwner, onChangeDraftInitiativeId: setPlanningDraftInitiativeId, onChangeDraftIcon: setPlanningDraftIcon, onChangeDraftColor: setPlanningDraftColor, onCollapseTreePane: () => setPlanningTreeCollapsed(true), onExpandTreePane: () => setPlanningTreeCollapsed(false), onCollapsePrimaryPane: () => setPlanningPrimaryCollapsed(true), onExpandPrimaryPane: () => setPlanningPrimaryCollapsed(false), onCollapseSecondaryPane: () => setPlanningSecondaryCollapsed(true), onExpandSecondaryPane: () => setPlanningSecondaryCollapsed(false), onBackFromSecondary: () => {
|
|
4202
4248
|
planningEditorSubmitInFlightRef.current = false;
|
|
4203
4249
|
setIsSubmittingPlanningEditor(false);
|
|
4204
4250
|
setPlanningSecondaryEditor(null);
|
|
4205
4251
|
setPlanningNestedWorkstreamDetailId(null);
|
|
4206
|
-
}, treeCollapsed: planningTreeCollapsed, primaryCollapsed: planningPrimaryCollapsed, secondaryCollapsed: planningSecondaryCollapsed, onCancelEditor: closePlanningEditor, onCancelSecondaryEditor: closePlanningSecondaryEditor, onSubmitEditor: submitPlanningEditor, isSubmittingEditor: isSubmittingPlanningEditor, onCreateInitiative: () => openPlanningCreateEditor('initiative'), onCreateWorkstream: () => openPlanningCreateEditor('workstream'), onCreateTaskInWorkstream: openAddTaskModalForWorkstream, onCreateWorkstreamInInitiative: (initiativeId) => openPlanningCreateEditor('workstream', initiativeId), onAssignInitiativeToWorkstream: handleAssignInitiativeToWorkstream, onOpenTaskById: planningWorkspaceModel.openTask, onSetTaskStatus: handleSetPlanningTaskStatus, onChangeTaskAssignee: handleChangePlanningTaskAssignee, onArchivePlanningTask: handleArchivePlanningTask, onArchiveResolvedWorkstream: handleArchiveResolvedWorkstream, onArchiveResolvedInitiative: handleArchiveResolvedInitiative, taskReferences: taskReferences, onAssignTaskToWorkstream: handleAssignTaskToWorkstream, 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), onChangePlanningOwner: handleChangePlanningOwner, onArchiveInitiative: (initiativeId) => {
|
|
4252
|
+
}, treeCollapsed: planningTreeCollapsed, primaryCollapsed: planningPrimaryCollapsed, secondaryCollapsed: planningSecondaryCollapsed, onCancelEditor: closePlanningEditor, onCancelSecondaryEditor: closePlanningSecondaryEditor, onSubmitEditor: submitPlanningEditor, isSubmittingEditor: isSubmittingPlanningEditor, onCreateInitiative: () => openPlanningCreateEditor('initiative'), onCreateWorkstream: () => openPlanningCreateEditor('workstream'), onCreateTaskInWorkstream: openAddTaskModalForWorkstream, onCreateWorkstreamInInitiative: (initiativeId) => openPlanningCreateEditor('workstream', initiativeId), onAssignInitiativeToWorkstream: handleAssignInitiativeToWorkstream, onOpenTaskById: planningWorkspaceModel.openTask, onSetTaskStatus: handleSetPlanningTaskStatus, onChangeTaskAssignee: handleChangePlanningTaskAssignee, onArchivePlanningTask: handleArchivePlanningTask, onArchiveResolvedWorkstream: handleArchiveResolvedWorkstream, onArchiveResolvedInitiative: handleArchiveResolvedInitiative, taskReferences: taskReferences, onAssignTaskToWorkstream: handleAssignTaskToWorkstream, 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), onChangePlanningOwner: handleChangePlanningOwner, onChangePlanningIdentity: handleChangePlanningIdentity, onArchiveInitiative: (initiativeId) => {
|
|
4207
4253
|
void props.archiveInitiative(initiativeId).then(() => {
|
|
4208
4254
|
pushNotice('Initiative archived', 'success');
|
|
4209
4255
|
}).catch((error) => {
|
|
@@ -4327,7 +4373,7 @@ export function StandaloneLayout(props) {
|
|
|
4327
4373
|
: taskforceAgentDrawerNode, _jsxs(Modal, { isOpen: activeTab === 'add', onClose: handleCloseModal, title: editingTaskId ? (currentTask?.isDeleted ? 'Deleted Task' : 'Edit Task') : 'New Task', size: taskModalFullscreen ? 'full' : 'xl', theme: currentTheme, className: `${styles.taskforceTaskModalOverlay} ${taskforceAgentDrawerOpen ? styles.taskforceModalWithAssistantPanel : ''} ${taskforceAgentPanelCollapsed ? styles.taskforceModalWithAssistantPanelCollapsed : ''}`.trim(), overlayStyle: {
|
|
4328
4374
|
'--taskforce-task-modal-backdrop-top': `${taskforceAgentDrawerTop}px`,
|
|
4329
4375
|
'--taskforce-task-modal-backdrop-left': `${WORKSPACE_TOOL_RAIL_WIDTH}px`,
|
|
4330
|
-
}, headerActions: (_jsxs(_Fragment, { children: [!editingTaskId ? (_jsxs("button", { type: "button", onClick: (event) => handleSubmit(event), 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')] })) : null, _jsx("button", { className: "tf-control-icon", onClick: () => setTaskModalFullscreen((value) => !value), title: taskModalFullscreen ? 'Exit full screen' : 'Enter full screen', "aria-label": taskModalFullscreen ? 'Exit full screen' : 'Enter full screen', children: taskModalFullscreen ? _jsx(Minimize2, { size: 18 }) : _jsx(Maximize2, { size: 18 }) })] })), draggable: !taskModalFullscreen, closeOnOverlayClick: false, children: [_jsxs("div", { className: styles.taskNoticeAnchor, children: [_jsx(TaskActionHeader, { editingTaskId: editingTaskId, loading: loading, autoSaveState: autoSaveState, title: title, status: status, onStatusChange: setStatus, showCreateSubmit: false, currentTask: currentTask, currentTaskWorkstream: currentTaskWorkstream, currentTaskInitiative: currentTaskInitiative, workstreams: props.workstreams, onWorkstreamInputChange: setWorkstreamInput, onSetWorkstreamForCurrentTask: handleSetWorkstreamForCurrentTask, handleSubmit: handleSubmit, handleCopyId: handleCopyId, copiedId: copiedId, tasks: tasks, handleToggleInProgress: handleToggleInProgress, handleToggleReview: handleToggleReview, handleToggleComplete: handleToggleComplete, handleToggleCancel: handleToggleCancel, handleSetStatus: handleSetStatus, handleArchiveTask: handleArchiveTask, handleUnarchiveTask: (taskId) => {
|
|
4376
|
+
}, headerActions: (_jsxs(_Fragment, { children: [!editingTaskId ? (_jsxs("button", { type: "button", onClick: (event) => handleSubmit(event), 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')] })) : null, _jsx("button", { className: "tf-control-icon", onClick: () => setTaskModalFullscreen((value) => !value), title: taskModalFullscreen ? 'Exit full screen' : 'Enter full screen', "aria-label": taskModalFullscreen ? 'Exit full screen' : 'Enter full screen', children: taskModalFullscreen ? _jsx(Minimize2, { size: 18 }) : _jsx(Maximize2, { size: 18 }) })] })), draggable: !taskModalFullscreen, closeOnOverlayClick: false, children: [_jsxs("div", { className: styles.taskNoticeAnchor, children: [_jsx(TaskActionHeader, { editingTaskId: editingTaskId, loading: loading, submitDisabled: descriptionImageUploadPending, autoSaveState: autoSaveState, title: title, status: status, onStatusChange: setStatus, showCreateSubmit: false, currentTask: currentTask, currentTaskWorkstream: currentTaskWorkstream, currentTaskInitiative: currentTaskInitiative, workstreams: props.workstreams, onWorkstreamInputChange: setWorkstreamInput, onSetWorkstreamForCurrentTask: handleSetWorkstreamForCurrentTask, handleSubmit: handleSubmit, handleCopyId: handleCopyId, copiedId: copiedId, tasks: tasks, handleToggleInProgress: handleToggleInProgress, handleToggleReview: handleToggleReview, handleToggleComplete: handleToggleComplete, handleToggleCancel: handleToggleCancel, handleSetStatus: handleSetStatus, handleArchiveTask: handleArchiveTask, handleUnarchiveTask: (taskId) => {
|
|
4331
4377
|
if (currentTask?.isDeleted) {
|
|
4332
4378
|
const deletedRecord = deletedTaskRecordByTaskId.get(taskId);
|
|
4333
4379
|
if (!deletedRecord)
|
|
@@ -4353,10 +4399,10 @@ export function StandaloneLayout(props) {
|
|
|
4353
4399
|
: undefined, onAskAgent: handleAskTaskforceAgentForTask }), _jsx(TopNoticeLayer, { notice: error ? { message: error, tone: 'error' } : uiNotice, onDismiss: () => {
|
|
4354
4400
|
clearTaskError();
|
|
4355
4401
|
clearNotice();
|
|
4356
|
-
}, placement: "task" })] }), _jsx(TaskForm, { editingTaskId: editingTaskId, initialActivityEntryId: props.initialActivityEntryId, title: title, description: description, checklistItems: checklistItems, category: category, type: type, priority: priority, complexity: complexity, manualComplexityEnabled: manualComplexityEnabled, assignee: assignee, scheduledDate: scheduledDate, dueDate: dueDate, formTaxonomies: formTaxonomies, onTaxonomyChange: (id, val) => setFormTaxonomies(prev => ({ ...prev, [id]: val })), taxonomies: taxonomies, comments: comments, newCommentText: newCommentText, contextFiles: attachments, currentWorkspaceId: currentWorkspaceId, currentActorId: authUserId, apiBaseUrl: apiBaseUrl, runtimeMode: runtimeMode, showImageReviews: true, descriptionFocused: descriptionFocused, showMarkdownHelp: showMarkdownHelp, checklistEnabled: checklistDropdownEnabled, categories: activeCategories, types: activeTypes, priorities: priorities, taxonomyDisplayLabels: taxonomyDisplayLabels, assigneeOptions: assigneeOptions, workstreams: props.workstreams, initiatives: props.initiatives, copiedId: copiedId, onTitleChange: setTitle, onTitleDraftChange: setTitleDraft, onDescriptionChange: setDescription, onDescriptionDraftChange: setDescriptionDraft, onChecklistItemsChange: setChecklistItems, onCategoryChange: setCategory, onTypeChange: setType, onPriorityChange: setPriority, onComplexityChange: setComplexity, onAssigneeChange: setAssignee, onScheduledDateChange: setScheduledDate, onDueDateChange: setDueDate, onNewCommentTextChange: setNewCommentText, onDescriptionFocusedChange: setDescriptionFocused, onShowMarkdownHelpChange: setShowMarkdownHelp, onOpenSettings: (section) => {
|
|
4402
|
+
}, placement: "task" })] }), _jsx(TaskForm, { editingTaskId: editingTaskId, initialActivityEntryId: props.initialActivityEntryId, title: title, description: description, checklistItems: checklistItems, category: category, type: type, priority: priority, complexity: complexity, manualComplexityEnabled: manualComplexityEnabled, assignee: assignee, scheduledDate: scheduledDate, dueDate: dueDate, formTaxonomies: formTaxonomies, onTaxonomyChange: (id, val) => setFormTaxonomies(prev => ({ ...prev, [id]: val })), taxonomies: taxonomies, comments: comments, newCommentText: newCommentText, contextFiles: attachments, currentWorkspaceId: currentWorkspaceId, descriptionImageDraftId: descriptionImageDraftId, currentActorId: authUserId, apiBaseUrl: apiBaseUrl, runtimeMode: runtimeMode, showImageReviews: true, descriptionFocused: descriptionFocused, showMarkdownHelp: showMarkdownHelp, checklistEnabled: checklistDropdownEnabled, categories: activeCategories, types: activeTypes, priorities: priorities, taxonomyDisplayLabels: taxonomyDisplayLabels, assigneeOptions: assigneeOptions, workstreams: props.workstreams, initiatives: props.initiatives, copiedId: copiedId, onTitleChange: setTitle, onTitleDraftChange: setTitleDraft, onDescriptionChange: setDescription, onDescriptionDraftChange: setDescriptionDraft, onChecklistItemsChange: setChecklistItems, onCategoryChange: setCategory, onTypeChange: setType, onPriorityChange: setPriority, onComplexityChange: setComplexity, onAssigneeChange: setAssignee, onScheduledDateChange: setScheduledDate, onDueDateChange: setDueDate, onNewCommentTextChange: setNewCommentText, onDescriptionFocusedChange: setDescriptionFocused, onShowMarkdownHelpChange: setShowMarkdownHelp, onOpenSettings: (section) => {
|
|
4357
4403
|
setSettingsSection(section);
|
|
4358
4404
|
setActiveTab('settings');
|
|
4359
|
-
}, onSubmit: handleSubmit, commentsEndRef: commentsEndRef, onAddComment: () => handleAddComment(newCommentText), taskReferences: taskTextReferences, onAddContextFile: (file) => {
|
|
4405
|
+
}, onSubmit: handleSubmit, onDescriptionImageUploadStart: registerDescriptionImageUpload, commentsEndRef: commentsEndRef, onAddComment: () => handleAddComment(newCommentText), taskReferences: taskTextReferences, onAddContextFile: (file) => {
|
|
4360
4406
|
updateTaskContextAttachments((current) => [...current, file]);
|
|
4361
4407
|
}, onRemoveContextFile: async (index) => {
|
|
4362
4408
|
updateTaskContextAttachments((current) => current.filter((_, i) => i !== index));
|
|
@@ -4368,7 +4414,14 @@ export function StandaloneLayout(props) {
|
|
|
4368
4414
|
return { path: s, caption, timestamp: new Date().toISOString() };
|
|
4369
4415
|
return { ...s, caption };
|
|
4370
4416
|
}));
|
|
4371
|
-
},
|
|
4417
|
+
}, onSetCardCover: async (assetId) => {
|
|
4418
|
+
if (!editingTaskId)
|
|
4419
|
+
return;
|
|
4420
|
+
const saved = await handleUpdateTask(editingTaskId, { cardCoverAssetId: assetId });
|
|
4421
|
+
if (saved === false) {
|
|
4422
|
+
throw new Error('Unable to update the task card image.');
|
|
4423
|
+
}
|
|
4424
|
+
}, cardCoverDisabled: attachmentsDirty, onOpenContextImage: (attachment) => {
|
|
4372
4425
|
dispatchPreviewContextAttachment(attachment, {
|
|
4373
4426
|
ownerType: 'task',
|
|
4374
4427
|
ownerId: editingTaskId,
|
|
@@ -42,9 +42,9 @@ export function WidgetView(props) {
|
|
|
42
42
|
// Actions
|
|
43
43
|
handleEdit, handleDelete, handleCopyId, handleUpdateTask, handleToggleComplete, handleToggleCancel, handleToggleInProgress, handleToggleReview, handleSetStatus, handleArchiveTask, handleBulkArchive, handleUnarchive, handleRestoreDeletedTask, handleRestoreSelectedDeletedTasks, handlePermanentlyDeleteDeletedTask, handleEmptyDeletedTasks, fetchArchive,
|
|
44
44
|
// Form State
|
|
45
|
-
editingTaskId, loading, error, clearTaskError, title, setTitle, setTitleDraft, description, setDescription, setDescriptionDraft, checklistItems, setChecklistItems, category, setCategory, type, setType, priority, setPriority, complexity, setComplexity, status, setStatus, manualComplexityEnabled, checklistDropdownEnabled, showTaskCardStatusLabel, assignee, setAssignee, scheduledDate, setScheduledDate, dueDate, setDueDate, workstreamInput, setWorkstreamInput, formTaxonomies, setFormTaxonomies, comments, newCommentText, setNewCommentText, attachments, setAttachments, setAttachmentsDirty, descriptionFocused, setDescriptionFocused, showMarkdownHelp, setShowMarkdownHelp,
|
|
45
|
+
editingTaskId, loading, error, clearTaskError, title, setTitle, setTitleDraft, description, setDescription, setDescriptionDraft, checklistItems, setChecklistItems, category, setCategory, type, setType, priority, setPriority, complexity, setComplexity, status, setStatus, manualComplexityEnabled, checklistDropdownEnabled, showTaskCardStatusLabel, assignee, setAssignee, scheduledDate, setScheduledDate, dueDate, setDueDate, workstreamInput, setWorkstreamInput, formTaxonomies, setFormTaxonomies, comments, newCommentText, setNewCommentText, attachments, setAttachments, setAttachmentsDirty, descriptionImageUploadPending, descriptionImageDraftId, registerDescriptionImageUpload, descriptionFocused, setDescriptionFocused, showMarkdownHelp, setShowMarkdownHelp,
|
|
46
46
|
// Form Actions
|
|
47
|
-
handleSubmit, resetForm, handleAddComment, handleSetWorkstreamForCurrentTask, handleOpenTaskById,
|
|
47
|
+
handleSubmit, resetForm, discardDescriptionImageDraft, handleAddComment, handleSetWorkstreamForCurrentTask, handleOpenTaskById,
|
|
48
48
|
// Modals
|
|
49
49
|
autoSaveState, unsavedModalOpen, setUnsavedModalOpen, pendingNavigation, handleNavigation, handleClose, scheduleWarningPrompt, confirmScheduleWarning, cancelScheduleWarning,
|
|
50
50
|
// Misc
|
|
@@ -188,6 +188,9 @@ export function WidgetView(props) {
|
|
|
188
188
|
};
|
|
189
189
|
const handleDiscard = () => {
|
|
190
190
|
setUnsavedModalOpen(false);
|
|
191
|
+
if (activeTab === 'add' && !editingTaskId) {
|
|
192
|
+
void discardDescriptionImageDraft();
|
|
193
|
+
}
|
|
191
194
|
if (pendingNavigation) {
|
|
192
195
|
// If we are discarding, we just execute pending nav.
|
|
193
196
|
// Core logic had `if (activeTab === 'add' && !returnTab) resetForm();`
|
|
@@ -322,7 +325,7 @@ export function WidgetView(props) {
|
|
|
322
325
|
handleNavigation(() => {
|
|
323
326
|
setActiveTab('settings');
|
|
324
327
|
});
|
|
325
|
-
}, title: "Settings", "aria-label": "Settings", children: _jsx(Settings, { size: 18 }) }), _jsx("button", { className: "tf-control-icon", onClick: handleXClick, title: activeTab === 'tasks' ? "Close" : "Back to Tasks", "aria-label": activeTab === 'tasks' ? "Close" : "Back to Tasks", children: activeTab === 'tasks' ? _jsx(X, { size: 20 }) : _jsx(ArrowLeft, { size: 20 }) })] })] }), _jsx(TopNoticeLayer, { notice: activeTab === 'add' ? null : uiNotice, onDismiss: clearNotice }), _jsx(AttachmentPreviewHost, { theme: currentTheme }), activeTab === 'add' && (_jsxs("div", { className: styles.taskNoticeAnchor, children: [_jsx(TaskActionHeader, { editingTaskId: editingTaskId, loading: loading, autoSaveState: autoSaveState, title: title, status: status, onStatusChange: setStatus, currentTask: currentTask, currentTaskWorkstream: currentTaskWorkstream, currentTaskInitiative: currentTaskInitiative, workstreams: props.workstreams, onWorkstreamInputChange: setWorkstreamInput, onSetWorkstreamForCurrentTask: handleSetWorkstreamForCurrentTask, handleSubmit: handleSubmit, handleCopyId: handleCopyId, copiedId: copiedId, tasks: tasks, handleToggleInProgress: handleToggleInProgress, handleToggleReview: handleToggleReview, handleToggleComplete: handleToggleComplete, handleToggleCancel: handleToggleCancel, handleSetStatus: handleSetStatus, handleArchiveTask: handleArchiveTask, handleUnarchiveTask: (taskId) => {
|
|
328
|
+
}, title: "Settings", "aria-label": "Settings", children: _jsx(Settings, { size: 18 }) }), _jsx("button", { className: "tf-control-icon", onClick: handleXClick, title: activeTab === 'tasks' ? "Close" : "Back to Tasks", "aria-label": activeTab === 'tasks' ? "Close" : "Back to Tasks", children: activeTab === 'tasks' ? _jsx(X, { size: 20 }) : _jsx(ArrowLeft, { size: 20 }) })] })] }), _jsx(TopNoticeLayer, { notice: activeTab === 'add' ? null : uiNotice, onDismiss: clearNotice }), _jsx(AttachmentPreviewHost, { theme: currentTheme }), activeTab === 'add' && (_jsxs("div", { className: styles.taskNoticeAnchor, children: [_jsx(TaskActionHeader, { editingTaskId: editingTaskId, loading: loading, submitDisabled: descriptionImageUploadPending, autoSaveState: autoSaveState, title: title, status: status, onStatusChange: setStatus, currentTask: currentTask, currentTaskWorkstream: currentTaskWorkstream, currentTaskInitiative: currentTaskInitiative, workstreams: props.workstreams, onWorkstreamInputChange: setWorkstreamInput, onSetWorkstreamForCurrentTask: handleSetWorkstreamForCurrentTask, handleSubmit: handleSubmit, handleCopyId: handleCopyId, copiedId: copiedId, tasks: tasks, handleToggleInProgress: handleToggleInProgress, handleToggleReview: handleToggleReview, handleToggleComplete: handleToggleComplete, handleToggleCancel: handleToggleCancel, handleSetStatus: handleSetStatus, handleArchiveTask: handleArchiveTask, handleUnarchiveTask: (taskId) => {
|
|
326
329
|
if (currentTask?.isDeleted) {
|
|
327
330
|
const deletedRecord = deletedRecordByTaskId.get(taskId);
|
|
328
331
|
if (deletedRecord) {
|
|
@@ -359,12 +362,12 @@ export function WidgetView(props) {
|
|
|
359
362
|
void handleDelete(taskId);
|
|
360
363
|
}, onDeleteAllDeleted: () => {
|
|
361
364
|
void handleEmptyDeletedTasks();
|
|
362
|
-
}, onFetchArchive: fetchArchive, onAddTaskToCategory: handleAddTaskToCategory, supplementalTasks: deletedScopeTasks })), activeTab === 'add' && (_jsx(TaskForm, { editingTaskId: editingTaskId, initialActivityEntryId: props.initialActivityEntryId, title: title, description: description, checklistItems: checklistItems, category: category, type: type, priority: priority, complexity: complexity, manualComplexityEnabled: manualComplexityEnabled, assignee: assignee, scheduledDate: scheduledDate, dueDate: dueDate, formTaxonomies: formTaxonomies, onTaxonomyChange: onTaxonomyChange, taxonomies: taxonomies, comments: comments, newCommentText: newCommentText, contextFiles: attachments, currentWorkspaceId: currentWorkspaceId, currentActorId: authUserId, apiBaseUrl: "", descriptionFocused: descriptionFocused, showMarkdownHelp: showMarkdownHelp, checklistEnabled: checklistDropdownEnabled, categories: activeCategories, types: activeTypes, priorities: priorities, taxonomyDisplayLabels: taxonomyDisplayLabels, assigneeOptions: assigneeOptions, workstreams: props.workstreams, initiatives: props.initiatives, copiedId: copiedId, onTitleChange: setTitle, onTitleDraftChange: setTitleDraft, onDescriptionChange: setDescription, onDescriptionDraftChange: setDescriptionDraft, onChecklistItemsChange: setChecklistItems, onCategoryChange: setCategory, onTypeChange: setType, onPriorityChange: setPriority, onComplexityChange: setComplexity, onAssigneeChange: setAssignee, onScheduledDateChange: setScheduledDate, onDueDateChange: setDueDate, onNewCommentTextChange: setNewCommentText, onDescriptionFocusedChange: setDescriptionFocused, onShowMarkdownHelpChange: setShowMarkdownHelp, onOpenSettings: (section) => {
|
|
365
|
+
}, onFetchArchive: fetchArchive, onAddTaskToCategory: handleAddTaskToCategory, supplementalTasks: deletedScopeTasks })), activeTab === 'add' && (_jsx(TaskForm, { editingTaskId: editingTaskId, initialActivityEntryId: props.initialActivityEntryId, title: title, description: description, checklistItems: checklistItems, category: category, type: type, priority: priority, complexity: complexity, manualComplexityEnabled: manualComplexityEnabled, assignee: assignee, scheduledDate: scheduledDate, dueDate: dueDate, formTaxonomies: formTaxonomies, onTaxonomyChange: onTaxonomyChange, taxonomies: taxonomies, comments: comments, newCommentText: newCommentText, contextFiles: attachments, currentWorkspaceId: currentWorkspaceId, descriptionImageDraftId: descriptionImageDraftId, currentActorId: authUserId, apiBaseUrl: "", descriptionFocused: descriptionFocused, showMarkdownHelp: showMarkdownHelp, checklistEnabled: checklistDropdownEnabled, categories: activeCategories, types: activeTypes, priorities: priorities, taxonomyDisplayLabels: taxonomyDisplayLabels, assigneeOptions: assigneeOptions, workstreams: props.workstreams, initiatives: props.initiatives, copiedId: copiedId, onTitleChange: setTitle, onTitleDraftChange: setTitleDraft, onDescriptionChange: setDescription, onDescriptionDraftChange: setDescriptionDraft, onChecklistItemsChange: setChecklistItems, onCategoryChange: setCategory, onTypeChange: setType, onPriorityChange: setPriority, onComplexityChange: setComplexity, onAssigneeChange: setAssignee, onScheduledDateChange: setScheduledDate, onDueDateChange: setDueDate, onNewCommentTextChange: setNewCommentText, onDescriptionFocusedChange: setDescriptionFocused, onShowMarkdownHelpChange: setShowMarkdownHelp, onOpenSettings: (section) => {
|
|
363
366
|
handleNavigation(() => {
|
|
364
367
|
setSettingsSection(section);
|
|
365
368
|
setActiveTab('settings');
|
|
366
369
|
});
|
|
367
|
-
}, onSubmit: handleSubmit, commentsEndRef: commentsEndRef, onAddComment: () => handleAddComment(newCommentText), taskReferences: taskTextReferences, onAddContextFile: (file) => {
|
|
370
|
+
}, onSubmit: handleSubmit, onDescriptionImageUploadStart: registerDescriptionImageUpload, commentsEndRef: commentsEndRef, onAddComment: () => handleAddComment(newCommentText), taskReferences: taskTextReferences, onAddContextFile: (file) => {
|
|
368
371
|
setAttachmentsDirty(true);
|
|
369
372
|
setAttachments(prev => [...prev, file]);
|
|
370
373
|
}, onRemoveContextFile: async (index) => {
|
|
@@ -6,6 +6,7 @@ import { type PlanningFavorite } from '../../../utils/planningFavorites';
|
|
|
6
6
|
import type { PlanningTaskScope } from '../planningScope';
|
|
7
7
|
import type { PlanningInitiativeSummary, PlanningLinkOptions, PlanningWorkstreamSummary } from '../../features/planning/planningWorkspaceModel';
|
|
8
8
|
import type { PlanningEntityHydrationState } from '../../features/planning/planningWorkspaceModel';
|
|
9
|
+
import { type PlanningIdentityPatch } from '../../features/planning/PlanningVisualIdentity';
|
|
9
10
|
import { type PlanningTaskArrangeMode } from '../../features/planning/planningTaskArrangement';
|
|
10
11
|
import { type PlanningOwnerOption } from '../../features/planning/PlanningOwnerDropdown';
|
|
11
12
|
import { type PlanningNavigatorSort } from '../../features/planning/planningNavigator';
|
|
@@ -93,10 +94,14 @@ type PlanningDrawerProps = {
|
|
|
93
94
|
draftDescription: string;
|
|
94
95
|
draftOwner: string;
|
|
95
96
|
draftInitiativeId: string;
|
|
97
|
+
draftIcon?: Exclude<PlanningIdentityPatch['icon'], undefined>;
|
|
98
|
+
draftColor?: Exclude<PlanningIdentityPatch['color'], undefined>;
|
|
96
99
|
onChangeDraftTitle: (value: string) => void;
|
|
97
100
|
onChangeDraftDescription: (value: string) => void;
|
|
98
101
|
onChangeDraftOwner: (value: string) => void;
|
|
99
102
|
onChangeDraftInitiativeId: (value: string) => void;
|
|
103
|
+
onChangeDraftIcon?: (value: Exclude<PlanningIdentityPatch['icon'], undefined>) => void;
|
|
104
|
+
onChangeDraftColor?: (value: Exclude<PlanningIdentityPatch['color'], undefined>) => void;
|
|
100
105
|
onCollapseTreePane: () => void;
|
|
101
106
|
onExpandTreePane: () => void;
|
|
102
107
|
onCollapsePrimaryPane: () => void;
|
|
@@ -122,6 +127,7 @@ type PlanningDrawerProps = {
|
|
|
122
127
|
onEditInitiative: (initiativeId: string) => void;
|
|
123
128
|
onEditWorkstream: (workstreamId: string) => void;
|
|
124
129
|
onChangePlanningOwner: (entityType: 'initiative' | 'workstream', entityId: string, ownerId: string) => void | Promise<void>;
|
|
130
|
+
onChangePlanningIdentity?: (entityType: 'initiative' | 'workstream', entityId: string, patch: PlanningIdentityPatch) => void | Promise<void>;
|
|
125
131
|
onChangeTaskAssignee?: (taskId: string, assignee: string) => void | Promise<void>;
|
|
126
132
|
onArchiveInitiative: (initiativeId: string) => void;
|
|
127
133
|
onUnarchiveInitiative: (initiativeId: string) => void;
|
|
@@ -143,4 +149,4 @@ type PlanningDrawerProps = {
|
|
|
143
149
|
onRemovePlanningContextFile?: (entityType: 'initiative' | 'workstream', entityId: string, index: number) => void;
|
|
144
150
|
onUpdatePlanningContextCaption?: (entityType: 'initiative' | 'workstream', entityId: string, index: number, caption: string) => void;
|
|
145
151
|
};
|
|
146
|
-
export declare function PlanningDrawer({ open, leftOffset, returnFocusRef, onWidthChange, initiatives, standaloneWorkstreams, planningLoadState, onRetryPlanning, taskScope, activeInitiativeId, activeWorkstreamId, navigatorSort, navigatorSortReady, onNavigatorSortChange, taskArrangeMode, onTaskArrangeModeChange, onReorderWorkstreamTasks, planningFavorites, onTogglePlanningFavorite, favoritesSectionCollapsed, initiativesSectionCollapsed, workstreamsSectionCollapsed, onToggleFavoritesSection, onToggleInitiativesSection, onToggleWorkstreamsSection, expandedInitiativeIds, detail, editor, secondaryEditor, secondaryPane, primaryHydrationState, secondaryHydrationState, onRetryPrimaryHydration, onRetrySecondaryHydration, currentWorkspaceId, currentOwnerId, theme, assigneeOptions, linkOptions, showTaskCardStatusLabel, draftInitiativeSummary, draftTitle, draftDescription, draftOwner, draftInitiativeId, onChangeDraftTitle, onChangeDraftDescription, onChangeDraftOwner, onChangeDraftInitiativeId, onCollapseTreePane, onExpandTreePane, onCollapsePrimaryPane, onExpandPrimaryPane, onCollapseSecondaryPane, onExpandSecondaryPane, onBackFromSecondary, treeCollapsed, primaryCollapsed, secondaryCollapsed, onCancelEditor, onCancelSecondaryEditor, onSubmitEditor, isSubmittingEditor, onCreateInitiative, onCreateWorkstream, onToggleInitiative, onSelectInitiative, onSelectWorkstream, onOpenInitiativeDetails, onOpenWorkstreamDetails, onOpenNestedWorkstreamDetails, onEditInitiative, onEditWorkstream, onChangePlanningOwner, onChangeTaskAssignee, onArchiveInitiative, onUnarchiveInitiative, onArchiveWorkstream, onUnarchiveWorkstream, onArchivePlanningTask, onArchiveResolvedWorkstream, onArchiveResolvedInitiative, onCreateTaskInWorkstream, onCreateWorkstreamInInitiative, onAssignInitiativeToWorkstream, onOpenTaskById, onSetTaskStatus, taskReferences, onAssignTaskToWorkstream, onAttachTaskToWorkstreamByReference, onAttachWorkstreamToInitiativeByReference, onAddPlanningContextFile, onRemovePlanningContextFile, onUpdatePlanningContextCaption, }: PlanningDrawerProps): import("react/jsx-runtime").JSX.Element;
|
|
152
|
+
export declare function PlanningDrawer({ open, leftOffset, returnFocusRef, onWidthChange, initiatives, standaloneWorkstreams, planningLoadState, onRetryPlanning, taskScope, activeInitiativeId, activeWorkstreamId, navigatorSort, navigatorSortReady, onNavigatorSortChange, taskArrangeMode, onTaskArrangeModeChange, onReorderWorkstreamTasks, planningFavorites, onTogglePlanningFavorite, favoritesSectionCollapsed, initiativesSectionCollapsed, workstreamsSectionCollapsed, onToggleFavoritesSection, onToggleInitiativesSection, onToggleWorkstreamsSection, expandedInitiativeIds, detail, editor, secondaryEditor, secondaryPane, primaryHydrationState, secondaryHydrationState, onRetryPrimaryHydration, onRetrySecondaryHydration, currentWorkspaceId, currentOwnerId, theme, assigneeOptions, linkOptions, showTaskCardStatusLabel, draftInitiativeSummary, draftTitle, draftDescription, draftOwner, draftInitiativeId, draftIcon, draftColor, onChangeDraftTitle, onChangeDraftDescription, onChangeDraftOwner, onChangeDraftInitiativeId, onChangeDraftIcon, onChangeDraftColor, onCollapseTreePane, onExpandTreePane, onCollapsePrimaryPane, onExpandPrimaryPane, onCollapseSecondaryPane, onExpandSecondaryPane, onBackFromSecondary, treeCollapsed, primaryCollapsed, secondaryCollapsed, onCancelEditor, onCancelSecondaryEditor, onSubmitEditor, isSubmittingEditor, onCreateInitiative, onCreateWorkstream, onToggleInitiative, onSelectInitiative, onSelectWorkstream, onOpenInitiativeDetails, onOpenWorkstreamDetails, onOpenNestedWorkstreamDetails, onEditInitiative, onEditWorkstream, onChangePlanningOwner, onChangePlanningIdentity, onChangeTaskAssignee, onArchiveInitiative, onUnarchiveInitiative, onArchiveWorkstream, onUnarchiveWorkstream, onArchivePlanningTask, onArchiveResolvedWorkstream, onArchiveResolvedInitiative, onCreateTaskInWorkstream, onCreateWorkstreamInInitiative, onAssignInitiativeToWorkstream, onOpenTaskById, onSetTaskStatus, taskReferences, onAssignTaskToWorkstream, onAttachTaskToWorkstreamByReference, onAttachWorkstreamToInitiativeByReference, onAddPlanningContextFile, onRemovePlanningContextFile, onUpdatePlanningContextCaption, }: PlanningDrawerProps): import("react/jsx-runtime").JSX.Element;
|