@taskforcehq/taskforce 0.3.301 → 0.3.303
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 +37 -2
- package/dist/TaskforceCore.filter-persistence.test.js +1 -1
- package/dist/TaskforceCore.js +72 -33
- package/dist/TaskforceCore.test.js +848 -130
- package/dist/components/features/TaskSettings.js +14 -82
- package/dist/components/features/TaskSettings.test.js +33 -70
- package/dist/components/features/settings/TaxonomyLibraryManager.js +8 -2
- package/dist/components/features/settings/TaxonomyLibraryManager.test.js +1 -1
- package/dist/components/task/TaskActionHeader.js +6 -3
- package/dist/components/task/TaskCard.js +6 -3
- package/dist/components/task/TaskForm.js +2 -2
- package/dist/components/task/TaskForm.test.js +41 -2
- package/dist/components/task/TaskKanban.test.js +17 -0
- package/dist/components/ui/ReferenceBadgeButton.js +1 -1
- package/dist/components/views/PlansPage.d.ts +3 -1
- package/dist/components/views/PlansPage.js +109 -49
- package/dist/components/views/PlansPage.test.d.ts +1 -0
- package/dist/components/views/PlansPage.test.js +100 -0
- package/dist/components/views/StandaloneLayout.d.ts +1 -0
- package/dist/components/views/StandaloneLayout.js +473 -256
- package/dist/components/views/panels/PlanningDrawer.js +18 -1
- package/dist/components/views/standalone/modals/AccountHubModal.d.ts +48 -0
- package/dist/components/views/standalone/modals/AccountHubModal.js +36 -0
- package/dist/components/views/standalone/modals/AccountHubModal.test.d.ts +1 -0
- package/dist/components/views/standalone/modals/AccountHubModal.test.js +26 -0
- package/dist/components/views/standalone/modals/CreateWorkspaceConfirmModal.d.ts +9 -0
- package/dist/components/views/standalone/modals/CreateWorkspaceConfirmModal.js +8 -0
- package/dist/components/views/standalone/modals/EditProfileModal.d.ts +26 -0
- package/dist/components/views/standalone/modals/EditProfileModal.js +10 -0
- package/dist/components/views/standalone/modals/HelpModal.d.ts +9 -0
- package/dist/components/views/standalone/modals/HelpModal.js +8 -0
- package/dist/components/views/standalone/modals/ScheduleWarningModal.d.ts +13 -0
- package/dist/components/views/standalone/modals/ScheduleWarningModal.js +6 -0
- package/dist/components/views/standalone/modals/SyncStatusModal.d.ts +61 -0
- package/dist/components/views/standalone/modals/SyncStatusModal.js +38 -0
- package/dist/components/views/standalone/modals/TeamManagementModal.d.ts +64 -0
- package/dist/components/views/standalone/modals/TeamManagementModal.js +10 -0
- package/dist/components/views/standalone/modals/types.d.ts +2 -0
- package/dist/components/views/standalone/modals/types.js +1 -0
- package/dist/components/views/teamManagementAccess.d.ts +1 -1
- package/dist/components/views/teamManagementAccess.js +2 -2
- package/dist/components/views/teamManagementAccess.test.js +3 -3
- package/dist/config/deployment.js +2 -2
- package/dist/config/deployment.test.js +5 -3
- package/dist/core/AiProfileService.js +7 -2
- package/dist/core/AiProfiles.test.js +19 -0
- package/dist/core/EntitlementsPolicy.test.js +2 -2
- package/dist/core/GlobalSettingsService.js +78 -18
- package/dist/core/PlanEntitlementService.d.ts +29 -5
- package/dist/core/PlanEntitlementService.js +297 -219
- package/dist/core/SignupMonetizationSettings.test.js +173 -49
- package/dist/core/SyncReconciliationService.d.ts +2 -0
- package/dist/core/SyncReconciliationService.js +3 -0
- package/dist/core/SystemAdmin.test.js +186 -96
- package/dist/core/TaskAuditTimeline.test.js +40 -0
- package/dist/core/Taskforce.d.ts +100 -10
- package/dist/core/Taskforce.ids.test.js +133 -0
- package/dist/core/Taskforce.js +459 -127
- package/dist/core/Taskforce.mcpAuth.test.js +0 -2
- package/dist/core/UserProfileAvatarDrafts.test.d.ts +1 -0
- package/dist/core/UserProfileAvatarDrafts.test.js +111 -0
- package/dist/core/taskReferencePolicy.d.ts +28 -0
- package/dist/core/taskReferencePolicy.js +189 -0
- package/dist/core/types.d.ts +13 -12
- package/dist/hooks/tasks/useTaskFormActions.js +3 -0
- package/dist/hooks/useSyncOrchestrator.js +17 -3
- package/dist/hooks/useSyncOrchestrator.retry-closure.test.js +97 -5
- package/dist/hooks/useTaskData.js +3 -2
- package/dist/hooks/useTaskData.test.js +66 -0
- package/dist/hooks/useTaskforce.d.ts +8 -0
- package/dist/hooks/useTaskforce.js +72 -19
- package/dist/hooks/useTaskforce.sync-behavior.test.js +185 -6
- package/dist/mcp/aiProfileBootstrap.d.ts +29 -0
- package/dist/mcp/aiProfileBootstrap.js +80 -0
- package/dist/mcp/aiProfileBootstrap.test.d.ts +1 -0
- package/dist/mcp/aiProfileBootstrap.test.js +68 -0
- package/dist/mcp/clientIntegrations.d.ts +2 -8
- package/dist/mcp/clientIntegrations.js +21 -40
- package/dist/mcp/clientIntegrations.test.js +28 -2
- package/dist/mcp/clientProfileDefaults.d.ts +12 -0
- package/dist/mcp/clientProfileDefaults.js +37 -0
- package/dist/mcp/runtime.d.ts +10 -7
- package/dist/mcp/runtime.js +131 -48
- package/dist/mcp/runtime.test.js +321 -83
- package/dist/migrations/billingSchemaParity.test.js +3 -0
- package/dist/migrations/taskSchemaMigrations.js +68 -1
- package/dist/qaOpen.test.d.ts +1 -0
- package/dist/qaOpen.test.js +56 -0
- package/dist/server/index.cookieProxy.test.js +2 -0
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.js +17 -1
- package/dist/server/index.test.js +15 -1
- package/dist/server/mockStripe.d.ts +1 -0
- package/dist/server/mockStripe.js +2 -0
- package/dist/server/routes/admin.js +105 -45
- package/dist/server/routes/auth.d.ts +6 -0
- package/dist/server/routes/auth.js +505 -30
- package/dist/server/routes/billing.js +517 -24
- package/dist/server/routes/billing.test.js +967 -45
- package/dist/server/routes/documents.js +6 -1
- package/dist/server/routes/shared.d.ts +1 -1
- package/dist/server/routes/shared.js +16 -6
- package/dist/server/routes/sync.integration.test.js +290 -0
- package/dist/server/routes/sync.js +234 -1922
- package/dist/server/routes/tasks.js +18 -4
- package/dist/server/routes.js +29 -22
- package/dist/server/routes.test.js +639 -82
- package/dist/shared/runtimeContract.d.ts +1 -1
- package/dist/sync/cloudSyncApi.d.ts +1 -0
- package/dist/sync/collaborationSyncPayload.d.ts +17 -0
- package/dist/sync/collaborationSyncPayload.js +131 -0
- package/dist/sync/collaborationSyncPayload.test.d.ts +1 -0
- package/dist/sync/collaborationSyncPayload.test.js +104 -0
- package/dist/sync/collaborationSyncState.d.ts +15 -0
- package/dist/sync/collaborationSyncState.js +60 -0
- package/dist/sync/contentSyncPayload.d.ts +45 -0
- package/dist/sync/contentSyncPayload.js +104 -0
- package/dist/sync/contentSyncPayload.test.d.ts +1 -0
- package/dist/sync/contentSyncPayload.test.js +104 -0
- package/dist/sync/contentSyncState.d.ts +98 -0
- package/dist/sync/contentSyncState.js +1004 -0
- package/dist/sync/planningSyncPayload.d.ts +9 -0
- package/dist/sync/planningSyncPayload.js +82 -0
- package/dist/sync/planningSyncPayload.test.d.ts +1 -0
- package/dist/sync/planningSyncPayload.test.js +68 -0
- package/dist/sync/syncApplyHandlers.d.ts +83 -0
- package/dist/sync/syncApplyHandlers.js +445 -0
- package/dist/sync/syncService.d.ts +1 -0
- package/dist/sync/syncService.js +21 -8
- package/dist/sync/taskSyncPayload.d.ts +33 -0
- package/dist/sync/taskSyncPayload.js +126 -0
- package/dist/sync/taskSyncPayload.test.d.ts +1 -0
- package/dist/sync/taskSyncPayload.test.js +54 -0
- package/dist/sync/workspacePullFeed.d.ts +38 -0
- package/dist/sync/workspacePullFeed.js +349 -0
- package/dist/sync/workspacePullFeed.test.d.ts +1 -0
- package/dist/sync/workspacePullFeed.test.js +278 -0
- package/dist/sync/workspaceSyncModel.d.ts +4 -1
- package/dist/sync/workspaceSyncModel.js +9 -2
- package/dist/sync/workspaceSyncModel.test.js +29 -0
- package/dist/test/setup.js +1 -1
- package/dist/types.d.ts +1 -0
- package/dist/ui/assets/{AgentsModule-Bdq3T1Ts.js → AgentsModule-CpsTmrIW.js} +1 -1
- package/dist/ui/assets/{AnnotatedAttachmentWorkspace-jKUVo-PJ.js → AnnotatedAttachmentWorkspace-C_TmXZwA.js} +1 -1
- package/dist/ui/assets/{DocumentWorkspace-DuQa-uIC.js → DocumentWorkspace-C3GyzrWm.js} +2 -2
- package/dist/ui/assets/{InitiativesModule-C8Pi2VTk.js → InitiativesModule-4-Rh2K2n.js} +1 -1
- package/dist/ui/assets/PlansPage-BP7AYOqr.js +1 -0
- package/dist/ui/assets/TaskSettings-BOC5F6Ag.js +8 -0
- package/dist/ui/assets/{TaskSettings-BwB9NtmJ.css → TaskSettings-CnIBL_Eb.css} +1 -1
- package/dist/ui/assets/{WorkflowsModule-b6TLuHwJ.js → WorkflowsModule-CGk9s3NJ.js} +1 -1
- package/dist/ui/assets/index-CLIMgR6g.js +6 -0
- package/dist/ui/assets/index-DneETxcu.css +1 -0
- package/dist/ui/assets/{vendor-icons-QZyhEwgT.js → vendor-icons-pWocEipT.js} +1 -1
- package/dist/ui/index.html +3 -3
- package/dist/utils/accountProfileSummaryCache.d.ts +31 -0
- package/dist/utils/accountProfileSummaryCache.js +97 -0
- package/dist/utils/accountProfileSummaryCache.test.d.ts +1 -0
- package/dist/utils/accountProfileSummaryCache.test.js +63 -0
- package/dist/utils/taskActivity.js +17 -4
- package/dist/utils/taskActivity.test.js +27 -0
- package/dist/utils/taskNormalization.js +10 -2
- package/dist/utils/taskReferences.d.ts +11 -1
- package/dist/utils/taskReferences.js +33 -1
- package/package.json +4 -3
- package/scripts/qa-open-lib.mjs +175 -0
- package/scripts/qa-open-lib.mjs.d.ts +49 -0
- package/scripts/qa-open.mjs +352 -0
- package/dist/ui/assets/PlansPage-B6BDECSi.js +0 -1
- package/dist/ui/assets/TaskSettings-DUJgRTPU.js +0 -8
- package/dist/ui/assets/index-BiiF1cLQ.css +0 -1
- package/dist/ui/assets/index-xBWLPOEb.js +0 -6
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{j as e,r as i,s as Ft,R as Fe}from"./vendor-react-CKJs5o3c.js";import{t as M,h as fe,f as B,i as rt,j as ot,k as Ot,m as Ht,R as Wt,n as I,o as ct,p as Gt,q as Kt}from"./index-xBWLPOEb.js";import{r as Ut,W as Jt,t as Vt,l as Yt,as as Xt,at as Oe,n as qt,Z as He,X as wt,au as lt,e as gt,av as yt,aw as Qt,ax as Zt,a as en,i as tn,ay as nn,az as sn,aA as an,aB as _e,aC as rn,s as on,aD as cn,D as ln,aE as dn,T as un,ar as dt,R as mn,aF as fn,B as hn,U as pn,S as vn}from"./vendor-icons-QZyhEwgT.js";import{s as wn,M as ke,r as Se}from"./vendor-markdown-BUxTU7dS.js";import"./vendor-dnd-DRzYolkg.js";import"./vendor-router-BbWMxlnO.js";const gn="_index_18mna_1",yn="_header_18mna_8",xn="_title_18mna_17",bn="_refreshBtn_18mna_26",_n="_search_18mna_48",kn="_searchIcon_18mna_54",Sn="_searchInput_18mna_63",jn="_list_18mna_80",Cn="_state_18mna_89",Nn="_stateError_18mna_97",Tn="_item_18mna_104",En="_itemActive_18mna_124",Rn="_itemIcon_18mna_132",An="_itemBody_18mna_142",$n="_itemTitle_18mna_150",Ln="_itemTask_18mna_162",In="_itemBadge_18mna_172",Bn="_itemMeta_18mna_185",Dn="_itemMetaDetails_18mna_195",Pn="_itemMetaReference_18mna_202",R={index:gn,header:yn,title:xn,refreshBtn:bn,search:_n,searchIcon:kn,searchInput:Sn,list:jn,state:Cn,stateError:Nn,item:Tn,itemActive:En,itemIcon:Rn,itemBody:An,itemTitle:$n,itemTask:Ln,itemBadge:In,itemMeta:Bn,itemMetaDetails:Dn,itemMetaReference:Pn};function Mn({docType:t}){switch(t){case"implementation-plan":return e.jsx(qt,{size:13});case"review":return e.jsx(Oe,{size:13});case"walkthrough":return e.jsx(Xt,{size:13});default:return e.jsx(Yt,{size:13})}}function zn(t){return t<1024?`${t}B`:t<1024*1024?`${(t/1024).toFixed(1)}KB`:`${(t/(1024*1024)).toFixed(1)}MB`}function Fn(t){if(!t)return"";const l=new Date(t),r=new Date().getTime()-l.getTime(),u=Math.floor(r/(1e3*60*60*24));return u===0?"Today":u===1?"Yesterday":u<7?`${u}d ago`:u<30?`${Math.floor(u/7)}w ago`:l.toLocaleDateString()}function On(t,l){t.key!=="Enter"&&t.key!==" "||(t.preventDefault(),l())}function Hn({documents:t,selectedDocId:l,loading:c,error:r,searchQuery:u,taskById:m,onSearchChange:v,onSelect:S,onRefresh:g,hasActiveFilters:w}){return e.jsxs("div",{className:R.index,children:[e.jsxs("div",{className:R.header,children:[e.jsxs("span",{className:R.title,children:[e.jsx(Ut,{size:14}),"Documents"]}),e.jsx("button",{className:R.refreshBtn,onClick:g,title:"Refresh document list",disabled:c,children:e.jsx(Jt,{size:13,className:c?M.docSpinning:void 0})})]}),e.jsxs("div",{className:R.search,children:[e.jsx(Vt,{size:12,className:R.searchIcon}),e.jsx("input",{type:"text",placeholder:"Search documents…",value:u,onChange:p=>v(p.target.value),className:R.searchInput})]}),e.jsxs("div",{className:`${R.list} tf-scrollbar`,children:[c&&e.jsx("div",{className:R.state,children:"Loading documents…"}),!c&&r&&e.jsx("div",{className:R.stateError,children:r}),!c&&!r&&t.length===0&&e.jsx("div",{className:R.state,children:w?"No documents match your filters.":"No documents found. Documents added as task attachments will appear here."}),!c&&t.map(p=>{const _=p.taskId?m.get(p.taskId):null,b=p.id===l,L=fe(p),z=Ce(p),D=typeof p.attachmentCount=="number"&&Number.isFinite(p.attachmentCount)?p.attachmentCount:p.taskId?1:0,N=D>1?`${D} tasks linked`:D===1?_?.title||"1 task linked":null;return e.jsxs("div",{role:"button",tabIndex:0,className:`${R.item} ${b?R.itemActive:""}`,onClick:()=>S(p),onKeyDown:J=>On(J,()=>S(p)),children:[e.jsx("div",{className:R.itemIcon,children:e.jsx(Mn,{docType:p.docType})}),e.jsxs("div",{className:R.itemBody,children:[e.jsx("span",{className:R.itemTitle,title:L,children:L}),z==="unattached"&&e.jsx("span",{className:R.itemBadge,children:"Unattached"}),N&&e.jsx("span",{className:R.itemTask,title:N,children:N}),e.jsxs("span",{className:R.itemMeta,children:[e.jsxs("span",{className:R.itemMetaDetails,children:[zn(p.sizeBytes),p.updatedAt&&e.jsxs(e.Fragment,{children:[" · ",Fn(p.updatedAt)]})]}),p.referenceLabel&&e.jsx("span",{className:R.itemMetaReference,children:p.referenceLabel})]})]})]},p.id)})]})]})}function je(t){return function(l){return wn(l,t)}}const Wn="_viewer_biumc_1",Gn="_viewerMonochrome_biumc_10",Kn="_metaDocumentName_biumc_10",Un="_viewerEditMode_biumc_14",Jn="_meta_biumc_10",Vn="_metaLeft_biumc_30",Yn="_metaRenameRow_biumc_49",Xn="_typeBadge_biumc_56",qn="_typeBadgeImplementationPlan_biumc_71",Qn="_typeBadgeReview_biumc_77",Zn="_typeBadgeWalkthrough_biumc_83",es="_metaTaskName_biumc_89",ts="_statusBadge_biumc_98",ns="_metaDate_biumc_113",ss="_metaSize_biumc_114",as="_actions_biumc_122",is="_actionBtn_biumc_129",rs="_dangerBtn_biumc_156",os="_generateBtn_biumc_167",cs="_editBtn_biumc_178",ls="_saveBtn_biumc_189",ds="_layoutToggle_biumc_205",us="_layoutBtn_biumc_213",ms="_layoutBtnActive_biumc_229",fs="_saveStatus_biumc_234",hs="_saveStatusSaved_biumc_241",ps="_saveStatusError_biumc_245",vs="_unsaved_biumc_250",ws="_viewerContent_biumc_256",gs="_viewerBody_biumc_265",ys="_viewerMain_biumc_273",xs="_reviewRail_biumc_277",bs="_printHint_biumc_283",_s="_reviewSection_biumc_290",ks="_reviewHeader_biumc_299",Ss="_reviewTitle_biumc_307",js="_reviewSubtitle_biumc_316",Cs="_reviewControls_biumc_323",Ns="_reviewSelect_biumc_330",Ts="_reviewSessionMeta_biumc_334",Es="_reviewStatusResolved_biumc_342",Rs="_reviewSessionLabel_biumc_348",As="_reviewTitleEditRow_biumc_353",$s="_reviewSessionTimestamp_biumc_360",Ls="_reviewAnchorLabel_biumc_364",Is="_reviewComposer_biumc_370",Bs="_reviewAnchorChip_biumc_377",Ds="_reviewAnchorSnippet_biumc_390",Ps="_reviewAnchorClear_biumc_395",Ms="_reviewCommentActions_biumc_408",zs="_reviewCommentAction_biumc_408",Fs="_reviewCommentEditor_biumc_429",Os="_viewerState_biumc_435",Hs="_viewerStateError_biumc_442",Ws="_editorArea_biumc_449",Gs="_editorPane_biumc_456",Ks="_editorLayoutSplit_biumc_464",Us="_previewPane_biumc_465",Js="_editorLayoutEditor_biumc_469",Vs="_editorLayoutPreview_biumc_470",Ys="_editorPaneLabel_biumc_474",Xs="_editorTextarea_biumc_486",qs="_markdownSurface_biumc_528",a={viewer:Wn,viewerMonochrome:Gn,metaDocumentName:Kn,viewerEditMode:Un,meta:Jn,metaLeft:Vn,metaRenameRow:Yn,typeBadge:Xn,typeBadgeImplementationPlan:qn,typeBadgeReview:Qn,typeBadgeWalkthrough:Zn,metaTaskName:es,statusBadge:ts,metaDate:ns,metaSize:ss,actions:as,actionBtn:is,dangerBtn:rs,generateBtn:os,editBtn:cs,saveBtn:ls,layoutToggle:ds,layoutBtn:us,layoutBtnActive:ms,saveStatus:fs,saveStatusSaved:hs,saveStatusError:ps,unsaved:vs,viewerContent:ws,viewerBody:gs,viewerMain:ys,reviewRail:xs,printHint:bs,reviewSection:_s,reviewHeader:ks,reviewTitle:Ss,reviewSubtitle:js,reviewControls:Cs,reviewSelect:Ns,reviewSessionMeta:Ts,reviewStatusResolved:Es,reviewSessionLabel:Rs,reviewTitleEditRow:As,reviewSessionTimestamp:$s,reviewAnchorLabel:Ls,reviewComposer:Is,reviewAnchorChip:Bs,reviewAnchorSnippet:Ds,reviewAnchorClear:Ps,reviewCommentActions:Ms,reviewCommentAction:zs,reviewCommentEditor:Fs,viewerState:Os,viewerStateError:Hs,editorArea:Ws,editorPane:Gs,editorLayoutSplit:Ks,previewPane:Us,editorLayoutEditor:Js,editorLayoutPreview:Vs,editorPaneLabel:Ys,editorTextarea:Xs,markdownSurface:qs},Qs="_overlay_1unik_1",Zs="_modal_1unik_12",ea="_header_1unik_16",ta="_title_1unik_20",na="_docName_1unik_24",sa="_body_1unik_34",aa="_state_1unik_41",ia="_stateError_1unik_52",ra="_stateDone_1unik_63",oa="_toolbar_1unik_84",ca="_toolbarCount_1unik_95",la="_toolbarActions_1unik_100",da="_tree_1unik_105",ua="_taskRow_1unik_113",ma="_taskRowDimmed_1unik_126",fa="_taskCheck_1unik_130",ha="_taskExpandBtn_1unik_139",pa="_taskExpandSpacer_1unik_155",va="_taskTitle_1unik_160",wa="_taskBadge_1unik_169",ga="_footer_1unik_179",C={overlay:Qs,modal:Zs,header:ea,title:ta,docName:na,body:sa,state:aa,stateError:ia,stateDone:ra,toolbar:oa,toolbarCount:ca,toolbarActions:la,tree:da,taskRow:ua,taskRowDimmed:ma,taskCheck:fa,taskExpandBtn:ha,taskExpandSpacer:pa,taskTitle:va,taskBadge:wa,footer:ga},ya={1:"Low",2:"Medium",3:"High"};function me(t,l){return t.map(c=>({...c,selected:l,children:me(c.children,l)}))}function xt(t,l,c){return t.map(r=>r.idempotencyKey===l?{...r,selected:c,children:me(r.children,c)}:{...r,children:xt(r.children,l,c)})}function We(t){let l=0;for(const c of t)c.selected&&l++,l+=We(c.children);return l}function bt({node:t,depth:l,onToggle:c}){const[r,u]=i.useState(!0),m=t.children.length>0,v=l*20;return e.jsxs("div",{children:[e.jsxs("div",{className:`${C.taskRow} ${t.selected?"":C.taskRowDimmed}`,style:{paddingLeft:`${12+v}px`},children:[e.jsx("button",{className:C.taskCheck,onClick:()=>c(t.idempotencyKey,!t.selected),title:t.selected?"Deselect":"Select",children:t.selected?e.jsx(Qt,{size:14,style:{color:"var(--brand-primary-strong)"}}):e.jsx(Zt,{size:14,style:{color:"var(--text-muted)"}})}),m?e.jsx("button",{className:C.taskExpandBtn,onClick:()=>u(S=>!S),children:r?e.jsx(en,{size:12}):e.jsx(tn,{size:12})}):e.jsx("span",{className:C.taskExpandSpacer}),e.jsx("span",{className:C.taskTitle,title:t.description||void 0,children:t.title}),e.jsx("span",{className:C.taskBadge,style:{color:rt(t.type),borderColor:rt(t.type)},children:t.type}),e.jsx("span",{className:C.taskBadge,style:{color:ot(t.priority),borderColor:ot(t.priority)},children:ya[t.priority]})]}),m&&r&&e.jsx("div",{children:t.children.map(S=>e.jsx(bt,{node:S,depth:l+1,onToggle:c},S.idempotencyKey))})]})}function xa({content:t,docTitle:l,apiBaseUrl:c="",onClose:r,onGenerated:u}){const[m,v]=i.useState("preview"),[S,g]=i.useState(null),[w,p]=i.useState([]),[_,b]=i.useState(!0),[L,z]=i.useState(0),[D,N]=i.useState(null);i.useEffect(()=>{let y=!1;return b(!0),g(null),B("/api/taskforce/documents/generate-tasks/preview",{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({content:t})},c).then(j=>j.json()).then(j=>{if(!y){if(j.error)throw new Error(j.error);p(j.tasks||[]),v("preview")}}).catch(j=>{y||(g(j?.message||"Failed to parse plan"),v("error"))}).finally(()=>{y||b(!1)}),()=>{y=!0}},[t,c]);const J=i.useCallback((y,j)=>{p(q=>xt(q,y,j))},[]),F=()=>p(y=>me(y,!0)),W=()=>p(y=>me(y,!1)),O=We(w),Y=async()=>{v("generating"),N(null);try{const y=await B("/api/taskforce/documents/generate-tasks/commit",{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({tasks:w})},c),j=await y.json().catch(()=>({}));if(!y.ok)throw new Error(j.error||`Generation failed (${y.status})`);z(j.created??0),v("done"),u(j.created??0)}catch(y){N(y?.message||"Generation failed"),v("error")}};return e.jsx("div",{className:C.overlay,onClick:y=>{y.target===y.currentTarget&&r()},children:e.jsxs("div",{className:`tf-surface-modal tf-modal-shell ${C.modal}`,children:[e.jsxs("div",{className:`tf-modal-header ${C.header}`,children:[e.jsxs("div",{className:`tf-modal-title ${C.title}`,children:[e.jsx(He,{size:16,style:{color:"var(--brand-primary-strong)"}}),"Generate Tasks from Plan"]}),e.jsx("span",{className:C.docName,children:l}),e.jsx("button",{className:"tf-control-icon",onClick:r,title:"Close",children:e.jsx(wt,{size:16})})]}),e.jsxs("div",{className:C.body,children:[_&&e.jsxs("div",{className:C.state,children:[e.jsx(lt,{size:20,className:M.docSpinning}),"Parsing plan…"]}),!_&&m==="error"&&e.jsxs("div",{className:C.stateError,children:[e.jsx(gt,{size:16}),S||D||"An error occurred"]}),!_&&m==="done"&&e.jsxs("div",{className:C.stateDone,children:[e.jsx(yt,{size:24,style:{color:"var(--status-success)"}}),e.jsxs("strong",{children:[L," task",L!==1?"s":""," created"]}),e.jsx("p",{children:"Tasks are now in your board. Switch to the Kanban or Hierarchy view to see them."})]}),!_&&(m==="preview"||m==="confirm"||m==="generating")&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:C.toolbar,children:[e.jsxs("span",{className:C.toolbarCount,children:[O," of ",We(me(w,!0))," tasks selected"]}),e.jsxs("div",{className:C.toolbarActions,children:[e.jsx("button",{className:"tf-control-icon",onClick:F,children:"Select all"}),e.jsx("button",{className:"tf-control-icon",onClick:W,children:"Deselect all"})]})]}),w.length===0?e.jsx("div",{className:C.state,children:"No tasks could be parsed from this document. Make sure the document uses ## H2 headings for phases and bullet points for tasks."}):e.jsx("div",{className:`${C.tree} tf-scrollbar`,children:w.map(y=>e.jsx(bt,{node:y,depth:0,onToggle:J},y.idempotencyKey))})]})]}),!_&&m!=="done"&&m!=="error"&&e.jsxs("div",{className:C.footer,children:[e.jsx("button",{className:"tf-button-secondary",onClick:r,children:"Cancel"}),e.jsx("button",{className:"tf-button-primary",onClick:Y,disabled:O===0||m==="generating",children:m==="generating"?e.jsxs(e.Fragment,{children:[e.jsx(lt,{size:13,className:M.docSpinning})," Generating…"]}):e.jsxs(e.Fragment,{children:[e.jsx(He,{size:13})," Generate ",O," task",O!==1?"s":""]})})]}),!_&&m==="done"&&e.jsx("div",{className:C.footer,children:e.jsx("button",{className:"tf-button-primary",onClick:r,children:"Done"})})]})})}const ba={"implementation-plan":"Implementation Plan",review:"Review",walkthrough:"Walkthrough",planning:"Planning",other:"Document"},_a={"implementation-plan":a.typeBadgeImplementationPlan,review:a.typeBadgeReview,walkthrough:a.typeBadgeWalkthrough,planning:void 0,other:void 0},ka={editor:a.editorLayoutEditor,split:a.editorLayoutSplit,preview:a.editorLayoutPreview},Sa=1500,ja=`
|
|
1
|
+
import{j as e,r as i,s as Ft,R as Fe}from"./vendor-react-CKJs5o3c.js";import{t as M,h as fe,f as B,i as rt,j as ot,k as Ot,m as Ht,R as Gt,n as I,o as ct,q as Wt,s as Kt}from"./index-CLIMgR6g.js";import{r as Ut,t as Jt,u as Vt,l as Yt,at as Xt,au as Oe,n as qt,Z as He,X as wt,av as lt,e as gt,aw as yt,ax as Qt,ay as Zt,a as en,i as tn,az as nn,aA as sn,aB as an,aC as _e,aD as rn,s as on,aE as cn,D as ln,aF as dn,T as un,as as dt,R as mn,aG as fn,B as hn,U as pn,S as vn}from"./vendor-icons-pWocEipT.js";import{s as wn,M as ke,r as Se}from"./vendor-markdown-BUxTU7dS.js";import"./vendor-dnd-DRzYolkg.js";import"./vendor-router-BbWMxlnO.js";const gn="_index_18mna_1",yn="_header_18mna_8",xn="_title_18mna_17",bn="_refreshBtn_18mna_26",_n="_search_18mna_48",kn="_searchIcon_18mna_54",Sn="_searchInput_18mna_63",jn="_list_18mna_80",Cn="_state_18mna_89",Nn="_stateError_18mna_97",Tn="_item_18mna_104",En="_itemActive_18mna_124",Rn="_itemIcon_18mna_132",An="_itemBody_18mna_142",$n="_itemTitle_18mna_150",Ln="_itemTask_18mna_162",In="_itemBadge_18mna_172",Bn="_itemMeta_18mna_185",Dn="_itemMetaDetails_18mna_195",Pn="_itemMetaReference_18mna_202",R={index:gn,header:yn,title:xn,refreshBtn:bn,search:_n,searchIcon:kn,searchInput:Sn,list:jn,state:Cn,stateError:Nn,item:Tn,itemActive:En,itemIcon:Rn,itemBody:An,itemTitle:$n,itemTask:Ln,itemBadge:In,itemMeta:Bn,itemMetaDetails:Dn,itemMetaReference:Pn};function Mn({docType:t}){switch(t){case"implementation-plan":return e.jsx(qt,{size:13});case"review":return e.jsx(Oe,{size:13});case"walkthrough":return e.jsx(Xt,{size:13});default:return e.jsx(Yt,{size:13})}}function zn(t){return t<1024?`${t}B`:t<1024*1024?`${(t/1024).toFixed(1)}KB`:`${(t/(1024*1024)).toFixed(1)}MB`}function Fn(t){if(!t)return"";const l=new Date(t),r=new Date().getTime()-l.getTime(),u=Math.floor(r/(1e3*60*60*24));return u===0?"Today":u===1?"Yesterday":u<7?`${u}d ago`:u<30?`${Math.floor(u/7)}w ago`:l.toLocaleDateString()}function On(t,l){t.key!=="Enter"&&t.key!==" "||(t.preventDefault(),l())}function Hn({documents:t,selectedDocId:l,loading:c,error:r,searchQuery:u,taskById:m,onSearchChange:v,onSelect:S,onRefresh:g,hasActiveFilters:w}){return e.jsxs("div",{className:R.index,children:[e.jsxs("div",{className:R.header,children:[e.jsxs("span",{className:R.title,children:[e.jsx(Ut,{size:14}),"Documents"]}),e.jsx("button",{className:R.refreshBtn,onClick:g,title:"Refresh document list",disabled:c,children:e.jsx(Jt,{size:13,className:c?M.docSpinning:void 0})})]}),e.jsxs("div",{className:R.search,children:[e.jsx(Vt,{size:12,className:R.searchIcon}),e.jsx("input",{type:"text",placeholder:"Search documents…",value:u,onChange:p=>v(p.target.value),className:R.searchInput})]}),e.jsxs("div",{className:`${R.list} tf-scrollbar`,children:[c&&e.jsx("div",{className:R.state,children:"Loading documents…"}),!c&&r&&e.jsx("div",{className:R.stateError,children:r}),!c&&!r&&t.length===0&&e.jsx("div",{className:R.state,children:w?"No documents match your filters.":"No documents found. Documents added as task attachments will appear here."}),!c&&t.map(p=>{const _=p.taskId?m.get(p.taskId):null,b=p.id===l,L=fe(p),z=Ce(p),D=typeof p.attachmentCount=="number"&&Number.isFinite(p.attachmentCount)?p.attachmentCount:p.taskId?1:0,N=D>1?`${D} tasks linked`:D===1?_?.title||"1 task linked":null;return e.jsxs("div",{role:"button",tabIndex:0,className:`${R.item} ${b?R.itemActive:""}`,onClick:()=>S(p),onKeyDown:J=>On(J,()=>S(p)),children:[e.jsx("div",{className:R.itemIcon,children:e.jsx(Mn,{docType:p.docType})}),e.jsxs("div",{className:R.itemBody,children:[e.jsx("span",{className:R.itemTitle,title:L,children:L}),z==="unattached"&&e.jsx("span",{className:R.itemBadge,children:"Unattached"}),N&&e.jsx("span",{className:R.itemTask,title:N,children:N}),e.jsxs("span",{className:R.itemMeta,children:[e.jsxs("span",{className:R.itemMetaDetails,children:[zn(p.sizeBytes),p.updatedAt&&e.jsxs(e.Fragment,{children:[" · ",Fn(p.updatedAt)]})]}),p.referenceLabel&&e.jsx("span",{className:R.itemMetaReference,children:p.referenceLabel})]})]})]},p.id)})]})]})}function je(t){return function(l){return wn(l,t)}}const Gn="_viewer_biumc_1",Wn="_viewerMonochrome_biumc_10",Kn="_metaDocumentName_biumc_10",Un="_viewerEditMode_biumc_14",Jn="_meta_biumc_10",Vn="_metaLeft_biumc_30",Yn="_metaRenameRow_biumc_49",Xn="_typeBadge_biumc_56",qn="_typeBadgeImplementationPlan_biumc_71",Qn="_typeBadgeReview_biumc_77",Zn="_typeBadgeWalkthrough_biumc_83",es="_metaTaskName_biumc_89",ts="_statusBadge_biumc_98",ns="_metaDate_biumc_113",ss="_metaSize_biumc_114",as="_actions_biumc_122",is="_actionBtn_biumc_129",rs="_dangerBtn_biumc_156",os="_generateBtn_biumc_167",cs="_editBtn_biumc_178",ls="_saveBtn_biumc_189",ds="_layoutToggle_biumc_205",us="_layoutBtn_biumc_213",ms="_layoutBtnActive_biumc_229",fs="_saveStatus_biumc_234",hs="_saveStatusSaved_biumc_241",ps="_saveStatusError_biumc_245",vs="_unsaved_biumc_250",ws="_viewerContent_biumc_256",gs="_viewerBody_biumc_265",ys="_viewerMain_biumc_273",xs="_reviewRail_biumc_277",bs="_printHint_biumc_283",_s="_reviewSection_biumc_290",ks="_reviewHeader_biumc_299",Ss="_reviewTitle_biumc_307",js="_reviewSubtitle_biumc_316",Cs="_reviewControls_biumc_323",Ns="_reviewSelect_biumc_330",Ts="_reviewSessionMeta_biumc_334",Es="_reviewStatusResolved_biumc_342",Rs="_reviewSessionLabel_biumc_348",As="_reviewTitleEditRow_biumc_353",$s="_reviewSessionTimestamp_biumc_360",Ls="_reviewAnchorLabel_biumc_364",Is="_reviewComposer_biumc_370",Bs="_reviewAnchorChip_biumc_377",Ds="_reviewAnchorSnippet_biumc_390",Ps="_reviewAnchorClear_biumc_395",Ms="_reviewCommentActions_biumc_408",zs="_reviewCommentAction_biumc_408",Fs="_reviewCommentEditor_biumc_429",Os="_viewerState_biumc_435",Hs="_viewerStateError_biumc_442",Gs="_editorArea_biumc_449",Ws="_editorPane_biumc_456",Ks="_editorLayoutSplit_biumc_464",Us="_previewPane_biumc_465",Js="_editorLayoutEditor_biumc_469",Vs="_editorLayoutPreview_biumc_470",Ys="_editorPaneLabel_biumc_474",Xs="_editorTextarea_biumc_486",qs="_markdownSurface_biumc_528",a={viewer:Gn,viewerMonochrome:Wn,metaDocumentName:Kn,viewerEditMode:Un,meta:Jn,metaLeft:Vn,metaRenameRow:Yn,typeBadge:Xn,typeBadgeImplementationPlan:qn,typeBadgeReview:Qn,typeBadgeWalkthrough:Zn,metaTaskName:es,statusBadge:ts,metaDate:ns,metaSize:ss,actions:as,actionBtn:is,dangerBtn:rs,generateBtn:os,editBtn:cs,saveBtn:ls,layoutToggle:ds,layoutBtn:us,layoutBtnActive:ms,saveStatus:fs,saveStatusSaved:hs,saveStatusError:ps,unsaved:vs,viewerContent:ws,viewerBody:gs,viewerMain:ys,reviewRail:xs,printHint:bs,reviewSection:_s,reviewHeader:ks,reviewTitle:Ss,reviewSubtitle:js,reviewControls:Cs,reviewSelect:Ns,reviewSessionMeta:Ts,reviewStatusResolved:Es,reviewSessionLabel:Rs,reviewTitleEditRow:As,reviewSessionTimestamp:$s,reviewAnchorLabel:Ls,reviewComposer:Is,reviewAnchorChip:Bs,reviewAnchorSnippet:Ds,reviewAnchorClear:Ps,reviewCommentActions:Ms,reviewCommentAction:zs,reviewCommentEditor:Fs,viewerState:Os,viewerStateError:Hs,editorArea:Gs,editorPane:Ws,editorLayoutSplit:Ks,previewPane:Us,editorLayoutEditor:Js,editorLayoutPreview:Vs,editorPaneLabel:Ys,editorTextarea:Xs,markdownSurface:qs},Qs="_overlay_1unik_1",Zs="_modal_1unik_12",ea="_header_1unik_16",ta="_title_1unik_20",na="_docName_1unik_24",sa="_body_1unik_34",aa="_state_1unik_41",ia="_stateError_1unik_52",ra="_stateDone_1unik_63",oa="_toolbar_1unik_84",ca="_toolbarCount_1unik_95",la="_toolbarActions_1unik_100",da="_tree_1unik_105",ua="_taskRow_1unik_113",ma="_taskRowDimmed_1unik_126",fa="_taskCheck_1unik_130",ha="_taskExpandBtn_1unik_139",pa="_taskExpandSpacer_1unik_155",va="_taskTitle_1unik_160",wa="_taskBadge_1unik_169",ga="_footer_1unik_179",C={overlay:Qs,modal:Zs,header:ea,title:ta,docName:na,body:sa,state:aa,stateError:ia,stateDone:ra,toolbar:oa,toolbarCount:ca,toolbarActions:la,tree:da,taskRow:ua,taskRowDimmed:ma,taskCheck:fa,taskExpandBtn:ha,taskExpandSpacer:pa,taskTitle:va,taskBadge:wa,footer:ga},ya={1:"Low",2:"Medium",3:"High"};function me(t,l){return t.map(c=>({...c,selected:l,children:me(c.children,l)}))}function xt(t,l,c){return t.map(r=>r.idempotencyKey===l?{...r,selected:c,children:me(r.children,c)}:{...r,children:xt(r.children,l,c)})}function Ge(t){let l=0;for(const c of t)c.selected&&l++,l+=Ge(c.children);return l}function bt({node:t,depth:l,onToggle:c}){const[r,u]=i.useState(!0),m=t.children.length>0,v=l*20;return e.jsxs("div",{children:[e.jsxs("div",{className:`${C.taskRow} ${t.selected?"":C.taskRowDimmed}`,style:{paddingLeft:`${12+v}px`},children:[e.jsx("button",{className:C.taskCheck,onClick:()=>c(t.idempotencyKey,!t.selected),title:t.selected?"Deselect":"Select",children:t.selected?e.jsx(Qt,{size:14,style:{color:"var(--brand-primary-strong)"}}):e.jsx(Zt,{size:14,style:{color:"var(--text-muted)"}})}),m?e.jsx("button",{className:C.taskExpandBtn,onClick:()=>u(S=>!S),children:r?e.jsx(en,{size:12}):e.jsx(tn,{size:12})}):e.jsx("span",{className:C.taskExpandSpacer}),e.jsx("span",{className:C.taskTitle,title:t.description||void 0,children:t.title}),e.jsx("span",{className:C.taskBadge,style:{color:rt(t.type),borderColor:rt(t.type)},children:t.type}),e.jsx("span",{className:C.taskBadge,style:{color:ot(t.priority),borderColor:ot(t.priority)},children:ya[t.priority]})]}),m&&r&&e.jsx("div",{children:t.children.map(S=>e.jsx(bt,{node:S,depth:l+1,onToggle:c},S.idempotencyKey))})]})}function xa({content:t,docTitle:l,apiBaseUrl:c="",onClose:r,onGenerated:u}){const[m,v]=i.useState("preview"),[S,g]=i.useState(null),[w,p]=i.useState([]),[_,b]=i.useState(!0),[L,z]=i.useState(0),[D,N]=i.useState(null);i.useEffect(()=>{let y=!1;return b(!0),g(null),B("/api/taskforce/documents/generate-tasks/preview",{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({content:t})},c).then(j=>j.json()).then(j=>{if(!y){if(j.error)throw new Error(j.error);p(j.tasks||[]),v("preview")}}).catch(j=>{y||(g(j?.message||"Failed to parse plan"),v("error"))}).finally(()=>{y||b(!1)}),()=>{y=!0}},[t,c]);const J=i.useCallback((y,j)=>{p(q=>xt(q,y,j))},[]),F=()=>p(y=>me(y,!0)),G=()=>p(y=>me(y,!1)),O=Ge(w),Y=async()=>{v("generating"),N(null);try{const y=await B("/api/taskforce/documents/generate-tasks/commit",{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({tasks:w})},c),j=await y.json().catch(()=>({}));if(!y.ok)throw new Error(j.error||`Generation failed (${y.status})`);z(j.created??0),v("done"),u(j.created??0)}catch(y){N(y?.message||"Generation failed"),v("error")}};return e.jsx("div",{className:C.overlay,onClick:y=>{y.target===y.currentTarget&&r()},children:e.jsxs("div",{className:`tf-surface-modal tf-modal-shell ${C.modal}`,children:[e.jsxs("div",{className:`tf-modal-header ${C.header}`,children:[e.jsxs("div",{className:`tf-modal-title ${C.title}`,children:[e.jsx(He,{size:16,style:{color:"var(--brand-primary-strong)"}}),"Generate Tasks from Plan"]}),e.jsx("span",{className:C.docName,children:l}),e.jsx("button",{className:"tf-control-icon",onClick:r,title:"Close",children:e.jsx(wt,{size:16})})]}),e.jsxs("div",{className:C.body,children:[_&&e.jsxs("div",{className:C.state,children:[e.jsx(lt,{size:20,className:M.docSpinning}),"Parsing plan…"]}),!_&&m==="error"&&e.jsxs("div",{className:C.stateError,children:[e.jsx(gt,{size:16}),S||D||"An error occurred"]}),!_&&m==="done"&&e.jsxs("div",{className:C.stateDone,children:[e.jsx(yt,{size:24,style:{color:"var(--status-success)"}}),e.jsxs("strong",{children:[L," task",L!==1?"s":""," created"]}),e.jsx("p",{children:"Tasks are now in your board. Switch to the Kanban or Hierarchy view to see them."})]}),!_&&(m==="preview"||m==="confirm"||m==="generating")&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:C.toolbar,children:[e.jsxs("span",{className:C.toolbarCount,children:[O," of ",Ge(me(w,!0))," tasks selected"]}),e.jsxs("div",{className:C.toolbarActions,children:[e.jsx("button",{className:"tf-control-icon",onClick:F,children:"Select all"}),e.jsx("button",{className:"tf-control-icon",onClick:G,children:"Deselect all"})]})]}),w.length===0?e.jsx("div",{className:C.state,children:"No tasks could be parsed from this document. Make sure the document uses ## H2 headings for phases and bullet points for tasks."}):e.jsx("div",{className:`${C.tree} tf-scrollbar`,children:w.map(y=>e.jsx(bt,{node:y,depth:0,onToggle:J},y.idempotencyKey))})]})]}),!_&&m!=="done"&&m!=="error"&&e.jsxs("div",{className:C.footer,children:[e.jsx("button",{className:"tf-button-secondary",onClick:r,children:"Cancel"}),e.jsx("button",{className:"tf-button-primary",onClick:Y,disabled:O===0||m==="generating",children:m==="generating"?e.jsxs(e.Fragment,{children:[e.jsx(lt,{size:13,className:M.docSpinning})," Generating…"]}):e.jsxs(e.Fragment,{children:[e.jsx(He,{size:13})," Generate ",O," task",O!==1?"s":""]})})]}),!_&&m==="done"&&e.jsx("div",{className:C.footer,children:e.jsx("button",{className:"tf-button-primary",onClick:r,children:"Done"})})]})})}const ba={"implementation-plan":"Implementation Plan",review:"Review",walkthrough:"Walkthrough",planning:"Planning",other:"Document"},_a={"implementation-plan":a.typeBadgeImplementationPlan,review:a.typeBadgeReview,walkthrough:a.typeBadgeWalkthrough,planning:void 0,other:void 0},ka={editor:a.editorLayoutEditor,split:a.editorLayoutSplit,preview:a.editorLayoutPreview},Sa=1500,ja=`
|
|
2
2
|
@page {
|
|
3
3
|
margin: 0.94in 1.02in 1in;
|
|
4
4
|
}
|
|
@@ -247,4 +247,4 @@ body {
|
|
|
247
247
|
<body>${l}</body>
|
|
248
248
|
</html>`}async function Ea(t,l){try{await l.fonts?.ready}catch{}await new Promise(c=>{const r=t.requestAnimationFrame?.bind(t)??(u=>window.setTimeout(()=>u(0),0));r(()=>r(()=>c()))})}function Ra(t){return window.setTimeout(t,Sa)}function mt(t){try{return new Date(t).toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return t}}function ft(t){return t?t.kind==="document"?"Entire document":t.kind==="quote"?t.quote?`Quote: "${t.quote}"`:"Quoted text":t.kind==="line-range"?t.startLine===t.endLine?`Line ${t.startLine}`:`Lines ${t.startLine}-${t.endLine}`:null:null}function Aa(t){return t.authorActor?.label?t.authorActor.label:t.authorActorId==="user"||t.authorActorId==="human"?"You":t.authorActorId?t.authorActorId:"Reviewer"}function ht(t){return t.replace(/\s+/g," ").trim()}function $a(t,l){if(!l)return 0;let c=0,r=0;for(;r>=0&&(r=t.indexOf(l,r),!(r<0));)c+=1,r+=l.length;return c}function La(t,l,c){const r=document.createTreeWalker(t,NodeFilter.SHOW_TEXT);let u=r.nextNode(),m=0;for(;u;){const v=u.textContent||"";if(u===l)return m+Math.max(0,Math.min(c,v.length));m+=v.length,u=r.nextNode()}return null}function Ia(t,l,c){const r=c.replace(/\s+/g," ").trim();if(!r)return null;const u=t.textContent||"",m=ht(u),v=[];let S=m.indexOf(r);for(;S>=0;)v.push(S),S=m.indexOf(r,S+r.length);let g=null;const w=La(t,l.startContainer,l.startOffset);if(w!==null){const z=ht(u.slice(0,w));g=$a(z,r)}const p=g!==null&&g>=0&&g<v.length?g:v.length===1?0:null,_=p!==null?v[p]:v[0]??-1;if(_<0)return{kind:"quote",quote:r,occurrenceIndex:g};const b=m.slice(Math.max(0,_-40),_).trim()||null,L=m.slice(_+r.length,_+r.length+40).trim()||null;return{kind:"quote",quote:r,occurrenceIndex:p,prefix:b,suffix:L}}function Ba(t,l,c){if(l<0)return t;const r=t.split(`
|
|
249
249
|
`);let u=-1;const m=/^(\s*(?:[-*+]|\d+\.)\s+)\[( |x|X)\](.*)$/,v=c?"x":" ";return r.map(g=>{const w=g.match(m);return!w||(u+=1,u!==l)?g:`${w[1]}[${v}]${w[3]}`}).join(`
|
|
250
|
-
`)}function Da({doc:t,taskTitle:l,apiBaseUrl:c="",onSaved:r,onDeleted:u,enableTaskGeneration:m=!1}){const v=fe(t),[S,g]=i.useState(v),w=S,p=Ot({...t,displayName:S}),_=Ht(t),[b,L]=i.useState(null),[z,D]=i.useState(!1),[N,J]=i.useState(null),[F,W]=i.useState(!1),[O,Y]=i.useState(!1),[y,j]=i.useState([]),[q,Ne]=i.useState(!1),[ee,A]=i.useState(null),[se,V]=i.useState(null),[E,P]=i.useState(""),[x,$]=i.useState(!1),[H,Q]=i.useState(null),[he,ae]=i.useState(!1),[Te,Ee]=i.useState(""),[ie,ue]=i.useState(null),[pe,re]=i.useState(""),[T,ve]=i.useState(!1),[G,oe]=i.useState(""),[K,Re]=i.useState("split"),[X,U]=i.useState({type:"idle"}),[_t,Ae]=i.useState(!1),[Ke,kt]=i.useState(!1),[we,Ue]=i.useState(!1),[ge,te]=i.useState(!1),[$e,ce]=i.useState(w),le=t.editable!==!1,Je=Ce(t),St=Je==="unattached"&&!!t.assetId,Le=T&&G!==(b??""),Ie=i.useRef(null),Be=i.useRef(null),Ve=i.useRef(null),de=i.useRef(null),ye=i.useRef(null),Ye=i.useRef(null),Xe=i.useRef(null),h=y.find(n=>n.id===se)||y[0]||null,qe=i.useCallback(async()=>{D(!0),J(null),L(null);try{const n=await B(t.apiUrl,{credentials:"same-origin"},c);if(!n.ok)throw new Error(`Failed to load document (${n.status})`);const s=await n.text();L(s),oe(s)}catch(n){J(n?.message||"Failed to load document")}finally{D(!1)}},[c,t.apiUrl]),xe=i.useCallback(async n=>{if(!t.assetId){j([]),V(null),A(null);return}const s=n?.silent===!0;s||(Ne(!0),A(null));try{const o=await B(`/api/taskforce/document-reviews/sessions?assetId=${encodeURIComponent(t.assetId)}`,{credentials:"include"},c),d=await o.json().catch(()=>({}));if(!o.ok)throw new Error(d.error||`Failed to load reviews (${o.status})`);const f=Array.isArray(d.sessions)?d.sessions:[];j(f),V(k=>k&&f.some(Z=>Z.id===k)?k:f[0]?.id??null)}catch(o){s||(A(o?.message||"Failed to load reviews"),j([]),V(null))}finally{s||Ne(!1)}},[c,t.assetId]),De=i.useCallback(async()=>{if(!t.assetId||x)return null;$(!0),A(null);try{const n=await B("/api/taskforce/document-reviews/sessions",{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({assetId:t.assetId,title:`Review ${y.length+1}`})},c),s=await n.json().catch(()=>({}));if(!n.ok)throw new Error(s.error||`Failed to create review (${n.status})`);const o=s.session||null;if(!o)throw new Error("Review session payload missing.");return j(d=>[o,...d.filter(f=>f.id!==o.id)]),V(o.id),o}catch(n){return A(n?.message||"Failed to create review"),null}finally{$(!1)}},[c,t.assetId,x,y.length]);i.useEffect(()=>{qe(),xe(),ve(!1),U({type:"idle"}),te(!1);const n=fe(t);g(n),ce(n),W(!1),Y(!1),P(""),Q(null),ae(!1),Ee(""),ue(null),re("")},[t,qe,xe]),i.useEffect(()=>{if(!h)return;const n=Ye.current;typeof n?.scrollIntoView=="function"&&n.scrollIntoView({block:"end"})},[h?.comments.length,h?.id]),i.useEffect(()=>{Ee(h?.title?.trim()||""),ae(!1)},[h?.id,h?.title]),i.useEffect(()=>{ge&&window.setTimeout(()=>{Be.current?.focus(),Be.current?.select()},0)},[ge]),i.useEffect(()=>{if(!t.assetId||T)return;const n=()=>{document.visibilityState==="visible"&&xe({silent:!0})},s=window.setInterval(n,15e3);return window.addEventListener("focus",n),document.addEventListener("visibilitychange",n),()=>{window.clearInterval(s),window.removeEventListener("focus",n),document.removeEventListener("visibilitychange",n)}},[t.assetId,T,xe]),i.useEffect(()=>{if(!T)return;const n=s=>{(s.metaKey||s.ctrlKey)&&s.key==="s"&&(s.preventDefault(),Qe())};return window.addEventListener("keydown",n),()=>window.removeEventListener("keydown",n)},[T,G]);const ne=i.useCallback(()=>{ye.current!==null&&(window.clearTimeout(ye.current),ye.current=null),de.current&&(de.current.remove(),de.current=null)},[]);i.useEffect(()=>()=>{ne()},[ne]);const be=i.useCallback(n=>{if(!T||K!=="split")return;const s=Ie.current,o=Ve.current;if(!s||!o)return;const d=n==="editor"?s:o,f=n==="editor"?o:s,k=Math.max(d.scrollHeight-d.clientHeight,0),Z=Math.max(f.scrollHeight-f.clientHeight,0),ze=k<=0?0:d.scrollTop/k,it=Z*ze;Math.abs(f.scrollTop-it)<=1||(f.scrollTop=it)},[T,K]);i.useEffect(()=>{!T||K!=="split"||be("editor")},[G,T,K,be]);const jt=()=>{le&&(oe(b??""),U({type:"idle"}),ve(!0),setTimeout(()=>Ie.current?.focus(),50))},Ct=()=>{Le&&!window.confirm("Discard unsaved changes?")||(ve(!1),oe(b??""),U({type:"idle"}))},Qe=i.useCallback(async()=>{if(le&&X.type!=="saving"){U({type:"saving"});try{const n=await B("/api/taskforce/documents/save",{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({fsPath:t.fsPath,content:G})},c),s=await n.json().catch(()=>({}));if(!n.ok)throw new Error(s.error||`Save failed (${n.status})`);const o=s.updatedAt||new Date().toISOString();L(G),U({type:"saved",savedAt:o}),r?.(o),ve(!1)}catch(n){U({type:"error",message:n?.message||"Save failed"})}}},[c,t.fsPath,G,X.type,r,le]),Nt=i.useCallback(()=>{const n=T?G:b??"";if(!n.trim())return;ne();const s=document.createElement("iframe");s.setAttribute("aria-hidden","true"),s.tabIndex=-1,s.style.position="fixed",s.style.right="0",s.style.bottom="0",s.style.width="0",s.style.height="0",s.style.border="0",s.style.opacity="0",s.style.pointerEvents="none",document.body.appendChild(s),de.current=s;const o=s.contentWindow,d=s.contentDocument;if(!o||!d){ne();return}d.open(),d.write(Ta(n)),d.close();let f=!1;const k=async()=>{f||de.current!==s||(f=!0,await Ea(o,d),de.current===s&&(o.focus(),o.print(),ye.current=Ra(ne)))};o.addEventListener("afterprint",ne,{once:!0}),k()},[ne,b,G,T]),Tt=async()=>{const n=t.apiUrl,s=new URL(ct(n,c),window.location.origin).toString();try{await navigator.clipboard.writeText(s)}catch{const o=document.createElement("textarea");o.value=s,document.body.appendChild(o),o.select(),document.execCommand("copy"),document.body.removeChild(o)}W(!0),setTimeout(()=>W(!1),2e3)},Et=i.useCallback(async()=>{if(_){try{await navigator.clipboard.writeText(_)}catch{const n=document.createElement("textarea");n.value=_,document.body.appendChild(n),n.select(),document.execCommand("copy"),document.body.removeChild(n)}Y(!0),setTimeout(()=>Y(!1),2e3)}},[_]),Rt=()=>{const n=t.apiUrl.includes("?")?"&":"?",s=ct(`${t.apiUrl}${n}download=1&filename=${encodeURIComponent(p)}`,c),o=document.createElement("a");o.href=s,o.click()},Pe=i.useCallback(async()=>{if(!t.assetId)return;const n=$e.trim();if(!n){ce(w),te(!1);return}if(n===w){te(!1);return}const s=await B(`/api/taskforce/documents/${encodeURIComponent(t.assetId)}`,{method:"PATCH",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({displayName:n})},c),o=await s.json().catch(()=>({}));if(!s.ok){window.alert(o.error||`Rename failed (${s.status})`);return}g(n),ce(n),te(!1),r?.(o.updatedAt||new Date().toISOString())},[c,t.assetId,r,w,$e]),At=i.useCallback(n=>{if(n.key==="Enter"){n.preventDefault(),Pe();return}n.key==="Escape"&&(n.preventDefault(),ce(w),te(!1))},[Pe,w]),$t=i.useCallback(async()=>{if(!(!t.assetId||we)&&window.confirm(`Permanently delete "${w}" from storage?`)){Ue(!0);try{const n=await B(`/api/taskforce/documents/${encodeURIComponent(t.assetId)}`,{method:"DELETE",credentials:"include"},c),s=await n.json().catch(()=>({}));if(!n.ok)throw new Error(s.error||`Delete failed (${n.status})`);u?.()}catch(n){window.alert(n?.message||"Delete failed")}finally{Ue(!1)}}},[c,we,t.assetId,u,w]),Lt=i.useCallback(async()=>{if(!(!h||x)){$(!0),A(null);try{const n=h.status==="resolved"?"open":"resolved",s=await B(`/api/taskforce/document-reviews/sessions/${encodeURIComponent(h.id)}`,{method:"PATCH",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({status:n})},c),o=await s.json().catch(()=>({}));if(!s.ok)throw new Error(o.error||`Failed to update review (${s.status})`);const d=o.session||null;if(!d)throw new Error("Review session payload missing.");j(f=>f.map(k=>k.id===d.id?d:k))}catch(n){A(n?.message||"Failed to update review")}finally{$(!1)}}},[h,c,x]),It=i.useCallback(async()=>{if(!h||x)return;const n=Te.trim();$(!0),A(null);try{const s=await B(`/api/taskforce/document-reviews/sessions/${encodeURIComponent(h.id)}`,{method:"PATCH",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({title:n||null})},c),o=await s.json().catch(()=>({}));if(!s.ok)throw new Error(o.error||`Failed to update review (${s.status})`);const d=o.session||null;if(!d)throw new Error("Review session payload missing.");j(f=>f.map(k=>k.id===d.id?d:k)),ae(!1)}catch(s){A(s?.message||"Failed to update review")}finally{$(!1)}},[h,c,x,Te]),Ze=T?G:b??"",Bt=i.useCallback(()=>{if(T)return;const n=typeof window.getSelection=="function"?window.getSelection():null,s=n?.toString().replace(/\s+/g," ").trim()||"";if(!n||!s)return;const o=n.rangeCount>0?n.getRangeAt(0):null,d=Xe.current;if(!o||!d)return;const f=o.commonAncestorContainer,k=f.nodeType===Node.TEXT_NODE?f.parentNode:f;if(!(k instanceof Node)||!d.contains(k))return;const Z=Ia(d,o,s);Z&&Q(Z)},[T]),et=i.useCallback(async()=>{const n=E.trim();if(!n||x)return;let s=h;if(s||(s=await De()),!!s){$(!0),A(null);try{const o=await B(`/api/taskforce/document-reviews/sessions/${encodeURIComponent(s.id)}/comments`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({body:n,anchor:H||{kind:"document"}})},c),d=await o.json().catch(()=>({}));if(!o.ok)throw new Error(d.error||`Failed to add comment (${o.status})`);const f=d.session||null;if(!f)throw new Error("Review session payload missing.");j(k=>{const Z=k.filter(ze=>ze.id!==f.id);return[f,...Z]}),V(f.id),P(""),Q(null)}catch(o){A(o?.message||"Failed to add comment")}finally{$(!1)}}},[h,c,De,H,x,E]),Dt=i.useCallback((n,s)=>{ue(n),re(s)},[]),Pt=i.useCallback(async()=>{if(!h||!ie||x)return;const n=pe.trim();if(n){$(!0),A(null);try{const s=await B(`/api/taskforce/document-reviews/sessions/${encodeURIComponent(h.id)}/comments/${encodeURIComponent(ie)}`,{method:"PATCH",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({body:n})},c),o=await s.json().catch(()=>({}));if(!s.ok)throw new Error(o.error||`Failed to update comment (${s.status})`);const d=o.session||null;if(!d)throw new Error("Review session payload missing.");j(f=>f.map(k=>k.id===d.id?d:k)),ue(null),re("")}catch(s){A(s?.message||"Failed to update comment")}finally{$(!1)}}},[h,c,pe,ie,x]),Mt=i.useCallback(async n=>{if(!(!h||x)&&window.confirm("Delete this review comment?")){$(!0),A(null);try{const s=await B(`/api/taskforce/document-reviews/sessions/${encodeURIComponent(h.id)}/comments/${encodeURIComponent(n)}`,{method:"DELETE",credentials:"include"},c),o=await s.json().catch(()=>({}));if(!s.ok)throw new Error(o.error||`Failed to delete comment (${s.status})`);const d=o.session||null;if(!d)throw new Error("Review session payload missing.");j(f=>f.map(k=>k.id===d.id?d:k)),ie===n&&(ue(null),re(""))}catch(s){A(s?.message||"Failed to delete comment")}finally{$(!1)}}},[h,c,ie,x]),tt=i.useCallback(async n=>{if(!le)return!1;U({type:"saving"});try{const s=await B("/api/taskforce/documents/save",{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({fsPath:t.fsPath,content:n})},c),o=await s.json().catch(()=>({}));if(!s.ok)throw new Error(o.error||`Save failed (${s.status})`);const d=o.updatedAt||new Date().toISOString();return L(n),oe(n),U({type:"saved",savedAt:d}),r?.(d),!0}catch(s){return U({type:"error",message:s?.message||"Save failed"}),!1}},[c,t.fsPath,r,le]),zt=i.useCallback((n,s)=>{const o=T?G:b??"",d=Ba(o,n,s);if(d!==o){if(T){oe(d),U(f=>f.type==="saving"?f:{type:"idle"});return}tt(d)}},[b,G,T,tt]);let nt=-1;const Me=n=>!n||!Array.isArray(n.children)?!1:n.children.some(s=>s?s.type==="element"&&s.tagName==="input"&&s.properties?.type==="checkbox"?!0:Me(s):!1),st=n=>!n||!Array.isArray(n.children)?!1:n.children.some(s=>typeof s?.checked=="boolean"?!0:Me(s)),at={input({type:n,checked:s,...o}){if(n!=="checkbox")return e.jsx("input",{type:n,checked:s,...o});nt+=1;const d=nt;return e.jsx("input",{...o,type:"checkbox",checked:!!s,disabled:!1,onClick:f=>f.stopPropagation(),onChange:f=>zt(d,f.currentTarget.checked)})},ul({children:n,node:s,...o}){const d=st(s);return e.jsx("ul",{...o,style:d?{paddingLeft:"1.25em"}:void 0,"data-task-list":d?"true":void 0,children:n})},ol({children:n,node:s,...o}){const d=st(s);return e.jsx("ol",{...o,style:d?{paddingLeft:"1.25em"}:void 0,"data-task-list":d?"true":void 0,children:n})},li({children:n,node:s,...o}){const d=typeof s?.checked=="boolean"||Me(s);return e.jsx("li",{...o,style:d?{listStyleType:"none",listStyle:"none",marginLeft:0}:void 0,"data-task-item":d?"true":void 0,children:n})}};return e.jsxs("div",{className:`${a.viewer} ${T?a.viewerEditMode:""} ${Ke?a.viewerMonochrome:""}`,children:[e.jsxs("div",{className:a.meta,children:[e.jsxs("div",{className:a.metaLeft,children:[e.jsxs("span",{className:`${a.typeBadge} ${_a[t.docType]??""}`,children:[e.jsx(nn,{size:10}),ba[t.docType]]}),ge?e.jsx("div",{className:a.metaRenameRow,children:e.jsx("input",{ref:Be,type:"text",className:M.input,value:$e,onChange:n=>ce(n.target.value),onBlur:()=>{Pe()},onKeyDown:At})}):e.jsx("span",{className:a.metaDocumentName,title:w,onDoubleClick:()=>{t.assetId&&(ce(w),te(!0))},children:w}),l&&e.jsx("span",{className:a.metaTaskName,title:`From task: ${l}`,children:l}),Je==="unattached"&&e.jsx("span",{className:a.statusBadge,children:"Unattached"}),t.updatedAt&&e.jsxs("span",{className:a.metaDate,title:ut(t.updatedAt),children:[e.jsx(sn,{size:11}),ut(t.updatedAt)]}),e.jsxs("span",{className:a.metaSize,children:[e.jsx(an,{size:11}),Ca(t.sizeBytes)]}),_&&e.jsx(Wt,{label:_,copied:O,onClick:()=>{Et()},title:"Copy document reference"}),X.type==="saved"&&e.jsxs("span",{className:`${a.saveStatus} ${a.saveStatusSaved}`,children:[e.jsx(yt,{size:11}),"Saved"]}),X.type==="error"&&e.jsxs("span",{className:`${a.saveStatus} ${a.saveStatusError}`,title:X.message,children:[e.jsx(gt,{size:11}),X.message||"Save failed"]}),Le&&X.type!=="saving"&&e.jsx("span",{className:a.unsaved,children:"Unsaved changes"})]}),e.jsx("div",{className:a.actions,children:T?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:a.layoutToggle,children:[e.jsx("button",{className:`${a.layoutBtn} ${K==="editor"?a.layoutBtnActive:""}`,onClick:()=>Re("editor"),title:"Editor only",children:e.jsx(_e,{size:12})}),e.jsx("button",{className:`${a.layoutBtn} ${K==="split"?a.layoutBtnActive:""}`,onClick:()=>Re("split"),title:"Split view",children:e.jsx(rn,{size:12})}),e.jsx("button",{className:`${a.layoutBtn} ${K==="preview"?a.layoutBtnActive:""}`,onClick:()=>Re("preview"),title:"Preview only",children:e.jsx(Oe,{size:12})})]}),e.jsxs("button",{className:a.actionBtn,onClick:Ct,title:"Discard changes",children:[e.jsx(wt,{size:13}),"Cancel"]}),e.jsxs("button",{className:`${a.actionBtn} ${a.saveBtn}`,onClick:Qe,disabled:X.type==="saving"||!Le,title:"Save (Ctrl+S)",children:[e.jsx(on,{size:13}),X.type==="saving"?"Saving…":"Save"]})]}):e.jsxs(e.Fragment,{children:[t.assetId&&e.jsxs("button",{className:a.actionBtn,onClick:()=>te(n=>!n),title:"Rename document",children:[e.jsx(_e,{size:13}),ge?"Close Rename":"Rename"]}),le&&e.jsxs("button",{className:`${a.actionBtn} ${a.editBtn}`,onClick:jt,title:"Edit document",children:[e.jsx(_e,{size:13}),"Edit"]}),e.jsxs("button",{className:a.actionBtn,onClick:Tt,title:"Copy link",children:[e.jsx(cn,{size:13}),F?"Copied!":"Copy link"]}),e.jsxs("button",{className:a.actionBtn,onClick:Rt,title:"Download .md",children:[e.jsx(ln,{size:13}),"Download"]}),e.jsxs("button",{className:a.actionBtn,onClick:Nt,title:"Print",children:[e.jsx(dn,{size:13}),"Print"]}),e.jsxs("button",{className:a.actionBtn,onClick:()=>kt(n=>!n),title:"Toggle black and white style",children:[e.jsx(Oe,{size:13}),Ke?"Color":"B/W"]}),m&&t.docType==="implementation-plan"&&!T&&e.jsxs("button",{className:`${a.actionBtn} ${a.generateBtn}`,onClick:()=>Ae(!0),title:"Generate tasks from this plan",children:[e.jsx(He,{size:13}),"Generate Tasks"]}),St&&e.jsxs("button",{className:`${a.actionBtn} ${a.dangerBtn}`,onClick:()=>{$t()},disabled:we,title:"Permanently delete this unattached document",children:[e.jsx(un,{size:13}),we?"Deleting…":"Delete Permanently"]})]})})]}),z&&e.jsx("div",{className:a.viewerState,children:"Loading…"}),!z&&N&&e.jsx("div",{className:a.viewerStateError,children:N}),!z&&!N&&(T?e.jsxs("div",{className:`${a.editorArea} ${ka[K]}`,children:[(K==="editor"||K==="split")&&e.jsxs("div",{className:a.editorPane,children:[e.jsx("div",{className:a.editorPaneLabel,children:"Markdown"}),e.jsx("textarea",{ref:Ie,className:`${a.editorTextarea} tf-scrollbar`,value:G,onScroll:()=>be("editor"),onChange:n=>{oe(n.target.value),U(s=>s.type==="saving"?s:{type:"idle"})},spellCheck:!0,placeholder:"Write markdown here…"})]}),(K==="preview"||K==="split")&&e.jsxs("div",{className:a.previewPane,children:[e.jsx("div",{className:a.editorPaneLabel,children:"Preview"}),e.jsx("div",{ref:Ve,className:`${M.docMarkdown} ${a.markdownSurface}`,"data-testid":"doc-preview-scroll",onScroll:()=>be("preview"),children:e.jsx(ke,{remarkPlugins:[Se],rehypePlugins:[je],components:at,children:Ze})})]})]}):e.jsxs("div",{className:a.viewerBody,children:[e.jsx("div",{className:`${a.viewerContent} ${a.viewerMain} tf-scrollbar`,children:e.jsx("div",{ref:Xe,className:`${M.docMarkdown} ${a.markdownSurface}`,onMouseUp:Bt,children:e.jsx(ke,{remarkPlugins:[Se],rehypePlugins:[je],components:at,children:Ze})})}),e.jsx("aside",{className:a.reviewRail,children:e.jsxs("section",{className:a.reviewSection,"aria-label":"Review and comments",children:[e.jsxs("div",{className:a.reviewHeader,children:[e.jsxs("div",{children:[e.jsxs("div",{className:a.reviewTitle,children:[e.jsx(dt,{size:14}),"Review & Comments"]}),e.jsx("p",{className:a.reviewSubtitle,children:"Comments stay attached to this document review session."})]}),e.jsxs("div",{className:a.reviewControls,children:[y.length>1&&e.jsx("select",{className:`${M.select} ${a.reviewSelect}`,value:h?.id||"",onChange:n=>V(n.target.value||null),"aria-label":"Select review session",children:y.map(n=>e.jsx("option",{value:n.id,children:n.title?.trim()||"Untitled review"},n.id))}),e.jsxs("button",{type:"button",className:a.actionBtn,onClick:()=>{De()},disabled:x||!t.assetId,children:[e.jsx(dt,{size:13}),"Start Review"]}),h&&e.jsxs("button",{type:"button",className:a.actionBtn,onClick:()=>{Lt()},disabled:x,children:[h.status==="resolved"?e.jsx(mn,{size:13}):e.jsx(fn,{size:13}),h.status==="resolved"?"Reopen":"Resolve"]})]})]}),h&&e.jsxs("div",{className:a.reviewSessionMeta,children:[e.jsx("span",{className:`${a.statusBadge} ${h.status==="resolved"?a.reviewStatusResolved:""}`,children:h.status==="resolved"?"Resolved":"Open"}),he?e.jsxs("div",{className:a.reviewTitleEditRow,children:[e.jsx("input",{type:"text",className:M.input,value:Te,onChange:n=>Ee(n.target.value),placeholder:"Untitled review"}),e.jsx("button",{type:"button",className:M.secondaryHeaderBtn,onClick:()=>{It()},disabled:x,children:"Save Title"})]}):e.jsx("span",{className:a.reviewSessionLabel,children:h.title?.trim()||"Untitled review"}),e.jsxs("span",{className:a.reviewSessionTimestamp,children:["Updated ",mt(h.updatedAt)]}),!he&&e.jsxs("button",{type:"button",className:a.actionBtn,onClick:()=>ae(!0),disabled:x,children:[e.jsx(_e,{size:13}),"Rename Review"]})]}),ee&&e.jsx("div",{className:a.viewerStateError,children:ee}),e.jsxs("div",{className:I.commentPanel,children:[e.jsxs("div",{className:I.commentThread,children:[q&&e.jsx("div",{className:I.emptyComments,children:"Loading review comments…"}),!q&&!h&&e.jsx("div",{className:I.emptyComments,children:"Start a review to collect comments for this document."}),!q&&h&&h.comments.length===0&&e.jsx("div",{className:I.emptyComments,children:"No comments yet. Add the first review note for this document."}),!q&&h&&h.comments.map(n=>{const s=n.authorActor?.kind==="ai",o=ft(n.anchor),d=s?hn:pn,f=ie===n.id;return e.jsxs("div",{className:`${I.comment} ${s?I.commentAi:I.commentUser}`,children:[e.jsxs("div",{className:I.commentHeader,children:[e.jsxs("span",{className:I.commentAuthor,style:n.authorActor?.color?{color:n.authorActor.color}:void 0,children:[e.jsx(d,{size:12,strokeWidth:1.5}),Aa(n)]}),e.jsx("span",{className:I.commentTime,children:mt(n.updatedAt)}),e.jsxs("span",{className:a.reviewCommentActions,children:[!f&&e.jsx("button",{type:"button",className:a.reviewCommentAction,onClick:()=>Dt(n.id,n.body),disabled:x,children:"Edit"}),f&&e.jsx("button",{type:"button",className:a.reviewCommentAction,onClick:()=>{ue(null),re("")},disabled:x,children:"Cancel"}),e.jsx("button",{type:"button",className:a.reviewCommentAction,onClick:()=>{Mt(n.id)},disabled:x,children:"Delete"})]})]}),o&&e.jsx("span",{className:a.reviewAnchorLabel,children:o}),e.jsx("div",{className:I.commentText,children:f?e.jsxs("div",{className:a.reviewCommentEditor,children:[e.jsx("textarea",{className:I.commentInput,value:pe,onChange:k=>re(k.target.value),disabled:x}),e.jsx("button",{type:"button",className:M.secondaryHeaderBtn,onClick:()=>{Pt()},disabled:x||!pe.trim(),children:"Save Comment"})]}):e.jsx(ke,{remarkPlugins:[Se],rehypePlugins:[je],children:n.body})})]},n.id)}),e.jsx("div",{ref:Ye})]}),e.jsxs("div",{className:I.commentInputArea,children:[e.jsxs("div",{className:a.reviewComposer,children:[H&&e.jsxs("div",{className:a.reviewAnchorChip,children:[e.jsx("span",{children:ft(H)||"Selected text"}),"quote"in H&&H.quote&&e.jsxs("span",{className:a.reviewAnchorSnippet,children:['"',H.quote,'"']}),e.jsx("button",{type:"button",className:a.reviewAnchorClear,onClick:()=>Q(null),children:"Clear"})]}),e.jsx("textarea",{className:I.commentInput,placeholder:h?.status==="resolved"?"Reopen this review to add more comments…":H?"Add a comment for the selected text…":"Add a comment for this document review…",value:E,onChange:n=>P(n.target.value),disabled:x||h?.status==="resolved",onKeyDown:n=>{n.key==="Enter"&&!n.shiftKey&&(n.preventDefault(),et())}})]}),e.jsx("button",{type:"button",className:I.sendCommentBtn,onClick:()=>{et()},disabled:x||!E.trim()||h?.status==="resolved","aria-label":"Send review comment",title:"Send review comment",children:e.jsx(vn,{size:15})})]})]})]})})]})),m&&_t&&b!==null&&e.jsx(xa,{content:b,docTitle:t.title,apiBaseUrl:c,onClose:()=>Ae(!1),onGenerated:n=>Ae(!1)}),!T&&e.jsx("div",{className:a.printHint,children:"For the cleanest output, disable browser Headers and footers in the print dialog."})]})}function pt(t){return typeof t=="string"?t.trim().replace(/\/+$/,""):""}function Pa(t){return t.runtimeMode==="local"?"":pt(t.apiBaseUrl)||pt(t.cloudAuthBaseUrl)||""}function Ge(t){let l=t;try{l=decodeURIComponent(t)}catch{l=t}return l.trim().replace(/\\/g,"/").replace(/^\/+/,"").replace(/^\.\//,"").replace(/^\.taskforce\//,"")}function Ma(t,l){return!!(t===l||t.endsWith(`/${l}`)||l.endsWith(`/${t}`))}function vt(t){const l=Ge(String(t||""));if(!l)return null;const c=l.match(/(^|\/)(asset-[a-f0-9]{32})(?=[^/]*$)/i);return c?.[2]?c[2].toLowerCase():null}function Ce(t){return t.attachmentState==="attached"||t.attachmentState==="unattached"?t.attachmentState:(typeof t.attachmentCount=="number"&&Number.isFinite(t.attachmentCount)?t.attachmentCount:0)>0||t.taskId?"attached":"unattached"}function za({tasks:t,apiBaseUrl:l="",documents:c,loading:r,error:u,selectedDoc:m,searchQuery:v,typeFilters:S,attachmentFilters:g,onSearchChange:w,onSelectDoc:p,onRefresh:_,enableTaskGeneration:b=!1}){const L=c.filter(N=>{const F=`${fe(N)} ${N.originalFilename||""}`.toLowerCase(),W=!v||F.includes(v.toLowerCase()),O=S.length===0||S.includes(N.docType),Y=Ce(N),y=g.length===0||g.includes(Y);return W&&O&&y}),z=v.trim().length>0||S.length>0||g.length>0,D=new Map(t.map(N=>[N.id,N]));return e.jsxs("div",{className:M.docWorkspace,children:[e.jsx("div",{className:M.docIndexPanel,children:e.jsx(Hn,{documents:L,selectedDocId:m?.id??null,loading:r,error:u,searchQuery:v,onSearchChange:w,onSelect:N=>p(N),onRefresh:_,taskById:D,hasActiveFilters:z})}),e.jsx("div",{className:M.docViewerPanel,children:m?e.jsx(Da,{doc:m,taskTitle:m.taskId?D.get(m.taskId)?.title??null:null,apiBaseUrl:l,onSaved:N=>_(),onDeleted:()=>{p(null),_()},enableTaskGeneration:b}):!r&&e.jsx("div",{className:M.docViewerEmpty,children:e.jsx("p",{className:"tf-empty-copy",children:L.length===0?"No documents match your current filters.":"Select a document to view it."})})})]})}function Ua({tasks:t,runtimeMode:l="local",apiBaseUrl:c="",cloudAuthBaseUrl:r="",typeFilters:u,attachmentFilters:m,onTypeFiltersChange:v,onAttachmentFiltersChange:S,requestedDocPath:g=null,requestedDocAssetId:w=null,onRequestedDocHandled:p,enableTaskGeneration:_=!1}){const[b,L]=i.useState([]),[z,D]=i.useState(!0),[N,J]=i.useState(null),[F,W]=i.useState(null),[O,Y]=i.useState(""),[y,j]=i.useState(()=>Gt.map(E=>E.value)),[q,Ne]=i.useState(()=>Kt.map(E=>E.value)),ee=Pa({runtimeMode:l,apiBaseUrl:c,cloudAuthBaseUrl:r}),A=u??y,se=m??q,V=i.useCallback(async()=>{D(!0),J(null);try{const E=await B("/api/taskforce/documents",{credentials:"include"},ee);if(!E.ok)throw new Error(`Failed to load documents (${E.status})`);const x=(await E.json()).documents||[];Array.isArray(x)&&x.length,L(x)}catch(E){J(E?.message||"Failed to load documents"),E?.message}finally{D(!1)}},[ee,l]);return i.useEffect(()=>{V()},[V]),i.useEffect(()=>{g||w||!F&&b.length>0&&W(b[0])},[b,F,w,g]),i.useEffect(()=>{if(!g&&!w||b.length===0)return;const E=g?Ge(g):"",P=String(w||"").trim().toLowerCase()||vt(g),x=b.find($=>{const H=vt($.fsPath)||String($.assetId||"").trim().toLowerCase()||null;if(P&&H&&H===P)return!0;if(!E)return!1;const Q=Ge($.fsPath);return Ma(Q,E)});if(x){W(x),p?.();return}},[w,g,b,p]),i.useEffect(()=>{if((g||w)&&!F)return;const E=b.filter(P=>{const $=`${fe(P)} ${P.originalFilename||""}`.toLowerCase(),H=!O||$.includes(O.toLowerCase()),Q=A.length===0||A.includes(P.docType),he=Ce(P),ae=se.length===0||se.includes(he);return H&&Q&&ae});F&&E.some(P=>P.id===F.id)||W(E[0]??null)},[se,b,w,g,O,F,A]),e.jsx(za,{tasks:t,apiBaseUrl:ee,documents:b,loading:z,error:N,selectedDoc:F,searchQuery:O,typeFilters:A,attachmentFilters:se,onSearchChange:Y,onSelectDoc:W,onRefresh:V,enableTaskGeneration:_})}export{Kt as DOCUMENT_ATTACHMENT_FILTER_OPTIONS,Gt as DOCUMENT_TYPE_FILTER_OPTIONS,za as DocumentWorkspace,Ua as DocumentWorkspaceShell,Ce as getEffectiveAttachmentState};
|
|
250
|
+
`)}function Da({doc:t,taskTitle:l,apiBaseUrl:c="",onSaved:r,onDeleted:u,enableTaskGeneration:m=!1}){const v=fe(t),[S,g]=i.useState(v),w=S,p=Ot({...t,displayName:S}),_=Ht(t),[b,L]=i.useState(null),[z,D]=i.useState(!1),[N,J]=i.useState(null),[F,G]=i.useState(!1),[O,Y]=i.useState(!1),[y,j]=i.useState([]),[q,Ne]=i.useState(!1),[ee,A]=i.useState(null),[se,V]=i.useState(null),[E,P]=i.useState(""),[x,$]=i.useState(!1),[H,Q]=i.useState(null),[he,ae]=i.useState(!1),[Te,Ee]=i.useState(""),[ie,ue]=i.useState(null),[pe,re]=i.useState(""),[T,ve]=i.useState(!1),[W,oe]=i.useState(""),[K,Re]=i.useState("split"),[X,U]=i.useState({type:"idle"}),[_t,Ae]=i.useState(!1),[Ke,kt]=i.useState(!1),[we,Ue]=i.useState(!1),[ge,te]=i.useState(!1),[$e,ce]=i.useState(w),le=t.editable!==!1,Je=Ce(t),St=Je==="unattached"&&!!t.assetId,Le=T&&W!==(b??""),Ie=i.useRef(null),Be=i.useRef(null),Ve=i.useRef(null),de=i.useRef(null),ye=i.useRef(null),Ye=i.useRef(null),Xe=i.useRef(null),h=y.find(n=>n.id===se)||y[0]||null,qe=i.useCallback(async()=>{D(!0),J(null),L(null);try{const n=await B(t.apiUrl,{credentials:"same-origin"},c);if(!n.ok)throw new Error(`Failed to load document (${n.status})`);const s=await n.text();L(s),oe(s)}catch(n){J(n?.message||"Failed to load document")}finally{D(!1)}},[c,t.apiUrl]),xe=i.useCallback(async n=>{if(!t.assetId){j([]),V(null),A(null);return}const s=n?.silent===!0;s||(Ne(!0),A(null));try{const o=await B(`/api/taskforce/document-reviews/sessions?assetId=${encodeURIComponent(t.assetId)}`,{credentials:"include"},c),d=await o.json().catch(()=>({}));if(!o.ok)throw new Error(d.error||`Failed to load reviews (${o.status})`);const f=Array.isArray(d.sessions)?d.sessions:[];j(f),V(k=>k&&f.some(Z=>Z.id===k)?k:f[0]?.id??null)}catch(o){s||(A(o?.message||"Failed to load reviews"),j([]),V(null))}finally{s||Ne(!1)}},[c,t.assetId]),De=i.useCallback(async()=>{if(!t.assetId||x)return null;$(!0),A(null);try{const n=await B("/api/taskforce/document-reviews/sessions",{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({assetId:t.assetId,title:`Review ${y.length+1}`})},c),s=await n.json().catch(()=>({}));if(!n.ok)throw new Error(s.error||`Failed to create review (${n.status})`);const o=s.session||null;if(!o)throw new Error("Review session payload missing.");return j(d=>[o,...d.filter(f=>f.id!==o.id)]),V(o.id),o}catch(n){return A(n?.message||"Failed to create review"),null}finally{$(!1)}},[c,t.assetId,x,y.length]);i.useEffect(()=>{qe(),xe(),ve(!1),U({type:"idle"}),te(!1);const n=fe(t);g(n),ce(n),G(!1),Y(!1),P(""),Q(null),ae(!1),Ee(""),ue(null),re("")},[t,qe,xe]),i.useEffect(()=>{if(!h)return;const n=Ye.current;typeof n?.scrollIntoView=="function"&&n.scrollIntoView({block:"end"})},[h?.comments.length,h?.id]),i.useEffect(()=>{Ee(h?.title?.trim()||""),ae(!1)},[h?.id,h?.title]),i.useEffect(()=>{ge&&window.setTimeout(()=>{Be.current?.focus(),Be.current?.select()},0)},[ge]),i.useEffect(()=>{if(!t.assetId||T)return;const n=()=>{document.visibilityState==="visible"&&xe({silent:!0})},s=window.setInterval(n,15e3);return window.addEventListener("focus",n),document.addEventListener("visibilitychange",n),()=>{window.clearInterval(s),window.removeEventListener("focus",n),document.removeEventListener("visibilitychange",n)}},[t.assetId,T,xe]),i.useEffect(()=>{if(!T)return;const n=s=>{(s.metaKey||s.ctrlKey)&&s.key==="s"&&(s.preventDefault(),Qe())};return window.addEventListener("keydown",n),()=>window.removeEventListener("keydown",n)},[T,W]);const ne=i.useCallback(()=>{ye.current!==null&&(window.clearTimeout(ye.current),ye.current=null),de.current&&(de.current.remove(),de.current=null)},[]);i.useEffect(()=>()=>{ne()},[ne]);const be=i.useCallback(n=>{if(!T||K!=="split")return;const s=Ie.current,o=Ve.current;if(!s||!o)return;const d=n==="editor"?s:o,f=n==="editor"?o:s,k=Math.max(d.scrollHeight-d.clientHeight,0),Z=Math.max(f.scrollHeight-f.clientHeight,0),ze=k<=0?0:d.scrollTop/k,it=Z*ze;Math.abs(f.scrollTop-it)<=1||(f.scrollTop=it)},[T,K]);i.useEffect(()=>{!T||K!=="split"||be("editor")},[W,T,K,be]);const jt=()=>{le&&(oe(b??""),U({type:"idle"}),ve(!0),setTimeout(()=>Ie.current?.focus(),50))},Ct=()=>{Le&&!window.confirm("Discard unsaved changes?")||(ve(!1),oe(b??""),U({type:"idle"}))},Qe=i.useCallback(async()=>{if(le&&X.type!=="saving"){U({type:"saving"});try{const n=await B("/api/taskforce/documents/save",{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({fsPath:t.fsPath,content:W})},c),s=await n.json().catch(()=>({}));if(!n.ok)throw new Error(s.error||`Save failed (${n.status})`);const o=s.updatedAt||new Date().toISOString();L(W),U({type:"saved",savedAt:o}),r?.(o),ve(!1)}catch(n){U({type:"error",message:n?.message||"Save failed"})}}},[c,t.fsPath,W,X.type,r,le]),Nt=i.useCallback(()=>{const n=T?W:b??"";if(!n.trim())return;ne();const s=document.createElement("iframe");s.setAttribute("aria-hidden","true"),s.tabIndex=-1,s.style.position="fixed",s.style.right="0",s.style.bottom="0",s.style.width="0",s.style.height="0",s.style.border="0",s.style.opacity="0",s.style.pointerEvents="none",document.body.appendChild(s),de.current=s;const o=s.contentWindow,d=s.contentDocument;if(!o||!d){ne();return}d.open(),d.write(Ta(n)),d.close();let f=!1;const k=async()=>{f||de.current!==s||(f=!0,await Ea(o,d),de.current===s&&(o.focus(),o.print(),ye.current=Ra(ne)))};o.addEventListener("afterprint",ne,{once:!0}),k()},[ne,b,W,T]),Tt=async()=>{const n=t.apiUrl,s=new URL(ct(n,c),window.location.origin).toString();try{await navigator.clipboard.writeText(s)}catch{const o=document.createElement("textarea");o.value=s,document.body.appendChild(o),o.select(),document.execCommand("copy"),document.body.removeChild(o)}G(!0),setTimeout(()=>G(!1),2e3)},Et=i.useCallback(async()=>{if(_){try{await navigator.clipboard.writeText(_)}catch{const n=document.createElement("textarea");n.value=_,document.body.appendChild(n),n.select(),document.execCommand("copy"),document.body.removeChild(n)}Y(!0),setTimeout(()=>Y(!1),2e3)}},[_]),Rt=()=>{const n=t.apiUrl.includes("?")?"&":"?",s=ct(`${t.apiUrl}${n}download=1&filename=${encodeURIComponent(p)}`,c),o=document.createElement("a");o.href=s,o.click()},Pe=i.useCallback(async()=>{if(!t.assetId)return;const n=$e.trim();if(!n){ce(w),te(!1);return}if(n===w){te(!1);return}const s=await B(`/api/taskforce/documents/${encodeURIComponent(t.assetId)}`,{method:"PATCH",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({displayName:n})},c),o=await s.json().catch(()=>({}));if(!s.ok){window.alert(o.error||`Rename failed (${s.status})`);return}g(n),ce(n),te(!1),r?.(o.updatedAt||new Date().toISOString())},[c,t.assetId,r,w,$e]),At=i.useCallback(n=>{if(n.key==="Enter"){n.preventDefault(),Pe();return}n.key==="Escape"&&(n.preventDefault(),ce(w),te(!1))},[Pe,w]),$t=i.useCallback(async()=>{if(!(!t.assetId||we)&&window.confirm(`Permanently delete "${w}" from storage?`)){Ue(!0);try{const n=await B(`/api/taskforce/documents/${encodeURIComponent(t.assetId)}`,{method:"DELETE",credentials:"include"},c),s=await n.json().catch(()=>({}));if(!n.ok)throw new Error(s.error||`Delete failed (${n.status})`);u?.()}catch(n){window.alert(n?.message||"Delete failed")}finally{Ue(!1)}}},[c,we,t.assetId,u,w]),Lt=i.useCallback(async()=>{if(!(!h||x)){$(!0),A(null);try{const n=h.status==="resolved"?"open":"resolved",s=await B(`/api/taskforce/document-reviews/sessions/${encodeURIComponent(h.id)}`,{method:"PATCH",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({status:n})},c),o=await s.json().catch(()=>({}));if(!s.ok)throw new Error(o.error||`Failed to update review (${s.status})`);const d=o.session||null;if(!d)throw new Error("Review session payload missing.");j(f=>f.map(k=>k.id===d.id?d:k))}catch(n){A(n?.message||"Failed to update review")}finally{$(!1)}}},[h,c,x]),It=i.useCallback(async()=>{if(!h||x)return;const n=Te.trim();$(!0),A(null);try{const s=await B(`/api/taskforce/document-reviews/sessions/${encodeURIComponent(h.id)}`,{method:"PATCH",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({title:n||null})},c),o=await s.json().catch(()=>({}));if(!s.ok)throw new Error(o.error||`Failed to update review (${s.status})`);const d=o.session||null;if(!d)throw new Error("Review session payload missing.");j(f=>f.map(k=>k.id===d.id?d:k)),ae(!1)}catch(s){A(s?.message||"Failed to update review")}finally{$(!1)}},[h,c,x,Te]),Ze=T?W:b??"",Bt=i.useCallback(()=>{if(T)return;const n=typeof window.getSelection=="function"?window.getSelection():null,s=n?.toString().replace(/\s+/g," ").trim()||"";if(!n||!s)return;const o=n.rangeCount>0?n.getRangeAt(0):null,d=Xe.current;if(!o||!d)return;const f=o.commonAncestorContainer,k=f.nodeType===Node.TEXT_NODE?f.parentNode:f;if(!(k instanceof Node)||!d.contains(k))return;const Z=Ia(d,o,s);Z&&Q(Z)},[T]),et=i.useCallback(async()=>{const n=E.trim();if(!n||x)return;let s=h;if(s||(s=await De()),!!s){$(!0),A(null);try{const o=await B(`/api/taskforce/document-reviews/sessions/${encodeURIComponent(s.id)}/comments`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({body:n,anchor:H||{kind:"document"}})},c),d=await o.json().catch(()=>({}));if(!o.ok)throw new Error(d.error||`Failed to add comment (${o.status})`);const f=d.session||null;if(!f)throw new Error("Review session payload missing.");j(k=>{const Z=k.filter(ze=>ze.id!==f.id);return[f,...Z]}),V(f.id),P(""),Q(null)}catch(o){A(o?.message||"Failed to add comment")}finally{$(!1)}}},[h,c,De,H,x,E]),Dt=i.useCallback((n,s)=>{ue(n),re(s)},[]),Pt=i.useCallback(async()=>{if(!h||!ie||x)return;const n=pe.trim();if(n){$(!0),A(null);try{const s=await B(`/api/taskforce/document-reviews/sessions/${encodeURIComponent(h.id)}/comments/${encodeURIComponent(ie)}`,{method:"PATCH",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({body:n})},c),o=await s.json().catch(()=>({}));if(!s.ok)throw new Error(o.error||`Failed to update comment (${s.status})`);const d=o.session||null;if(!d)throw new Error("Review session payload missing.");j(f=>f.map(k=>k.id===d.id?d:k)),ue(null),re("")}catch(s){A(s?.message||"Failed to update comment")}finally{$(!1)}}},[h,c,pe,ie,x]),Mt=i.useCallback(async n=>{if(!(!h||x)&&window.confirm("Delete this review comment?")){$(!0),A(null);try{const s=await B(`/api/taskforce/document-reviews/sessions/${encodeURIComponent(h.id)}/comments/${encodeURIComponent(n)}`,{method:"DELETE",credentials:"include"},c),o=await s.json().catch(()=>({}));if(!s.ok)throw new Error(o.error||`Failed to delete comment (${s.status})`);const d=o.session||null;if(!d)throw new Error("Review session payload missing.");j(f=>f.map(k=>k.id===d.id?d:k)),ie===n&&(ue(null),re(""))}catch(s){A(s?.message||"Failed to delete comment")}finally{$(!1)}}},[h,c,ie,x]),tt=i.useCallback(async n=>{if(!le)return!1;U({type:"saving"});try{const s=await B("/api/taskforce/documents/save",{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({fsPath:t.fsPath,content:n})},c),o=await s.json().catch(()=>({}));if(!s.ok)throw new Error(o.error||`Save failed (${s.status})`);const d=o.updatedAt||new Date().toISOString();return L(n),oe(n),U({type:"saved",savedAt:d}),r?.(d),!0}catch(s){return U({type:"error",message:s?.message||"Save failed"}),!1}},[c,t.fsPath,r,le]),zt=i.useCallback((n,s)=>{const o=T?W:b??"",d=Ba(o,n,s);if(d!==o){if(T){oe(d),U(f=>f.type==="saving"?f:{type:"idle"});return}tt(d)}},[b,W,T,tt]);let nt=-1;const Me=n=>!n||!Array.isArray(n.children)?!1:n.children.some(s=>s?s.type==="element"&&s.tagName==="input"&&s.properties?.type==="checkbox"?!0:Me(s):!1),st=n=>!n||!Array.isArray(n.children)?!1:n.children.some(s=>typeof s?.checked=="boolean"?!0:Me(s)),at={input({type:n,checked:s,...o}){if(n!=="checkbox")return e.jsx("input",{type:n,checked:s,...o});nt+=1;const d=nt;return e.jsx("input",{...o,type:"checkbox",checked:!!s,disabled:!1,onClick:f=>f.stopPropagation(),onChange:f=>zt(d,f.currentTarget.checked)})},ul({children:n,node:s,...o}){const d=st(s);return e.jsx("ul",{...o,style:d?{paddingLeft:"1.25em"}:void 0,"data-task-list":d?"true":void 0,children:n})},ol({children:n,node:s,...o}){const d=st(s);return e.jsx("ol",{...o,style:d?{paddingLeft:"1.25em"}:void 0,"data-task-list":d?"true":void 0,children:n})},li({children:n,node:s,...o}){const d=typeof s?.checked=="boolean"||Me(s);return e.jsx("li",{...o,style:d?{listStyleType:"none",listStyle:"none",marginLeft:0}:void 0,"data-task-item":d?"true":void 0,children:n})}};return e.jsxs("div",{className:`${a.viewer} ${T?a.viewerEditMode:""} ${Ke?a.viewerMonochrome:""}`,children:[e.jsxs("div",{className:a.meta,children:[e.jsxs("div",{className:a.metaLeft,children:[e.jsxs("span",{className:`${a.typeBadge} ${_a[t.docType]??""}`,children:[e.jsx(nn,{size:10}),ba[t.docType]]}),ge?e.jsx("div",{className:a.metaRenameRow,children:e.jsx("input",{ref:Be,type:"text",className:M.input,value:$e,onChange:n=>ce(n.target.value),onBlur:()=>{Pe()},onKeyDown:At})}):e.jsx("span",{className:a.metaDocumentName,title:w,onDoubleClick:()=>{t.assetId&&(ce(w),te(!0))},children:w}),l&&e.jsx("span",{className:a.metaTaskName,title:`From task: ${l}`,children:l}),Je==="unattached"&&e.jsx("span",{className:a.statusBadge,children:"Unattached"}),t.updatedAt&&e.jsxs("span",{className:a.metaDate,title:ut(t.updatedAt),children:[e.jsx(sn,{size:11}),ut(t.updatedAt)]}),e.jsxs("span",{className:a.metaSize,children:[e.jsx(an,{size:11}),Ca(t.sizeBytes)]}),_&&e.jsx(Gt,{label:_,copied:O,onClick:()=>{Et()},title:"Copy document reference"}),X.type==="saved"&&e.jsxs("span",{className:`${a.saveStatus} ${a.saveStatusSaved}`,children:[e.jsx(yt,{size:11}),"Saved"]}),X.type==="error"&&e.jsxs("span",{className:`${a.saveStatus} ${a.saveStatusError}`,title:X.message,children:[e.jsx(gt,{size:11}),X.message||"Save failed"]}),Le&&X.type!=="saving"&&e.jsx("span",{className:a.unsaved,children:"Unsaved changes"})]}),e.jsx("div",{className:a.actions,children:T?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:a.layoutToggle,children:[e.jsx("button",{className:`${a.layoutBtn} ${K==="editor"?a.layoutBtnActive:""}`,onClick:()=>Re("editor"),title:"Editor only",children:e.jsx(_e,{size:12})}),e.jsx("button",{className:`${a.layoutBtn} ${K==="split"?a.layoutBtnActive:""}`,onClick:()=>Re("split"),title:"Split view",children:e.jsx(rn,{size:12})}),e.jsx("button",{className:`${a.layoutBtn} ${K==="preview"?a.layoutBtnActive:""}`,onClick:()=>Re("preview"),title:"Preview only",children:e.jsx(Oe,{size:12})})]}),e.jsxs("button",{className:a.actionBtn,onClick:Ct,title:"Discard changes",children:[e.jsx(wt,{size:13}),"Cancel"]}),e.jsxs("button",{className:`${a.actionBtn} ${a.saveBtn}`,onClick:Qe,disabled:X.type==="saving"||!Le,title:"Save (Ctrl+S)",children:[e.jsx(on,{size:13}),X.type==="saving"?"Saving…":"Save"]})]}):e.jsxs(e.Fragment,{children:[t.assetId&&e.jsxs("button",{className:a.actionBtn,onClick:()=>te(n=>!n),title:"Rename document",children:[e.jsx(_e,{size:13}),ge?"Close Rename":"Rename"]}),le&&e.jsxs("button",{className:`${a.actionBtn} ${a.editBtn}`,onClick:jt,title:"Edit document",children:[e.jsx(_e,{size:13}),"Edit"]}),e.jsxs("button",{className:a.actionBtn,onClick:Tt,title:"Copy link",children:[e.jsx(cn,{size:13}),F?"Copied!":"Copy link"]}),e.jsxs("button",{className:a.actionBtn,onClick:Rt,title:"Download .md",children:[e.jsx(ln,{size:13}),"Download"]}),e.jsxs("button",{className:a.actionBtn,onClick:Nt,title:"Print",children:[e.jsx(dn,{size:13}),"Print"]}),e.jsxs("button",{className:a.actionBtn,onClick:()=>kt(n=>!n),title:"Toggle black and white style",children:[e.jsx(Oe,{size:13}),Ke?"Color":"B/W"]}),m&&t.docType==="implementation-plan"&&!T&&e.jsxs("button",{className:`${a.actionBtn} ${a.generateBtn}`,onClick:()=>Ae(!0),title:"Generate tasks from this plan",children:[e.jsx(He,{size:13}),"Generate Tasks"]}),St&&e.jsxs("button",{className:`${a.actionBtn} ${a.dangerBtn}`,onClick:()=>{$t()},disabled:we,title:"Permanently delete this unattached document",children:[e.jsx(un,{size:13}),we?"Deleting…":"Delete Permanently"]})]})})]}),z&&e.jsx("div",{className:a.viewerState,children:"Loading…"}),!z&&N&&e.jsx("div",{className:a.viewerStateError,children:N}),!z&&!N&&(T?e.jsxs("div",{className:`${a.editorArea} ${ka[K]}`,children:[(K==="editor"||K==="split")&&e.jsxs("div",{className:a.editorPane,children:[e.jsx("div",{className:a.editorPaneLabel,children:"Markdown"}),e.jsx("textarea",{ref:Ie,className:`${a.editorTextarea} tf-scrollbar`,value:W,onScroll:()=>be("editor"),onChange:n=>{oe(n.target.value),U(s=>s.type==="saving"?s:{type:"idle"})},spellCheck:!0,placeholder:"Write markdown here…"})]}),(K==="preview"||K==="split")&&e.jsxs("div",{className:a.previewPane,children:[e.jsx("div",{className:a.editorPaneLabel,children:"Preview"}),e.jsx("div",{ref:Ve,className:`${M.docMarkdown} ${a.markdownSurface}`,"data-testid":"doc-preview-scroll",onScroll:()=>be("preview"),children:e.jsx(ke,{remarkPlugins:[Se],rehypePlugins:[je],components:at,children:Ze})})]})]}):e.jsxs("div",{className:a.viewerBody,children:[e.jsx("div",{className:`${a.viewerContent} ${a.viewerMain} tf-scrollbar`,children:e.jsx("div",{ref:Xe,className:`${M.docMarkdown} ${a.markdownSurface}`,onMouseUp:Bt,children:e.jsx(ke,{remarkPlugins:[Se],rehypePlugins:[je],components:at,children:Ze})})}),e.jsx("aside",{className:a.reviewRail,children:e.jsxs("section",{className:a.reviewSection,"aria-label":"Review and comments",children:[e.jsxs("div",{className:a.reviewHeader,children:[e.jsxs("div",{children:[e.jsxs("div",{className:a.reviewTitle,children:[e.jsx(dt,{size:14}),"Review & Comments"]}),e.jsx("p",{className:a.reviewSubtitle,children:"Comments stay attached to this document review session."})]}),e.jsxs("div",{className:a.reviewControls,children:[y.length>1&&e.jsx("select",{className:`${M.select} ${a.reviewSelect}`,value:h?.id||"",onChange:n=>V(n.target.value||null),"aria-label":"Select review session",children:y.map(n=>e.jsx("option",{value:n.id,children:n.title?.trim()||"Untitled review"},n.id))}),e.jsxs("button",{type:"button",className:a.actionBtn,onClick:()=>{De()},disabled:x||!t.assetId,children:[e.jsx(dt,{size:13}),"Start Review"]}),h&&e.jsxs("button",{type:"button",className:a.actionBtn,onClick:()=>{Lt()},disabled:x,children:[h.status==="resolved"?e.jsx(mn,{size:13}):e.jsx(fn,{size:13}),h.status==="resolved"?"Reopen":"Resolve"]})]})]}),h&&e.jsxs("div",{className:a.reviewSessionMeta,children:[e.jsx("span",{className:`${a.statusBadge} ${h.status==="resolved"?a.reviewStatusResolved:""}`,children:h.status==="resolved"?"Resolved":"Open"}),he?e.jsxs("div",{className:a.reviewTitleEditRow,children:[e.jsx("input",{type:"text",className:M.input,value:Te,onChange:n=>Ee(n.target.value),placeholder:"Untitled review"}),e.jsx("button",{type:"button",className:M.secondaryHeaderBtn,onClick:()=>{It()},disabled:x,children:"Save Title"})]}):e.jsx("span",{className:a.reviewSessionLabel,children:h.title?.trim()||"Untitled review"}),e.jsxs("span",{className:a.reviewSessionTimestamp,children:["Updated ",mt(h.updatedAt)]}),!he&&e.jsxs("button",{type:"button",className:a.actionBtn,onClick:()=>ae(!0),disabled:x,children:[e.jsx(_e,{size:13}),"Rename Review"]})]}),ee&&e.jsx("div",{className:a.viewerStateError,children:ee}),e.jsxs("div",{className:I.commentPanel,children:[e.jsxs("div",{className:I.commentThread,children:[q&&e.jsx("div",{className:I.emptyComments,children:"Loading review comments…"}),!q&&!h&&e.jsx("div",{className:I.emptyComments,children:"Start a review to collect comments for this document."}),!q&&h&&h.comments.length===0&&e.jsx("div",{className:I.emptyComments,children:"No comments yet. Add the first review note for this document."}),!q&&h&&h.comments.map(n=>{const s=n.authorActor?.kind==="ai",o=ft(n.anchor),d=s?hn:pn,f=ie===n.id;return e.jsxs("div",{className:`${I.comment} ${s?I.commentAi:I.commentUser}`,children:[e.jsxs("div",{className:I.commentHeader,children:[e.jsxs("span",{className:I.commentAuthor,style:n.authorActor?.color?{color:n.authorActor.color}:void 0,children:[e.jsx(d,{size:12,strokeWidth:1.5}),Aa(n)]}),e.jsx("span",{className:I.commentTime,children:mt(n.updatedAt)}),e.jsxs("span",{className:a.reviewCommentActions,children:[!f&&e.jsx("button",{type:"button",className:a.reviewCommentAction,onClick:()=>Dt(n.id,n.body),disabled:x,children:"Edit"}),f&&e.jsx("button",{type:"button",className:a.reviewCommentAction,onClick:()=>{ue(null),re("")},disabled:x,children:"Cancel"}),e.jsx("button",{type:"button",className:a.reviewCommentAction,onClick:()=>{Mt(n.id)},disabled:x,children:"Delete"})]})]}),o&&e.jsx("span",{className:a.reviewAnchorLabel,children:o}),e.jsx("div",{className:I.commentText,children:f?e.jsxs("div",{className:a.reviewCommentEditor,children:[e.jsx("textarea",{className:I.commentInput,value:pe,onChange:k=>re(k.target.value),disabled:x}),e.jsx("button",{type:"button",className:M.secondaryHeaderBtn,onClick:()=>{Pt()},disabled:x||!pe.trim(),children:"Save Comment"})]}):e.jsx(ke,{remarkPlugins:[Se],rehypePlugins:[je],children:n.body})})]},n.id)}),e.jsx("div",{ref:Ye})]}),e.jsxs("div",{className:I.commentInputArea,children:[e.jsxs("div",{className:a.reviewComposer,children:[H&&e.jsxs("div",{className:a.reviewAnchorChip,children:[e.jsx("span",{children:ft(H)||"Selected text"}),"quote"in H&&H.quote&&e.jsxs("span",{className:a.reviewAnchorSnippet,children:['"',H.quote,'"']}),e.jsx("button",{type:"button",className:a.reviewAnchorClear,onClick:()=>Q(null),children:"Clear"})]}),e.jsx("textarea",{className:I.commentInput,placeholder:h?.status==="resolved"?"Reopen this review to add more comments…":H?"Add a comment for the selected text…":"Add a comment for this document review…",value:E,onChange:n=>P(n.target.value),disabled:x||h?.status==="resolved",onKeyDown:n=>{n.key==="Enter"&&!n.shiftKey&&(n.preventDefault(),et())}})]}),e.jsx("button",{type:"button",className:I.sendCommentBtn,onClick:()=>{et()},disabled:x||!E.trim()||h?.status==="resolved","aria-label":"Send review comment",title:"Send review comment",children:e.jsx(vn,{size:15})})]})]})]})})]})),m&&_t&&b!==null&&e.jsx(xa,{content:b,docTitle:t.title,apiBaseUrl:c,onClose:()=>Ae(!1),onGenerated:n=>Ae(!1)}),!T&&e.jsx("div",{className:a.printHint,children:"For the cleanest output, disable browser Headers and footers in the print dialog."})]})}function pt(t){return typeof t=="string"?t.trim().replace(/\/+$/,""):""}function Pa(t){return t.runtimeMode==="local"?"":pt(t.apiBaseUrl)||pt(t.cloudAuthBaseUrl)||""}function We(t){let l=t;try{l=decodeURIComponent(t)}catch{l=t}return l.trim().replace(/\\/g,"/").replace(/^\/+/,"").replace(/^\.\//,"").replace(/^\.taskforce\//,"")}function Ma(t,l){return!!(t===l||t.endsWith(`/${l}`)||l.endsWith(`/${t}`))}function vt(t){const l=We(String(t||""));if(!l)return null;const c=l.match(/(^|\/)(asset-[a-f0-9]{32})(?=[^/]*$)/i);return c?.[2]?c[2].toLowerCase():null}function Ce(t){return t.attachmentState==="attached"||t.attachmentState==="unattached"?t.attachmentState:(typeof t.attachmentCount=="number"&&Number.isFinite(t.attachmentCount)?t.attachmentCount:0)>0||t.taskId?"attached":"unattached"}function za({tasks:t,apiBaseUrl:l="",documents:c,loading:r,error:u,selectedDoc:m,searchQuery:v,typeFilters:S,attachmentFilters:g,onSearchChange:w,onSelectDoc:p,onRefresh:_,enableTaskGeneration:b=!1}){const L=c.filter(N=>{const F=`${fe(N)} ${N.originalFilename||""}`.toLowerCase(),G=!v||F.includes(v.toLowerCase()),O=S.length===0||S.includes(N.docType),Y=Ce(N),y=g.length===0||g.includes(Y);return G&&O&&y}),z=v.trim().length>0||S.length>0||g.length>0,D=new Map(t.map(N=>[N.id,N]));return e.jsxs("div",{className:M.docWorkspace,children:[e.jsx("div",{className:M.docIndexPanel,children:e.jsx(Hn,{documents:L,selectedDocId:m?.id??null,loading:r,error:u,searchQuery:v,onSearchChange:w,onSelect:N=>p(N),onRefresh:_,taskById:D,hasActiveFilters:z})}),e.jsx("div",{className:M.docViewerPanel,children:m?e.jsx(Da,{doc:m,taskTitle:m.taskId?D.get(m.taskId)?.title??null:null,apiBaseUrl:l,onSaved:N=>_(),onDeleted:()=>{p(null),_()},enableTaskGeneration:b}):!r&&e.jsx("div",{className:M.docViewerEmpty,children:e.jsx("p",{className:"tf-empty-copy",children:L.length===0?"No documents match your current filters.":"Select a document to view it."})})})]})}function Ua({tasks:t,runtimeMode:l="local",apiBaseUrl:c="",cloudAuthBaseUrl:r="",typeFilters:u,attachmentFilters:m,onTypeFiltersChange:v,onAttachmentFiltersChange:S,requestedDocPath:g=null,requestedDocAssetId:w=null,onRequestedDocHandled:p,enableTaskGeneration:_=!1}){const[b,L]=i.useState([]),[z,D]=i.useState(!0),[N,J]=i.useState(null),[F,G]=i.useState(null),[O,Y]=i.useState(""),[y,j]=i.useState(()=>Wt.map(E=>E.value)),[q,Ne]=i.useState(()=>Kt.map(E=>E.value)),ee=Pa({runtimeMode:l,apiBaseUrl:c,cloudAuthBaseUrl:r}),A=u??y,se=m??q,V=i.useCallback(async()=>{D(!0),J(null);try{const E=await B("/api/taskforce/documents",{credentials:"include"},ee);if(!E.ok)throw new Error(`Failed to load documents (${E.status})`);const x=(await E.json()).documents||[];Array.isArray(x)&&x.length,L(x)}catch(E){J(E?.message||"Failed to load documents"),E?.message}finally{D(!1)}},[ee,l]);return i.useEffect(()=>{V()},[V]),i.useEffect(()=>{g||w||!F&&b.length>0&&G(b[0])},[b,F,w,g]),i.useEffect(()=>{if(!g&&!w||b.length===0)return;const E=g?We(g):"",P=String(w||"").trim().toLowerCase()||vt(g),x=b.find($=>{const H=vt($.fsPath)||String($.assetId||"").trim().toLowerCase()||null;if(P&&H&&H===P)return!0;if(!E)return!1;const Q=We($.fsPath);return Ma(Q,E)});if(x){G(x),p?.();return}},[w,g,b,p]),i.useEffect(()=>{if((g||w)&&!F)return;const E=b.filter(P=>{const $=`${fe(P)} ${P.originalFilename||""}`.toLowerCase(),H=!O||$.includes(O.toLowerCase()),Q=A.length===0||A.includes(P.docType),he=Ce(P),ae=se.length===0||se.includes(he);return H&&Q&&ae});F&&E.some(P=>P.id===F.id)||G(E[0]??null)},[se,b,w,g,O,F,A]),e.jsx(za,{tasks:t,apiBaseUrl:ee,documents:b,loading:z,error:N,selectedDoc:F,searchQuery:O,typeFilters:A,attachmentFilters:se,onSearchChange:Y,onSelectDoc:G,onRefresh:V,enableTaskGeneration:_})}export{Kt as DOCUMENT_ATTACHMENT_FILTER_OPTIONS,Wt as DOCUMENT_TYPE_FILTER_OPTIONS,za as DocumentWorkspace,Ua as DocumentWorkspaceShell,Ce as getEffectiveAttachmentState};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as i,j as s}from"./vendor-react-CKJs5o3c.js";import{t as e}from"./index-
|
|
1
|
+
import{r as i,j as s}from"./vendor-react-CKJs5o3c.js";import{t as e}from"./index-CLIMgR6g.js";import{h as g,Z as v,b as j,k as f}from"./vendor-icons-pWocEipT.js";import"./vendor-markdown-BUxTU7dS.js";import"./vendor-dnd-DRzYolkg.js";import"./vendor-router-BbWMxlnO.js";function T({initiativeTemplates:n,onRefreshInitiativeTemplates:u,onCreateInitiativeFromTemplate:l}){const[a,o]=i.useState(""),[c,x]=i.useState(""),[d,m]=i.useState(!1),[r,p]=i.useState(null);return i.useEffect(()=>{if(!a&&n.length>0){const t=n[0];o(t.id)}},[n,a]),s.jsx("div",{className:`${e.standalonePage} ${e.standaloneContent}`,style:{overflow:"auto"},children:s.jsx("div",{className:e.settingsContent,style:{maxWidth:900,margin:"0 auto",width:"100%"},children:s.jsxs("div",{className:e.settingGroup,children:[s.jsxs("div",{className:e.settingTitleRow,children:[s.jsx("h2",{className:e.settingTitle,children:"Initiatives"}),s.jsx("button",{className:e.copyBtn,onClick:()=>{u?.()},children:"Refresh"})]}),s.jsx("p",{className:`${e.settingsHint} ${e.marginBottom12}`,children:"Create initiative-ready planning structures from reusable templates."}),s.jsxs("div",{className:e.exportItem,children:[s.jsx("label",{className:e.label,children:"Template"}),s.jsx("select",{className:e.input,value:a,onChange:t=>{const h=t.target.value;o(h)},children:n.map(t=>s.jsx("option",{value:t.id,children:t.name},t.id))})]}),s.jsxs("div",{className:`${e.exportItem} ${e.marginTop12}`,children:[s.jsx("label",{className:e.label,children:"Initiative Title"}),s.jsx("input",{className:e.input,placeholder:"e.g. Taskforce Private Beta Launch",value:c,onChange:t=>x(t.target.value)})]}),s.jsxs("button",{className:`${e.secondaryHeaderBtn} ${e.marginTop12}`,disabled:d||!a||!c.trim()||!l,onClick:async()=>{if(!l)return;m(!0);const t=await l({templateId:a,title:c.trim()});m(!1),p({type:t.success?"success":"error",message:t.success?"Initiative created from template.":t.error||"Failed to create initiative."})},children:[d?s.jsx(g,{size:14,className:e.spinner}):s.jsx(v,{size:14}),"Create Initiative"]}),r&&s.jsxs("div",{className:`${r.type==="success"?e.successMessage:e.errorMessage} ${e.marginTop12}`,children:[r.type==="success"?s.jsx(j,{size:14}):s.jsx(f,{size:14}),r.message]})]})})})}export{T as InitiativesModule};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as a,j as t}from"./vendor-react-CKJs5o3c.js";import{t as ye,y as he,z as X,B as Q,C as Se,E as _e}from"./index-CLIMgR6g.js";import{aJ as Ce,h as be,U as ve}from"./vendor-icons-pWocEipT.js";import{u as ke,a as Ee}from"./vendor-router-BbWMxlnO.js";import"./vendor-markdown-BUxTU7dS.js";import"./vendor-dnd-DRzYolkg.js";const xe="_plansWrapper_b8yvs_1",Ie="_contentFrame_b8yvs_28",we="_shellOwnsScroll_b8yvs_36",Ne="_withChrome_b8yvs_42",Pe="_siteVariant_b8yvs_46",je="_title_b8yvs_54",Te="_subtitle_b8yvs_63",Re="_header_b8yvs_67",Ue="_planCard_b8yvs_79",Be="_grid_b8yvs_92",$e="_planName_b8yvs_98",Oe="_featureText_b8yvs_102",Ae="_currentBadge_b8yvs_106",Me="_navAction_b8yvs_110",Le="_backBtn_b8yvs_111",Fe="_priceRows_b8yvs_122",De="_headerBar_b8yvs_139",Ke="_headerActions_b8yvs_148",Ve="_debugMeta_b8yvs_175",He="_clickablePlanCard_b8yvs_204",Ye="_activePlanCard_b8yvs_219",Ge="_callToAction_b8yvs_272",qe="_primaryCta_b8yvs_284",ze="_secondaryCta_b8yvs_295",We="_currentCta_b8yvs_307",Xe="_featuresList_b8yvs_321",Qe="_priceRow_b8yvs_122",Je="_priceRowAmount_b8yvs_346",Ze="_priceRowInterval_b8yvs_352",et="_ctaRow_b8yvs_357",tt="_featureItem_b8yvs_363",nt="_featureIcon_b8yvs_369",rt="_emptyState_b8yvs_383",st="_marketingEmptyState_b8yvs_392",at="_emptyBadge_b8yvs_420",it="_emptyHighlights_b8yvs_435",ot="_loader_b8yvs_457",ct="_spinner_b8yvs_467",lt="_statusBanner_b8yvs_520",ut="_successBanner_b8yvs_528",dt="_errorBanner_b8yvs_534",n={plansWrapper:xe,contentFrame:Ie,shellOwnsScroll:we,withChrome:Ne,siteVariant:Pe,title:je,subtitle:Te,header:Re,planCard:Ue,grid:Be,planName:$e,featureText:Oe,currentBadge:Ae,navAction:Me,backBtn:Le,priceRows:Fe,headerBar:De,headerActions:Ke,debugMeta:Ve,clickablePlanCard:He,activePlanCard:Ye,callToAction:Ge,primaryCta:qe,secondaryCta:ze,currentCta:We,featuresList:Xe,priceRow:Qe,priceRowAmount:Je,priceRowInterval:Ze,ctaRow:et,featureItem:tt,featureIcon:nt,emptyState:rt,marketingEmptyState:st,emptyBadge:at,emptyHighlights:it,loader:ot,spinner:ct,statusBanner:lt,successBanner:ut,errorBanner:dt};function mt(){const r=globalThis.__DEBUG_MODE__;return typeof r=="boolean"?r:!1}function pt(r){const i=String(r?.environment||"").trim(),m=String(r?.runtimeMode||"").trim();return!i&&!m?null:i&&m?`${i} (${m})`:i||m||null}function gt(r,i){if(r==null||!i)return"Contact Sales";try{return new Intl.NumberFormat("en-US",{style:"currency",currency:i.toUpperCase(),minimumFractionDigits:0}).format(r/100)}catch{return`${i.toUpperCase()} ${r/100}`}}function ft(){return"$0.00"}function de(r){return r?r.pricingType==="free"?!0:r.unitAmount!=null&&r.currency!=null:!1}function me(r){return r?r.pricingType==="free"?ft():gt(r.unitAmount,r.currency):"Unavailable"}function pe(r){const i=[r.pricing.month,r.pricing.year].filter(Boolean);if(i.some(f=>f.pricingType==="free"))return 0;const m=i.map(f=>f.pricingType==="stripe"&&typeof f.unitAmount=="number"?f.unitAmount:null).filter(f=>f!=null);return m.length>0?Math.min(...m):Number.POSITIVE_INFINITY}function yt(r){const i=String(r||"").trim().toLowerCase();return i==="active"||i==="trialing"||i==="grace"}function ht({heading:r,subtitle:i,variant:m="app",chrome:f,footer:R,isAuthenticated:U,authSessionResolved:se=!0,currentPlanId:V,currentPlanVersionId:M,currentEntitlementState:H,canManageCurrentPlan:v=!0,pricingEndpoint:J,statusBanner:y,onBack:C,backLabel:p,topActions:Y,shellOwnsScroll:G=!1,showPageBackButton:B=!0,fallbackPricingSource:Z=null,onSelectPlan:c}){const[L,P]=a.useState([]),[w,j]=a.useState(null),[F,ee]=a.useState(!0),[$,q]=a.useState(null),[z,x]=a.useState(0);a.useEffect(()=>{let s=!0;return(async()=>{const _=String(J||"/api/taskforce/public/pricing").trim()||"/api/taskforce/public/pricing";s&&(ee(!0),q(null));try{const S=await fetch(_,{method:"GET",credentials:"include"}),d=await S.json().catch(()=>({}));if(S.ok){s&&(P(Array.isArray(d?.plans)?d.plans:[]),j(d?.pricingSource&&typeof d.pricingSource=="object"?d.pricingSource:null));return}throw new Error(String(d?.error||`Failed to load pricing (${S.status})`))}catch(S){if(s){const d=S instanceof Error?S.message:"Failed to load pricing";q(d||"Failed to load pricing"),j(null)}}finally{s&&ee(!1)}})(),()=>{s=!1}},[J,z]);const W=a.useMemo(()=>[...L].sort((s,k)=>{const _=pe(s),S=pe(k);if(_!==S)return _-S;const d=s.defaultVersion?.versionNumber||0,u=k.defaultVersion?.versionNumber||0;return d!==u?d-u:String(s.displayName||s.planId).localeCompare(String(k.displayName||k.planId))}),[L]),te=a.useMemo(()=>pt(w||Z),[Z,w]),D=`${n.plansWrapper} ${G?n.shellOwnsScroll:"tf-scrollbar"} ${m==="site"?n.siteVariant:""} ${f?n.withChrome:""}`.trim(),h=s=>G?t.jsxs(t.Fragment,{children:[f,s,R]}):t.jsxs("div",{className:ye.standaloneWrapper,"data-theme":"dark",children:[f,s,R]});return h(F||!se?t.jsx(t.Fragment,{children:t.jsx("div",{className:D,children:t.jsx("div",{className:n.contentFrame,children:t.jsxs("div",{className:n.loader,children:[t.jsx(be,{size:48,className:n.spinner}),t.jsx("p",{children:"Loading plans..."})]})})})}):$?t.jsx(t.Fragment,{children:t.jsx("div",{className:D,children:t.jsx("div",{className:n.contentFrame,children:t.jsxs("div",{className:n.emptyState,children:[t.jsx("h2",{children:"Connecting to plan pricing..."}),t.jsx("p",{children:$}),t.jsx("button",{className:n.backBtn,onClick:()=>x(s=>s+1),children:"Retry"})]})})})}):t.jsx(t.Fragment,{children:t.jsx("div",{className:D,children:t.jsxs("div",{className:n.contentFrame,children:[t.jsxs("div",{className:n.header,children:[!f&&(B||Y)&&t.jsxs("div",{className:n.headerBar,children:[t.jsx("div",{children:B?t.jsx("button",{className:n.backBtn,onClick:C,children:p}):null}),t.jsx("div",{className:n.headerActions,children:Y})]}),t.jsx("h1",{className:n.title,children:r}),i&&t.jsx("p",{className:n.subtitle,children:i}),mt()&&te?t.jsxs("p",{className:n.debugMeta,children:["Pricing source: ",te]}):null,y&&t.jsx("div",{className:`${n.statusBanner} ${y.type==="success"?n.successBanner:n.errorBanner}`,children:y.message})]}),W.length===0?t.jsxs("div",{className:`${n.emptyState} ${n.marketingEmptyState}`,children:[t.jsx("span",{className:n.emptyBadge,children:"Coming Soon"}),t.jsx("h2",{children:"Paid plans are getting their final polish."}),t.jsx("p",{children:"Taskforce pricing is on the way with flexible options for solo operators, teams, and larger rollouts. Check back soon for launch tiers, feature bundles, and early access details."}),t.jsxs("div",{className:n.emptyHighlights,"aria-label":"Upcoming pricing highlights",children:[t.jsx("span",{children:"Launch-ready tiers"}),t.jsx("span",{children:"Team billing controls"}),t.jsx("span",{children:"Feature-based packaging"})]})]}):t.jsx("div",{className:n.grid,children:W.map(s=>{const k=s.pricing.month,_=s.pricing.year,S=de(k),d=de(_),u=String(s.defaultVersion?.planVersionId||"").trim(),g=!!(u&&M&&M===u&&yt(H))||!M&&!!(V&&V===s.planId),I=S?"month":d?"year":null,N=I==="year"?_:k,T=!!u&&(g?v:!!I),O=()=>{if(u){if(g){if(!v)return;c({planId:s.planId,planVersionId:u,interval:I||"month",pricingType:N?.pricingType||"stripe",isCurrentPlan:!0});return}I&&c({planId:s.planId,planVersionId:u,interval:I,pricingType:N?.pricingType||"stripe",isCurrentPlan:!1})}};return t.jsxs("div",{className:`${n.planCard} ${g?n.activePlanCard:""} ${T?n.clickablePlanCard:""}`,"data-testid":`plan-card-${s.planId}`,role:T?"button":void 0,tabIndex:T?0:void 0,onClick:T?O:void 0,onKeyDown:T?b=>{(b.key==="Enter"||b.key===" ")&&(b.preventDefault(),O())}:void 0,children:[g&&t.jsx("span",{className:n.currentBadge,children:"Current Plan"}),t.jsx("h3",{className:n.planName,children:s.displayName}),t.jsx("div",{className:n.featuresList,children:Array.isArray(s.features)&&s.features.length>0?s.features.map((b,ne)=>t.jsxs("div",{className:n.featureItem,children:[t.jsx(Ce,{className:n.featureIcon}),t.jsx("span",{className:n.featureText,children:String(b.featureKey||"").replace(/[_\-.]+/g," ").replace(/\b\w/g,re=>re.toUpperCase())})]},`${b.featureKey}-${ne}`)):t.jsx("span",{className:n.featureText,children:"No additional features included"})}),t.jsxs("div",{className:n.priceRows,children:[t.jsxs("div",{className:n.priceRow,children:[t.jsx("span",{className:n.priceRowAmount,children:me(k)}),t.jsx("span",{className:n.priceRowInterval,children:"/ month"})]}),t.jsxs("div",{className:n.priceRow,children:[t.jsx("span",{className:n.priceRowAmount,children:me(_)}),t.jsx("span",{className:n.priceRowInterval,children:"/ year"})]})]}),g?t.jsx("button",{className:`${n.callToAction} ${n.currentCta}`,"data-testid":`plan-manage-${s.planId}`,onClick:b=>{b.stopPropagation(),v&&c({planId:s.planId,planVersionId:u,interval:I||"month",pricingType:N?.pricingType||"stripe",isCurrentPlan:!0})},disabled:!u||!v,children:U&&v?"Manage Plan":"Current Plan"}):t.jsxs("div",{className:n.ctaRow,children:[t.jsx("button",{className:`${n.callToAction} ${n.secondaryCta}`,"data-testid":`plan-select-${s.planId}-month`,onClick:b=>{b.stopPropagation(),c({planId:s.planId,planVersionId:u,interval:"month",pricingType:k?.pricingType||"stripe",isCurrentPlan:!1})},disabled:!u||!S,children:k?.pricingType==="free"?U?"Select Free":"Get Started Free":U?"Choose Monthly":"Get Started Monthly"}),t.jsx("button",{className:`${n.callToAction} ${n.primaryCta}`,"data-testid":`plan-select-${s.planId}-year`,onClick:b=>{b.stopPropagation(),c({planId:s.planId,planVersionId:u,interval:"year",pricingType:_?.pricingType||"stripe",isCurrentPlan:!1})},disabled:!u||!d,children:_?.pricingType==="free"?U?"Select Free":"Get Started Free":U?"Choose Yearly":"Get Started Yearly"})]})]},s.planId)})})]})})}))}const St=1600,_t=new Set(["active","trialing","grace"]),A={planSelectionRequired:"Choose a plan to continue.",checkoutPending:"Complete checkout to continue.",misconfigured:"Onboarding policy is misconfigured. Contact support or a system administrator.",missingEntitlement:"No entitlement is linked to this account."},K={CHECKOUT_SESSION_EXPIRED:"Your previous checkout expired. Choose a plan to continue.",CHECKOUT_SESSION_SUPERSEDED:"A newer checkout replaced your previous checkout. Choose a plan to continue."};function Ct(r){return r==="year"?"year":"month"}function ge(r){const i=String(r||"").trim();return i?i.replace(/\/+$/,""):""}function oe(r={}){const i=new URLSearchParams;i.set("screen","plans");for(const[m,f]of Object.entries(r)){const R=String(f||"").trim();R&&i.set(m,R)}return`/?${i.toString()}`}function wt({isAuthenticated:r,authUserId:i,runtimeMode:m,authSessionResolved:f,currentTheme:R="dark",projectName:U,currentWorkspaceId:se,apiBaseUrl:V,connectedEnvironmentSource:M,resolveCloudAuthUrl:H,embedded:v=!1,shellOwnsScroll:J=!1}){const y=ke(),C=Ee(),[p,Y]=a.useState(null),[G,B]=a.useState(!1),[Z,c]=a.useState(null),L=a.useRef(!1),P=a.useRef(null),w=a.useMemo(()=>new URLSearchParams(C.search),[C.search]),j=String(w.get("checkout")||"").trim().toLowerCase(),F=String(w.get("gate")||"").trim().toLowerCase(),ee=String(w.get("planId")||"").trim(),$=String(w.get("planVersionId")||"").trim(),q=Ct(w.get("interval")),z=String(w.get("session_id")||"").trim(),x=a.useMemo(()=>ge(V),[V]),W=a.useMemo(()=>ge(M),[M]),te=a.useMemo(()=>({environment:he(W||x),runtimeMode:m==="cloud"?"cloud":"local"}),[x,W,m]),D=a.useCallback(e=>{const o=String(e||"").trim();return x?`${x}${o.startsWith("/")?o:`/${o}`}`:o},[x]),h=a.useCallback(e=>H?H(e):D(e),[D,H]),s=a.useCallback(()=>{const e=new URLSearchParams(C.search);e.delete("screen"),e.delete("gate"),e.delete("checkout"),e.delete("planId"),e.delete("planVersionId"),e.delete("interval");const o=e.toString();y(`/${o?`?${o}`:""}${C.hash||""}`)},[C.hash,C.search,y]),k=a.useMemo(()=>[x?`${x}/api/taskforce/public/pricing`:"","/api/taskforce/public/pricing"].map(o=>String(o||"").trim()).filter((o,l,E)=>o&&E.indexOf(o)===l),[x]),_=a.useMemo(()=>{const e=String(p?.entitlementState||"").trim().toLowerCase();return _t.has(e)},[p?.entitlementState]),S=a.useMemo(()=>{if(_)return null;const e=String(p?.billingConflictCode||"").trim().toUpperCase();if(e==="CHECKOUT_SESSION_EXPIRED")return K.CHECKOUT_SESSION_EXPIRED;if(e==="CHECKOUT_SESSION_SUPERSEDED")return K.CHECKOUT_SESSION_SUPERSEDED;const o=String(p?.message||"").trim();if(o)return o;const l=String(p?.gate||F||"").trim().toLowerCase();return l==="plan_selection_required"?A.planSelectionRequired:l==="checkout_pending"?A.checkoutPending:l==="misconfigured"?A.misconfigured:l==="missing_entitlement"?A.missingEntitlement:null},[p?.billingConflictCode,p?.gate,p?.message,F,_]),d=a.useCallback(()=>{const e=new URLSearchParams(C.search);e.delete("checkout"),e.delete("session_id"),e.delete("gate"),e.delete("planId"),e.delete("planVersionId"),e.delete("interval");const o=e.toString();y(`${C.pathname}${o?`?${o}`:""}${C.hash||""}`,{replace:!0})},[C.hash,C.pathname,C.search,y]),u=a.useCallback(()=>{P.current!=null&&window.clearTimeout(P.current),P.current=window.setTimeout(()=>{d(),P.current=null},St)},[d]),g=a.useCallback(async e=>{const o=h(X);if(!r)return Y(null),Q(o,{identityKey:i}),null;try{const l=await Se(o,{identityKey:i,force:e?.force===!0});return Y(l),l}catch{return null}},[i,h,r]),I=a.useCallback((e,o)=>{const l=String(e?.billingConflictCode||"").trim().toUpperCase();if(l==="CHECKOUT_SESSION_EXPIRED")return K.CHECKOUT_SESSION_EXPIRED;if(l==="CHECKOUT_SESSION_SUPERSEDED")return K.CHECKOUT_SESSION_SUPERSEDED;const E=String(e?.message||"").trim();return E||String(o||"Unable to confirm checkout completion.").trim()||"Unable to confirm checkout completion."},[]),N=a.useCallback(async(e,o)=>{if(!e){c({type:"error",message:"Selected plan is missing a default plan version."});return}B(!0),c(null);try{const l=await fetch(h("/api/taskforce/billing/checkout-session"),{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({planVersionId:e,interval:o})}),E=await l.json().catch(()=>({}));if(!l.ok){c({type:"error",message:String(E?.error||"Unable to start checkout for selected plan.")});return}const ae=String(E?.checkoutState||"").trim().toLowerCase();if(ae==="free"){c({type:"success",message:"Plan selected. Your access is ready."}),Q(h(X),{identityKey:i}),await g();return}if(ae==="updated"){c({type:"success",message:String(E?.message||"Your subscription was updated successfully.")}),Q(h(X),{identityKey:i}),await g();return}if(ae==="already_current_plan"){c({type:"success",message:String(E?.message||"You are already on this plan.")}),Q(h(X),{identityKey:i}),await g();return}const ce=String(E?.returnBaseUrl||"").trim();if(m==="local"&&ce)try{const ie=window.location.origin,ue=new URL(ce,ie).origin;if(ue!==ie){c({type:"error",message:`Checkout return is misconfigured for this runtime. Expected ${ie} but got ${ue}.`});return}}catch{c({type:"error",message:"Checkout return URL is invalid for this runtime."});return}const le=String(E?.url||"").trim();if(!le){c({type:"error",message:"Checkout did not return a redirect URL."});return}window.location.assign(le)}catch{c({type:"error",message:"Unable to start checkout for selected plan."})}finally{B(!1)}},[i,h,g,m]),T=a.useCallback(async e=>{if(!e)return{confirmed:!1,errorMessage:"Checkout session is missing."};try{const o=await fetch(h("/api/taskforce/billing/checkout-session/confirm"),{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({sessionId:e})}),l=await o.json().catch(()=>({}));return o.ok?(Q(h(X),{identityKey:i}),await g(),{confirmed:!0}):{confirmed:!1,errorMessage:String(l?.error||"Unable to confirm checkout completion.")}}catch{return{confirmed:!1,errorMessage:"Unable to confirm checkout completion."}}},[i,h,g]),O=a.useCallback(async()=>{if(!r){y(`/login?mode=login&next=${encodeURIComponent(oe())}`);return}B(!0),c(null);try{const e=await fetch(h("/api/taskforce/billing/portal-session"),{method:"POST",credentials:"include"}),o=await e.json().catch(()=>({}));if(!e.ok){c({type:"error",message:String(o?.error||"Failed to open billing portal.")});return}const l=String(o?.url||"").trim();if(!l){c({type:"error",message:"Portal session did not return a redirect URL."});return}window.location.assign(l)}catch{c({type:"error",message:"Failed to open billing portal."})}finally{B(!1)}},[h,r,y]);a.useEffect(()=>{g()},[g]),a.useEffect(()=>{_&&F==="missing_entitlement"&&d()},[d,F,_]),a.useEffect(()=>()=>{P.current!=null&&window.clearTimeout(P.current)},[]),a.useEffect(()=>{if(j==="success"){L.current=!0,c({type:"success",message:"Checkout completed successfully. Finalizing your plan..."}),(async()=>{const e=z?await T(z):{confirmed:!1,errorMessage:"Checkout session is missing."};if(!e.confirmed){const o=await g({force:!0});c({type:"error",message:I(o,e.errorMessage)}),u();return}c({type:"success",message:"Checkout completed successfully."}),u()})();return}if(j==="cancel"){(async()=>{const e=await g({force:!0});c({type:"error",message:I(e,"Checkout was canceled. No charge was made.")}),u()})();return}if((j==="start"||j==="free")&&r&&$&&!L.current){L.current=!0,N($,q);return}if(S){c({type:"error",message:S});return}c(e=>!e||e.type!=="error"?e:e.message===A.planSelectionRequired||e.message===A.misconfigured||e.message===A.missingEntitlement||e.message===K.CHECKOUT_SESSION_EXPIRED||e.message===K.CHECKOUT_SESSION_SUPERSEDED?null:e)},[j,T,S,r,g,q,$,z,I,u,N]);const b=a.useCallback(async e=>{if(!r){const o=e.pricingType==="free"?"free":"start",l=oe({checkout:o,planId:e.planId,planVersionId:e.planVersionId,interval:e.interval});y(`/login?mode=register&planId=${encodeURIComponent(e.planId)}&planVersionId=${encodeURIComponent(e.planVersionId)}&interval=${encodeURIComponent(e.interval)}&next=${encodeURIComponent(l)}`);return}if(e.isCurrentPlan){if(!p?.stripeCustomerId){c({type:"success",message:"Your current plan does not use Stripe billing."});return}await O();return}if(e.pricingType==="free"){await N(e.planVersionId,e.interval);return}await N(e.planVersionId,e.interval)},[r,y,O,N]),ne=a.useCallback(()=>{if(v){s();return}if(window.history.length>1){y(-1);return}y("/")},[s,v,y]),re=v?t.jsx(t.Fragment,{children:r&&p?.stripeCustomerId&&t.jsx("button",{className:n.navAction,onClick:()=>{O()},disabled:G,children:"Manage billing"})}):t.jsxs(t.Fragment,{children:[t.jsx("button",{className:n.navAction,onClick:ne,children:"Back"}),r&&p?.stripeCustomerId&&t.jsx("button",{className:n.navAction,onClick:()=>{O()},disabled:G,children:"Manage billing"}),!r&&t.jsxs("button",{className:n.navAction,onClick:()=>y(`/login?mode=login&next=${encodeURIComponent(oe())}`),children:[t.jsx(ve,{size:16,style:{marginRight:"8px",verticalAlign:"text-bottom"}}),"Sign In"]})]}),fe=v?null:t.jsx(_e,{projectName:U,currentWorkspaceId:se,runtimeMode:m==="cloud"?"cloud":"local",theme:R,actions:re});return t.jsx(ht,{chrome:fe,heading:"Subscription Plans",subtitle:"Manage your subscription and explore available features. Your current plan is highlighted below.",isAuthenticated:r,authSessionResolved:f,currentPlanId:String(p?.planId||ee||"").trim()||null,currentPlanVersionId:String(p?.planVersionId||$||"").trim()||null,currentEntitlementState:String(p?.entitlementState||"").trim()||null,canManageCurrentPlan:!!p?.stripeCustomerId,pricingEndpoint:k[0],statusBanner:Z,onBack:ne,backLabel:v?"Back to Board":"Back to App",topActions:v?re:null,shellOwnsScroll:J,showPageBackButton:!v,fallbackPricingSource:te,onSelectPlan:b})}export{wt as PlansPage};
|