@devalok/shilp-sutra-karm 0.8.2 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/dist/_chunks/chat-panel.js +376 -0
  2. package/dist/_chunks/daily-brief.js +177 -0
  3. package/dist/_chunks/kanban-board.js +597 -0
  4. package/dist/_chunks/project-card.js +121 -0
  5. package/dist/_chunks/render-adjustment-type.js +3596 -0
  6. package/dist/{tasks → _chunks}/task-constants.js +3 -3
  7. package/dist/_chunks/task-detail-panel.js +1305 -0
  8. package/dist/_chunks/use-composed-ref.js +12 -0
  9. package/dist/_chunks/vendor.js +11491 -0
  10. package/dist/admin/index.js +37 -60
  11. package/dist/board/index.js +3 -5
  12. package/dist/chat/index.js +6 -10
  13. package/dist/client/index.js +4 -6
  14. package/dist/dashboard/index.js +3 -4
  15. package/dist/index.js +189 -103
  16. package/dist/tasks/index.js +8 -14
  17. package/package.json +78 -80
  18. package/dist/admin/adjustments/approved-adjustments.js +0 -43
  19. package/dist/admin/break/break-admin-skeleton.js +0 -59
  20. package/dist/admin/break/break-admin.js +0 -373
  21. package/dist/admin/break/break-balance.js +0 -42
  22. package/dist/admin/break/breaks.js +0 -91
  23. package/dist/admin/break/delete-break.js +0 -55
  24. package/dist/admin/break/edit-break-balance.js +0 -113
  25. package/dist/admin/break/edit-break.js +0 -453
  26. package/dist/admin/break/header.js +0 -231
  27. package/dist/admin/break/leave-request.js +0 -162
  28. package/dist/admin/break/use-break-date-picker.js +0 -43
  29. package/dist/admin/dashboard/admin-dashboard.js +0 -337
  30. package/dist/admin/dashboard/associate-detail.js +0 -259
  31. package/dist/admin/dashboard/attendance-overview.js +0 -136
  32. package/dist/admin/dashboard/break-request.js +0 -176
  33. package/dist/admin/dashboard/calendar.js +0 -141
  34. package/dist/admin/dashboard/correction-list.js +0 -102
  35. package/dist/admin/dashboard/dashboard-header.js +0 -155
  36. package/dist/admin/dashboard/dashboard-skeleton.js +0 -109
  37. package/dist/admin/dashboard/leave-requests.js +0 -201
  38. package/dist/admin/dashboard/render-date.js +0 -144
  39. package/dist/admin/dashboard/use-calendar-navigation.js +0 -169
  40. package/dist/admin/dashboard/use-leave-request-interaction.js +0 -34
  41. package/dist/admin/utils/date-range-utils.js +0 -37
  42. package/dist/admin/utils/date-utils.js +0 -119
  43. package/dist/admin/utils/emoji-utils.js +0 -17
  44. package/dist/admin/utils/render-adjustment-type.js +0 -20
  45. package/dist/admin/utils/render-status.js +0 -22
  46. package/dist/board/board-column.js +0 -236
  47. package/dist/board/kanban-board.js +0 -218
  48. package/dist/board/task-card.js +0 -168
  49. package/dist/chat/chat-input.js +0 -54
  50. package/dist/chat/chat-panel.js +0 -151
  51. package/dist/chat/conversation-list.js +0 -99
  52. package/dist/chat/markdown-components.js +0 -35
  53. package/dist/chat/message-list.js +0 -59
  54. package/dist/chat/streaming-text.js +0 -17
  55. package/dist/client/accent-provider.js +0 -22
  56. package/dist/client/client-portal-header.js +0 -48
  57. package/dist/client/project-card.js +0 -60
  58. package/dist/dashboard/attendance-cta.js +0 -115
  59. package/dist/dashboard/daily-brief.js +0 -68
  60. package/dist/page-skeletons.js +0 -130
  61. package/dist/tasks/activity-tab.js +0 -185
  62. package/dist/tasks/conversation-tab.js +0 -138
  63. package/dist/tasks/files-tab.js +0 -186
  64. package/dist/tasks/review-tab.js +0 -170
  65. package/dist/tasks/subtasks-tab.js +0 -154
  66. package/dist/tasks/task-detail-panel.js +0 -210
  67. package/dist/tasks/task-properties.js +0 -324
  68. package/dist/utils/use-composed-ref.js +0 -12
@@ -0,0 +1,1305 @@
1
+ "use client";
2
+ import { jsxs as s, jsx as t, Fragment as ue } from "react/jsx-runtime";
3
+ import * as p from "react";
4
+ import { cn as N } from "@devalok/shilp-sutra/ui/lib/utils";
5
+ import { Sheet as Ve, SheetContent as $e, SheetTitle as je } from "@devalok/shilp-sutra/ui/sheet";
6
+ import { VisuallyHidden as ke } from "@devalok/shilp-sutra/ui/visually-hidden";
7
+ import { Skeleton as P } from "@devalok/shilp-sutra/ui/skeleton";
8
+ import { Progress as Be, Tabs as Fe, TabsList as ze, TabsTrigger as He } from "@devalok/shilp-sutra/ui";
9
+ import { Avatar as _, AvatarImage as V, AvatarFallback as $ } from "@devalok/shilp-sutra/ui/avatar";
10
+ import { Popover as ie, PopoverTrigger as ae, PopoverContent as le } from "@devalok/shilp-sutra/ui/popover";
11
+ import { IconColumns3 as Ye, IconChevronDown as qe, IconCheck as pe, IconUser as Me, IconUsers as Ge, IconX as G, IconPlus as j, IconFlag as he, IconCalendarEvent as xe, IconTag as fe, IconEye as be, IconSquareCheck as Ke, IconSquare as Je, IconListCheck as ge, IconMessage as Ne, IconGitPullRequest as X, IconMessageCircle as ye, IconSend as We, IconUpload as Qe, IconDownload as Xe, IconTrash as Ze, IconPaperclip as Z, IconFile as oe, IconPhoto as Ue, IconFileText as et, IconFileCode as tt, IconFileSpreadsheet as st, IconFileZip as rt, IconActivity as U, IconCircleCheck as nt, IconUserMinus as it, IconUserPlus as at, IconArrowRight as lt, IconEdit as ot } from "@tabler/icons-react";
12
+ import { getInitials as k } from "@devalok/shilp-sutra/composed/lib/string-utils";
13
+ import { MemberPicker as Q } from "@devalok/shilp-sutra/composed/member-picker";
14
+ import { a as ve, P as dt, R as ct } from "./task-constants.js";
15
+ import { EmptyState as B } from "@devalok/shilp-sutra/composed/empty-state";
16
+ import { Badge as mt } from "@devalok/shilp-sutra/ui/badge";
17
+ import { RichTextViewer as ut, RichTextEditor as pt } from "@devalok/shilp-sutra/composed/rich-text-editor";
18
+ import { Dialog as ht, DialogTrigger as xt, DialogContent as ft, DialogHeader as bt, DialogTitle as gt, DialogDescription as Nt, DialogFooter as yt, DialogClose as de } from "@devalok/shilp-sutra/ui/dialog";
19
+ import { Button as ce } from "@devalok/shilp-sutra/ui/button";
20
+ const vt = ["LOW", "MEDIUM", "HIGH", "URGENT"];
21
+ function L({
22
+ icon: n,
23
+ label: e,
24
+ children: b,
25
+ className: x
26
+ }) {
27
+ return /* @__PURE__ */ s(
28
+ "div",
29
+ {
30
+ className: N(
31
+ "flex items-center gap-ds-04 py-ds-03",
32
+ x
33
+ ),
34
+ children: [
35
+ /* @__PURE__ */ s("div", { className: "flex w-[120px] shrink-0 items-center gap-ds-03 text-text-placeholder", children: [
36
+ /* @__PURE__ */ t(n, { className: "h-ico-sm w-ico-sm", stroke: 1.5 }),
37
+ /* @__PURE__ */ t("span", { className: "text-ds-sm", children: e })
38
+ ] }),
39
+ /* @__PURE__ */ t("div", { className: "flex-1 min-w-0", children: b })
40
+ ]
41
+ }
42
+ );
43
+ }
44
+ function wt({ priority: n }) {
45
+ return /* @__PURE__ */ s("div", { className: "flex items-center gap-ds-02b", children: [
46
+ /* @__PURE__ */ t("div", { className: N("h-2 w-2 rounded-ds-full", ve[n]) }),
47
+ /* @__PURE__ */ t("span", { className: "text-ds-md text-text-primary", children: dt[n] || n })
48
+ ] });
49
+ }
50
+ const we = p.forwardRef(
51
+ function({
52
+ task: e,
53
+ columns: b,
54
+ members: x,
55
+ onUpdate: d,
56
+ onAssign: c,
57
+ onUnassign: g,
58
+ className: D,
59
+ readOnly: f = !1,
60
+ editableFields: m,
61
+ renderPriorityIndicator: y,
62
+ renderDatePicker: v,
63
+ onConfirmVisibilityChange: w
64
+ }, l) {
65
+ const [I, o] = p.useState(""), [i, h] = p.useState(!1), u = e.assignees.map((r) => r.user.id), C = p.useMemo(
66
+ () => x.map((r) => ({ id: r.id, name: r.name, avatar: r.image ?? void 0 })),
67
+ [x]
68
+ ), T = (r) => {
69
+ d("columnId", r);
70
+ }, A = (r) => {
71
+ d("ownerId", r === e.ownerId ? null : r);
72
+ }, S = (r) => {
73
+ u.includes(r) ? g(r) : c(r);
74
+ }, E = (r) => {
75
+ d("priority", r);
76
+ }, O = (r) => {
77
+ d("dueDate", r ? r.toISOString() : null);
78
+ }, F = () => {
79
+ const r = I.trim();
80
+ r && !e.labels.includes(r) && d("labels", [...e.labels, r]), o(""), h(!1);
81
+ }, K = (r) => {
82
+ d("labels", e.labels.filter((H) => H !== r));
83
+ }, J = () => {
84
+ const r = e.visibility === "INTERNAL" ? "EVERYONE" : "INTERNAL";
85
+ if (r === "EVERYONE" && w) {
86
+ w();
87
+ return;
88
+ }
89
+ d("visibility", r);
90
+ }, z = y || wt;
91
+ return /* @__PURE__ */ s("div", { ref: l, className: N("space-y-ds-01", D), children: [
92
+ /* @__PURE__ */ t(L, { icon: Ye, label: "Column", children: f && !(m != null && m.includes("columnId")) ? /* @__PURE__ */ t("span", { className: "px-ds-03 py-ds-02 text-ds-md text-text-primary", children: e.column.name }) : /* @__PURE__ */ s(ie, { children: [
93
+ /* @__PURE__ */ t(ae, { asChild: !0, children: /* @__PURE__ */ s(
94
+ "button",
95
+ {
96
+ type: "button",
97
+ className: "inline-flex items-center gap-ds-02b rounded-ds-md px-ds-03 py-ds-02 text-ds-md text-text-primary transition-colors hover:bg-field",
98
+ children: [
99
+ /* @__PURE__ */ t("span", { children: e.column.name }),
100
+ /* @__PURE__ */ t(qe, { className: "h-3 w-3 text-text-placeholder" })
101
+ ]
102
+ }
103
+ ) }),
104
+ /* @__PURE__ */ t(
105
+ le,
106
+ {
107
+ className: "w-[180px] border-border bg-layer-01 p-ds-02",
108
+ align: "start",
109
+ sideOffset: 4,
110
+ children: b.map((r) => /* @__PURE__ */ s(
111
+ "button",
112
+ {
113
+ type: "button",
114
+ onClick: () => T(r.id),
115
+ className: N(
116
+ "flex w-full items-center gap-ds-03 rounded-ds-md px-ds-03 py-ds-02b text-left text-ds-md transition-colors",
117
+ "hover:bg-field",
118
+ r.id === e.columnId ? "text-interactive" : "text-text-primary"
119
+ ),
120
+ children: [
121
+ r.name,
122
+ r.id === e.columnId && /* @__PURE__ */ t(pe, { className: "ml-auto h-ico-sm w-ico-sm" })
123
+ ]
124
+ },
125
+ r.id
126
+ ))
127
+ }
128
+ )
129
+ ] }) }),
130
+ !f && /* @__PURE__ */ t(L, { icon: Me, label: "Owner", children: /* @__PURE__ */ t(
131
+ Q,
132
+ {
133
+ members: C,
134
+ selectedIds: e.ownerId ? [e.ownerId] : [],
135
+ onSelect: A,
136
+ children: /* @__PURE__ */ t(
137
+ "button",
138
+ {
139
+ type: "button",
140
+ className: "inline-flex items-center gap-ds-03 rounded-ds-md px-ds-03 py-ds-02 transition-colors hover:bg-field",
141
+ children: e.owner ? /* @__PURE__ */ s(ue, { children: [
142
+ /* @__PURE__ */ s(_, { className: "h-ico-md w-ico-md", children: [
143
+ e.owner.image && /* @__PURE__ */ t(V, { src: e.owner.image, alt: e.owner.name }),
144
+ /* @__PURE__ */ t($, { className: "bg-layer-03 text-ds-xs font-semibold text-text-on-color", children: k(e.owner.name) })
145
+ ] }),
146
+ /* @__PURE__ */ t("span", { className: "text-ds-md text-text-primary", children: e.owner.name })
147
+ ] }) : /* @__PURE__ */ t("span", { className: "text-ds-md text-text-placeholder", children: "No owner" })
148
+ }
149
+ )
150
+ }
151
+ ) }),
152
+ /* @__PURE__ */ t(L, { icon: Ge, label: "Assignees", children: /* @__PURE__ */ s("div", { className: "flex flex-wrap items-center gap-ds-02b", children: [
153
+ e.assignees.map((r) => /* @__PURE__ */ s(
154
+ "div",
155
+ {
156
+ className: "inline-flex items-center gap-ds-02 rounded-ds-full bg-layer-02 py-ds-01 pl-ds-01 pr-ds-03",
157
+ children: [
158
+ /* @__PURE__ */ s(_, { className: "h-ico-sm w-ico-sm", children: [
159
+ r.user.image && /* @__PURE__ */ t(V, { src: r.user.image, alt: r.user.name }),
160
+ /* @__PURE__ */ t($, { className: "bg-layer-03 text-ds-xs font-semibold text-text-on-color", children: k(r.user.name) })
161
+ ] }),
162
+ /* @__PURE__ */ t("span", { className: "text-ds-sm text-text-secondary", children: r.user.name.split(" ")[0] }),
163
+ !f && /* @__PURE__ */ t(
164
+ "button",
165
+ {
166
+ type: "button",
167
+ onClick: () => g(r.user.id),
168
+ className: "ml-ds-01 rounded-ds-full p-ds-01 transition-colors hover:bg-field",
169
+ "aria-label": `Remove ${r.user.name}`,
170
+ children: /* @__PURE__ */ t(G, { className: "h-ds-03 w-ds-03 text-text-placeholder" })
171
+ }
172
+ )
173
+ ]
174
+ },
175
+ r.user.id
176
+ )),
177
+ !f && /* @__PURE__ */ t(
178
+ Q,
179
+ {
180
+ members: C,
181
+ selectedIds: u,
182
+ onSelect: S,
183
+ multiple: !0,
184
+ children: /* @__PURE__ */ t(
185
+ "button",
186
+ {
187
+ type: "button",
188
+ className: "inline-flex h-ico-md w-ico-md items-center justify-center rounded-ds-full border border-dashed border-border-subtle transition-colors hover:bg-field hover:border-text-placeholder",
189
+ "aria-label": "Add assignee",
190
+ children: /* @__PURE__ */ t(j, { className: "h-3 w-3 text-text-placeholder" })
191
+ }
192
+ )
193
+ }
194
+ ),
195
+ f && e.assignees.length === 0 && /* @__PURE__ */ t("span", { className: "text-ds-md text-text-placeholder", children: "None" })
196
+ ] }) }),
197
+ /* @__PURE__ */ t(L, { icon: he, label: "Priority", children: /* @__PURE__ */ s(ie, { children: [
198
+ /* @__PURE__ */ t(ae, { asChild: !0, children: /* @__PURE__ */ t(
199
+ "button",
200
+ {
201
+ type: "button",
202
+ className: "rounded-ds-md px-ds-03 py-ds-02 transition-colors hover:bg-field",
203
+ children: /* @__PURE__ */ t(z, { priority: e.priority })
204
+ }
205
+ ) }),
206
+ /* @__PURE__ */ t(
207
+ le,
208
+ {
209
+ className: "w-[160px] border-border bg-layer-01 p-ds-02",
210
+ align: "start",
211
+ sideOffset: 4,
212
+ children: vt.map((r) => /* @__PURE__ */ t(
213
+ "button",
214
+ {
215
+ type: "button",
216
+ onClick: () => E(r),
217
+ className: N(
218
+ "flex w-full items-center gap-ds-03 rounded-ds-md px-ds-03 py-ds-02b transition-colors",
219
+ "hover:bg-field",
220
+ r === e.priority && "bg-field"
221
+ ),
222
+ children: /* @__PURE__ */ t(z, { priority: r })
223
+ },
224
+ r
225
+ ))
226
+ }
227
+ )
228
+ ] }) }),
229
+ /* @__PURE__ */ t(L, { icon: xe, label: "Due Date", children: /* @__PURE__ */ s("div", { className: "flex items-center gap-ds-02", children: [
230
+ v ? v({
231
+ value: e.dueDate ? new Date(e.dueDate) : null,
232
+ onChange: O,
233
+ placeholder: "No due date",
234
+ className: "h-ds-xs-plus border-none bg-transparent px-ds-03 text-ds-md hover:bg-field"
235
+ }) : /* @__PURE__ */ t(
236
+ "input",
237
+ {
238
+ type: "date",
239
+ value: e.dueDate ? new Date(e.dueDate).toISOString().split("T")[0] : "",
240
+ onChange: (r) => O(r.target.value ? new Date(r.target.value) : null),
241
+ "aria-label": "Due date",
242
+ className: "h-ds-xs-plus border-none bg-transparent px-ds-03 text-ds-md text-text-primary outline-none hover:bg-field rounded-ds-md"
243
+ }
244
+ ),
245
+ e.dueDate && /* @__PURE__ */ t(
246
+ "button",
247
+ {
248
+ type: "button",
249
+ onClick: () => O(null),
250
+ className: "rounded-ds-md p-ds-02 transition-colors hover:bg-field",
251
+ "aria-label": "Clear due date",
252
+ children: /* @__PURE__ */ t(G, { className: "h-3 w-3 text-text-placeholder" })
253
+ }
254
+ )
255
+ ] }) }),
256
+ /* @__PURE__ */ t(L, { icon: fe, label: "Labels", children: /* @__PURE__ */ s("div", { className: "flex flex-wrap items-center gap-ds-02b", children: [
257
+ e.labels.map((r) => /* @__PURE__ */ s(
258
+ "span",
259
+ {
260
+ className: "inline-flex items-center gap-ds-02 rounded-ds-full bg-interactive/10 px-ds-03 py-ds-01 text-ds-sm font-medium text-interactive",
261
+ children: [
262
+ r,
263
+ !f && /* @__PURE__ */ t(
264
+ "button",
265
+ {
266
+ type: "button",
267
+ onClick: () => K(r),
268
+ className: "rounded-ds-full p-ds-01 transition-colors hover:bg-field",
269
+ "aria-label": `Remove label ${r}`,
270
+ children: /* @__PURE__ */ t(G, { className: "h-ds-03 w-ds-03" })
271
+ }
272
+ )
273
+ ]
274
+ },
275
+ r
276
+ )),
277
+ !f && (i ? /* @__PURE__ */ t("div", { className: "inline-flex items-center gap-ds-02", children: /* @__PURE__ */ t(
278
+ "input",
279
+ {
280
+ type: "text",
281
+ value: I,
282
+ onChange: (r) => o(r.target.value),
283
+ "aria-label": "New label name",
284
+ onKeyDown: (r) => {
285
+ r.key === "Enter" && F(), r.key === "Escape" && (h(!1), o(""));
286
+ },
287
+ onBlur: F,
288
+ placeholder: "Label name",
289
+ className: "h-5 w-20 rounded border border-border bg-transparent px-ds-02b text-ds-sm text-text-primary outline-none placeholder:text-text-placeholder focus:border-border-subtle",
290
+ autoFocus: !0
291
+ }
292
+ ) }) : /* @__PURE__ */ t(
293
+ "button",
294
+ {
295
+ type: "button",
296
+ onClick: () => h(!0),
297
+ className: "inline-flex h-ico-md w-ico-md items-center justify-center rounded-ds-full border border-dashed border-border-subtle transition-colors hover:bg-field hover:border-text-placeholder",
298
+ "aria-label": "Add label",
299
+ children: /* @__PURE__ */ t(j, { className: "h-3 w-3 text-text-placeholder" })
300
+ }
301
+ )),
302
+ f && e.labels.length === 0 && /* @__PURE__ */ t("span", { className: "text-ds-md text-text-placeholder", children: "None" })
303
+ ] }) }),
304
+ !f && /* @__PURE__ */ t(L, { icon: be, label: "Visibility", children: /* @__PURE__ */ s(
305
+ "button",
306
+ {
307
+ type: "button",
308
+ onClick: J,
309
+ className: N(
310
+ "inline-flex items-center gap-ds-02b rounded-ds-full px-ds-03 py-ds-01 text-ds-sm font-semibold tracking-wide transition-colors",
311
+ e.visibility === "EVERYONE" ? "bg-success-surface text-text-success" : "bg-layer-02 text-text-tertiary"
312
+ ),
313
+ children: [
314
+ /* @__PURE__ */ t(
315
+ "span",
316
+ {
317
+ className: N(
318
+ "h-ds-02b w-ds-02b rounded-ds-full",
319
+ e.visibility === "EVERYONE" ? "bg-success" : "bg-icon-disabled"
320
+ )
321
+ }
322
+ ),
323
+ e.visibility === "EVERYONE" ? "Everyone" : "Internal"
324
+ ]
325
+ }
326
+ ) })
327
+ ] });
328
+ }
329
+ );
330
+ we.displayName = "TaskProperties";
331
+ const Ie = p.forwardRef(
332
+ function({
333
+ subtasks: e,
334
+ terminalColumnId: b,
335
+ onCreateSubtask: x,
336
+ onToggleSubtask: d,
337
+ onClickSubtask: c,
338
+ className: g,
339
+ readOnly: D = !1
340
+ }, f) {
341
+ const [m, y] = p.useState(""), [v, w] = p.useState(!1), l = p.useRef(null), I = e.filter(
342
+ (u) => {
343
+ var C;
344
+ return ((C = u.column) == null ? void 0 : C.isTerminal) || u.columnId === b;
345
+ }
346
+ ).length, o = e.length, i = () => {
347
+ const u = m.trim();
348
+ u && (x(u), y(""));
349
+ }, h = (u) => {
350
+ u.key === "Enter" && (u.preventDefault(), i()), u.key === "Escape" && (w(!1), y(""));
351
+ };
352
+ return p.useEffect(() => {
353
+ v && l.current && l.current.focus();
354
+ }, [v]), /* @__PURE__ */ s("div", { ref: f, className: N("flex flex-col", g), children: [
355
+ o > 0 && /* @__PURE__ */ s("div", { className: "mb-ds-05 flex items-center gap-ds-04", children: [
356
+ /* @__PURE__ */ t(Be, { value: o > 0 ? I / o * 100 : 0, className: "h-ds-02b" }),
357
+ /* @__PURE__ */ s("span", { className: "shrink-0 text-ds-sm font-medium text-text-placeholder", children: [
358
+ I,
359
+ "/",
360
+ o
361
+ ] })
362
+ ] }),
363
+ e.length > 0 ? /* @__PURE__ */ t("div", { className: "space-y-ds-01", children: e.map((u) => {
364
+ var A, S;
365
+ const C = ((A = u.column) == null ? void 0 : A.isTerminal) || u.columnId === b, T = (S = u.assignees[0]) == null ? void 0 : S.user;
366
+ return /* @__PURE__ */ s(
367
+ "div",
368
+ {
369
+ role: "button",
370
+ tabIndex: 0,
371
+ className: N(
372
+ "group flex items-center gap-ds-03 rounded-ds-lg px-ds-03 py-ds-02b transition-colors",
373
+ "hover:bg-field cursor-pointer"
374
+ ),
375
+ onClick: () => c == null ? void 0 : c(u.id),
376
+ onKeyDown: (E) => {
377
+ (E.key === "Enter" || E.key === " ") && (E.preventDefault(), c == null || c(u.id));
378
+ },
379
+ children: [
380
+ /* @__PURE__ */ t(
381
+ "button",
382
+ {
383
+ type: "button",
384
+ onClick: (E) => {
385
+ E.stopPropagation(), D || d(u.id, !C);
386
+ },
387
+ className: N(
388
+ "shrink-0 rounded p-ds-01 transition-colors",
389
+ D ? "cursor-default" : "hover:bg-layer-02"
390
+ ),
391
+ children: C ? /* @__PURE__ */ t(Ke, { className: "h-ico-sm w-ico-sm text-interactive", stroke: 1.5 }) : /* @__PURE__ */ t(Je, { className: "h-ico-sm w-ico-sm text-text-placeholder", stroke: 1.5 })
392
+ }
393
+ ),
394
+ /* @__PURE__ */ t(
395
+ "div",
396
+ {
397
+ className: N(
398
+ "h-2 w-2 shrink-0 rounded-ds-full",
399
+ ve[u.priority]
400
+ )
401
+ }
402
+ ),
403
+ /* @__PURE__ */ t(
404
+ "span",
405
+ {
406
+ className: N(
407
+ "flex-1 truncate text-ds-md",
408
+ C ? "text-text-placeholder line-through" : "text-text-primary"
409
+ ),
410
+ children: u.title
411
+ }
412
+ ),
413
+ T && /* @__PURE__ */ s(_, { className: "h-ico-md w-ico-md shrink-0", children: [
414
+ T.image && /* @__PURE__ */ t(V, { src: T.image, alt: T.name }),
415
+ /* @__PURE__ */ t($, { className: "bg-layer-03 text-ds-xs font-semibold text-text-on-color", children: k(T.name) })
416
+ ] })
417
+ ]
418
+ },
419
+ u.id
420
+ );
421
+ }) }) : !v && /* @__PURE__ */ t(
422
+ B,
423
+ {
424
+ icon: /* @__PURE__ */ t(ge, {}),
425
+ title: "No subtasks",
426
+ description: "Break this task into smaller pieces",
427
+ compact: !0
428
+ }
429
+ ),
430
+ !D && (v ? /* @__PURE__ */ s("div", { className: "mt-ds-03 flex items-center gap-ds-03 rounded-ds-lg border border-border bg-layer-01 shadow-01 px-ds-04 py-ds-03", children: [
431
+ /* @__PURE__ */ t(
432
+ "input",
433
+ {
434
+ ref: l,
435
+ type: "text",
436
+ value: m,
437
+ onChange: (u) => y(u.target.value),
438
+ onKeyDown: h,
439
+ onBlur: () => {
440
+ m.trim() || w(!1);
441
+ },
442
+ placeholder: "Subtask title...",
443
+ className: "flex-1 bg-transparent text-ds-md text-text-primary placeholder:text-text-placeholder outline-none"
444
+ }
445
+ ),
446
+ /* @__PURE__ */ t(
447
+ "button",
448
+ {
449
+ type: "button",
450
+ onClick: i,
451
+ disabled: !m.trim(),
452
+ className: "inline-flex h-6 items-center gap-ds-02 rounded-ds-md bg-interactive px-ds-03 text-ds-sm font-semibold text-text-on-color transition-colors hover:bg-interactive-hover disabled:opacity-[0.38]",
453
+ children: "Add"
454
+ }
455
+ )
456
+ ] }) : /* @__PURE__ */ s(
457
+ "button",
458
+ {
459
+ type: "button",
460
+ onClick: () => w(!0),
461
+ className: "mt-ds-03 inline-flex items-center gap-ds-02b rounded-ds-lg px-ds-03 py-ds-02b text-ds-md text-text-placeholder transition-colors hover:bg-field hover:text-text-secondary",
462
+ children: [
463
+ /* @__PURE__ */ t(j, { className: "h-ico-sm w-ico-sm", stroke: 1.5 }),
464
+ "Add subtask"
465
+ ]
466
+ }
467
+ ))
468
+ ] });
469
+ }
470
+ );
471
+ Ie.displayName = "SubtasksTab";
472
+ function It(n) {
473
+ return new Date(n).toLocaleDateString("en-IN", {
474
+ month: "short",
475
+ day: "numeric",
476
+ hour: "numeric",
477
+ minute: "2-digit"
478
+ });
479
+ }
480
+ const Dt = [
481
+ { status: "APPROVED", label: "Approve", icon: pe },
482
+ { status: "CHANGES_REQUESTED", label: "Request Changes", icon: Ne },
483
+ { status: "REJECTED", label: "Reject", icon: G }
484
+ ], De = p.forwardRef(
485
+ function({
486
+ reviews: e,
487
+ members: b,
488
+ onRequestReview: x,
489
+ onUpdateStatus: d,
490
+ className: c
491
+ }, g) {
492
+ const [D, f] = p.useState({}), [m, y] = p.useState(null), v = p.useMemo(
493
+ () => b.map((l) => ({ id: l.id, name: l.name, avatar: l.image ?? void 0 })),
494
+ [b]
495
+ ), w = (l, I) => {
496
+ d(l, I, D[l]), f((o) => {
497
+ const i = { ...o };
498
+ return delete i[l], i;
499
+ }), y(null);
500
+ };
501
+ return /* @__PURE__ */ s("div", { ref: g, className: N("flex flex-col", c), children: [
502
+ e.length > 0 ? /* @__PURE__ */ t("div", { className: "space-y-ds-04", children: e.map((l) => {
503
+ const I = ct[l.status], o = m === l.id;
504
+ return /* @__PURE__ */ s(
505
+ "div",
506
+ {
507
+ className: "rounded-ds-lg border border-border bg-layer-01 shadow-01 p-ds-04",
508
+ children: [
509
+ /* @__PURE__ */ s("div", { className: "flex items-center gap-ds-03", children: [
510
+ /* @__PURE__ */ s(_, { className: "h-ds-xs w-ds-xs shrink-0", children: [
511
+ l.reviewer.image && /* @__PURE__ */ t(
512
+ V,
513
+ {
514
+ src: l.reviewer.image,
515
+ alt: l.reviewer.name
516
+ }
517
+ ),
518
+ /* @__PURE__ */ t($, { className: "bg-layer-03 text-ds-xs font-semibold text-text-on-color", children: k(l.reviewer.name) })
519
+ ] }),
520
+ /* @__PURE__ */ s("div", { className: "flex-1 min-w-0", children: [
521
+ /* @__PURE__ */ t("span", { className: "text-ds-md font-medium text-text-primary", children: l.reviewer.name }),
522
+ /* @__PURE__ */ s("span", { className: "ml-ds-03 text-ds-sm text-text-placeholder", children: [
523
+ "requested by ",
524
+ l.requestedBy.name
525
+ ] })
526
+ ] }),
527
+ /* @__PURE__ */ t(
528
+ mt,
529
+ {
530
+ color: I.color,
531
+ children: I.label
532
+ }
533
+ )
534
+ ] }),
535
+ l.feedback && /* @__PURE__ */ t("div", { className: "mt-ds-03 rounded-ds-md bg-layer-02 px-ds-04 py-ds-03", children: /* @__PURE__ */ t("p", { className: "text-ds-sm text-text-secondary", children: l.feedback }) }),
536
+ l.status === "PENDING" && /* @__PURE__ */ t("div", { className: "mt-ds-03", children: o ? /* @__PURE__ */ s("div", { className: "space-y-ds-03", children: [
537
+ /* @__PURE__ */ t(
538
+ "textarea",
539
+ {
540
+ value: D[l.id] || "",
541
+ onChange: (i) => f((h) => ({
542
+ ...h,
543
+ [l.id]: i.target.value
544
+ })),
545
+ placeholder: "Add feedback (optional)...",
546
+ rows: 2,
547
+ className: "w-full resize-none rounded-ds-md border border-border bg-transparent px-ds-03 py-ds-03 text-ds-sm text-text-primary placeholder:text-text-placeholder outline-none focus:border-border-subtle"
548
+ }
549
+ ),
550
+ /* @__PURE__ */ s("div", { className: "flex items-center gap-ds-02b", children: [
551
+ Dt.map((i) => {
552
+ const h = i.icon;
553
+ return /* @__PURE__ */ s(
554
+ "button",
555
+ {
556
+ type: "button",
557
+ onClick: () => w(l.id, i.status),
558
+ className: N(
559
+ "inline-flex items-center gap-ds-02 rounded-ds-md px-ds-03 py-ds-02 text-ds-sm font-semibold transition-colors",
560
+ i.status === "APPROVED" && "bg-success-surface text-text-success hover:opacity-[0.9]",
561
+ i.status === "CHANGES_REQUESTED" && "bg-warning-surface text-text-warning hover:opacity-[0.9]",
562
+ i.status === "REJECTED" && "bg-error-surface text-text-error hover:opacity-[0.9]"
563
+ ),
564
+ children: [
565
+ /* @__PURE__ */ t(h, { className: "h-3 w-3", stroke: 2 }),
566
+ i.label
567
+ ]
568
+ },
569
+ i.status
570
+ );
571
+ }),
572
+ /* @__PURE__ */ t(
573
+ "button",
574
+ {
575
+ type: "button",
576
+ onClick: () => y(null),
577
+ className: "ml-auto text-ds-sm text-text-placeholder hover:text-text-secondary",
578
+ children: "Cancel"
579
+ }
580
+ )
581
+ ] })
582
+ ] }) : /* @__PURE__ */ t(
583
+ "button",
584
+ {
585
+ type: "button",
586
+ onClick: () => y(l.id),
587
+ className: "text-ds-sm font-medium text-interactive transition-colors hover:underline",
588
+ children: "Respond"
589
+ }
590
+ ) }),
591
+ /* @__PURE__ */ t("p", { className: "mt-ds-03 text-ds-xs text-text-placeholder", children: It(l.createdAt) })
592
+ ]
593
+ },
594
+ l.id
595
+ );
596
+ }) }) : /* @__PURE__ */ t(
597
+ B,
598
+ {
599
+ icon: /* @__PURE__ */ t(X, {}),
600
+ title: "No reviews yet",
601
+ description: "Request a review from a team member",
602
+ compact: !0
603
+ }
604
+ ),
605
+ /* @__PURE__ */ t(
606
+ Q,
607
+ {
608
+ members: v,
609
+ selectedIds: [],
610
+ onSelect: (l) => x(l),
611
+ children: /* @__PURE__ */ s(
612
+ "button",
613
+ {
614
+ type: "button",
615
+ className: "mt-ds-04 inline-flex items-center gap-ds-02b rounded-ds-lg px-ds-03 py-ds-02b text-ds-md text-text-placeholder transition-colors hover:bg-field hover:text-text-secondary",
616
+ children: [
617
+ /* @__PURE__ */ t(j, { className: "h-ico-sm w-ico-sm", stroke: 1.5 }),
618
+ "Request Review"
619
+ ]
620
+ }
621
+ )
622
+ }
623
+ )
624
+ ] });
625
+ }
626
+ );
627
+ De.displayName = "ReviewTab";
628
+ function Ct(n) {
629
+ const e = new Date(n), x = (/* @__PURE__ */ new Date()).getTime() - e.getTime(), d = Math.floor(x / 6e4), c = Math.floor(d / 60), g = Math.floor(c / 24);
630
+ return d < 1 ? "Just now" : d < 60 ? `${d}m ago` : c < 24 ? `${c}h ago` : g < 7 ? `${g}d ago` : e.toLocaleDateString("en-IN", {
631
+ month: "short",
632
+ day: "numeric",
633
+ hour: "numeric",
634
+ minute: "2-digit"
635
+ });
636
+ }
637
+ function Tt(n) {
638
+ return n.authorType === "INTERNAL" && n.internalAuthor ? n.internalAuthor : n.authorType === "CLIENT" && n.clientAuthor ? {
639
+ id: n.clientAuthor.id,
640
+ name: n.clientAuthor.name,
641
+ email: n.clientAuthor.email,
642
+ image: null
643
+ } : { id: n.authorId, name: "Unknown", image: null };
644
+ }
645
+ function Et(n) {
646
+ return n.replace(/<[^>]*>/g, "");
647
+ }
648
+ const Ce = p.forwardRef(
649
+ function({
650
+ comments: e,
651
+ taskVisibility: b,
652
+ onPostComment: x,
653
+ className: d,
654
+ clientMode: c = !1,
655
+ richText: g = !1,
656
+ renderEditor: D,
657
+ renderViewer: f
658
+ }, m) {
659
+ const [y, v] = p.useState(""), w = p.useRef(null), l = D ?? (g ? (i) => /* @__PURE__ */ t(
660
+ pt,
661
+ {
662
+ content: i.content,
663
+ onChange: i.onChange,
664
+ placeholder: i.placeholder,
665
+ editable: !0,
666
+ className: "min-h-[80px]"
667
+ }
668
+ ) : void 0), I = f ?? (g ? (i) => /* @__PURE__ */ t(ut, { content: i.content, className: i.className }) : void 0), o = () => {
669
+ const i = y.trim();
670
+ i.replace(/<[^>]*>/g, "").trim() && (x(i, c ? "CLIENT" : "INTERNAL"), v(""));
671
+ };
672
+ return p.useEffect(() => {
673
+ w.current && (w.current.scrollTop = w.current.scrollHeight);
674
+ }, [e.length]), /* @__PURE__ */ s("div", { ref: m, className: N("flex flex-col", d), children: [
675
+ e.length > 0 ? /* @__PURE__ */ t(
676
+ "div",
677
+ {
678
+ ref: w,
679
+ className: "flex-1 space-y-ds-05 overflow-y-auto",
680
+ children: e.map((i) => {
681
+ const h = Tt(i), u = i.authorType === "CLIENT";
682
+ return /* @__PURE__ */ s("div", { className: "flex gap-ds-03", children: [
683
+ /* @__PURE__ */ s(_, { className: "h-ds-xs-plus w-ds-xs-plus shrink-0 mt-ds-01", children: [
684
+ h.image && /* @__PURE__ */ t(V, { src: h.image, alt: h.name }),
685
+ /* @__PURE__ */ t(
686
+ $,
687
+ {
688
+ className: N(
689
+ "text-ds-xs font-semibold",
690
+ /* avatar initials — below scale, leave as-is */
691
+ u ? "bg-warning-surface text-text-warning" : "bg-layer-03 text-text-on-color"
692
+ ),
693
+ children: k(h.name)
694
+ }
695
+ )
696
+ ] }),
697
+ /* @__PURE__ */ s("div", { className: "flex-1 min-w-0", children: [
698
+ /* @__PURE__ */ s("div", { className: "flex items-baseline gap-ds-03", children: [
699
+ /* @__PURE__ */ t("span", { className: "text-ds-md font-medium text-text-primary", children: h.name }),
700
+ c ? !u && /* @__PURE__ */ t("span", { className: "rounded bg-layer-03 px-ds-02 py-px text-ds-xs font-semibold uppercase tracking-wider text-text-on-color", children: "Team" }) : u && /* @__PURE__ */ t("span", { className: "rounded bg-warning-surface px-ds-02 py-px text-ds-xs font-semibold uppercase tracking-wider text-text-warning", children: "Client" }),
701
+ /* @__PURE__ */ t("span", { className: "text-ds-sm text-text-placeholder", children: Ct(i.createdAt) })
702
+ ] }),
703
+ /* @__PURE__ */ t("div", { className: "mt-ds-02", children: I ? I({
704
+ content: i.content,
705
+ className: "[&_.ProseMirror]:!min-h-0 [&_.ProseMirror]:!p-0"
706
+ }) : /* @__PURE__ */ t("p", { className: "text-ds-md text-text-secondary whitespace-pre-wrap", children: Et(i.content) }) })
707
+ ] })
708
+ ] }, i.id);
709
+ })
710
+ }
711
+ ) : /* @__PURE__ */ t(
712
+ B,
713
+ {
714
+ icon: /* @__PURE__ */ t(ye, {}),
715
+ title: "No comments yet",
716
+ description: "Start a conversation about this task",
717
+ compact: !0
718
+ }
719
+ ),
720
+ /* @__PURE__ */ s("div", { className: "mt-ds-05 space-y-ds-03", children: [
721
+ b === "EVERYONE" && !c && /* @__PURE__ */ t("p", { className: "text-ds-xs text-text-warning", children: "This task is visible to clients. Comments may be seen by external users." }),
722
+ l ? l({
723
+ content: y,
724
+ onChange: v,
725
+ placeholder: "Write a comment..."
726
+ }) : /* @__PURE__ */ t(
727
+ "textarea",
728
+ {
729
+ value: y,
730
+ onChange: (i) => v(i.target.value),
731
+ placeholder: "Write a comment...",
732
+ rows: 3,
733
+ className: "w-full resize-none rounded-ds-md border border-border bg-transparent px-ds-04 py-ds-03 text-ds-md text-text-primary placeholder:text-text-placeholder outline-none focus:border-border-subtle"
734
+ }
735
+ ),
736
+ /* @__PURE__ */ t("div", { className: "flex justify-end", children: /* @__PURE__ */ s(
737
+ "button",
738
+ {
739
+ type: "button",
740
+ onClick: o,
741
+ disabled: !y.replace(/<[^>]*>/g, "").trim(),
742
+ className: "inline-flex items-center gap-ds-02b rounded-ds-lg bg-interactive px-ds-04 py-ds-02b text-ds-sm font-semibold text-text-on-color transition-colors hover:bg-interactive-hover disabled:opacity-[0.38] disabled:cursor-not-allowed",
743
+ children: [
744
+ /* @__PURE__ */ t(We, { className: "h-ico-sm w-ico-sm", stroke: 2 }),
745
+ "Comment"
746
+ ]
747
+ }
748
+ ) })
749
+ ] })
750
+ ] });
751
+ }
752
+ );
753
+ Ce.displayName = "ConversationTab";
754
+ function Rt(n) {
755
+ if (!n) return oe;
756
+ const e = n.toLowerCase();
757
+ return ["jpg", "jpeg", "png", "gif", "svg", "webp", "bmp"].includes(e) ? Ue : ["pdf", "doc", "docx", "txt", "rtf"].includes(e) ? et : ["js", "ts", "jsx", "tsx", "py", "rb", "go", "rs", "html", "css", "json"].includes(e) ? tt : ["xls", "xlsx", "csv"].includes(e) ? st : ["zip", "tar", "gz", "rar", "7z"].includes(e) ? rt : oe;
758
+ }
759
+ function At(n) {
760
+ return new Date(n).toLocaleDateString("en-IN", {
761
+ month: "short",
762
+ day: "numeric",
763
+ year: "numeric"
764
+ });
765
+ }
766
+ const Te = p.forwardRef(
767
+ function({
768
+ files: e,
769
+ onUpload: b,
770
+ onDelete: x,
771
+ isUploading: d = !1,
772
+ className: c,
773
+ readOnly: g = !1
774
+ }, D) {
775
+ const f = p.useRef(null), [m, y] = p.useState(!1), v = (o) => {
776
+ var h;
777
+ const i = (h = o.target.files) == null ? void 0 : h[0];
778
+ i && b(i), f.current && (f.current.value = "");
779
+ }, w = (o) => {
780
+ var h;
781
+ o.preventDefault(), y(!1);
782
+ const i = (h = o.dataTransfer.files) == null ? void 0 : h[0];
783
+ i && b(i);
784
+ }, l = (o) => {
785
+ o.preventDefault(), y(!0);
786
+ }, I = () => {
787
+ y(!1);
788
+ };
789
+ return /* @__PURE__ */ s("div", { ref: D, className: N("flex flex-col", c), children: [
790
+ !g && /* @__PURE__ */ s(
791
+ "div",
792
+ {
793
+ role: "region",
794
+ "aria-label": "File upload drop zone",
795
+ onDrop: w,
796
+ onDragOver: l,
797
+ onDragLeave: I,
798
+ className: N(
799
+ "rounded-ds-lg border-2 border-dashed transition-colors",
800
+ m ? "border-interactive bg-interactive/5" : "border-border"
801
+ ),
802
+ children: [
803
+ /* @__PURE__ */ s("div", { className: "flex flex-col items-center gap-ds-03 py-ds-06", children: [
804
+ /* @__PURE__ */ t("div", { className: "flex h-ds-sm-plus w-ds-sm-plus items-center justify-center rounded-ds-lg bg-layer-02", children: /* @__PURE__ */ t(
805
+ Qe,
806
+ {
807
+ className: "h-ico-sm w-ico-sm text-text-placeholder",
808
+ stroke: 1.5
809
+ }
810
+ ) }),
811
+ /* @__PURE__ */ s("div", { className: "text-center", children: [
812
+ /* @__PURE__ */ t(
813
+ "button",
814
+ {
815
+ type: "button",
816
+ onClick: () => {
817
+ var o;
818
+ return (o = f.current) == null ? void 0 : o.click();
819
+ },
820
+ disabled: d,
821
+ className: "text-ds-md font-medium text-interactive transition-colors hover:underline disabled:opacity-[0.38]",
822
+ children: d ? "Uploading..." : "Click to upload"
823
+ }
824
+ ),
825
+ /* @__PURE__ */ s("span", { className: "text-ds-md text-text-placeholder", children: [
826
+ " ",
827
+ "or drag and drop"
828
+ ] })
829
+ ] })
830
+ ] }),
831
+ /* @__PURE__ */ t(
832
+ "input",
833
+ {
834
+ ref: f,
835
+ type: "file",
836
+ onChange: v,
837
+ className: "hidden"
838
+ }
839
+ )
840
+ ]
841
+ }
842
+ ),
843
+ e.length > 0 ? /* @__PURE__ */ t("div", { className: "mt-ds-05 space-y-ds-02", children: e.map((o) => {
844
+ const i = Rt(o.fileType);
845
+ return /* @__PURE__ */ s(
846
+ "div",
847
+ {
848
+ className: "group flex items-center gap-ds-04 rounded-ds-lg px-ds-03 py-ds-03 transition-colors hover:bg-field",
849
+ children: [
850
+ /* @__PURE__ */ t("div", { className: "flex h-ds-sm w-ds-sm shrink-0 items-center justify-center rounded-ds-lg bg-layer-02", children: /* @__PURE__ */ t(
851
+ i,
852
+ {
853
+ className: "h-ico-sm w-ico-sm text-text-tertiary",
854
+ stroke: 1.5
855
+ }
856
+ ) }),
857
+ /* @__PURE__ */ s("div", { className: "flex-1 min-w-0", children: [
858
+ /* @__PURE__ */ t("p", { className: "truncate text-ds-md font-medium text-text-primary", children: o.title }),
859
+ /* @__PURE__ */ s("p", { className: "text-ds-sm text-text-placeholder", children: [
860
+ At(o.createdAt),
861
+ /* @__PURE__ */ t("span", { className: "mx-ds-02b", children: "by" }),
862
+ o.uploadedBy.name
863
+ ] })
864
+ ] }),
865
+ /* @__PURE__ */ s("div", { className: "flex items-center gap-ds-02 opacity-0 transition-opacity group-hover:opacity-100", children: [
866
+ o.downloadUrl && /* @__PURE__ */ t(
867
+ "a",
868
+ {
869
+ href: /^https?:\/\//.test(o.downloadUrl) ? o.downloadUrl : "#",
870
+ target: "_blank",
871
+ rel: "noopener noreferrer",
872
+ className: "inline-flex h-ds-xs-plus w-ds-xs-plus items-center justify-center rounded-ds-md transition-colors hover:bg-layer-02",
873
+ title: "Download",
874
+ children: /* @__PURE__ */ t(Xe, { className: "h-ico-sm w-ico-sm text-text-tertiary" })
875
+ }
876
+ ),
877
+ !g && /* @__PURE__ */ s(ht, { children: [
878
+ /* @__PURE__ */ t(xt, { asChild: !0, children: /* @__PURE__ */ t(
879
+ "button",
880
+ {
881
+ type: "button",
882
+ className: "inline-flex h-ds-xs-plus w-ds-xs-plus items-center justify-center rounded-ds-md transition-colors hover:bg-error-surface",
883
+ title: "Delete",
884
+ children: /* @__PURE__ */ t(Ze, { className: "h-ico-sm w-ico-sm text-text-error" })
885
+ }
886
+ ) }),
887
+ /* @__PURE__ */ s(ft, { children: [
888
+ /* @__PURE__ */ s(bt, { children: [
889
+ /* @__PURE__ */ t(gt, { children: "Delete file?" }),
890
+ /* @__PURE__ */ s(Nt, { children: [
891
+ '"',
892
+ o.title,
893
+ '" will be permanently deleted. This cannot be undone.'
894
+ ] })
895
+ ] }),
896
+ /* @__PURE__ */ s(yt, { children: [
897
+ /* @__PURE__ */ t(de, { asChild: !0, children: /* @__PURE__ */ t(ce, { variant: "outline", size: "sm", children: "Cancel" }) }),
898
+ /* @__PURE__ */ t(de, { asChild: !0, children: /* @__PURE__ */ t(
899
+ ce,
900
+ {
901
+ variant: "solid",
902
+ color: "error",
903
+ size: "sm",
904
+ onClick: () => x(o.id),
905
+ children: "Delete"
906
+ }
907
+ ) })
908
+ ] })
909
+ ] })
910
+ ] })
911
+ ] })
912
+ ]
913
+ },
914
+ o.id
915
+ );
916
+ }) }) : /* @__PURE__ */ t("div", { className: "mt-ds-03", children: /* @__PURE__ */ t(
917
+ B,
918
+ {
919
+ icon: /* @__PURE__ */ t(Z, {}),
920
+ title: "No files attached",
921
+ description: "Upload files to share with your team",
922
+ compact: !0
923
+ }
924
+ ) })
925
+ ] });
926
+ }
927
+ );
928
+ Te.displayName = "FilesTab";
929
+ const St = {
930
+ "task.created": {
931
+ icon: j,
932
+ color: "text-success-text",
933
+ dotColor: "bg-success",
934
+ getDescription: () => "created this task"
935
+ },
936
+ "task.updated": {
937
+ icon: ot,
938
+ color: "text-category-slate-text",
939
+ dotColor: "bg-category-slate",
940
+ getDescription: (n) => {
941
+ const e = n.metadata;
942
+ return (e == null ? void 0 : e.field) === "title" ? "updated the title" : (e == null ? void 0 : e.field) === "description" ? "updated the description" : (e == null ? void 0 : e.field) === "priority" ? `changed priority to ${(e == null ? void 0 : e.newValue) || "unknown"}` : (e == null ? void 0 : e.field) === "dueDate" ? "updated the due date" : (e == null ? void 0 : e.field) === "labels" ? "updated labels" : "updated this task";
943
+ }
944
+ },
945
+ "task.moved": {
946
+ icon: lt,
947
+ color: "text-warning-text",
948
+ dotColor: "bg-warning",
949
+ getDescription: (n) => {
950
+ const e = n.metadata, b = (e == null ? void 0 : e.fromColumn) || "unknown", x = (e == null ? void 0 : e.toColumn) || "unknown";
951
+ return `moved from ${b} to ${x}`;
952
+ }
953
+ },
954
+ "task.assigned": {
955
+ icon: at,
956
+ color: "text-category-cyan-text",
957
+ dotColor: "bg-category-cyan",
958
+ getDescription: (n) => {
959
+ const e = n.metadata;
960
+ return `assigned ${(e == null ? void 0 : e.assigneeName) || "a user"}`;
961
+ }
962
+ },
963
+ "task.unassigned": {
964
+ icon: it,
965
+ color: "text-text-secondary",
966
+ dotColor: "bg-icon-disabled",
967
+ getDescription: (n) => {
968
+ const e = n.metadata;
969
+ return `removed ${(e == null ? void 0 : e.assigneeName) || "a user"}`;
970
+ }
971
+ },
972
+ "task.commented": {
973
+ icon: Ne,
974
+ color: "text-interactive",
975
+ dotColor: "bg-interactive",
976
+ getDescription: () => "added a comment"
977
+ },
978
+ "task.file_uploaded": {
979
+ icon: Z,
980
+ color: "text-category-indigo-text",
981
+ dotColor: "bg-category-indigo",
982
+ getDescription: (n) => {
983
+ const e = n.metadata;
984
+ return `uploaded ${(e == null ? void 0 : e.fileName) || "a file"}`;
985
+ }
986
+ },
987
+ "task.review_requested": {
988
+ icon: X,
989
+ color: "text-warning-text",
990
+ dotColor: "bg-warning",
991
+ getDescription: (n) => {
992
+ const e = n.metadata;
993
+ return `requested review from ${(e == null ? void 0 : e.reviewerName) || "a reviewer"}`;
994
+ }
995
+ },
996
+ "task.review_completed": {
997
+ icon: nt,
998
+ color: "text-success-text",
999
+ dotColor: "bg-success",
1000
+ getDescription: (n) => {
1001
+ const e = n.metadata;
1002
+ return `${(e == null ? void 0 : e.status) || "reviewed"} the task`;
1003
+ }
1004
+ },
1005
+ "task.visibility_changed": {
1006
+ icon: be,
1007
+ color: "text-text-tertiary",
1008
+ dotColor: "bg-icon-secondary",
1009
+ getDescription: (n) => {
1010
+ const e = n.metadata;
1011
+ return `changed visibility to ${(e == null ? void 0 : e.visibility) || "unknown"}`;
1012
+ }
1013
+ },
1014
+ "task.priority_changed": {
1015
+ icon: he,
1016
+ color: "text-error-text",
1017
+ dotColor: "bg-error",
1018
+ getDescription: (n) => {
1019
+ const e = n.metadata;
1020
+ return `changed priority to ${(e == null ? void 0 : e.priority) || "unknown"}`;
1021
+ }
1022
+ },
1023
+ "task.labels_changed": {
1024
+ icon: fe,
1025
+ color: "text-category-amber-text",
1026
+ dotColor: "bg-category-amber",
1027
+ getDescription: () => "updated labels"
1028
+ },
1029
+ "task.due_date_changed": {
1030
+ icon: xe,
1031
+ color: "text-warning-text",
1032
+ dotColor: "bg-warning",
1033
+ getDescription: (n) => {
1034
+ const e = n.metadata;
1035
+ return e != null && e.dueDate ? `set due date to ${e.dueDate}` : "updated the due date";
1036
+ }
1037
+ }
1038
+ }, Pt = {
1039
+ icon: U,
1040
+ color: "text-text-placeholder",
1041
+ dotColor: "bg-icon-disabled",
1042
+ getDescription: (n) => n.action
1043
+ };
1044
+ function Lt(n) {
1045
+ const e = new Date(n), x = (/* @__PURE__ */ new Date()).getTime() - e.getTime(), d = Math.floor(x / 6e4), c = Math.floor(d / 60), g = Math.floor(c / 24);
1046
+ return d < 1 ? "Just now" : d < 60 ? `${d}m ago` : c < 24 ? `${c}h ago` : g < 7 ? `${g}d ago` : e.toLocaleDateString("en-IN", {
1047
+ month: "short",
1048
+ day: "numeric",
1049
+ hour: "numeric",
1050
+ minute: "2-digit"
1051
+ });
1052
+ }
1053
+ function Ot(n) {
1054
+ const e = n.metadata;
1055
+ return e != null && e.actorName ? e.actorName : n.actorType === "SYSTEM" ? "System" : n.actorType === "AGENT" ? "AI Agent" : "Someone";
1056
+ }
1057
+ const Ee = p.forwardRef(
1058
+ function({ activities: e, className: b }, x) {
1059
+ return e.length === 0 ? /* @__PURE__ */ t(
1060
+ B,
1061
+ {
1062
+ ref: x,
1063
+ icon: /* @__PURE__ */ t(U, {}),
1064
+ title: "No activity yet",
1065
+ description: "Actions on this task will appear here",
1066
+ compact: !0,
1067
+ className: b
1068
+ }
1069
+ ) : /* @__PURE__ */ s("div", { ref: x, className: N("relative", b), children: [
1070
+ /* @__PURE__ */ t("div", { className: "absolute left-[11px] top-2 bottom-2 w-px bg-border" }),
1071
+ /* @__PURE__ */ t("div", { className: "space-y-ds-05", children: e.map((d) => {
1072
+ const c = St[d.action] || Pt, g = c.icon, D = Ot(d), f = c.getDescription(d);
1073
+ return /* @__PURE__ */ s("div", { className: "relative flex gap-ds-04 pl-0", children: [
1074
+ /* @__PURE__ */ t("div", { className: "relative z-raised flex h-[22px] w-[22px] shrink-0 items-center justify-center rounded-ds-full bg-layer-01", children: /* @__PURE__ */ t(
1075
+ "div",
1076
+ {
1077
+ className: N(
1078
+ "flex h-ico-md w-ico-md items-center justify-center rounded-ds-full bg-layer-02"
1079
+ ),
1080
+ children: /* @__PURE__ */ t(
1081
+ g,
1082
+ {
1083
+ className: N("h-3 w-3", c.color),
1084
+ stroke: 2
1085
+ }
1086
+ )
1087
+ }
1088
+ ) }),
1089
+ /* @__PURE__ */ s("div", { className: "flex-1 min-w-0 pt-ds-01", children: [
1090
+ /* @__PURE__ */ s("p", { className: "text-ds-sm", children: [
1091
+ /* @__PURE__ */ t("span", { className: "font-medium text-text-primary", children: D }),
1092
+ /* @__PURE__ */ s("span", { className: "text-text-tertiary", children: [
1093
+ " ",
1094
+ f
1095
+ ] })
1096
+ ] }),
1097
+ /* @__PURE__ */ t("p", { className: "mt-ds-01 text-ds-xs text-text-placeholder", children: Lt(d.timestamp) })
1098
+ ] })
1099
+ ] }, d.id);
1100
+ }) })
1101
+ ] });
1102
+ }
1103
+ );
1104
+ Ee.displayName = "ActivityTab";
1105
+ const me = [
1106
+ { id: "subtasks", label: "Subtasks", icon: ge },
1107
+ { id: "review", label: "Review", icon: X },
1108
+ { id: "conversation", label: "Conversation", icon: ye },
1109
+ { id: "files", label: "Files", icon: Z },
1110
+ { id: "activity", label: "Activity", icon: U }
1111
+ ];
1112
+ function _t() {
1113
+ return /* @__PURE__ */ s("div", { className: "space-y-ds-06 p-ds-06", children: [
1114
+ /* @__PURE__ */ t(P, { className: "h-ds-xs-plus w-3/4 bg-field" }),
1115
+ /* @__PURE__ */ t("div", { className: "space-y-ds-04", children: Array.from({ length: 6 }).map((n, e) => /* @__PURE__ */ s("div", { className: "flex items-center gap-ds-04", children: [
1116
+ /* @__PURE__ */ t(P, { className: "h-[16px] w-[120px] bg-field" }),
1117
+ /* @__PURE__ */ t(P, { className: "h-[16px] flex-1 bg-field" })
1118
+ ] }, e)) }),
1119
+ /* @__PURE__ */ t("div", { className: "flex gap-ds-05 border-b border-border pb-ds-03", children: Array.from({ length: 5 }).map((n, e) => /* @__PURE__ */ t(P, { className: "h-[12px] w-[64px] bg-field" }, e)) }),
1120
+ /* @__PURE__ */ s("div", { className: "space-y-ds-04", children: [
1121
+ /* @__PURE__ */ t(P, { className: "h-ds-md w-full bg-field" }),
1122
+ /* @__PURE__ */ t(P, { className: "h-ds-md w-full bg-field" }),
1123
+ /* @__PURE__ */ t(P, { className: "h-ds-md w-4/5 bg-field" })
1124
+ ] })
1125
+ ] });
1126
+ }
1127
+ const Vt = p.forwardRef(function({
1128
+ task: e,
1129
+ loading: b = !1,
1130
+ open: x,
1131
+ onOpenChange: d,
1132
+ columns: c,
1133
+ members: g,
1134
+ activities: D = [],
1135
+ enrichedComments: f,
1136
+ clientMode: m = !1,
1137
+ clientEditableFields: y = ["priority", "dueDate"],
1138
+ onTitleUpdate: v,
1139
+ onPropertyUpdate: w,
1140
+ onAssign: l,
1141
+ onUnassign: I,
1142
+ onCreateSubtask: o,
1143
+ onToggleSubtask: i,
1144
+ onRequestReview: h,
1145
+ onUpdateReviewStatus: u,
1146
+ onPostComment: C,
1147
+ onUploadFile: T,
1148
+ onDeleteFile: A,
1149
+ onTabChange: S,
1150
+ renderEditor: E,
1151
+ renderViewer: O,
1152
+ renderPriorityIndicator: F,
1153
+ renderDatePicker: K,
1154
+ isUploading: J = !1
1155
+ }, z) {
1156
+ var se, re, ne;
1157
+ const [r, H] = p.useState(m ? "conversation" : "subtasks"), [W, Y] = p.useState(!1), [ee, q] = p.useState(""), M = p.useRef(null);
1158
+ p.useEffect(() => {
1159
+ e && (q(e.title), Y(!1));
1160
+ }, [e == null ? void 0 : e.id]), p.useEffect(() => {
1161
+ x && H(m ? "conversation" : "subtasks");
1162
+ }, [x, m]);
1163
+ const Re = (a) => {
1164
+ H(a), S == null || S(a);
1165
+ }, te = () => {
1166
+ Y(!1);
1167
+ const a = ee.trim();
1168
+ a && a !== (e == null ? void 0 : e.title) ? v == null || v(a) : e && q(e.title);
1169
+ }, Ae = (a) => {
1170
+ a.key === "Enter" && (a.preventDefault(), te()), a.key === "Escape" && (Y(!1), e && q(e.title));
1171
+ };
1172
+ p.useEffect(() => {
1173
+ W && M.current && (M.current.focus(), M.current.select());
1174
+ }, [W]);
1175
+ const Se = (se = c.find((a) => a.isTerminal)) == null ? void 0 : se.id, Pe = ((re = c.find((a) => a.isDefault)) == null ? void 0 : re.id) || ((ne = c[0]) == null ? void 0 : ne.id) || "", Le = m ? me.filter((a) => a.id === "conversation") : me, Oe = f || (e == null ? void 0 : e.comments) || [];
1176
+ return /* @__PURE__ */ t(Ve, { open: x, onOpenChange: d, children: /* @__PURE__ */ s(
1177
+ $e,
1178
+ {
1179
+ ref: z,
1180
+ side: "right",
1181
+ className: N(
1182
+ /* intentional: task detail side panel takes 40% of screen, min 380px for form usability */
1183
+ "w-full sm:max-w-none sm:w-[40%] min-w-[380px] p-0",
1184
+ "flex flex-col overflow-hidden",
1185
+ "border-l border-border bg-layer-01"
1186
+ ),
1187
+ children: [
1188
+ /* @__PURE__ */ t(ke, { children: /* @__PURE__ */ t(je, { children: (e == null ? void 0 : e.title) || "Task Details" }) }),
1189
+ b || !e ? /* @__PURE__ */ t(_t, {}) : /* @__PURE__ */ s(ue, { children: [
1190
+ /* @__PURE__ */ s("div", { className: "shrink-0 border-b border-border px-ds-06 pb-ds-05 pt-ds-06", children: [
1191
+ !m && W ? /* @__PURE__ */ t(
1192
+ "input",
1193
+ {
1194
+ ref: M,
1195
+ type: "text",
1196
+ value: ee,
1197
+ onChange: (a) => q(a.target.value),
1198
+ onBlur: te,
1199
+ onKeyDown: Ae,
1200
+ className: "w-full bg-transparent text-ds-lg font-semibold text-text-primary outline-none"
1201
+ }
1202
+ ) : (
1203
+ // eslint-disable-next-line jsx-a11y/click-events-have-key-events
1204
+ /* @__PURE__ */ t(
1205
+ "h2",
1206
+ {
1207
+ onClick: m ? void 0 : () => Y(!0),
1208
+ className: N(
1209
+ "text-ds-lg font-semibold text-text-primary",
1210
+ !m && "cursor-text hover:text-interactive transition-colors"
1211
+ ),
1212
+ children: e.title
1213
+ }
1214
+ )
1215
+ ),
1216
+ e.parentTaskId && /* @__PURE__ */ t("p", { className: "mt-ds-02 text-ds-sm text-text-placeholder", children: "Subtask" })
1217
+ ] }),
1218
+ /* @__PURE__ */ s("div", { className: "flex-1 overflow-y-auto", children: [
1219
+ /* @__PURE__ */ t("div", { className: "border-b border-border px-ds-06 py-ds-05", children: /* @__PURE__ */ t(
1220
+ we,
1221
+ {
1222
+ task: e,
1223
+ columns: c,
1224
+ members: g,
1225
+ onUpdate: (a, R) => {
1226
+ m && !y.includes(a) || w == null || w(a, R);
1227
+ },
1228
+ onAssign: (a) => l == null ? void 0 : l(a),
1229
+ onUnassign: (a) => I == null ? void 0 : I(a),
1230
+ readOnly: m,
1231
+ editableFields: m ? y : void 0,
1232
+ renderPriorityIndicator: F,
1233
+ renderDatePicker: K
1234
+ }
1235
+ ) }),
1236
+ /* @__PURE__ */ t("div", { className: "sticky top-0 z-raised bg-layer-01 px-ds-06", children: /* @__PURE__ */ t(Fe, { value: r, onValueChange: Re, children: /* @__PURE__ */ t(ze, { variant: "line", children: Le.map((a) => /* @__PURE__ */ s(He, { value: a.id, children: [
1237
+ /* @__PURE__ */ t(a.icon, { className: "h-ico-sm w-ico-sm", stroke: 1.5 }),
1238
+ a.label
1239
+ ] }, a.id)) }) }) }),
1240
+ /* @__PURE__ */ s("div", { className: "px-ds-06 py-ds-05", children: [
1241
+ r === "subtasks" && /* @__PURE__ */ t(
1242
+ Ie,
1243
+ {
1244
+ subtasks: e.subtasks ?? [],
1245
+ terminalColumnId: Se,
1246
+ projectId: e.projectId,
1247
+ parentTaskId: e.id,
1248
+ defaultColumnId: Pe,
1249
+ onCreateSubtask: m ? () => {
1250
+ } : (a) => o == null ? void 0 : o(a),
1251
+ onToggleSubtask: m ? () => {
1252
+ } : (a, R) => i == null ? void 0 : i(a, R),
1253
+ readOnly: m
1254
+ }
1255
+ ),
1256
+ r === "review" && !m && /* @__PURE__ */ t(
1257
+ De,
1258
+ {
1259
+ reviews: e.reviewRequests,
1260
+ members: g,
1261
+ onRequestReview: (a) => h == null ? void 0 : h(a),
1262
+ onUpdateStatus: (a, R, _e) => u == null ? void 0 : u(a, R, _e)
1263
+ }
1264
+ ),
1265
+ r === "conversation" && /* @__PURE__ */ t(
1266
+ Ce,
1267
+ {
1268
+ comments: Oe,
1269
+ taskVisibility: e.visibility,
1270
+ onPostComment: (a, R) => C == null ? void 0 : C(a, R),
1271
+ clientMode: m,
1272
+ renderEditor: E,
1273
+ renderViewer: O
1274
+ }
1275
+ ),
1276
+ r === "files" && /* @__PURE__ */ t(
1277
+ Te,
1278
+ {
1279
+ files: e.files ?? [],
1280
+ onUpload: m ? () => {
1281
+ } : (a, R) => T == null ? void 0 : T(a, R),
1282
+ onDelete: m ? () => {
1283
+ } : (a) => A == null ? void 0 : A(a),
1284
+ isUploading: J,
1285
+ readOnly: m
1286
+ }
1287
+ ),
1288
+ r === "activity" && /* @__PURE__ */ t(Ee, { activities: D })
1289
+ ] })
1290
+ ] })
1291
+ ] })
1292
+ ]
1293
+ }
1294
+ ) });
1295
+ });
1296
+ Vt.displayName = "TaskDetailPanel";
1297
+ export {
1298
+ Ee as A,
1299
+ Ce as C,
1300
+ Te as F,
1301
+ De as R,
1302
+ Ie as S,
1303
+ Vt as T,
1304
+ we as a
1305
+ };