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