organify-ui 0.3.38 → 0.3.39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -975,6 +975,16 @@ declare namespace TaskDetailDialog {
975
975
  var displayName: string;
976
976
  }
977
977
 
978
+ /** Backend ColumnStatus enum values */
979
+ type ColumnStatus = 'TODO' | 'IN_PROGRESS' | 'UNDER_REVIEW' | 'DONE' | 'BLOCKED' | 'WAITING_FOR_CLIENT' | 'TESTING';
980
+ interface ColumnEditData {
981
+ id: string;
982
+ name: string;
983
+ status: ColumnStatus;
984
+ color?: string;
985
+ wipLimit?: number;
986
+ }
987
+
978
988
  interface KanbanTask {
979
989
  id: string;
980
990
  title: string;
@@ -1013,6 +1023,8 @@ interface KanbanColumnData {
1013
1023
  id: string;
1014
1024
  title: string;
1015
1025
  color?: string;
1026
+ /** The ColumnStatus mapped to this column (e.g. TODO, IN_PROGRESS, DONE) */
1027
+ status?: ColumnStatus;
1016
1028
  tasks: KanbanTask[];
1017
1029
  /** WIP limit — column header turns red when exceeded */
1018
1030
  wipLimit?: number;
@@ -1029,6 +1041,10 @@ interface KanbanBoardProps {
1029
1041
  onAddColumn?: (title?: string) => void;
1030
1042
  /** Called with (columnId, newTitle) when column is renamed inline */
1031
1043
  onRenameColumn?: (columnId: string, newTitle: string) => void;
1044
+ /** Called when user opens column edit dialog and saves changes */
1045
+ onEditColumn?: (columnId: string, data: Partial<Omit<ColumnEditData, 'id'>>) => Promise<void> | void;
1046
+ /** Called when user deletes a column from the edit dialog */
1047
+ onDeleteColumn?: (columnId: string) => Promise<void> | void;
1032
1048
  className?: string;
1033
1049
  /**
1034
1050
  * External drag-and-drop library integration
@@ -1075,6 +1091,8 @@ interface ColumnComponentProps {
1075
1091
  onTaskClick: (task: KanbanTask, columnId: string) => void;
1076
1092
  onAddTask?: (columnId: string, title?: string) => void;
1077
1093
  onRenameColumn?: (columnId: string, newTitle: string) => void;
1094
+ onEditColumn?: (columnId: string, data: Partial<Omit<ColumnEditData, 'id'>>) => Promise<void> | void;
1095
+ onDeleteColumn?: (columnId: string) => Promise<void> | void;
1078
1096
  externalDnD?: boolean;
1079
1097
  draggedTask?: {
1080
1098
  task: KanbanTask;
@@ -1087,11 +1105,11 @@ interface ColumnComponentProps {
1087
1105
  isDropTarget?: boolean;
1088
1106
  onTouchDragStart?: (task: KanbanTask, columnId: string) => void;
1089
1107
  }
1090
- declare function Column({ column, onTaskClick, onAddTask, onRenameColumn, externalDnD, draggedTask, onDragStart, onDragEnd, onDragOver, onDrop, isDropTarget, onTouchDragStart, }: ColumnComponentProps): react_jsx_runtime.JSX.Element;
1108
+ declare function Column({ column, onTaskClick, onAddTask, onRenameColumn, onEditColumn, onDeleteColumn, externalDnD, draggedTask, onDragStart, onDragEnd, onDragOver, onDrop, isDropTarget, onTouchDragStart, }: ColumnComponentProps): react_jsx_runtime.JSX.Element;
1091
1109
  declare namespace Column {
1092
1110
  var displayName: string;
1093
1111
  }
1094
- declare function KanbanBoard({ columns, onColumnChange, onTaskMove, onAddTask, onAddColumn, onRenameColumn, className, externalDnD, onTaskUpdate, onToggleLabel, onCreateLabel, availableLabels, onAddLabel, onRemoveLabel, onToggleAssignee, availableUsers, availableGroups, onToggleAssigneeGroup, onAddAssignee, onRemoveAssignee, onAddSubtask, onToggleSubtask, onDeleteSubtask, onDeleteTask, onUpdateSubtask, onTaskClick, }: KanbanBoardProps): react_jsx_runtime.JSX.Element;
1112
+ declare function KanbanBoard({ columns, onColumnChange, onTaskMove, onAddTask, onAddColumn, onRenameColumn, onEditColumn, onDeleteColumn, className, externalDnD, onTaskUpdate, onToggleLabel, onCreateLabel, availableLabels, onAddLabel, onRemoveLabel, onToggleAssignee, availableUsers, availableGroups, onToggleAssigneeGroup, onAddAssignee, onRemoveAssignee, onAddSubtask, onToggleSubtask, onDeleteSubtask, onDeleteTask, onUpdateSubtask, onTaskClick, }: KanbanBoardProps): react_jsx_runtime.JSX.Element;
1095
1113
  declare namespace KanbanBoard {
1096
1114
  var displayName: string;
1097
1115
  }
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ export { NotificationBell, NotificationItem, NotificationList, OrganifyNotificat
3
3
  export { createAiClient, useAiChat, useAiCommand, useAiSuggest, useAiUsage } from './chunk-NV4RWAQ2.js';
4
4
  export { I18nProvider, createTranslator, useI18n } from './chunk-FQA33MF4.js';
5
5
  export { ThemeProvider, useTheme } from './chunk-RFOKENE3.js';
6
- import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, UserAvatar, ResponsiveDialog, Separator, Label, Input, Textarea, Button, UserDisplayName, Tabs, TabsList, TabsTrigger, TabsContent, Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from './chunk-V3UZIPZA.js';
6
+ import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, UserAvatar, ResponsiveDialog, Separator, Label, Input, Textarea, Button, UserDisplayName, Tabs, TabsList, TabsTrigger, TabsContent, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, DialogFooter, DialogClose } from './chunk-V3UZIPZA.js';
7
7
  export { AiChatSidebar, Alert, Button, ChatMessages, ChatSidebar, CommandBar, CreateRoomDialog, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, InlineAiButton, Input, Label, MOCK_PROJECTS, MOCK_USERS, OrgLoader, OrgLoaderInline, OrganifyChat, ResponsiveDialog, RoomManagementPanel, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, TypingIndicatorMock, UserAvatar, UserDisplayName, alertVariants, buttonVariants, generateAutoReplies, getMockMentionOptions, getRoomPermissions, inputVariants, invalidateUserCache, orgLoaderVariants, resolveUser, seedUserCache, typingIndicator, useAiInline, useChat, useResolvedUser } from './chunk-V3UZIPZA.js';
8
8
  import { cn, Drawer, DrawerContent, DrawerHeader, DrawerTitle, DrawerDescription, Skeleton, useOrganify, useOrganifyGql, Avatar, AvatarFallback, useOrganifyUser, useOrganifyApi, Badge, ScrollArea, useOrganifyWorkspace, useOrganifyNavigation, useOrganifyProject, TooltipProvider, Tooltip, TooltipTrigger, TooltipContent, AvatarImage } from './chunk-UUBQQVDM.js';
9
9
  export { Avatar, AvatarFallback, AvatarImage, Badge, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, OrganifyContext, OrganifyProvider, ScrollArea, ScrollBar, Skeleton, SkeletonCard, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, avatarVariants, badgeVariants, cn, useOrganify, useOrganifyApi, useOrganifyGql, useOrganifyNavigation, useOrganifyProject, useOrganifyRest, useOrganifyUser, useOrganifyWorkspace } from './chunk-UUBQQVDM.js';
@@ -13,7 +13,7 @@ import * as React11 from 'react';
13
13
  import * as SwitchPrimitive from '@radix-ui/react-switch';
14
14
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
15
15
  import * as ProgressPrimitive from '@radix-ui/react-progress';
16
- import { X, XIcon, GripVertical, Check, ChevronRight, Circle, Search, MoreHorizontal, AlertCircle, AlertTriangle, CheckCircle2, Info, Sparkles, Plus, Zap, Trash2, Calendar, Link2, Ban, ArrowRight } from 'lucide-react';
16
+ import { X, XIcon, GripVertical, Settings2, Check, ChevronRight, Circle, Search, MoreHorizontal, AlertCircle, AlertTriangle, CheckCircle2, Info, Sparkles, Plus, Zap, Trash2, Calendar, Link2, Ban, ArrowRight } from 'lucide-react';
17
17
  import { cva } from 'class-variance-authority';
18
18
  import * as SheetPrimitive from '@radix-ui/react-dialog';
19
19
  import { createPortal } from 'react-dom';
@@ -6844,6 +6844,224 @@ function TaskDetailDialog({
6844
6844
  );
6845
6845
  }
6846
6846
  TaskDetailDialog.displayName = "TaskDetailDialog";
6847
+ var COLUMN_STATUS_OPTIONS = [
6848
+ { value: "TODO", label: "A Fazer", description: "Tarefas por iniciar", color: "#94a3b8" },
6849
+ { value: "IN_PROGRESS", label: "Em Progresso", description: "Trabalho ativo", color: "#3b82f6" },
6850
+ { value: "UNDER_REVIEW", label: "Em Revis\xE3o", description: "Aguardando revis\xE3o", color: "#a855f7" },
6851
+ { value: "TESTING", label: "Testes", description: "Em fase de testes", color: "#f59e0b" },
6852
+ { value: "BLOCKED", label: "Bloqueado", description: "Impedido de avan\xE7ar", color: "#ef4444" },
6853
+ { value: "WAITING_FOR_CLIENT", label: "Aguardando Cliente", description: "\xC0 espera de resposta do cliente", color: "#f97316" },
6854
+ { value: "DONE", label: "Conclu\xEDdo", description: "Trabalho finalizado", color: "#10b981" }
6855
+ ];
6856
+ var COLUMN_COLORS = [
6857
+ null,
6858
+ // no color
6859
+ "#ef4444",
6860
+ // red
6861
+ "#f97316",
6862
+ // orange
6863
+ "#f59e0b",
6864
+ // amber
6865
+ "#84cc16",
6866
+ // lime
6867
+ "#10b981",
6868
+ // emerald
6869
+ "#06b6d4",
6870
+ // cyan
6871
+ "#3b82f6",
6872
+ // blue
6873
+ "#8b5cf6",
6874
+ // violet
6875
+ "#d946ef",
6876
+ // fuchsia
6877
+ "#ec4899",
6878
+ // pink
6879
+ "#94a3b8"
6880
+ // slate
6881
+ ];
6882
+ function EditColumnDialog({
6883
+ column,
6884
+ open,
6885
+ onOpenChange,
6886
+ onSave,
6887
+ onDelete
6888
+ }) {
6889
+ const [name, setName] = React11.useState("");
6890
+ const [status, setStatus] = React11.useState("TODO");
6891
+ const [color, setColor] = React11.useState(null);
6892
+ const [wipLimit, setWipLimit] = React11.useState("");
6893
+ const [saving, setSaving] = React11.useState(false);
6894
+ const [confirmDelete, setConfirmDelete] = React11.useState(false);
6895
+ React11.useEffect(() => {
6896
+ if (open && column) {
6897
+ setName(column.name);
6898
+ setStatus(column.status);
6899
+ setColor(column.color ?? null);
6900
+ setWipLimit(column.wipLimit != null ? String(column.wipLimit) : "");
6901
+ setConfirmDelete(false);
6902
+ }
6903
+ }, [open, column]);
6904
+ const handleSave = async () => {
6905
+ if (!column || !name.trim()) return;
6906
+ setSaving(true);
6907
+ try {
6908
+ const data = {};
6909
+ if (name.trim() !== column.name) data.name = name.trim();
6910
+ if (status !== column.status) data.status = status;
6911
+ if (color !== (column.color ?? null)) data.color = color ?? void 0;
6912
+ const wip = wipLimit.trim() ? parseInt(wipLimit, 10) : void 0;
6913
+ if (wip !== column.wipLimit) data.wipLimit = wip;
6914
+ if (Object.keys(data).length > 0) {
6915
+ await onSave(column.id, data);
6916
+ }
6917
+ onOpenChange(false);
6918
+ } finally {
6919
+ setSaving(false);
6920
+ }
6921
+ };
6922
+ const handleDelete = async () => {
6923
+ if (!column || !onDelete) return;
6924
+ setSaving(true);
6925
+ try {
6926
+ await onDelete(column.id);
6927
+ onOpenChange(false);
6928
+ } finally {
6929
+ setSaving(false);
6930
+ }
6931
+ };
6932
+ const statusOption = COLUMN_STATUS_OPTIONS.find((o) => o.value === status);
6933
+ return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs(DialogContent, { className: "sm:max-w-[440px] bg-elevated border-theme-subtle text-theme", children: [
6934
+ /* @__PURE__ */ jsx(DialogHeader, { children: /* @__PURE__ */ jsx(DialogTitle, { className: "text-theme", children: "Editar Coluna" }) }),
6935
+ /* @__PURE__ */ jsxs("div", { className: "space-y-5 py-2", children: [
6936
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
6937
+ /* @__PURE__ */ jsx(Label, { htmlFor: "col-name", className: "text-xs font-medium text-theme-muted uppercase tracking-wide", children: "Nome da Coluna" }),
6938
+ /* @__PURE__ */ jsx(
6939
+ Input,
6940
+ {
6941
+ id: "col-name",
6942
+ value: name,
6943
+ onChange: (e) => setName(e.target.value),
6944
+ placeholder: "Ex: Em Progresso",
6945
+ className: "bg-void border-theme-subtle text-theme",
6946
+ onKeyDown: (e) => {
6947
+ if (e.key === "Enter") handleSave();
6948
+ }
6949
+ }
6950
+ )
6951
+ ] }),
6952
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
6953
+ /* @__PURE__ */ jsx(Label, { className: "text-xs font-medium text-theme-muted uppercase tracking-wide", children: "Tipo de Coluna (Estado)" }),
6954
+ /* @__PURE__ */ jsxs(Select, { value: status, onValueChange: (v) => setStatus(v), children: [
6955
+ /* @__PURE__ */ jsx(SelectTrigger, { className: "bg-void border-theme-subtle text-theme", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
6956
+ /* @__PURE__ */ jsx(SelectContent, { className: "bg-elevated border-theme-subtle", children: COLUMN_STATUS_OPTIONS.map((opt) => /* @__PURE__ */ jsx(SelectItem, { value: opt.value, children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
6957
+ /* @__PURE__ */ jsx(
6958
+ "div",
6959
+ {
6960
+ className: "w-2.5 h-2.5 rounded-full shrink-0",
6961
+ style: { backgroundColor: opt.color }
6962
+ }
6963
+ ),
6964
+ /* @__PURE__ */ jsxs("div", { children: [
6965
+ /* @__PURE__ */ jsx("span", { className: "text-sm text-theme", children: opt.label }),
6966
+ /* @__PURE__ */ jsx("span", { className: "text-xs text-theme-muted ml-2", children: opt.description })
6967
+ ] })
6968
+ ] }) }, opt.value)) })
6969
+ ] }),
6970
+ statusOption && /* @__PURE__ */ jsxs("p", { className: "text-[11px] text-theme-muted leading-snug", children: [
6971
+ "Tarefas nesta coluna ser\xE3o tratadas como ",
6972
+ /* @__PURE__ */ jsx("strong", { className: "text-theme", children: statusOption.label }),
6973
+ ". Ao mover uma tarefa para c\xE1, o estado ser\xE1 atualizado automaticamente."
6974
+ ] })
6975
+ ] }),
6976
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
6977
+ /* @__PURE__ */ jsx(Label, { className: "text-xs font-medium text-theme-muted uppercase tracking-wide", children: "Cor do Indicador" }),
6978
+ /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: COLUMN_COLORS.map((c, i) => /* @__PURE__ */ jsx(
6979
+ "button",
6980
+ {
6981
+ type: "button",
6982
+ onClick: () => setColor(c),
6983
+ className: cn(
6984
+ "w-7 h-7 rounded-lg border-2 transition-all flex items-center justify-center",
6985
+ color === c ? "border-primary scale-110 shadow-lg shadow-primary/20" : "border-theme-subtle hover:border-theme hover:scale-105",
6986
+ !c && "bg-void"
6987
+ ),
6988
+ style: c ? { backgroundColor: c } : void 0,
6989
+ children: !c && color === null && /* @__PURE__ */ jsx("svg", { width: "10", height: "10", viewBox: "0 0 10 10", fill: "none", stroke: "currentColor", strokeWidth: "1.5", className: "text-theme-muted", children: /* @__PURE__ */ jsx("path", { d: "M1 1l8 8M9 1l-8 8" }) })
6990
+ },
6991
+ i
6992
+ )) })
6993
+ ] }),
6994
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
6995
+ /* @__PURE__ */ jsx(Label, { htmlFor: "col-wip", className: "text-xs font-medium text-theme-muted uppercase tracking-wide", children: "Limite WIP (Work in Progress)" }),
6996
+ /* @__PURE__ */ jsx(
6997
+ Input,
6998
+ {
6999
+ id: "col-wip",
7000
+ type: "number",
7001
+ min: 0,
7002
+ value: wipLimit,
7003
+ onChange: (e) => setWipLimit(e.target.value),
7004
+ placeholder: "Sem limite",
7005
+ className: "bg-void border-theme-subtle text-theme w-32"
7006
+ }
7007
+ ),
7008
+ /* @__PURE__ */ jsx("p", { className: "text-[11px] text-theme-muted", children: "Destaca a coluna quando h\xE1 mais tarefas que o limite definido." })
7009
+ ] }),
7010
+ onDelete && /* @__PURE__ */ jsx("div", { className: "pt-3 border-t border-theme-subtle", children: !confirmDelete ? /* @__PURE__ */ jsxs(
7011
+ Button,
7012
+ {
7013
+ variant: "ghost",
7014
+ size: "sm",
7015
+ onClick: () => setConfirmDelete(true),
7016
+ className: "text-red-400 hover:text-red-300 hover:bg-red-500/10",
7017
+ children: [
7018
+ /* @__PURE__ */ jsx(OrgTrash, { className: "w-3.5 h-3.5 mr-2" }),
7019
+ "Eliminar coluna"
7020
+ ]
7021
+ }
7022
+ ) : /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
7023
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-red-400", children: "Tem certeza? As tarefas nesta coluna ser\xE3o movidas para o backlog." }),
7024
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
7025
+ /* @__PURE__ */ jsx(
7026
+ Button,
7027
+ {
7028
+ variant: "destructive",
7029
+ size: "sm",
7030
+ onClick: handleDelete,
7031
+ disabled: saving,
7032
+ className: "text-xs",
7033
+ children: saving ? "A eliminar\u2026" : "Sim, eliminar"
7034
+ }
7035
+ ),
7036
+ /* @__PURE__ */ jsx(
7037
+ Button,
7038
+ {
7039
+ variant: "ghost",
7040
+ size: "sm",
7041
+ onClick: () => setConfirmDelete(false),
7042
+ className: "text-xs",
7043
+ children: "Cancelar"
7044
+ }
7045
+ )
7046
+ ] })
7047
+ ] }) })
7048
+ ] }),
7049
+ /* @__PURE__ */ jsxs(DialogFooter, { className: "gap-2", children: [
7050
+ /* @__PURE__ */ jsx(DialogClose, { asChild: true, children: /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", className: "text-theme-muted", children: "Cancelar" }) }),
7051
+ /* @__PURE__ */ jsx(
7052
+ Button,
7053
+ {
7054
+ variant: "default",
7055
+ size: "sm",
7056
+ onClick: handleSave,
7057
+ disabled: saving || !name.trim(),
7058
+ children: saving ? "A guardar\u2026" : "Guardar"
7059
+ }
7060
+ )
7061
+ ] })
7062
+ ] }) });
7063
+ }
7064
+ EditColumnDialog.displayName = "EditColumnDialog";
6847
7065
  var priorityColors2 = {
6848
7066
  LOW: "bg-slate-500/15 text-slate-400 border-slate-500/30",
6849
7067
  MEDIUM: "bg-blue-500/15 text-blue-400 border-blue-500/30",
@@ -7001,6 +7219,8 @@ function Column({
7001
7219
  onTaskClick,
7002
7220
  onAddTask,
7003
7221
  onRenameColumn,
7222
+ onEditColumn,
7223
+ onDeleteColumn,
7004
7224
  externalDnD,
7005
7225
  draggedTask,
7006
7226
  onDragStart,
@@ -7016,6 +7236,14 @@ function Column({
7016
7236
  const [isAddingTask, setIsAddingTask] = React11.useState(false);
7017
7237
  const [newTaskTitle, setNewTaskTitle] = React11.useState("");
7018
7238
  const taskInputRef = React11.useRef(null);
7239
+ const [editDialogOpen, setEditDialogOpen] = React11.useState(false);
7240
+ const columnEditData = React11.useMemo(() => ({
7241
+ id: column.id,
7242
+ name: column.title,
7243
+ status: column.status ?? "TODO",
7244
+ color: column.color,
7245
+ wipLimit: column.wipLimit
7246
+ }), [column.id, column.title, column.status, column.color, column.wipLimit]);
7019
7247
  React11.useEffect(() => {
7020
7248
  if (isRenaming) renameInputRef.current?.focus();
7021
7249
  }, [isRenaming]);
@@ -7070,7 +7298,7 @@ function Column({
7070
7298
  isDropTarget && "border-primary-light/50 bg-primary/5"
7071
7299
  ),
7072
7300
  children: [
7073
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 px-3 py-3 border-b border-theme-subtle", children: [
7301
+ /* @__PURE__ */ jsxs("div", { className: "group/col-header flex items-center gap-2 px-3 py-3 border-b border-theme-subtle", children: [
7074
7302
  column.color && /* @__PURE__ */ jsx(
7075
7303
  "div",
7076
7304
  {
@@ -7102,23 +7330,34 @@ function Column({
7102
7330
  children: column.title
7103
7331
  }
7104
7332
  ),
7105
- /* @__PURE__ */ jsx("div", { className: "flex items-center gap-1 shrink-0", children: /* @__PURE__ */ jsxs(
7106
- Badge,
7107
- {
7108
- variant: column.wipLimit && column.tasks.length > column.wipLimit ? "error" : "default",
7109
- className: cn(
7110
- "text-xs",
7111
- column.wipLimit && column.tasks.length > column.wipLimit ? "bg-red-500/20 text-red-400 border-red-500/40 animate-pulse" : "bg-theme-highlight text-theme-muted border-theme-subtle"
7112
- ),
7113
- children: [
7114
- column.tasks.length,
7115
- column.wipLimit != null && /* @__PURE__ */ jsxs("span", { className: "text-theme-muted", children: [
7116
- "/",
7117
- column.wipLimit
7118
- ] })
7119
- ]
7120
- }
7121
- ) })
7333
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 shrink-0", children: [
7334
+ onEditColumn && /* @__PURE__ */ jsx(
7335
+ "button",
7336
+ {
7337
+ onClick: () => setEditDialogOpen(true),
7338
+ className: "p-1 rounded-md text-theme-muted opacity-0 group-hover/col-header:opacity-100 hover:text-theme hover:bg-theme-highlight transition-all",
7339
+ title: "Editar coluna",
7340
+ children: /* @__PURE__ */ jsx(Settings2, { className: "w-3.5 h-3.5" })
7341
+ }
7342
+ ),
7343
+ /* @__PURE__ */ jsxs(
7344
+ Badge,
7345
+ {
7346
+ variant: column.wipLimit && column.tasks.length > column.wipLimit ? "error" : "default",
7347
+ className: cn(
7348
+ "text-xs",
7349
+ column.wipLimit && column.tasks.length > column.wipLimit ? "bg-red-500/20 text-red-400 border-red-500/40 animate-pulse" : "bg-theme-highlight text-theme-muted border-theme-subtle"
7350
+ ),
7351
+ children: [
7352
+ column.tasks.length,
7353
+ column.wipLimit != null && /* @__PURE__ */ jsxs("span", { className: "text-theme-muted", children: [
7354
+ "/",
7355
+ column.wipLimit
7356
+ ] })
7357
+ ]
7358
+ }
7359
+ )
7360
+ ] })
7122
7361
  ] }),
7123
7362
  column.wipLimit != null && column.tasks.length > column.wipLimit && /* @__PURE__ */ jsxs("div", { className: "px-3 py-1.5 bg-red-500/10 border-b border-red-500/20 text-[10px] font-medium text-red-400 text-center", children: [
7124
7363
  "\u26A0 WIP limit exceeded (",
@@ -7200,7 +7439,17 @@ function Column({
7200
7439
  "Adicionar tarefa"
7201
7440
  ]
7202
7441
  }
7203
- ) })
7442
+ ) }),
7443
+ onEditColumn && /* @__PURE__ */ jsx(
7444
+ EditColumnDialog,
7445
+ {
7446
+ column: columnEditData,
7447
+ open: editDialogOpen,
7448
+ onOpenChange: setEditDialogOpen,
7449
+ onSave: onEditColumn,
7450
+ onDelete: onDeleteColumn
7451
+ }
7452
+ )
7204
7453
  ]
7205
7454
  }
7206
7455
  );
@@ -7213,6 +7462,8 @@ function KanbanBoard({
7213
7462
  onAddTask,
7214
7463
  onAddColumn,
7215
7464
  onRenameColumn,
7465
+ onEditColumn,
7466
+ onDeleteColumn,
7216
7467
  className,
7217
7468
  externalDnD = false,
7218
7469
  onTaskUpdate,
@@ -7343,6 +7594,8 @@ function KanbanBoard({
7343
7594
  onTaskClick: handleTaskClick,
7344
7595
  onAddTask,
7345
7596
  onRenameColumn,
7597
+ onEditColumn,
7598
+ onDeleteColumn,
7346
7599
  externalDnD,
7347
7600
  draggedTask: effectiveDraggedTask,
7348
7601
  onDragStart: handleDragStart,