organify-ui 0.3.37 → 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 +42 -4
- package/dist/index.js +630 -186
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3,17 +3,17 @@ 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';
|
|
10
10
|
import { OrgDiamond, OrgPlus, OrgComment, OrgEdit, OrgTrash, OrgSprint, OrgCheckCircle, OrgAttachment, OrgCalendar, OrgMail, OrgBoard, OrgRocket, OrgWarning, OrgFlag, OrgShield, OrgZap, OrgStar } from './chunk-MZKEDV5W.js';
|
|
11
11
|
export { OrgAI, OrgActivity, OrgArrowLeft, OrgArrowRight, OrgAttachment, OrgBell, OrgBoard, OrgCalendar, OrgCelebrate, OrgChart, OrgChat, OrgCheck, OrgCheckCircle, OrgChevronDown, OrgChevronLeft, OrgChevronRight, OrgChevronUp, OrgClock, OrgClose, OrgComment, OrgCopy, OrgCreditCard, OrgTrash as OrgDelete, OrgDeveloper, OrgDiamond, OrgDoor, OrgDownload, OrgEdit, OrgError, OrgExecutive, OrgEye, OrgEyeOff, OrgFile, OrgFilter, OrgFlag, OrgFolder, OrgGauge, OrgGlobe, OrgGrid, OrgHeart, OrgHome, OrgInfo, OrgIntegration, OrgLink, OrgList, OrgLock, OrgLogo, OrgLogout, OrgMail, OrgMention, OrgMenu, OrgMoon, OrgPMO, OrgPause, OrgPlay, OrgPlus, OrgProjectManager, OrgReport, OrgRocket, OrgSearch, OrgSettings, OrgShield, OrgSort, OrgSprint, OrgStakeholder, OrgStar, OrgSun, OrgTag, OrgTarget, OrgTeam, OrgTrash, OrgTutorial, OrgUnlock, OrgUpload, OrgUser, OrgWarning, OrgWave, OrgWordmark, OrgWorkflow, OrgWorkspace, OrgZap } from './chunk-MZKEDV5W.js';
|
|
12
|
-
import * as
|
|
12
|
+
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 } 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';
|
|
@@ -27,8 +27,8 @@ export { toast } from 'sonner';
|
|
|
27
27
|
import { useQueryClient, useQuery } from '@tanstack/react-query';
|
|
28
28
|
export { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
29
29
|
|
|
30
|
-
var Toggle =
|
|
31
|
-
const id =
|
|
30
|
+
var Toggle = React11.forwardRef(({ className, label, description, ...props }, ref) => {
|
|
31
|
+
const id = React11.useId();
|
|
32
32
|
if (label) {
|
|
33
33
|
return /* @__PURE__ */ jsxs(
|
|
34
34
|
"div",
|
|
@@ -70,7 +70,7 @@ var Toggle = React5.forwardRef(({ className, label, description, ...props }, ref
|
|
|
70
70
|
);
|
|
71
71
|
});
|
|
72
72
|
Toggle.displayName = "Toggle";
|
|
73
|
-
var Progress =
|
|
73
|
+
var Progress = React11.forwardRef(({ className, value, showLabel, label, variant = "default", ...props }, ref) => /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
74
74
|
(label || showLabel) && /* @__PURE__ */ jsxs("div", { className: "flex items-end justify-between", children: [
|
|
75
75
|
label && /* @__PURE__ */ jsx("span", { className: "text-label uppercase tracking-widest text-org-text-muted", children: label }),
|
|
76
76
|
showLabel && /* @__PURE__ */ jsxs("span", { className: "font-mono text-lg text-primary-light", children: [
|
|
@@ -248,8 +248,8 @@ function EmptyState({
|
|
|
248
248
|
);
|
|
249
249
|
}
|
|
250
250
|
function useMediaQuery(query) {
|
|
251
|
-
const [matches, setMatches] =
|
|
252
|
-
|
|
251
|
+
const [matches, setMatches] = React11.useState(false);
|
|
252
|
+
React11.useEffect(() => {
|
|
253
253
|
const mql = window.matchMedia(query);
|
|
254
254
|
setMatches(mql.matches);
|
|
255
255
|
const handler = (e) => setMatches(e.matches);
|
|
@@ -674,7 +674,7 @@ function DockSidebar({
|
|
|
674
674
|
...props
|
|
675
675
|
}) {
|
|
676
676
|
const handleToggle = () => onExpandedChange?.(!expanded);
|
|
677
|
-
|
|
677
|
+
React11.useEffect(() => {
|
|
678
678
|
if (!mobileOpen) return;
|
|
679
679
|
const onKey = (e) => {
|
|
680
680
|
if (e.key === "Escape") onMobileClose?.();
|
|
@@ -682,7 +682,7 @@ function DockSidebar({
|
|
|
682
682
|
document.addEventListener("keydown", onKey);
|
|
683
683
|
return () => document.removeEventListener("keydown", onKey);
|
|
684
684
|
}, [mobileOpen, onMobileClose]);
|
|
685
|
-
|
|
685
|
+
React11.useEffect(() => {
|
|
686
686
|
if (!mobileOpen) return;
|
|
687
687
|
document.body.style.overflow = "hidden";
|
|
688
688
|
return () => {
|
|
@@ -924,8 +924,8 @@ var DELETE_WORKSPACE_MUTATION = `
|
|
|
924
924
|
}
|
|
925
925
|
`;
|
|
926
926
|
function useMediaQuery2(query) {
|
|
927
|
-
const [matches, setMatches] =
|
|
928
|
-
|
|
927
|
+
const [matches, setMatches] = React11.useState(false);
|
|
928
|
+
React11.useEffect(() => {
|
|
929
929
|
const mql = window.matchMedia(query);
|
|
930
930
|
setMatches(mql.matches);
|
|
931
931
|
const handler = (e) => setMatches(e.matches);
|
|
@@ -945,13 +945,13 @@ function WorkspaceSwitcher({ compact = false, onCreateWorkspace, className }) {
|
|
|
945
945
|
onWorkspaceChange
|
|
946
946
|
} = useOrganify();
|
|
947
947
|
const gql = useOrganifyGql();
|
|
948
|
-
const [isOpen, setIsOpen] =
|
|
949
|
-
const [createDialogOpen, setCreateDialogOpen] =
|
|
950
|
-
const [editingWorkspace, setEditingWorkspace] =
|
|
951
|
-
const [deletingWorkspace, setDeletingWorkspace] =
|
|
952
|
-
const dropdownRef =
|
|
948
|
+
const [isOpen, setIsOpen] = React11.useState(false);
|
|
949
|
+
const [createDialogOpen, setCreateDialogOpen] = React11.useState(false);
|
|
950
|
+
const [editingWorkspace, setEditingWorkspace] = React11.useState(null);
|
|
951
|
+
const [deletingWorkspace, setDeletingWorkspace] = React11.useState(null);
|
|
952
|
+
const dropdownRef = React11.useRef(null);
|
|
953
953
|
const isMobile = useMediaQuery2("(max-width: 767px)");
|
|
954
|
-
|
|
954
|
+
React11.useEffect(() => {
|
|
955
955
|
if (isMobile) return;
|
|
956
956
|
function handleClickOutside(event) {
|
|
957
957
|
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
|
|
@@ -961,7 +961,7 @@ function WorkspaceSwitcher({ compact = false, onCreateWorkspace, className }) {
|
|
|
961
961
|
document.addEventListener("mousedown", handleClickOutside);
|
|
962
962
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
963
963
|
}, [isMobile]);
|
|
964
|
-
const handleCreateWorkspace =
|
|
964
|
+
const handleCreateWorkspace = React11.useCallback(
|
|
965
965
|
async (data) => {
|
|
966
966
|
const optimisticId = `temp-${Date.now()}`;
|
|
967
967
|
const optimisticSlug = data.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
|
|
@@ -1001,7 +1001,7 @@ function WorkspaceSwitcher({ compact = false, onCreateWorkspace, className }) {
|
|
|
1001
1001
|
},
|
|
1002
1002
|
[workspaces, gql, onWorkspacesChange, onWorkspaceChange, onCreateWorkspace]
|
|
1003
1003
|
);
|
|
1004
|
-
const handleUpdateWorkspace =
|
|
1004
|
+
const handleUpdateWorkspace = React11.useCallback(
|
|
1005
1005
|
async (slug, data) => {
|
|
1006
1006
|
const prevWorkspaces = [...workspaces];
|
|
1007
1007
|
const prevActive = workspace;
|
|
@@ -1036,7 +1036,7 @@ function WorkspaceSwitcher({ compact = false, onCreateWorkspace, className }) {
|
|
|
1036
1036
|
},
|
|
1037
1037
|
[workspaces, workspace, gql, onWorkspacesChange, onWorkspaceChange]
|
|
1038
1038
|
);
|
|
1039
|
-
const handleDeleteWorkspace =
|
|
1039
|
+
const handleDeleteWorkspace = React11.useCallback(
|
|
1040
1040
|
async (slug) => {
|
|
1041
1041
|
const prevWorkspaces = [...workspaces];
|
|
1042
1042
|
const prevActive = workspace;
|
|
@@ -1266,7 +1266,7 @@ function SwitcherItem({
|
|
|
1266
1266
|
onEdit,
|
|
1267
1267
|
onDelete
|
|
1268
1268
|
}) {
|
|
1269
|
-
const [showActions, setShowActions] =
|
|
1269
|
+
const [showActions, setShowActions] = React11.useState(false);
|
|
1270
1270
|
const isOptimistic = ws.id.startsWith("temp-");
|
|
1271
1271
|
const content = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1272
1272
|
/* @__PURE__ */ jsx(
|
|
@@ -1340,11 +1340,11 @@ function CreateWorkspaceInlineDialog({
|
|
|
1340
1340
|
onOpenChange,
|
|
1341
1341
|
onSubmit
|
|
1342
1342
|
}) {
|
|
1343
|
-
const [name, setName] =
|
|
1344
|
-
const [description, setDescription] =
|
|
1345
|
-
const [loading, setLoading] =
|
|
1346
|
-
const [error, setError] =
|
|
1347
|
-
|
|
1343
|
+
const [name, setName] = React11.useState("");
|
|
1344
|
+
const [description, setDescription] = React11.useState("");
|
|
1345
|
+
const [loading, setLoading] = React11.useState(false);
|
|
1346
|
+
const [error, setError] = React11.useState("");
|
|
1347
|
+
React11.useEffect(() => {
|
|
1348
1348
|
if (open) {
|
|
1349
1349
|
setName("");
|
|
1350
1350
|
setDescription("");
|
|
@@ -1417,11 +1417,11 @@ function EditWorkspaceDialog({
|
|
|
1417
1417
|
workspace,
|
|
1418
1418
|
onSubmit
|
|
1419
1419
|
}) {
|
|
1420
|
-
const [name, setName] =
|
|
1421
|
-
const [description, setDescription] =
|
|
1422
|
-
const [loading, setLoading] =
|
|
1423
|
-
const [error, setError] =
|
|
1424
|
-
|
|
1420
|
+
const [name, setName] = React11.useState("");
|
|
1421
|
+
const [description, setDescription] = React11.useState("");
|
|
1422
|
+
const [loading, setLoading] = React11.useState(false);
|
|
1423
|
+
const [error, setError] = React11.useState("");
|
|
1424
|
+
React11.useEffect(() => {
|
|
1425
1425
|
if (open && workspace) {
|
|
1426
1426
|
setName(workspace.name);
|
|
1427
1427
|
setDescription(workspace.description ?? "");
|
|
@@ -1495,10 +1495,10 @@ function DeleteWorkspaceDialog({
|
|
|
1495
1495
|
workspace,
|
|
1496
1496
|
onConfirm
|
|
1497
1497
|
}) {
|
|
1498
|
-
const [loading, setLoading] =
|
|
1499
|
-
const [error, setError] =
|
|
1500
|
-
const [confirmText, setConfirmText] =
|
|
1501
|
-
|
|
1498
|
+
const [loading, setLoading] = React11.useState(false);
|
|
1499
|
+
const [error, setError] = React11.useState("");
|
|
1500
|
+
const [confirmText, setConfirmText] = React11.useState("");
|
|
1501
|
+
React11.useEffect(() => {
|
|
1502
1502
|
if (open) {
|
|
1503
1503
|
setError("");
|
|
1504
1504
|
setConfirmText("");
|
|
@@ -4225,9 +4225,9 @@ function CommentItem({
|
|
|
4225
4225
|
onDelete,
|
|
4226
4226
|
onReact
|
|
4227
4227
|
}) {
|
|
4228
|
-
const [editing, setEditing] =
|
|
4229
|
-
const [editContent, setEditContent] =
|
|
4230
|
-
const [showReactions, setShowReactions] =
|
|
4228
|
+
const [editing, setEditing] = React11.useState(false);
|
|
4229
|
+
const [editContent, setEditContent] = React11.useState(comment.content);
|
|
4230
|
+
const [showReactions, setShowReactions] = React11.useState(false);
|
|
4231
4231
|
const isAuthor = comment.author.id === currentUser.id;
|
|
4232
4232
|
const isPending = comment._status === "pending";
|
|
4233
4233
|
const isError = comment._status === "error";
|
|
@@ -4391,9 +4391,9 @@ function CommentInput({
|
|
|
4391
4391
|
compact = false,
|
|
4392
4392
|
alwaysExpanded = true
|
|
4393
4393
|
}) {
|
|
4394
|
-
const [content, setContent] =
|
|
4395
|
-
const textareaRef =
|
|
4396
|
-
|
|
4394
|
+
const [content, setContent] = React11.useState("");
|
|
4395
|
+
const textareaRef = React11.useRef(null);
|
|
4396
|
+
React11.useEffect(() => {
|
|
4397
4397
|
if (autoFocus && textareaRef.current) {
|
|
4398
4398
|
textareaRef.current.focus();
|
|
4399
4399
|
}
|
|
@@ -4513,7 +4513,7 @@ function CommentThread({
|
|
|
4513
4513
|
displayName: providerUser?.name ?? "",
|
|
4514
4514
|
avatarUrl: providerUser?.avatarUrl ?? null
|
|
4515
4515
|
};
|
|
4516
|
-
const effectiveOnFetch =
|
|
4516
|
+
const effectiveOnFetch = React11.useCallback(
|
|
4517
4517
|
async (_entityType, _entityId) => {
|
|
4518
4518
|
if (onFetch) return onFetch(_entityType, _entityId);
|
|
4519
4519
|
const data = await gql(
|
|
@@ -4532,7 +4532,7 @@ function CommentThread({
|
|
|
4532
4532
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
4533
4533
|
[gql, onFetch]
|
|
4534
4534
|
);
|
|
4535
|
-
const effectiveOnAdd =
|
|
4535
|
+
const effectiveOnAdd = React11.useCallback(
|
|
4536
4536
|
async (input) => {
|
|
4537
4537
|
if (onAdd) return onAdd(input);
|
|
4538
4538
|
const data = await gql(
|
|
@@ -4549,7 +4549,7 @@ function CommentThread({
|
|
|
4549
4549
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
4550
4550
|
[gql, onAdd, currentUser.id]
|
|
4551
4551
|
);
|
|
4552
|
-
const effectiveOnEdit =
|
|
4552
|
+
const effectiveOnEdit = React11.useCallback(
|
|
4553
4553
|
async (commentId, content) => {
|
|
4554
4554
|
if (onEdit) return onEdit(commentId, content);
|
|
4555
4555
|
const data = await gql(
|
|
@@ -4571,7 +4571,7 @@ function CommentThread({
|
|
|
4571
4571
|
},
|
|
4572
4572
|
[gql, onEdit]
|
|
4573
4573
|
);
|
|
4574
|
-
const effectiveOnDelete =
|
|
4574
|
+
const effectiveOnDelete = React11.useCallback(
|
|
4575
4575
|
async (commentId) => {
|
|
4576
4576
|
if (onDelete) return onDelete(commentId);
|
|
4577
4577
|
await gql(
|
|
@@ -4582,15 +4582,15 @@ function CommentThread({
|
|
|
4582
4582
|
},
|
|
4583
4583
|
[gql, onDelete]
|
|
4584
4584
|
);
|
|
4585
|
-
const [comments, setComments] =
|
|
4586
|
-
const [loading, setLoading] =
|
|
4587
|
-
const [showAll, setShowAll] =
|
|
4588
|
-
const [replyingTo, setReplyingTo] =
|
|
4589
|
-
const hasFetchedRef =
|
|
4590
|
-
|
|
4585
|
+
const [comments, setComments] = React11.useState(externalComments || []);
|
|
4586
|
+
const [loading, setLoading] = React11.useState(!externalComments);
|
|
4587
|
+
const [showAll, setShowAll] = React11.useState(false);
|
|
4588
|
+
const [replyingTo, setReplyingTo] = React11.useState(null);
|
|
4589
|
+
const hasFetchedRef = React11.useRef(false);
|
|
4590
|
+
React11.useEffect(() => {
|
|
4591
4591
|
hasFetchedRef.current = false;
|
|
4592
4592
|
}, [entityId, entityType]);
|
|
4593
|
-
|
|
4593
|
+
React11.useEffect(() => {
|
|
4594
4594
|
if (externalComments) return;
|
|
4595
4595
|
if (hasFetchedRef.current) return;
|
|
4596
4596
|
hasFetchedRef.current = true;
|
|
@@ -4608,12 +4608,12 @@ function CommentThread({
|
|
|
4608
4608
|
cancelled = true;
|
|
4609
4609
|
};
|
|
4610
4610
|
}, [entityType, entityId, externalComments, effectiveOnFetch]);
|
|
4611
|
-
|
|
4611
|
+
React11.useEffect(() => {
|
|
4612
4612
|
if (externalComments) {
|
|
4613
4613
|
setComments(externalComments);
|
|
4614
4614
|
}
|
|
4615
4615
|
}, [externalComments]);
|
|
4616
|
-
|
|
4616
|
+
React11.useEffect(() => {
|
|
4617
4617
|
if (externalComments || onFetch) return;
|
|
4618
4618
|
if (!entityId || entityType !== "task") return;
|
|
4619
4619
|
const projectsServiceUrl = api?.services?.projects || api?.gatewayUrl;
|
|
@@ -4873,7 +4873,7 @@ function CommentThread({
|
|
|
4873
4873
|
/* @__PURE__ */ jsx("p", { className: "text-[11px] text-theme-muted mt-0.5", children: "Seja o primeiro a comentar." })
|
|
4874
4874
|
] }),
|
|
4875
4875
|
!loading && visibleComments.length > 0 && /* @__PURE__ */ jsxs("div", { className: "space-y-0.5", children: [
|
|
4876
|
-
visibleComments.map((comment) => /* @__PURE__ */ jsxs(
|
|
4876
|
+
visibleComments.map((comment) => /* @__PURE__ */ jsxs(React11.Fragment, { children: [
|
|
4877
4877
|
/* @__PURE__ */ jsx(
|
|
4878
4878
|
CommentItem,
|
|
4879
4879
|
{
|
|
@@ -4962,11 +4962,11 @@ function LabelPicker({
|
|
|
4962
4962
|
trigger,
|
|
4963
4963
|
disabled = false
|
|
4964
4964
|
}) {
|
|
4965
|
-
const [open, setOpen] =
|
|
4966
|
-
const [search, setSearch] =
|
|
4967
|
-
const [isCreating, setIsCreating] =
|
|
4968
|
-
const [newLabelName, setNewLabelName] =
|
|
4969
|
-
const [newLabelColor, setNewLabelColor] =
|
|
4965
|
+
const [open, setOpen] = React11.useState(false);
|
|
4966
|
+
const [search, setSearch] = React11.useState("");
|
|
4967
|
+
const [isCreating, setIsCreating] = React11.useState(false);
|
|
4968
|
+
const [newLabelName, setNewLabelName] = React11.useState("");
|
|
4969
|
+
const [newLabelColor, setNewLabelColor] = React11.useState(presetColors[8]);
|
|
4970
4970
|
const selectedIds = new Set(selectedLabels.map((l) => l.id));
|
|
4971
4971
|
const filteredLabels = availableLabels.filter(
|
|
4972
4972
|
(label) => label.name.toLowerCase().includes(search.toLowerCase())
|
|
@@ -5122,8 +5122,8 @@ function AssigneePicker({
|
|
|
5122
5122
|
disabled = false,
|
|
5123
5123
|
maxAssignees
|
|
5124
5124
|
}) {
|
|
5125
|
-
const [open, setOpen] =
|
|
5126
|
-
const [search, setSearch] =
|
|
5125
|
+
const [open, setOpen] = React11.useState(false);
|
|
5126
|
+
const [search, setSearch] = React11.useState("");
|
|
5127
5127
|
const selectedIds = new Set(selectedAssignees.map((a) => a.id));
|
|
5128
5128
|
const canAddMore = maxAssignees ? selectedAssignees.length < maxAssignees : true;
|
|
5129
5129
|
const filteredUsers = availableUsers.filter(
|
|
@@ -5243,8 +5243,8 @@ var statusColors = {
|
|
|
5243
5243
|
DONE: "bg-emerald-500/15 text-emerald-400 border-emerald-500/30"
|
|
5244
5244
|
};
|
|
5245
5245
|
function useMediaQuery3(query) {
|
|
5246
|
-
const [matches, setMatches] =
|
|
5247
|
-
|
|
5246
|
+
const [matches, setMatches] = React11.useState(false);
|
|
5247
|
+
React11.useEffect(() => {
|
|
5248
5248
|
const mql = window.matchMedia(query);
|
|
5249
5249
|
setMatches(mql.matches);
|
|
5250
5250
|
const handler = (e) => setMatches(e.matches);
|
|
@@ -5261,13 +5261,13 @@ function EditableField({
|
|
|
5261
5261
|
inputClassName,
|
|
5262
5262
|
as: Tag = "span"
|
|
5263
5263
|
}) {
|
|
5264
|
-
const [editing, setEditing] =
|
|
5265
|
-
const [localValue, setLocalValue] =
|
|
5266
|
-
const inputRef =
|
|
5267
|
-
|
|
5264
|
+
const [editing, setEditing] = React11.useState(false);
|
|
5265
|
+
const [localValue, setLocalValue] = React11.useState(value);
|
|
5266
|
+
const inputRef = React11.useRef(null);
|
|
5267
|
+
React11.useEffect(() => {
|
|
5268
5268
|
setLocalValue(value);
|
|
5269
5269
|
}, [value]);
|
|
5270
|
-
|
|
5270
|
+
React11.useEffect(() => {
|
|
5271
5271
|
if (editing && inputRef.current) {
|
|
5272
5272
|
inputRef.current.focus();
|
|
5273
5273
|
inputRef.current.select();
|
|
@@ -5321,9 +5321,9 @@ function EditableField({
|
|
|
5321
5321
|
);
|
|
5322
5322
|
}
|
|
5323
5323
|
function EditableDate({ value, onSave, placeholder = "Adicionar data" }) {
|
|
5324
|
-
const [editing, setEditing] =
|
|
5325
|
-
const inputRef =
|
|
5326
|
-
|
|
5324
|
+
const [editing, setEditing] = React11.useState(false);
|
|
5325
|
+
const inputRef = React11.useRef(null);
|
|
5326
|
+
React11.useEffect(() => {
|
|
5327
5327
|
if (editing && inputRef.current) {
|
|
5328
5328
|
inputRef.current.focus();
|
|
5329
5329
|
}
|
|
@@ -5363,13 +5363,13 @@ function EditableDate({ value, onSave, placeholder = "Adicionar data" }) {
|
|
|
5363
5363
|
);
|
|
5364
5364
|
}
|
|
5365
5365
|
function EditableStoryPoints({ value, onSave }) {
|
|
5366
|
-
const [editing, setEditing] =
|
|
5367
|
-
const [localValue, setLocalValue] =
|
|
5368
|
-
const inputRef =
|
|
5369
|
-
|
|
5366
|
+
const [editing, setEditing] = React11.useState(false);
|
|
5367
|
+
const [localValue, setLocalValue] = React11.useState(value !== void 0 ? String(value) : "");
|
|
5368
|
+
const inputRef = React11.useRef(null);
|
|
5369
|
+
React11.useEffect(() => {
|
|
5370
5370
|
setLocalValue(value !== void 0 ? String(value) : "");
|
|
5371
5371
|
}, [value]);
|
|
5372
|
-
|
|
5372
|
+
React11.useEffect(() => {
|
|
5373
5373
|
if (editing && inputRef.current) {
|
|
5374
5374
|
inputRef.current.focus();
|
|
5375
5375
|
inputRef.current.select();
|
|
@@ -5494,13 +5494,13 @@ function AssigneeItem({ assignee, onRemove, showDelete = true }) {
|
|
|
5494
5494
|
] });
|
|
5495
5495
|
}
|
|
5496
5496
|
function SubtaskItem({ subtask, onToggle, onDelete, onUpdate }) {
|
|
5497
|
-
const [editing, setEditing] =
|
|
5498
|
-
const [localTitle, setLocalTitle] =
|
|
5499
|
-
const inputRef =
|
|
5500
|
-
|
|
5497
|
+
const [editing, setEditing] = React11.useState(false);
|
|
5498
|
+
const [localTitle, setLocalTitle] = React11.useState(subtask.title);
|
|
5499
|
+
const inputRef = React11.useRef(null);
|
|
5500
|
+
React11.useEffect(() => {
|
|
5501
5501
|
setLocalTitle(subtask.title);
|
|
5502
5502
|
}, [subtask.title]);
|
|
5503
|
-
|
|
5503
|
+
React11.useEffect(() => {
|
|
5504
5504
|
if (editing && inputRef.current) {
|
|
5505
5505
|
inputRef.current.focus();
|
|
5506
5506
|
inputRef.current.select();
|
|
@@ -5578,10 +5578,10 @@ function SubtaskItem({ subtask, onToggle, onDelete, onUpdate }) {
|
|
|
5578
5578
|
] });
|
|
5579
5579
|
}
|
|
5580
5580
|
function SubtaskAddForm({ onAdd }) {
|
|
5581
|
-
const [adding, setAdding] =
|
|
5582
|
-
const [title, setTitle] =
|
|
5583
|
-
const inputRef =
|
|
5584
|
-
|
|
5581
|
+
const [adding, setAdding] = React11.useState(false);
|
|
5582
|
+
const [title, setTitle] = React11.useState("");
|
|
5583
|
+
const inputRef = React11.useRef(null);
|
|
5584
|
+
React11.useEffect(() => {
|
|
5585
5585
|
if (adding && inputRef.current) {
|
|
5586
5586
|
inputRef.current.focus();
|
|
5587
5587
|
}
|
|
@@ -5659,6 +5659,177 @@ function SubtaskAddForm({ onAdd }) {
|
|
|
5659
5659
|
)
|
|
5660
5660
|
] });
|
|
5661
5661
|
}
|
|
5662
|
+
function DependencySection({
|
|
5663
|
+
taskId,
|
|
5664
|
+
dependencies,
|
|
5665
|
+
onAdd,
|
|
5666
|
+
onRemove,
|
|
5667
|
+
availableTasks
|
|
5668
|
+
}) {
|
|
5669
|
+
const [adding, setAdding] = React11.useState(false);
|
|
5670
|
+
const [selectedTask, setSelectedTask] = React11.useState("");
|
|
5671
|
+
const [depType, setDepType] = React11.useState("BLOCKS");
|
|
5672
|
+
const [loading, setLoading] = React11.useState(null);
|
|
5673
|
+
const [search, setSearch] = React11.useState("");
|
|
5674
|
+
const blockers = dependencies?.filter((d) => d.type === "BLOCKED_BY") ?? [];
|
|
5675
|
+
const blocking = dependencies?.filter((d) => d.type === "BLOCKS") ?? [];
|
|
5676
|
+
const linkedIds = new Set(dependencies?.map((d) => d.relatedTask.id) ?? []);
|
|
5677
|
+
const filteredTasks = (availableTasks ?? []).filter((t) => t.id !== taskId && !linkedIds.has(t.id)).filter((t) => {
|
|
5678
|
+
if (!search) return true;
|
|
5679
|
+
const q = search.toLowerCase();
|
|
5680
|
+
return t.title.toLowerCase().includes(q) || String(t.number ?? "").includes(q);
|
|
5681
|
+
});
|
|
5682
|
+
const handleAdd = async () => {
|
|
5683
|
+
if (!onAdd || !selectedTask) return;
|
|
5684
|
+
setLoading("add");
|
|
5685
|
+
try {
|
|
5686
|
+
await onAdd(taskId, selectedTask, depType);
|
|
5687
|
+
setSelectedTask("");
|
|
5688
|
+
setSearch("");
|
|
5689
|
+
setAdding(false);
|
|
5690
|
+
} finally {
|
|
5691
|
+
setLoading(null);
|
|
5692
|
+
}
|
|
5693
|
+
};
|
|
5694
|
+
const handleRemove = async (depId) => {
|
|
5695
|
+
if (!onRemove) return;
|
|
5696
|
+
setLoading(depId);
|
|
5697
|
+
try {
|
|
5698
|
+
await onRemove(taskId, depId);
|
|
5699
|
+
} finally {
|
|
5700
|
+
setLoading(null);
|
|
5701
|
+
}
|
|
5702
|
+
};
|
|
5703
|
+
const renderDepItem = (dep) => {
|
|
5704
|
+
const isBlocker = dep.type === "BLOCKED_BY";
|
|
5705
|
+
return /* @__PURE__ */ jsxs(
|
|
5706
|
+
"div",
|
|
5707
|
+
{
|
|
5708
|
+
className: "flex items-center gap-2 p-2 rounded-lg bg-theme-subtle/50 group",
|
|
5709
|
+
children: [
|
|
5710
|
+
/* @__PURE__ */ jsxs(
|
|
5711
|
+
Badge,
|
|
5712
|
+
{
|
|
5713
|
+
className: cn(
|
|
5714
|
+
"text-[10px] shrink-0 rounded-full px-2 py-0.5",
|
|
5715
|
+
isBlocker ? "border border-red-500/30 bg-red-500/10 text-red-600 dark:text-red-400" : "border border-amber-500/30 bg-amber-500/10 text-amber-600 dark:text-amber-400"
|
|
5716
|
+
),
|
|
5717
|
+
children: [
|
|
5718
|
+
isBlocker ? /* @__PURE__ */ jsx(Ban, { className: "w-3 h-3 mr-1" }) : /* @__PURE__ */ jsx(ArrowRight, { className: "w-3 h-3 mr-1" }),
|
|
5719
|
+
isBlocker ? "Bloqueado por" : "Bloqueia"
|
|
5720
|
+
]
|
|
5721
|
+
}
|
|
5722
|
+
),
|
|
5723
|
+
/* @__PURE__ */ jsxs("span", { className: "text-sm truncate flex-1 text-theme-primary", children: [
|
|
5724
|
+
dep.relatedTask.number ? `#${dep.relatedTask.number} ` : "",
|
|
5725
|
+
dep.relatedTask.title
|
|
5726
|
+
] }),
|
|
5727
|
+
dep.relatedTask.status && /* @__PURE__ */ jsx(Badge, { className: "text-[10px] shrink-0 rounded-full px-2 py-0.5 border border-theme-subtle bg-theme-subtle/50 text-theme-muted", children: dep.relatedTask.status }),
|
|
5728
|
+
onRemove && /* @__PURE__ */ jsx(
|
|
5729
|
+
Button,
|
|
5730
|
+
{
|
|
5731
|
+
variant: "ghost",
|
|
5732
|
+
size: "sm",
|
|
5733
|
+
onClick: () => handleRemove(dep.id),
|
|
5734
|
+
disabled: loading === dep.id,
|
|
5735
|
+
className: "h-6 w-6 p-0 opacity-0 group-hover:opacity-100 transition-opacity shrink-0",
|
|
5736
|
+
children: /* @__PURE__ */ jsx(Trash2, { className: "w-3 h-3 text-red-500" })
|
|
5737
|
+
}
|
|
5738
|
+
)
|
|
5739
|
+
]
|
|
5740
|
+
},
|
|
5741
|
+
dep.id
|
|
5742
|
+
);
|
|
5743
|
+
};
|
|
5744
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
5745
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
5746
|
+
/* @__PURE__ */ jsxs("label", { className: "text-xs font-medium text-theme-muted uppercase tracking-wide flex items-center gap-1.5", children: [
|
|
5747
|
+
/* @__PURE__ */ jsx(Link2, { className: "w-3.5 h-3.5" }),
|
|
5748
|
+
"Depend\xEAncias"
|
|
5749
|
+
] }),
|
|
5750
|
+
onAdd && availableTasks && availableTasks.length > 0 && /* @__PURE__ */ jsx(
|
|
5751
|
+
Button,
|
|
5752
|
+
{
|
|
5753
|
+
variant: "ghost",
|
|
5754
|
+
size: "sm",
|
|
5755
|
+
onClick: () => setAdding(!adding),
|
|
5756
|
+
className: "h-6 w-6 p-0 text-theme-muted hover:text-theme-primary",
|
|
5757
|
+
children: /* @__PURE__ */ jsx(Plus, { className: "w-3.5 h-3.5" })
|
|
5758
|
+
}
|
|
5759
|
+
)
|
|
5760
|
+
] }),
|
|
5761
|
+
blockers.length > 0 && /* @__PURE__ */ jsx("div", { className: "space-y-1", children: blockers.map(renderDepItem) }),
|
|
5762
|
+
blocking.length > 0 && /* @__PURE__ */ jsx("div", { className: "space-y-1", children: blocking.map(renderDepItem) }),
|
|
5763
|
+
adding && /* @__PURE__ */ jsxs("div", { className: "space-y-2 p-3 rounded-lg border border-theme-subtle bg-theme-subtle/30", children: [
|
|
5764
|
+
/* @__PURE__ */ jsx("div", { className: "flex gap-2", children: /* @__PURE__ */ jsxs(
|
|
5765
|
+
Select,
|
|
5766
|
+
{
|
|
5767
|
+
value: depType,
|
|
5768
|
+
onValueChange: (v) => setDepType(v),
|
|
5769
|
+
children: [
|
|
5770
|
+
/* @__PURE__ */ jsx(SelectTrigger, { className: "h-8 w-[140px] text-xs", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
|
|
5771
|
+
/* @__PURE__ */ jsxs(SelectContent, { children: [
|
|
5772
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "BLOCKS", children: "Bloqueia" }),
|
|
5773
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "BLOCKED_BY", children: "Bloqueado por" })
|
|
5774
|
+
] })
|
|
5775
|
+
]
|
|
5776
|
+
}
|
|
5777
|
+
) }),
|
|
5778
|
+
/* @__PURE__ */ jsx(
|
|
5779
|
+
Input,
|
|
5780
|
+
{
|
|
5781
|
+
value: search,
|
|
5782
|
+
onChange: (e) => setSearch(e.target.value),
|
|
5783
|
+
placeholder: "Pesquisar task...",
|
|
5784
|
+
className: "h-8 text-xs"
|
|
5785
|
+
}
|
|
5786
|
+
),
|
|
5787
|
+
filteredTasks.length > 0 ? /* @__PURE__ */ jsx("div", { className: "max-h-[160px] overflow-y-auto space-y-1", children: filteredTasks.slice(0, 20).map((t) => /* @__PURE__ */ jsxs(
|
|
5788
|
+
"button",
|
|
5789
|
+
{
|
|
5790
|
+
type: "button",
|
|
5791
|
+
onClick: () => setSelectedTask(t.id),
|
|
5792
|
+
className: cn(
|
|
5793
|
+
"w-full text-left p-2 rounded text-xs transition-colors",
|
|
5794
|
+
selectedTask === t.id ? "bg-indigo-500/10 text-indigo-600 dark:text-indigo-400 ring-1 ring-indigo-500/30" : "hover:bg-theme-subtle text-theme-secondary"
|
|
5795
|
+
),
|
|
5796
|
+
children: [
|
|
5797
|
+
t.number ? `#${t.number} ` : "",
|
|
5798
|
+
t.title
|
|
5799
|
+
]
|
|
5800
|
+
},
|
|
5801
|
+
t.id
|
|
5802
|
+
)) }) : /* @__PURE__ */ jsx("p", { className: "text-xs text-theme-muted italic py-2", children: "Nenhuma task dispon\xEDvel" }),
|
|
5803
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-2 pt-1", children: [
|
|
5804
|
+
/* @__PURE__ */ jsx(
|
|
5805
|
+
Button,
|
|
5806
|
+
{
|
|
5807
|
+
size: "sm",
|
|
5808
|
+
onClick: handleAdd,
|
|
5809
|
+
disabled: !selectedTask || loading === "add",
|
|
5810
|
+
className: "h-7 text-xs",
|
|
5811
|
+
children: loading === "add" ? "A adicionar..." : "Adicionar"
|
|
5812
|
+
}
|
|
5813
|
+
),
|
|
5814
|
+
/* @__PURE__ */ jsx(
|
|
5815
|
+
Button,
|
|
5816
|
+
{
|
|
5817
|
+
variant: "ghost",
|
|
5818
|
+
size: "sm",
|
|
5819
|
+
onClick: () => {
|
|
5820
|
+
setAdding(false);
|
|
5821
|
+
setSelectedTask("");
|
|
5822
|
+
setSearch("");
|
|
5823
|
+
},
|
|
5824
|
+
className: "h-7 text-xs",
|
|
5825
|
+
children: "Cancelar"
|
|
5826
|
+
}
|
|
5827
|
+
)
|
|
5828
|
+
] })
|
|
5829
|
+
] }),
|
|
5830
|
+
!dependencies?.length && !adding && /* @__PURE__ */ jsx("p", { className: "text-sm text-theme-muted italic", children: "Sem depend\xEAncias" })
|
|
5831
|
+
] });
|
|
5832
|
+
}
|
|
5662
5833
|
function SubtaskSection({
|
|
5663
5834
|
taskId,
|
|
5664
5835
|
subtasks,
|
|
@@ -5669,7 +5840,7 @@ function SubtaskSection({
|
|
|
5669
5840
|
onDelete,
|
|
5670
5841
|
onUpdate
|
|
5671
5842
|
}) {
|
|
5672
|
-
const [loading, setLoading] =
|
|
5843
|
+
const [loading, setLoading] = React11.useState(null);
|
|
5673
5844
|
const handleAdd = async (title) => {
|
|
5674
5845
|
if (onAdd) {
|
|
5675
5846
|
setLoading("add");
|
|
@@ -5762,6 +5933,9 @@ function TaskDetailContent({
|
|
|
5762
5933
|
onDeleteSubtask,
|
|
5763
5934
|
onUpdateSubtask,
|
|
5764
5935
|
onDeleteTask,
|
|
5936
|
+
onAddDependency,
|
|
5937
|
+
onRemoveDependency,
|
|
5938
|
+
availableTasks,
|
|
5765
5939
|
comments,
|
|
5766
5940
|
currentUser,
|
|
5767
5941
|
statuses,
|
|
@@ -5978,6 +6152,17 @@ function TaskDetailContent({
|
|
|
5978
6152
|
}
|
|
5979
6153
|
),
|
|
5980
6154
|
/* @__PURE__ */ jsx(Separator, { className: "bg-theme-subtle" }),
|
|
6155
|
+
/* @__PURE__ */ jsx(
|
|
6156
|
+
DependencySection,
|
|
6157
|
+
{
|
|
6158
|
+
taskId: task.id,
|
|
6159
|
+
dependencies: task.dependencies,
|
|
6160
|
+
onAdd: onAddDependency,
|
|
6161
|
+
onRemove: onRemoveDependency,
|
|
6162
|
+
availableTasks
|
|
6163
|
+
}
|
|
6164
|
+
),
|
|
6165
|
+
/* @__PURE__ */ jsx(Separator, { className: "bg-theme-subtle" }),
|
|
5981
6166
|
/* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
5982
6167
|
/* @__PURE__ */ jsx("label", { className: "text-xs font-medium text-theme-muted uppercase tracking-wide", children: "Coment\xE1rios" }),
|
|
5983
6168
|
/* @__PURE__ */ jsx(
|
|
@@ -6054,6 +6239,9 @@ function TaskDetailSheet({
|
|
|
6054
6239
|
onDeleteSubtask,
|
|
6055
6240
|
onUpdateSubtask,
|
|
6056
6241
|
onDeleteTask,
|
|
6242
|
+
onAddDependency,
|
|
6243
|
+
onRemoveDependency,
|
|
6244
|
+
availableTasks,
|
|
6057
6245
|
comments,
|
|
6058
6246
|
currentUser,
|
|
6059
6247
|
loading = false,
|
|
@@ -6082,6 +6270,9 @@ function TaskDetailSheet({
|
|
|
6082
6270
|
onDeleteSubtask,
|
|
6083
6271
|
onUpdateSubtask,
|
|
6084
6272
|
onDeleteTask,
|
|
6273
|
+
onAddDependency,
|
|
6274
|
+
onRemoveDependency,
|
|
6275
|
+
availableTasks,
|
|
6085
6276
|
comments,
|
|
6086
6277
|
currentUser,
|
|
6087
6278
|
statuses: availableStatuses,
|
|
@@ -6213,7 +6404,7 @@ function TaskCard({
|
|
|
6213
6404
|
className,
|
|
6214
6405
|
...props
|
|
6215
6406
|
}) {
|
|
6216
|
-
const [sheetOpen, setSheetOpen] =
|
|
6407
|
+
const [sheetOpen, setSheetOpen] = React11.useState(false);
|
|
6217
6408
|
if (!task) {
|
|
6218
6409
|
return /* @__PURE__ */ jsx(TaskCardSkeleton, { compact, className });
|
|
6219
6410
|
}
|
|
@@ -6653,6 +6844,224 @@ function TaskDetailDialog({
|
|
|
6653
6844
|
);
|
|
6654
6845
|
}
|
|
6655
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";
|
|
6656
7065
|
var priorityColors2 = {
|
|
6657
7066
|
LOW: "bg-slate-500/15 text-slate-400 border-slate-500/30",
|
|
6658
7067
|
MEDIUM: "bg-blue-500/15 text-blue-400 border-blue-500/30",
|
|
@@ -6701,8 +7110,8 @@ function TaskCard2({
|
|
|
6701
7110
|
onDragEnd,
|
|
6702
7111
|
onTouchDragStart
|
|
6703
7112
|
}) {
|
|
6704
|
-
const touchTimerRef =
|
|
6705
|
-
const hasMoved =
|
|
7113
|
+
const touchTimerRef = React11.useRef(null);
|
|
7114
|
+
const hasMoved = React11.useRef(false);
|
|
6706
7115
|
const handleTouchStart = (e) => {
|
|
6707
7116
|
hasMoved.current = false;
|
|
6708
7117
|
touchTimerRef.current = setTimeout(() => {
|
|
@@ -6810,6 +7219,8 @@ function Column({
|
|
|
6810
7219
|
onTaskClick,
|
|
6811
7220
|
onAddTask,
|
|
6812
7221
|
onRenameColumn,
|
|
7222
|
+
onEditColumn,
|
|
7223
|
+
onDeleteColumn,
|
|
6813
7224
|
externalDnD,
|
|
6814
7225
|
draggedTask,
|
|
6815
7226
|
onDragStart,
|
|
@@ -6819,16 +7230,24 @@ function Column({
|
|
|
6819
7230
|
isDropTarget,
|
|
6820
7231
|
onTouchDragStart
|
|
6821
7232
|
}) {
|
|
6822
|
-
const [isRenaming, setIsRenaming] =
|
|
6823
|
-
const [renameValue, setRenameValue] =
|
|
6824
|
-
const renameInputRef =
|
|
6825
|
-
const [isAddingTask, setIsAddingTask] =
|
|
6826
|
-
const [newTaskTitle, setNewTaskTitle] =
|
|
6827
|
-
const taskInputRef =
|
|
6828
|
-
|
|
7233
|
+
const [isRenaming, setIsRenaming] = React11.useState(false);
|
|
7234
|
+
const [renameValue, setRenameValue] = React11.useState(column.title);
|
|
7235
|
+
const renameInputRef = React11.useRef(null);
|
|
7236
|
+
const [isAddingTask, setIsAddingTask] = React11.useState(false);
|
|
7237
|
+
const [newTaskTitle, setNewTaskTitle] = React11.useState("");
|
|
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]);
|
|
7247
|
+
React11.useEffect(() => {
|
|
6829
7248
|
if (isRenaming) renameInputRef.current?.focus();
|
|
6830
7249
|
}, [isRenaming]);
|
|
6831
|
-
|
|
7250
|
+
React11.useEffect(() => {
|
|
6832
7251
|
if (isAddingTask) taskInputRef.current?.focus();
|
|
6833
7252
|
}, [isAddingTask]);
|
|
6834
7253
|
const handleRenameSubmit = () => {
|
|
@@ -6879,7 +7298,7 @@ function Column({
|
|
|
6879
7298
|
isDropTarget && "border-primary-light/50 bg-primary/5"
|
|
6880
7299
|
),
|
|
6881
7300
|
children: [
|
|
6882
|
-
/* @__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: [
|
|
6883
7302
|
column.color && /* @__PURE__ */ jsx(
|
|
6884
7303
|
"div",
|
|
6885
7304
|
{
|
|
@@ -6911,23 +7330,34 @@ function Column({
|
|
|
6911
7330
|
children: column.title
|
|
6912
7331
|
}
|
|
6913
7332
|
),
|
|
6914
|
-
/* @__PURE__ */
|
|
6915
|
-
|
|
6916
|
-
|
|
6917
|
-
|
|
6918
|
-
|
|
6919
|
-
"text-
|
|
6920
|
-
|
|
6921
|
-
|
|
6922
|
-
|
|
6923
|
-
|
|
6924
|
-
|
|
6925
|
-
|
|
6926
|
-
|
|
6927
|
-
|
|
6928
|
-
|
|
6929
|
-
|
|
6930
|
-
|
|
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
|
+
] })
|
|
6931
7361
|
] }),
|
|
6932
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: [
|
|
6933
7363
|
"\u26A0 WIP limit exceeded (",
|
|
@@ -7009,7 +7439,17 @@ function Column({
|
|
|
7009
7439
|
"Adicionar tarefa"
|
|
7010
7440
|
]
|
|
7011
7441
|
}
|
|
7012
|
-
) })
|
|
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
|
+
)
|
|
7013
7453
|
]
|
|
7014
7454
|
}
|
|
7015
7455
|
);
|
|
@@ -7022,6 +7462,8 @@ function KanbanBoard({
|
|
|
7022
7462
|
onAddTask,
|
|
7023
7463
|
onAddColumn,
|
|
7024
7464
|
onRenameColumn,
|
|
7465
|
+
onEditColumn,
|
|
7466
|
+
onDeleteColumn,
|
|
7025
7467
|
className,
|
|
7026
7468
|
externalDnD = false,
|
|
7027
7469
|
onTaskUpdate,
|
|
@@ -7043,13 +7485,13 @@ function KanbanBoard({
|
|
|
7043
7485
|
onUpdateSubtask,
|
|
7044
7486
|
onTaskClick
|
|
7045
7487
|
}) {
|
|
7046
|
-
const [draggedTask, setDraggedTask] =
|
|
7047
|
-
const [dropTargetColumnId, setDropTargetColumnId] =
|
|
7048
|
-
const [touchDraggedTask, setTouchDraggedTask] =
|
|
7049
|
-
const handleTouchDragStart =
|
|
7488
|
+
const [draggedTask, setDraggedTask] = React11.useState(null);
|
|
7489
|
+
const [dropTargetColumnId, setDropTargetColumnId] = React11.useState(null);
|
|
7490
|
+
const [touchDraggedTask, setTouchDraggedTask] = React11.useState(null);
|
|
7491
|
+
const handleTouchDragStart = React11.useCallback((task, fromColumnId) => {
|
|
7050
7492
|
setTouchDraggedTask({ task, fromColumnId });
|
|
7051
7493
|
}, []);
|
|
7052
|
-
const handleTouchDrop =
|
|
7494
|
+
const handleTouchDrop = React11.useCallback((toColumnId) => {
|
|
7053
7495
|
if (!touchDraggedTask) return;
|
|
7054
7496
|
const { task, fromColumnId } = touchDraggedTask;
|
|
7055
7497
|
if (fromColumnId !== toColumnId) {
|
|
@@ -7065,15 +7507,15 @@ function KanbanBoard({
|
|
|
7065
7507
|
}
|
|
7066
7508
|
setTouchDraggedTask(null);
|
|
7067
7509
|
}, [touchDraggedTask, columns, onTaskMove, onColumnChange]);
|
|
7068
|
-
const cancelTouchDrag =
|
|
7510
|
+
const cancelTouchDrag = React11.useCallback(() => setTouchDraggedTask(null), []);
|
|
7069
7511
|
const isTouchDragging = touchDraggedTask !== null;
|
|
7070
7512
|
const effectiveDraggedTask = draggedTask || touchDraggedTask;
|
|
7071
|
-
const [sheetOpen, setSheetOpen] =
|
|
7072
|
-
const [selectedTask, setSelectedTask] =
|
|
7073
|
-
const [isAddingColumn, setIsAddingColumn] =
|
|
7074
|
-
const [newColumnTitle, setNewColumnTitle] =
|
|
7075
|
-
const addColumnInputRef =
|
|
7076
|
-
|
|
7513
|
+
const [sheetOpen, setSheetOpen] = React11.useState(false);
|
|
7514
|
+
const [selectedTask, setSelectedTask] = React11.useState(null);
|
|
7515
|
+
const [isAddingColumn, setIsAddingColumn] = React11.useState(false);
|
|
7516
|
+
const [newColumnTitle, setNewColumnTitle] = React11.useState("");
|
|
7517
|
+
const addColumnInputRef = React11.useRef(null);
|
|
7518
|
+
React11.useEffect(() => {
|
|
7077
7519
|
if (isAddingColumn) addColumnInputRef.current?.focus();
|
|
7078
7520
|
}, [isAddingColumn]);
|
|
7079
7521
|
const handleAddColumnSubmit = () => {
|
|
@@ -7152,6 +7594,8 @@ function KanbanBoard({
|
|
|
7152
7594
|
onTaskClick: handleTaskClick,
|
|
7153
7595
|
onAddTask,
|
|
7154
7596
|
onRenameColumn,
|
|
7597
|
+
onEditColumn,
|
|
7598
|
+
onDeleteColumn,
|
|
7155
7599
|
externalDnD,
|
|
7156
7600
|
draggedTask: effectiveDraggedTask,
|
|
7157
7601
|
onDragStart: handleDragStart,
|
|
@@ -7445,7 +7889,7 @@ function PlanBadgeFull({
|
|
|
7445
7889
|
config.bgColor,
|
|
7446
7890
|
config.borderColor
|
|
7447
7891
|
),
|
|
7448
|
-
children: /* @__PURE__ */ jsx("span", { className: config.color, children:
|
|
7892
|
+
children: /* @__PURE__ */ jsx("span", { className: config.color, children: React11.cloneElement(config.icon, {
|
|
7449
7893
|
className: "w-5 h-5"
|
|
7450
7894
|
}) })
|
|
7451
7895
|
}
|
|
@@ -7521,14 +7965,14 @@ function BoardsSwitcher({
|
|
|
7521
7965
|
compact = false,
|
|
7522
7966
|
className
|
|
7523
7967
|
}) {
|
|
7524
|
-
const [isOpen, setIsOpen] =
|
|
7525
|
-
const [isCreating, setIsCreating] =
|
|
7526
|
-
const [newBoardName, setNewBoardName] =
|
|
7527
|
-
const [menuPos, setMenuPos] =
|
|
7528
|
-
const triggerRef =
|
|
7529
|
-
const dropdownRef =
|
|
7530
|
-
const createInputRef =
|
|
7531
|
-
|
|
7968
|
+
const [isOpen, setIsOpen] = React11.useState(false);
|
|
7969
|
+
const [isCreating, setIsCreating] = React11.useState(false);
|
|
7970
|
+
const [newBoardName, setNewBoardName] = React11.useState("");
|
|
7971
|
+
const [menuPos, setMenuPos] = React11.useState(null);
|
|
7972
|
+
const triggerRef = React11.useRef(null);
|
|
7973
|
+
const dropdownRef = React11.useRef(null);
|
|
7974
|
+
const createInputRef = React11.useRef(null);
|
|
7975
|
+
React11.useEffect(() => {
|
|
7532
7976
|
if (!isOpen) return;
|
|
7533
7977
|
function handleClickOutside(event) {
|
|
7534
7978
|
if (!triggerRef.current?.contains(event.target) && !dropdownRef.current?.contains(event.target)) {
|
|
@@ -7540,7 +7984,7 @@ function BoardsSwitcher({
|
|
|
7540
7984
|
document.addEventListener("mousedown", handleClickOutside);
|
|
7541
7985
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
7542
7986
|
}, [isOpen]);
|
|
7543
|
-
|
|
7987
|
+
React11.useEffect(() => {
|
|
7544
7988
|
if (!isOpen) return;
|
|
7545
7989
|
const close = () => setIsOpen(false);
|
|
7546
7990
|
window.addEventListener("scroll", close, true);
|
|
@@ -7550,7 +7994,7 @@ function BoardsSwitcher({
|
|
|
7550
7994
|
window.removeEventListener("resize", close);
|
|
7551
7995
|
};
|
|
7552
7996
|
}, [isOpen]);
|
|
7553
|
-
|
|
7997
|
+
React11.useEffect(() => {
|
|
7554
7998
|
if (isCreating) createInputRef.current?.focus();
|
|
7555
7999
|
}, [isCreating]);
|
|
7556
8000
|
const handleToggle = () => {
|
|
@@ -7691,11 +8135,11 @@ function SprintFilter({
|
|
|
7691
8135
|
compact = false,
|
|
7692
8136
|
className
|
|
7693
8137
|
}) {
|
|
7694
|
-
const [isOpen, setIsOpen] =
|
|
7695
|
-
const [menuPos, setMenuPos] =
|
|
7696
|
-
const triggerRef =
|
|
7697
|
-
const dropdownRef =
|
|
7698
|
-
|
|
8138
|
+
const [isOpen, setIsOpen] = React11.useState(false);
|
|
8139
|
+
const [menuPos, setMenuPos] = React11.useState(null);
|
|
8140
|
+
const triggerRef = React11.useRef(null);
|
|
8141
|
+
const dropdownRef = React11.useRef(null);
|
|
8142
|
+
React11.useEffect(() => {
|
|
7699
8143
|
if (!isOpen) return;
|
|
7700
8144
|
function handleClickOutside(event) {
|
|
7701
8145
|
if (!triggerRef.current?.contains(event.target) && !dropdownRef.current?.contains(event.target)) {
|
|
@@ -7705,7 +8149,7 @@ function SprintFilter({
|
|
|
7705
8149
|
document.addEventListener("mousedown", handleClickOutside);
|
|
7706
8150
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
7707
8151
|
}, [isOpen]);
|
|
7708
|
-
|
|
8152
|
+
React11.useEffect(() => {
|
|
7709
8153
|
if (!isOpen) return;
|
|
7710
8154
|
const close = () => setIsOpen(false);
|
|
7711
8155
|
window.addEventListener("scroll", close, true);
|
|
@@ -7724,7 +8168,7 @@ function SprintFilter({
|
|
|
7724
8168
|
};
|
|
7725
8169
|
const selectedSprint = selectedSprintId ? sprints.find((s) => s.id === selectedSprintId) : null;
|
|
7726
8170
|
const displayLabel = selectedSprint ? selectedSprint.name : selectedSprintId === null ? "Todas as tarefas" : activeSprint?.name ?? "Todas as tarefas";
|
|
7727
|
-
const sortedSprints =
|
|
8171
|
+
const sortedSprints = React11.useMemo(() => {
|
|
7728
8172
|
const order = { ACTIVE: 0, PLANNED: 1, COMPLETED: 2 };
|
|
7729
8173
|
return [...sprints].sort((a, b) => (order[a.status] ?? 9) - (order[b.status] ?? 9));
|
|
7730
8174
|
}, [sprints]);
|
|
@@ -7887,7 +8331,7 @@ function ActivityTrail({
|
|
|
7887
8331
|
className,
|
|
7888
8332
|
compact = false
|
|
7889
8333
|
}) {
|
|
7890
|
-
const [showFilters, setShowFilters] =
|
|
8334
|
+
const [showFilters, setShowFilters] = React11.useState(false);
|
|
7891
8335
|
const filteredActivities = filterActions && filterActions.length > 0 ? activities.filter((a) => filterActions.includes(a.action)) : activities;
|
|
7892
8336
|
const grouped = groupByDate(filteredActivities);
|
|
7893
8337
|
return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col", className), children: [
|
|
@@ -8257,7 +8701,7 @@ function Checkbox({
|
|
|
8257
8701
|
}
|
|
8258
8702
|
);
|
|
8259
8703
|
}
|
|
8260
|
-
var Switch =
|
|
8704
|
+
var Switch = React11.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
8261
8705
|
SwitchPrimitive.Root,
|
|
8262
8706
|
{
|
|
8263
8707
|
className: cn(
|
|
@@ -8675,11 +9119,11 @@ function CreateProjectDialog({
|
|
|
8675
9119
|
const gql = useOrganifyGql();
|
|
8676
9120
|
const { workspace } = useOrganifyWorkspace();
|
|
8677
9121
|
const { navigate } = useOrganifyNavigation();
|
|
8678
|
-
const [name, setName] =
|
|
8679
|
-
const [type, setType] =
|
|
8680
|
-
const [error, setError] =
|
|
8681
|
-
const [loading, setLoading] =
|
|
8682
|
-
|
|
9122
|
+
const [name, setName] = React11.useState("");
|
|
9123
|
+
const [type, setType] = React11.useState("KANBAN");
|
|
9124
|
+
const [error, setError] = React11.useState("");
|
|
9125
|
+
const [loading, setLoading] = React11.useState(false);
|
|
9126
|
+
React11.useEffect(() => {
|
|
8683
9127
|
if (open) {
|
|
8684
9128
|
setName("");
|
|
8685
9129
|
setType("KANBAN");
|
|
@@ -8798,10 +9242,10 @@ function CreateWorkspaceDialog({
|
|
|
8798
9242
|
const gql = useOrganifyGql();
|
|
8799
9243
|
const { navigate } = useOrganifyNavigation();
|
|
8800
9244
|
const { workspaces, onWorkspacesChange, onWorkspaceChange } = useOrganify();
|
|
8801
|
-
const [name, setName] =
|
|
8802
|
-
const [error, setError] =
|
|
8803
|
-
const [loading, setLoading] =
|
|
8804
|
-
|
|
9245
|
+
const [name, setName] = React11.useState("");
|
|
9246
|
+
const [error, setError] = React11.useState("");
|
|
9247
|
+
const [loading, setLoading] = React11.useState(false);
|
|
9248
|
+
React11.useEffect(() => {
|
|
8805
9249
|
if (open) {
|
|
8806
9250
|
setName("");
|
|
8807
9251
|
setError("");
|
|
@@ -8914,13 +9358,13 @@ function CreateSprintDialog({
|
|
|
8914
9358
|
const gql = useOrganifyGql();
|
|
8915
9359
|
const { project } = useOrganifyProject();
|
|
8916
9360
|
const effectiveProjectId = propProjectId ?? project?.id;
|
|
8917
|
-
const [name, setName] =
|
|
8918
|
-
const [goal, setGoal] =
|
|
8919
|
-
const [startDate, setStartDate] =
|
|
8920
|
-
const [endDate, setEndDate] =
|
|
8921
|
-
const [error, setError] =
|
|
8922
|
-
const [loading, setLoading] =
|
|
8923
|
-
|
|
9361
|
+
const [name, setName] = React11.useState("");
|
|
9362
|
+
const [goal, setGoal] = React11.useState("");
|
|
9363
|
+
const [startDate, setStartDate] = React11.useState("");
|
|
9364
|
+
const [endDate, setEndDate] = React11.useState("");
|
|
9365
|
+
const [error, setError] = React11.useState("");
|
|
9366
|
+
const [loading, setLoading] = React11.useState(false);
|
|
9367
|
+
React11.useEffect(() => {
|
|
8924
9368
|
if (open) {
|
|
8925
9369
|
setName("");
|
|
8926
9370
|
setGoal("");
|
|
@@ -9061,12 +9505,12 @@ function CreateEpicDialog({
|
|
|
9061
9505
|
const gql = useOrganifyGql();
|
|
9062
9506
|
const { project } = useOrganifyProject();
|
|
9063
9507
|
const effectiveProjectId = propProjectId ?? project?.id;
|
|
9064
|
-
const [name, setName] =
|
|
9065
|
-
const [description, setDescription] =
|
|
9066
|
-
const [color, setColor] =
|
|
9067
|
-
const [error, setError] =
|
|
9068
|
-
const [loading, setLoading] =
|
|
9069
|
-
|
|
9508
|
+
const [name, setName] = React11.useState("");
|
|
9509
|
+
const [description, setDescription] = React11.useState("");
|
|
9510
|
+
const [color, setColor] = React11.useState(EPIC_COLORS[0]);
|
|
9511
|
+
const [error, setError] = React11.useState("");
|
|
9512
|
+
const [loading, setLoading] = React11.useState(false);
|
|
9513
|
+
React11.useEffect(() => {
|
|
9070
9514
|
if (open) {
|
|
9071
9515
|
setName("");
|
|
9072
9516
|
setDescription("");
|
|
@@ -9202,11 +9646,11 @@ function CreateTaskDialog({
|
|
|
9202
9646
|
const gql = useOrganifyGql();
|
|
9203
9647
|
const projectCtx = useOrganifyProject();
|
|
9204
9648
|
const projectId = projectIdProp ?? projectCtx?.project?.id;
|
|
9205
|
-
const [title, setTitle] =
|
|
9206
|
-
const [priority, setPriority] =
|
|
9207
|
-
const [error, setError] =
|
|
9208
|
-
const [loading, setLoading] =
|
|
9209
|
-
|
|
9649
|
+
const [title, setTitle] = React11.useState("");
|
|
9650
|
+
const [priority, setPriority] = React11.useState("NONE");
|
|
9651
|
+
const [error, setError] = React11.useState("");
|
|
9652
|
+
const [loading, setLoading] = React11.useState(false);
|
|
9653
|
+
React11.useEffect(() => {
|
|
9210
9654
|
if (open) {
|
|
9211
9655
|
setTitle("");
|
|
9212
9656
|
setPriority("NONE");
|
|
@@ -9334,14 +9778,14 @@ function InviteMemberDialog({
|
|
|
9334
9778
|
const gql = useOrganifyGql();
|
|
9335
9779
|
const { workspace } = useOrganifyWorkspace();
|
|
9336
9780
|
const effectiveSlug = propWorkspaceSlug ?? workspace?.slug;
|
|
9337
|
-
const [email, setEmail] =
|
|
9338
|
-
const [role, setRole] =
|
|
9339
|
-
const [error, setError] =
|
|
9340
|
-
const [loading, setLoading] =
|
|
9341
|
-
const [sentInvites, setSentInvites] =
|
|
9342
|
-
const [loadingInvites, setLoadingInvites] =
|
|
9343
|
-
const [activeTab, setActiveTab] =
|
|
9344
|
-
const loadInvites =
|
|
9781
|
+
const [email, setEmail] = React11.useState("");
|
|
9782
|
+
const [role, setRole] = React11.useState("MEMBER");
|
|
9783
|
+
const [error, setError] = React11.useState("");
|
|
9784
|
+
const [loading, setLoading] = React11.useState(false);
|
|
9785
|
+
const [sentInvites, setSentInvites] = React11.useState([]);
|
|
9786
|
+
const [loadingInvites, setLoadingInvites] = React11.useState(false);
|
|
9787
|
+
const [activeTab, setActiveTab] = React11.useState(defaultView);
|
|
9788
|
+
const loadInvites = React11.useCallback(async () => {
|
|
9345
9789
|
if (!open || !effectiveSlug) return;
|
|
9346
9790
|
setLoadingInvites(true);
|
|
9347
9791
|
try {
|
|
@@ -9357,7 +9801,7 @@ function InviteMemberDialog({
|
|
|
9357
9801
|
setLoadingInvites(false);
|
|
9358
9802
|
}
|
|
9359
9803
|
}, [open, effectiveSlug, gql]);
|
|
9360
|
-
|
|
9804
|
+
React11.useEffect(() => {
|
|
9361
9805
|
if (open) {
|
|
9362
9806
|
setEmail("");
|
|
9363
9807
|
setRole("MEMBER");
|