organify-ui 0.3.3 → 0.3.4
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/{chat-mock-data-DST5Tn_H.d.ts → ai-chat-sidebar-BYphYj2N.d.ts} +34 -2
- package/dist/{chunk-Z7OW3K7Y.js → chunk-NUA6OPJV.js} +658 -208
- package/dist/chunk-NUA6OPJV.js.map +1 -0
- package/dist/components/chat/index.d.ts +53 -3
- package/dist/components/chat/index.js +1 -1
- package/dist/index.d.ts +22 -7
- package/dist/index.js +369 -208
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/globals.css +33 -0
- package/dist/chunk-Z7OW3K7Y.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
export { I18nProvider, createTranslator, useI18n } from './chunk-FQA33MF4.js';
|
|
2
2
|
export { ThemeProvider, useTheme } from './chunk-RFOKENE3.js';
|
|
3
|
-
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, Drawer, DrawerContent, DrawerHeader, DrawerTitle, DrawerDescription, Separator, ResponsiveDialog, Label, Input, Textarea, Button, Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from './chunk-
|
|
4
|
-
export { Alert, Button, ChatMessages, ChatSidebar, CreateRoomDialog, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, 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, alertVariants, buttonVariants, generateAutoReplies, getMockMentionOptions, getRoomPermissions, inputVariants, orgLoaderVariants, typingIndicator, useChat } from './chunk-
|
|
3
|
+
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, Drawer, DrawerContent, DrawerHeader, DrawerTitle, DrawerDescription, Separator, ResponsiveDialog, Label, Input, Textarea, Button, Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from './chunk-NUA6OPJV.js';
|
|
4
|
+
export { AiChatSidebar, Alert, Button, ChatMessages, ChatSidebar, CreateRoomDialog, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, 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, alertVariants, buttonVariants, generateAutoReplies, getMockMentionOptions, getRoomPermissions, inputVariants, orgLoaderVariants, typingIndicator, useChat } from './chunk-NUA6OPJV.js';
|
|
5
5
|
import { Popover, PopoverTrigger, PopoverContent } from './chunk-A2H2TBSV.js';
|
|
6
6
|
export { NotificationBell, NotificationItem, NotificationList, OrganifyNotifications, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, PresenceAvatarStack, PresenceIndicator, useNotifications, usePresence } from './chunk-A2H2TBSV.js';
|
|
7
7
|
import { cn, Avatar, AvatarImage, AvatarFallback, TooltipProvider, Tooltip, TooltipTrigger, TooltipContent, Skeleton, useOrganify, useOrganifyGql, ScrollArea, useOrganifyUser, useOrganifyApi, Badge, useOrganifyWorkspace, useOrganifyNavigation, useOrganifyProject } from './chunk-VHQZS77G.js';
|
|
8
8
|
export { Avatar, AvatarFallback, AvatarImage, Badge, OrganifyContext, OrganifyProvider, ScrollArea, ScrollBar, Skeleton, SkeletonCard, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, avatarVariants, badgeVariants, cn, useOrganify, useOrganifyApi, useOrganifyGql, useOrganifyNavigation, useOrganifyProject, useOrganifyRest, useOrganifyUser, useOrganifyWorkspace } from './chunk-VHQZS77G.js';
|
|
9
9
|
import { OrgDiamond, OrgPlus, OrgComment, OrgEdit, OrgTrash, OrgCheckCircle, OrgAttachment, OrgCalendar, OrgMail, OrgBoard, OrgSprint, OrgRocket, OrgWarning, OrgFlag, OrgShield, OrgZap, OrgStar } from './chunk-MZKEDV5W.js';
|
|
10
10
|
export { OrgAI, OrgActivity, OrgArrowLeft, OrgArrowRight, OrgAttachment, OrgBell, OrgBoard, OrgCalendar, OrgCelebrate, OrgChart, OrgChat, OrgCheck, OrgCheckCircle, OrgChevronDown, OrgChevronLeft, OrgChevronRight, OrgChevronUp, OrgClock, OrgClose, OrgComment, OrgCopy, OrgCreditCard, 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';
|
|
11
|
-
import * as
|
|
11
|
+
import * as React5 from 'react';
|
|
12
12
|
import * as SwitchPrimitive from '@radix-ui/react-switch';
|
|
13
13
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
14
14
|
import * as ProgressPrimitive from '@radix-ui/react-progress';
|
|
@@ -25,8 +25,8 @@ export { toast } from 'sonner';
|
|
|
25
25
|
import { useQueryClient, useQuery } from '@tanstack/react-query';
|
|
26
26
|
export { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
27
27
|
|
|
28
|
-
var Toggle =
|
|
29
|
-
const id =
|
|
28
|
+
var Toggle = React5.forwardRef(({ className, label, description, ...props }, ref) => {
|
|
29
|
+
const id = React5.useId();
|
|
30
30
|
if (label) {
|
|
31
31
|
return /* @__PURE__ */ jsxs(
|
|
32
32
|
"div",
|
|
@@ -167,7 +167,7 @@ function UserAvatar({
|
|
|
167
167
|
] }) });
|
|
168
168
|
}
|
|
169
169
|
UserAvatar.displayName = "UserAvatar";
|
|
170
|
-
var Progress =
|
|
170
|
+
var Progress = React5.forwardRef(({ className, value, showLabel, label, variant = "default", ...props }, ref) => /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
171
171
|
(label || showLabel) && /* @__PURE__ */ jsxs("div", { className: "flex items-end justify-between", children: [
|
|
172
172
|
label && /* @__PURE__ */ jsx("span", { className: "text-label uppercase tracking-widest text-org-text-muted", children: label }),
|
|
173
173
|
showLabel && /* @__PURE__ */ jsxs("span", { className: "font-mono text-lg text-primary-light", children: [
|
|
@@ -345,8 +345,8 @@ function EmptyState({
|
|
|
345
345
|
);
|
|
346
346
|
}
|
|
347
347
|
function useMediaQuery(query) {
|
|
348
|
-
const [matches, setMatches] =
|
|
349
|
-
|
|
348
|
+
const [matches, setMatches] = React5.useState(false);
|
|
349
|
+
React5.useEffect(() => {
|
|
350
350
|
const mql = window.matchMedia(query);
|
|
351
351
|
setMatches(mql.matches);
|
|
352
352
|
const handler = (e) => setMatches(e.matches);
|
|
@@ -763,77 +763,127 @@ function DockSidebar({
|
|
|
763
763
|
onExpandedChange,
|
|
764
764
|
hoverExpand = false,
|
|
765
765
|
renderLink,
|
|
766
|
+
mobileOpen = false,
|
|
767
|
+
onMobileClose,
|
|
766
768
|
className,
|
|
767
769
|
// Destructure hoverExpand out so it doesn't leak to DOM via ...props
|
|
768
770
|
...props
|
|
769
771
|
}) {
|
|
770
772
|
const handleToggle = () => onExpandedChange?.(!expanded);
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
{
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
773
|
+
React5.useEffect(() => {
|
|
774
|
+
if (!mobileOpen) return;
|
|
775
|
+
const onKey = (e) => {
|
|
776
|
+
if (e.key === "Escape") onMobileClose?.();
|
|
777
|
+
};
|
|
778
|
+
document.addEventListener("keydown", onKey);
|
|
779
|
+
return () => document.removeEventListener("keydown", onKey);
|
|
780
|
+
}, [mobileOpen, onMobileClose]);
|
|
781
|
+
React5.useEffect(() => {
|
|
782
|
+
if (!mobileOpen) return;
|
|
783
|
+
document.body.style.overflow = "hidden";
|
|
784
|
+
return () => {
|
|
785
|
+
document.body.style.overflow = "";
|
|
786
|
+
};
|
|
787
|
+
}, [mobileOpen]);
|
|
788
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
789
|
+
mobileOpen && /* @__PURE__ */ jsx(
|
|
790
|
+
"div",
|
|
791
|
+
{
|
|
792
|
+
className: "fixed inset-0 z-[49] bg-black/60 backdrop-blur-sm sm:hidden animate-in fade-in duration-200",
|
|
793
|
+
onClick: onMobileClose,
|
|
794
|
+
"aria-hidden": "true"
|
|
795
|
+
}
|
|
796
|
+
),
|
|
797
|
+
/* @__PURE__ */ jsxs(
|
|
798
|
+
"aside",
|
|
799
|
+
{
|
|
800
|
+
className: cn(
|
|
801
|
+
// Desktop: normal fixed sidebar
|
|
802
|
+
"hidden sm:flex",
|
|
803
|
+
sidebarVariants({ state: expanded ? "expanded" : "collapsed" }),
|
|
804
|
+
// Mobile: overlay drawer mode
|
|
805
|
+
mobileOpen && "flex sm:flex fixed inset-y-0 left-0 z-50 w-64 shadow-2xl shadow-black/50 animate-in slide-in-from-left duration-300",
|
|
806
|
+
!mobileOpen && "max-sm:hidden",
|
|
807
|
+
className
|
|
808
|
+
),
|
|
809
|
+
onMouseEnter: () => hoverExpand && onExpandedChange?.(true),
|
|
810
|
+
onMouseLeave: () => hoverExpand && onExpandedChange?.(false),
|
|
811
|
+
...props,
|
|
812
|
+
children: [
|
|
813
|
+
/* @__PURE__ */ jsxs("div", { className: cn(
|
|
814
|
+
"flex items-center px-3 h-16 border-b border-white/10",
|
|
815
|
+
expanded || mobileOpen ? "justify-between" : "justify-center"
|
|
816
|
+
), children: [
|
|
817
|
+
header,
|
|
818
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
819
|
+
mobileOpen && /* @__PURE__ */ jsx(
|
|
820
|
+
"button",
|
|
821
|
+
{
|
|
822
|
+
type: "button",
|
|
823
|
+
onClick: onMobileClose,
|
|
824
|
+
"aria-label": "Fechar menu",
|
|
825
|
+
className: "flex h-7 w-7 items-center justify-center rounded-xl text-org-text-muted hover:bg-white/[0.05] hover:text-org-text sm:hidden",
|
|
826
|
+
children: /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", children: /* @__PURE__ */ jsx("path", { d: "M4 4L12 12M12 4L4 12", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }) })
|
|
827
|
+
}
|
|
793
828
|
),
|
|
794
|
-
|
|
795
|
-
"
|
|
829
|
+
/* @__PURE__ */ jsx(
|
|
830
|
+
"button",
|
|
796
831
|
{
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
fill: "none",
|
|
832
|
+
type: "button",
|
|
833
|
+
onClick: handleToggle,
|
|
834
|
+
"aria-label": expanded ? "Collapse sidebar" : "Expand sidebar",
|
|
801
835
|
className: cn(
|
|
802
|
-
"
|
|
803
|
-
|
|
836
|
+
"hidden sm:flex h-7 w-7 items-center justify-center rounded-xl",
|
|
837
|
+
"text-org-text-muted transition-all hover:bg-white/[0.05] hover:text-org-text"
|
|
804
838
|
),
|
|
805
|
-
children: /* @__PURE__ */ jsx(
|
|
839
|
+
children: /* @__PURE__ */ jsx(
|
|
840
|
+
"svg",
|
|
841
|
+
{
|
|
842
|
+
width: "16",
|
|
843
|
+
height: "16",
|
|
844
|
+
viewBox: "0 0 16 16",
|
|
845
|
+
fill: "none",
|
|
846
|
+
className: cn(
|
|
847
|
+
"transition-transform duration-[400ms]",
|
|
848
|
+
expanded ? "rotate-0" : "rotate-180"
|
|
849
|
+
),
|
|
850
|
+
children: /* @__PURE__ */ jsx("path", { d: "M10 12L6 8L10 4", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })
|
|
851
|
+
}
|
|
852
|
+
)
|
|
806
853
|
}
|
|
807
854
|
)
|
|
808
|
-
}
|
|
809
|
-
)
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
855
|
+
] })
|
|
856
|
+
] }),
|
|
857
|
+
/* @__PURE__ */ jsx("nav", { className: "flex-1 overflow-y-auto overflow-x-hidden py-2 px-2 space-y-0.5", children: items.map((entry, i) => /* @__PURE__ */ jsx(
|
|
858
|
+
SidebarEntry,
|
|
859
|
+
{
|
|
860
|
+
entry,
|
|
861
|
+
expanded: expanded || mobileOpen,
|
|
862
|
+
renderLink,
|
|
863
|
+
onNavigate: mobileOpen ? onMobileClose : void 0
|
|
864
|
+
},
|
|
865
|
+
isSeparator(entry) ? `sep-${i}` : entry.id
|
|
866
|
+
)) }),
|
|
867
|
+
bottomItems && bottomItems.length > 0 && /* @__PURE__ */ jsx("div", { className: "border-t border-white/10 py-2 px-2 space-y-0.5", children: bottomItems.map((entry, i) => /* @__PURE__ */ jsx(
|
|
868
|
+
SidebarEntry,
|
|
869
|
+
{
|
|
870
|
+
entry,
|
|
871
|
+
expanded: expanded || mobileOpen,
|
|
872
|
+
renderLink,
|
|
873
|
+
onNavigate: mobileOpen ? onMobileClose : void 0
|
|
874
|
+
},
|
|
875
|
+
isSeparator(entry) ? `bsep-${i}` : entry.id
|
|
876
|
+
)) })
|
|
877
|
+
]
|
|
878
|
+
}
|
|
879
|
+
)
|
|
880
|
+
] });
|
|
832
881
|
}
|
|
833
882
|
function SidebarEntry({
|
|
834
883
|
entry,
|
|
835
884
|
expanded,
|
|
836
|
-
renderLink
|
|
885
|
+
renderLink,
|
|
886
|
+
onNavigate
|
|
837
887
|
}) {
|
|
838
888
|
if (isSeparator(entry)) {
|
|
839
889
|
return /* @__PURE__ */ jsxs("div", { className: "py-2", children: [
|
|
@@ -846,16 +896,22 @@ function SidebarEntry({
|
|
|
846
896
|
{
|
|
847
897
|
item: entry,
|
|
848
898
|
expanded,
|
|
849
|
-
renderLink
|
|
899
|
+
renderLink,
|
|
900
|
+
onNavigate
|
|
850
901
|
}
|
|
851
902
|
);
|
|
852
903
|
}
|
|
853
904
|
function SidebarButton({
|
|
854
905
|
item,
|
|
855
906
|
expanded,
|
|
856
|
-
renderLink
|
|
907
|
+
renderLink,
|
|
908
|
+
onNavigate
|
|
857
909
|
}) {
|
|
858
910
|
const { icon, label, href, onClick, active, badge, disabled } = item;
|
|
911
|
+
const handleClick = () => {
|
|
912
|
+
onClick?.();
|
|
913
|
+
onNavigate?.();
|
|
914
|
+
};
|
|
859
915
|
const content = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
860
916
|
/* @__PURE__ */ jsx("span", { className: "flex h-9 w-9 flex-shrink-0 items-center justify-center rounded-xl transition-all", children: icon }),
|
|
861
917
|
/* @__PURE__ */ jsx(
|
|
@@ -891,13 +947,13 @@ function SidebarButton({
|
|
|
891
947
|
!expanded && "justify-center"
|
|
892
948
|
);
|
|
893
949
|
if (href && renderLink) {
|
|
894
|
-
return renderLink({ href, children: content, className: sharedClass, onClick });
|
|
950
|
+
return renderLink({ href, children: content, className: sharedClass, onClick: handleClick });
|
|
895
951
|
}
|
|
896
952
|
return /* @__PURE__ */ jsxs(
|
|
897
953
|
"button",
|
|
898
954
|
{
|
|
899
955
|
type: "button",
|
|
900
|
-
onClick,
|
|
956
|
+
onClick: handleClick,
|
|
901
957
|
disabled,
|
|
902
958
|
"aria-current": active ? "page" : void 0,
|
|
903
959
|
className: sharedClass,
|
|
@@ -964,12 +1020,12 @@ function WorkspaceSwitcher({ compact = false, onCreateWorkspace, className }) {
|
|
|
964
1020
|
onWorkspaceChange
|
|
965
1021
|
} = useOrganify();
|
|
966
1022
|
const gql = useOrganifyGql();
|
|
967
|
-
const [isOpen, setIsOpen] =
|
|
968
|
-
const [createDialogOpen, setCreateDialogOpen] =
|
|
969
|
-
const [editingWorkspace, setEditingWorkspace] =
|
|
970
|
-
const [deletingWorkspace, setDeletingWorkspace] =
|
|
971
|
-
const dropdownRef =
|
|
972
|
-
|
|
1023
|
+
const [isOpen, setIsOpen] = React5.useState(false);
|
|
1024
|
+
const [createDialogOpen, setCreateDialogOpen] = React5.useState(false);
|
|
1025
|
+
const [editingWorkspace, setEditingWorkspace] = React5.useState(null);
|
|
1026
|
+
const [deletingWorkspace, setDeletingWorkspace] = React5.useState(null);
|
|
1027
|
+
const dropdownRef = React5.useRef(null);
|
|
1028
|
+
React5.useEffect(() => {
|
|
973
1029
|
function handleClickOutside(event) {
|
|
974
1030
|
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
|
|
975
1031
|
setIsOpen(false);
|
|
@@ -978,7 +1034,7 @@ function WorkspaceSwitcher({ compact = false, onCreateWorkspace, className }) {
|
|
|
978
1034
|
document.addEventListener("mousedown", handleClickOutside);
|
|
979
1035
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
980
1036
|
}, []);
|
|
981
|
-
const handleCreateWorkspace =
|
|
1037
|
+
const handleCreateWorkspace = React5.useCallback(
|
|
982
1038
|
async (data) => {
|
|
983
1039
|
const optimisticId = `temp-${Date.now()}`;
|
|
984
1040
|
const optimisticSlug = data.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
|
|
@@ -1018,7 +1074,7 @@ function WorkspaceSwitcher({ compact = false, onCreateWorkspace, className }) {
|
|
|
1018
1074
|
},
|
|
1019
1075
|
[workspaces, gql, onWorkspacesChange, onWorkspaceChange, onCreateWorkspace]
|
|
1020
1076
|
);
|
|
1021
|
-
const handleUpdateWorkspace =
|
|
1077
|
+
const handleUpdateWorkspace = React5.useCallback(
|
|
1022
1078
|
async (slug, data) => {
|
|
1023
1079
|
const prevWorkspaces = [...workspaces];
|
|
1024
1080
|
const prevActive = workspace;
|
|
@@ -1053,7 +1109,7 @@ function WorkspaceSwitcher({ compact = false, onCreateWorkspace, className }) {
|
|
|
1053
1109
|
},
|
|
1054
1110
|
[workspaces, workspace, gql, onWorkspacesChange, onWorkspaceChange]
|
|
1055
1111
|
);
|
|
1056
|
-
const handleDeleteWorkspace =
|
|
1112
|
+
const handleDeleteWorkspace = React5.useCallback(
|
|
1057
1113
|
async (slug) => {
|
|
1058
1114
|
const prevWorkspaces = [...workspaces];
|
|
1059
1115
|
const prevActive = workspace;
|
|
@@ -1242,7 +1298,7 @@ function SwitcherItem({
|
|
|
1242
1298
|
onEdit,
|
|
1243
1299
|
onDelete
|
|
1244
1300
|
}) {
|
|
1245
|
-
const [showActions, setShowActions] =
|
|
1301
|
+
const [showActions, setShowActions] = React5.useState(false);
|
|
1246
1302
|
const isOptimistic = ws.id.startsWith("temp-");
|
|
1247
1303
|
const content = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1248
1304
|
/* @__PURE__ */ jsx(
|
|
@@ -1316,11 +1372,11 @@ function CreateWorkspaceInlineDialog({
|
|
|
1316
1372
|
onOpenChange,
|
|
1317
1373
|
onSubmit
|
|
1318
1374
|
}) {
|
|
1319
|
-
const [name, setName] =
|
|
1320
|
-
const [description, setDescription] =
|
|
1321
|
-
const [loading, setLoading] =
|
|
1322
|
-
const [error, setError] =
|
|
1323
|
-
|
|
1375
|
+
const [name, setName] = React5.useState("");
|
|
1376
|
+
const [description, setDescription] = React5.useState("");
|
|
1377
|
+
const [loading, setLoading] = React5.useState(false);
|
|
1378
|
+
const [error, setError] = React5.useState("");
|
|
1379
|
+
React5.useEffect(() => {
|
|
1324
1380
|
if (open) {
|
|
1325
1381
|
setName("");
|
|
1326
1382
|
setDescription("");
|
|
@@ -1393,11 +1449,11 @@ function EditWorkspaceDialog({
|
|
|
1393
1449
|
workspace,
|
|
1394
1450
|
onSubmit
|
|
1395
1451
|
}) {
|
|
1396
|
-
const [name, setName] =
|
|
1397
|
-
const [description, setDescription] =
|
|
1398
|
-
const [loading, setLoading] =
|
|
1399
|
-
const [error, setError] =
|
|
1400
|
-
|
|
1452
|
+
const [name, setName] = React5.useState("");
|
|
1453
|
+
const [description, setDescription] = React5.useState("");
|
|
1454
|
+
const [loading, setLoading] = React5.useState(false);
|
|
1455
|
+
const [error, setError] = React5.useState("");
|
|
1456
|
+
React5.useEffect(() => {
|
|
1401
1457
|
if (open && workspace) {
|
|
1402
1458
|
setName(workspace.name);
|
|
1403
1459
|
setDescription(workspace.description ?? "");
|
|
@@ -1471,10 +1527,10 @@ function DeleteWorkspaceDialog({
|
|
|
1471
1527
|
workspace,
|
|
1472
1528
|
onConfirm
|
|
1473
1529
|
}) {
|
|
1474
|
-
const [loading, setLoading] =
|
|
1475
|
-
const [error, setError] =
|
|
1476
|
-
const [confirmText, setConfirmText] =
|
|
1477
|
-
|
|
1530
|
+
const [loading, setLoading] = React5.useState(false);
|
|
1531
|
+
const [error, setError] = React5.useState("");
|
|
1532
|
+
const [confirmText, setConfirmText] = React5.useState("");
|
|
1533
|
+
React5.useEffect(() => {
|
|
1478
1534
|
if (open) {
|
|
1479
1535
|
setError("");
|
|
1480
1536
|
setConfirmText("");
|
|
@@ -4104,7 +4160,7 @@ function SheetContent({
|
|
|
4104
4160
|
"data-slot": "sheet-content",
|
|
4105
4161
|
className: cn(
|
|
4106
4162
|
"data-[state=open]:animate-in data-[state=closed]:animate-out fixed z-50 flex flex-col gap-4 shadow-xl dark:shadow-[0_24px_80px_-15px_rgba(0,0,0,0.8)] transition ease-[cubic-bezier(0.25,1,0.5,1)] data-[state=closed]:duration-300 data-[state=open]:duration-500",
|
|
4107
|
-
"
|
|
4163
|
+
"[background:var(--org-bg-elevated,#110E22)] [color:var(--org-text,#F0ECF9)] [border-color:var(--org-glass-border,rgba(167,139,250,0.15))]",
|
|
4108
4164
|
side === "right" && "data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right inset-y-0 right-0 h-full w-3/4 border-l-2 sm:max-w-sm",
|
|
4109
4165
|
side === "left" && "data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left inset-y-0 left-0 h-full w-3/4 border-r-2 sm:max-w-sm",
|
|
4110
4166
|
side === "top" && "data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top inset-x-0 top-0 h-auto border-b-2",
|
|
@@ -4202,9 +4258,9 @@ function CommentItem({
|
|
|
4202
4258
|
onDelete,
|
|
4203
4259
|
onReact
|
|
4204
4260
|
}) {
|
|
4205
|
-
const [editing, setEditing] =
|
|
4206
|
-
const [editContent, setEditContent] =
|
|
4207
|
-
const [showReactions, setShowReactions] =
|
|
4261
|
+
const [editing, setEditing] = React5.useState(false);
|
|
4262
|
+
const [editContent, setEditContent] = React5.useState(comment.content);
|
|
4263
|
+
const [showReactions, setShowReactions] = React5.useState(false);
|
|
4208
4264
|
const isAuthor = comment.author.id === currentUser.id;
|
|
4209
4265
|
const isPending = comment._status === "pending";
|
|
4210
4266
|
const isError = comment._status === "error";
|
|
@@ -4368,9 +4424,9 @@ function CommentInput({
|
|
|
4368
4424
|
compact = false,
|
|
4369
4425
|
alwaysExpanded = true
|
|
4370
4426
|
}) {
|
|
4371
|
-
const [content, setContent] =
|
|
4372
|
-
const textareaRef =
|
|
4373
|
-
|
|
4427
|
+
const [content, setContent] = React5.useState("");
|
|
4428
|
+
const textareaRef = React5.useRef(null);
|
|
4429
|
+
React5.useEffect(() => {
|
|
4374
4430
|
if (autoFocus && textareaRef.current) {
|
|
4375
4431
|
textareaRef.current.focus();
|
|
4376
4432
|
}
|
|
@@ -4490,7 +4546,7 @@ function CommentThread({
|
|
|
4490
4546
|
displayName: providerUser?.name ?? "",
|
|
4491
4547
|
avatarUrl: providerUser?.avatarUrl ?? null
|
|
4492
4548
|
};
|
|
4493
|
-
const effectiveOnFetch =
|
|
4549
|
+
const effectiveOnFetch = React5.useCallback(
|
|
4494
4550
|
async (_entityType, _entityId) => {
|
|
4495
4551
|
if (onFetch) return onFetch(_entityType, _entityId);
|
|
4496
4552
|
const data = await gql(
|
|
@@ -4509,7 +4565,7 @@ function CommentThread({
|
|
|
4509
4565
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
4510
4566
|
[gql, onFetch]
|
|
4511
4567
|
);
|
|
4512
|
-
const effectiveOnAdd =
|
|
4568
|
+
const effectiveOnAdd = React5.useCallback(
|
|
4513
4569
|
async (input) => {
|
|
4514
4570
|
if (onAdd) return onAdd(input);
|
|
4515
4571
|
const data = await gql(
|
|
@@ -4526,7 +4582,7 @@ function CommentThread({
|
|
|
4526
4582
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
4527
4583
|
[gql, onAdd, currentUser.id]
|
|
4528
4584
|
);
|
|
4529
|
-
const effectiveOnEdit =
|
|
4585
|
+
const effectiveOnEdit = React5.useCallback(
|
|
4530
4586
|
async (commentId, content) => {
|
|
4531
4587
|
if (onEdit) return onEdit(commentId, content);
|
|
4532
4588
|
const data = await gql(
|
|
@@ -4548,7 +4604,7 @@ function CommentThread({
|
|
|
4548
4604
|
},
|
|
4549
4605
|
[gql, onEdit]
|
|
4550
4606
|
);
|
|
4551
|
-
const effectiveOnDelete =
|
|
4607
|
+
const effectiveOnDelete = React5.useCallback(
|
|
4552
4608
|
async (commentId) => {
|
|
4553
4609
|
if (onDelete) return onDelete(commentId);
|
|
4554
4610
|
await gql(
|
|
@@ -4559,15 +4615,15 @@ function CommentThread({
|
|
|
4559
4615
|
},
|
|
4560
4616
|
[gql, onDelete]
|
|
4561
4617
|
);
|
|
4562
|
-
const [comments, setComments] =
|
|
4563
|
-
const [loading, setLoading] =
|
|
4564
|
-
const [showAll, setShowAll] =
|
|
4565
|
-
const [replyingTo, setReplyingTo] =
|
|
4566
|
-
const hasFetchedRef =
|
|
4567
|
-
|
|
4618
|
+
const [comments, setComments] = React5.useState(externalComments || []);
|
|
4619
|
+
const [loading, setLoading] = React5.useState(!externalComments);
|
|
4620
|
+
const [showAll, setShowAll] = React5.useState(false);
|
|
4621
|
+
const [replyingTo, setReplyingTo] = React5.useState(null);
|
|
4622
|
+
const hasFetchedRef = React5.useRef(false);
|
|
4623
|
+
React5.useEffect(() => {
|
|
4568
4624
|
hasFetchedRef.current = false;
|
|
4569
4625
|
}, [entityId, entityType]);
|
|
4570
|
-
|
|
4626
|
+
React5.useEffect(() => {
|
|
4571
4627
|
if (externalComments) return;
|
|
4572
4628
|
if (hasFetchedRef.current) return;
|
|
4573
4629
|
hasFetchedRef.current = true;
|
|
@@ -4585,12 +4641,12 @@ function CommentThread({
|
|
|
4585
4641
|
cancelled = true;
|
|
4586
4642
|
};
|
|
4587
4643
|
}, [entityType, entityId, externalComments, effectiveOnFetch]);
|
|
4588
|
-
|
|
4644
|
+
React5.useEffect(() => {
|
|
4589
4645
|
if (externalComments) {
|
|
4590
4646
|
setComments(externalComments);
|
|
4591
4647
|
}
|
|
4592
4648
|
}, [externalComments]);
|
|
4593
|
-
|
|
4649
|
+
React5.useEffect(() => {
|
|
4594
4650
|
if (externalComments || onFetch) return;
|
|
4595
4651
|
if (!entityId || entityType !== "task") return;
|
|
4596
4652
|
const projectsServiceUrl = api?.services?.projects || api?.gatewayUrl;
|
|
@@ -4850,7 +4906,7 @@ function CommentThread({
|
|
|
4850
4906
|
/* @__PURE__ */ jsx("p", { className: "text-[11px] text-theme-muted mt-0.5", children: "Seja o primeiro a comentar." })
|
|
4851
4907
|
] }),
|
|
4852
4908
|
!loading && visibleComments.length > 0 && /* @__PURE__ */ jsxs("div", { className: "space-y-0.5", children: [
|
|
4853
|
-
visibleComments.map((comment) => /* @__PURE__ */ jsxs(
|
|
4909
|
+
visibleComments.map((comment) => /* @__PURE__ */ jsxs(React5.Fragment, { children: [
|
|
4854
4910
|
/* @__PURE__ */ jsx(
|
|
4855
4911
|
CommentItem,
|
|
4856
4912
|
{
|
|
@@ -4939,11 +4995,11 @@ function LabelPicker({
|
|
|
4939
4995
|
trigger,
|
|
4940
4996
|
disabled = false
|
|
4941
4997
|
}) {
|
|
4942
|
-
const [open, setOpen] =
|
|
4943
|
-
const [search, setSearch] =
|
|
4944
|
-
const [isCreating, setIsCreating] =
|
|
4945
|
-
const [newLabelName, setNewLabelName] =
|
|
4946
|
-
const [newLabelColor, setNewLabelColor] =
|
|
4998
|
+
const [open, setOpen] = React5.useState(false);
|
|
4999
|
+
const [search, setSearch] = React5.useState("");
|
|
5000
|
+
const [isCreating, setIsCreating] = React5.useState(false);
|
|
5001
|
+
const [newLabelName, setNewLabelName] = React5.useState("");
|
|
5002
|
+
const [newLabelColor, setNewLabelColor] = React5.useState(presetColors[8]);
|
|
4947
5003
|
const selectedIds = new Set(selectedLabels.map((l) => l.id));
|
|
4948
5004
|
const filteredLabels = availableLabels.filter(
|
|
4949
5005
|
(label) => label.name.toLowerCase().includes(search.toLowerCase())
|
|
@@ -5098,8 +5154,8 @@ function AssigneePicker({
|
|
|
5098
5154
|
disabled = false,
|
|
5099
5155
|
maxAssignees
|
|
5100
5156
|
}) {
|
|
5101
|
-
const [open, setOpen] =
|
|
5102
|
-
const [search, setSearch] =
|
|
5157
|
+
const [open, setOpen] = React5.useState(false);
|
|
5158
|
+
const [search, setSearch] = React5.useState("");
|
|
5103
5159
|
const selectedIds = new Set(selectedAssignees.map((a) => a.id));
|
|
5104
5160
|
const canAddMore = maxAssignees ? selectedAssignees.length < maxAssignees : true;
|
|
5105
5161
|
const filteredUsers = availableUsers.filter(
|
|
@@ -5184,8 +5240,8 @@ var statusColors = {
|
|
|
5184
5240
|
DONE: "bg-emerald-500/15 text-emerald-400 border-emerald-500/30"
|
|
5185
5241
|
};
|
|
5186
5242
|
function useMediaQuery2(query) {
|
|
5187
|
-
const [matches, setMatches] =
|
|
5188
|
-
|
|
5243
|
+
const [matches, setMatches] = React5.useState(false);
|
|
5244
|
+
React5.useEffect(() => {
|
|
5189
5245
|
const mql = window.matchMedia(query);
|
|
5190
5246
|
setMatches(mql.matches);
|
|
5191
5247
|
const handler = (e) => setMatches(e.matches);
|
|
@@ -5202,13 +5258,13 @@ function EditableField({
|
|
|
5202
5258
|
inputClassName,
|
|
5203
5259
|
as: Tag = "span"
|
|
5204
5260
|
}) {
|
|
5205
|
-
const [editing, setEditing] =
|
|
5206
|
-
const [localValue, setLocalValue] =
|
|
5207
|
-
const inputRef =
|
|
5208
|
-
|
|
5261
|
+
const [editing, setEditing] = React5.useState(false);
|
|
5262
|
+
const [localValue, setLocalValue] = React5.useState(value);
|
|
5263
|
+
const inputRef = React5.useRef(null);
|
|
5264
|
+
React5.useEffect(() => {
|
|
5209
5265
|
setLocalValue(value);
|
|
5210
5266
|
}, [value]);
|
|
5211
|
-
|
|
5267
|
+
React5.useEffect(() => {
|
|
5212
5268
|
if (editing && inputRef.current) {
|
|
5213
5269
|
inputRef.current.focus();
|
|
5214
5270
|
inputRef.current.select();
|
|
@@ -5262,9 +5318,9 @@ function EditableField({
|
|
|
5262
5318
|
);
|
|
5263
5319
|
}
|
|
5264
5320
|
function EditableDate({ value, onSave, placeholder = "Adicionar data" }) {
|
|
5265
|
-
const [editing, setEditing] =
|
|
5266
|
-
const inputRef =
|
|
5267
|
-
|
|
5321
|
+
const [editing, setEditing] = React5.useState(false);
|
|
5322
|
+
const inputRef = React5.useRef(null);
|
|
5323
|
+
React5.useEffect(() => {
|
|
5268
5324
|
if (editing && inputRef.current) {
|
|
5269
5325
|
inputRef.current.focus();
|
|
5270
5326
|
}
|
|
@@ -5348,13 +5404,13 @@ function AssigneeItem({ assignee, onRemove, showDelete = true }) {
|
|
|
5348
5404
|
] });
|
|
5349
5405
|
}
|
|
5350
5406
|
function SubtaskItem({ subtask, onToggle, onDelete, onUpdate }) {
|
|
5351
|
-
const [editing, setEditing] =
|
|
5352
|
-
const [localTitle, setLocalTitle] =
|
|
5353
|
-
const inputRef =
|
|
5354
|
-
|
|
5407
|
+
const [editing, setEditing] = React5.useState(false);
|
|
5408
|
+
const [localTitle, setLocalTitle] = React5.useState(subtask.title);
|
|
5409
|
+
const inputRef = React5.useRef(null);
|
|
5410
|
+
React5.useEffect(() => {
|
|
5355
5411
|
setLocalTitle(subtask.title);
|
|
5356
5412
|
}, [subtask.title]);
|
|
5357
|
-
|
|
5413
|
+
React5.useEffect(() => {
|
|
5358
5414
|
if (editing && inputRef.current) {
|
|
5359
5415
|
inputRef.current.focus();
|
|
5360
5416
|
inputRef.current.select();
|
|
@@ -5428,10 +5484,10 @@ function SubtaskItem({ subtask, onToggle, onDelete, onUpdate }) {
|
|
|
5428
5484
|
] });
|
|
5429
5485
|
}
|
|
5430
5486
|
function SubtaskAddForm({ onAdd }) {
|
|
5431
|
-
const [adding, setAdding] =
|
|
5432
|
-
const [title, setTitle] =
|
|
5433
|
-
const inputRef =
|
|
5434
|
-
|
|
5487
|
+
const [adding, setAdding] = React5.useState(false);
|
|
5488
|
+
const [title, setTitle] = React5.useState("");
|
|
5489
|
+
const inputRef = React5.useRef(null);
|
|
5490
|
+
React5.useEffect(() => {
|
|
5435
5491
|
if (adding && inputRef.current) {
|
|
5436
5492
|
inputRef.current.focus();
|
|
5437
5493
|
}
|
|
@@ -5519,7 +5575,7 @@ function SubtaskSection({
|
|
|
5519
5575
|
onDelete,
|
|
5520
5576
|
onUpdate
|
|
5521
5577
|
}) {
|
|
5522
|
-
const [loading, setLoading] =
|
|
5578
|
+
const [loading, setLoading] = React5.useState(null);
|
|
5523
5579
|
const handleAdd = async (title) => {
|
|
5524
5580
|
if (onAdd) {
|
|
5525
5581
|
setLoading("add");
|
|
@@ -5977,7 +6033,7 @@ function TaskCard({
|
|
|
5977
6033
|
className,
|
|
5978
6034
|
...props
|
|
5979
6035
|
}) {
|
|
5980
|
-
const [sheetOpen, setSheetOpen] =
|
|
6036
|
+
const [sheetOpen, setSheetOpen] = React5.useState(false);
|
|
5981
6037
|
if (!task) {
|
|
5982
6038
|
return /* @__PURE__ */ jsx(TaskCardSkeleton, { compact, className });
|
|
5983
6039
|
}
|
|
@@ -6416,8 +6472,33 @@ function TaskCard2({
|
|
|
6416
6472
|
isDragging,
|
|
6417
6473
|
externalDnD,
|
|
6418
6474
|
onDragStart,
|
|
6419
|
-
onDragEnd
|
|
6475
|
+
onDragEnd,
|
|
6476
|
+
onTouchDragStart
|
|
6420
6477
|
}) {
|
|
6478
|
+
const touchTimerRef = React5.useRef(null);
|
|
6479
|
+
const hasMoved = React5.useRef(false);
|
|
6480
|
+
const handleTouchStart = (e) => {
|
|
6481
|
+
hasMoved.current = false;
|
|
6482
|
+
touchTimerRef.current = setTimeout(() => {
|
|
6483
|
+
if (!hasMoved.current) {
|
|
6484
|
+
onTouchDragStart?.(task, columnId);
|
|
6485
|
+
if (navigator.vibrate) navigator.vibrate(50);
|
|
6486
|
+
}
|
|
6487
|
+
}, 300);
|
|
6488
|
+
};
|
|
6489
|
+
const handleTouchMove = () => {
|
|
6490
|
+
hasMoved.current = true;
|
|
6491
|
+
if (touchTimerRef.current) {
|
|
6492
|
+
clearTimeout(touchTimerRef.current);
|
|
6493
|
+
touchTimerRef.current = null;
|
|
6494
|
+
}
|
|
6495
|
+
};
|
|
6496
|
+
const handleTouchEnd = () => {
|
|
6497
|
+
if (touchTimerRef.current) {
|
|
6498
|
+
clearTimeout(touchTimerRef.current);
|
|
6499
|
+
touchTimerRef.current = null;
|
|
6500
|
+
}
|
|
6501
|
+
};
|
|
6421
6502
|
const displayLabels = (task.labels || []).map(
|
|
6422
6503
|
(label) => typeof label === "string" ? label : label.name
|
|
6423
6504
|
);
|
|
@@ -6428,14 +6509,18 @@ function TaskCard2({
|
|
|
6428
6509
|
onDragStart: !externalDnD ? (e) => onDragStart?.(e, task, columnId) : void 0,
|
|
6429
6510
|
onDragEnd: !externalDnD ? onDragEnd : void 0,
|
|
6430
6511
|
onClick,
|
|
6512
|
+
onTouchStart: handleTouchStart,
|
|
6513
|
+
onTouchMove: handleTouchMove,
|
|
6514
|
+
onTouchEnd: handleTouchEnd,
|
|
6431
6515
|
"data-task-id": task.id,
|
|
6432
6516
|
"data-column-id": columnId,
|
|
6433
6517
|
"data-index": index,
|
|
6434
6518
|
className: cn(
|
|
6435
|
-
"group relative flex flex-col gap-2 p-3 cursor-pointer",
|
|
6519
|
+
"group relative flex flex-col gap-2 p-3 cursor-pointer select-none",
|
|
6436
6520
|
"bg-theme-subtle backdrop-blur-md border border-theme-subtle",
|
|
6437
6521
|
"transition-all duration-[400ms] ease-[cubic-bezier(0.25,1,0.5,1)] rounded-xl",
|
|
6438
6522
|
"hover:border-primary-light/30",
|
|
6523
|
+
"active:scale-[0.98]",
|
|
6439
6524
|
isDragging && "opacity-50 scale-95"
|
|
6440
6525
|
),
|
|
6441
6526
|
children: [
|
|
@@ -6447,7 +6532,7 @@ function TaskCard2({
|
|
|
6447
6532
|
children: /* @__PURE__ */ jsx(GripVertical, { className: "w-4 h-4" })
|
|
6448
6533
|
}
|
|
6449
6534
|
),
|
|
6450
|
-
/* @__PURE__ */ jsx("h4", { className: "text-sm font-medium text-theme pr-6", children: task.title }),
|
|
6535
|
+
/* @__PURE__ */ jsx("h4", { className: "text-sm font-medium text-theme pr-6 line-clamp-2", children: task.title }),
|
|
6451
6536
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [
|
|
6452
6537
|
task.priority && /* @__PURE__ */ jsx(
|
|
6453
6538
|
Badge,
|
|
@@ -6488,18 +6573,19 @@ function Column({
|
|
|
6488
6573
|
onDragEnd,
|
|
6489
6574
|
onDragOver,
|
|
6490
6575
|
onDrop,
|
|
6491
|
-
isDropTarget
|
|
6576
|
+
isDropTarget,
|
|
6577
|
+
onTouchDragStart
|
|
6492
6578
|
}) {
|
|
6493
|
-
const [isRenaming, setIsRenaming] =
|
|
6494
|
-
const [renameValue, setRenameValue] =
|
|
6495
|
-
const renameInputRef =
|
|
6496
|
-
const [isAddingTask, setIsAddingTask] =
|
|
6497
|
-
const [newTaskTitle, setNewTaskTitle] =
|
|
6498
|
-
const taskInputRef =
|
|
6499
|
-
|
|
6579
|
+
const [isRenaming, setIsRenaming] = React5.useState(false);
|
|
6580
|
+
const [renameValue, setRenameValue] = React5.useState(column.title);
|
|
6581
|
+
const renameInputRef = React5.useRef(null);
|
|
6582
|
+
const [isAddingTask, setIsAddingTask] = React5.useState(false);
|
|
6583
|
+
const [newTaskTitle, setNewTaskTitle] = React5.useState("");
|
|
6584
|
+
const taskInputRef = React5.useRef(null);
|
|
6585
|
+
React5.useEffect(() => {
|
|
6500
6586
|
if (isRenaming) renameInputRef.current?.focus();
|
|
6501
6587
|
}, [isRenaming]);
|
|
6502
|
-
|
|
6588
|
+
React5.useEffect(() => {
|
|
6503
6589
|
if (isAddingTask) taskInputRef.current?.focus();
|
|
6504
6590
|
}, [isAddingTask]);
|
|
6505
6591
|
const handleRenameSubmit = () => {
|
|
@@ -6543,9 +6629,10 @@ function Column({
|
|
|
6543
6629
|
} : void 0,
|
|
6544
6630
|
onDrop: !externalDnD ? (e) => onDrop?.(e, column.id) : void 0,
|
|
6545
6631
|
className: cn(
|
|
6546
|
-
"flex flex-col w-72 shrink-0 h-
|
|
6632
|
+
"flex flex-col w-[280px] sm:w-72 shrink-0 max-h-[calc(100vh-10rem)]",
|
|
6547
6633
|
"bg-theme-glass backdrop-blur-md border border-theme-subtle rounded-xl",
|
|
6548
6634
|
"transition-all duration-[400ms] ease-[cubic-bezier(0.25,1,0.5,1)]",
|
|
6635
|
+
"snap-start",
|
|
6549
6636
|
isDropTarget && "border-primary-light/50 bg-primary/5"
|
|
6550
6637
|
),
|
|
6551
6638
|
children: [
|
|
@@ -6581,16 +6668,30 @@ function Column({
|
|
|
6581
6668
|
children: column.title
|
|
6582
6669
|
}
|
|
6583
6670
|
),
|
|
6584
|
-
/* @__PURE__ */ jsx(
|
|
6671
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center gap-1 shrink-0", children: /* @__PURE__ */ jsxs(
|
|
6585
6672
|
Badge,
|
|
6586
6673
|
{
|
|
6587
|
-
variant: "default",
|
|
6588
|
-
className:
|
|
6589
|
-
|
|
6674
|
+
variant: column.wipLimit && column.tasks.length > column.wipLimit ? "error" : "default",
|
|
6675
|
+
className: cn(
|
|
6676
|
+
"text-xs",
|
|
6677
|
+
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"
|
|
6678
|
+
),
|
|
6679
|
+
children: [
|
|
6680
|
+
column.tasks.length,
|
|
6681
|
+
column.wipLimit != null && /* @__PURE__ */ jsxs("span", { className: "text-theme-muted", children: [
|
|
6682
|
+
"/",
|
|
6683
|
+
column.wipLimit
|
|
6684
|
+
] })
|
|
6685
|
+
]
|
|
6590
6686
|
}
|
|
6591
|
-
)
|
|
6687
|
+
) })
|
|
6688
|
+
] }),
|
|
6689
|
+
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: [
|
|
6690
|
+
"\u26A0 WIP limit exceeded (",
|
|
6691
|
+
column.tasks.length - column.wipLimit,
|
|
6692
|
+
" over)"
|
|
6592
6693
|
] }),
|
|
6593
|
-
/* @__PURE__ */ jsx(ScrollArea, { className: "flex-1 min-h-0", children: /* @__PURE__ */ jsxs("div", { className: "p-2 space-y-2", children: [
|
|
6694
|
+
/* @__PURE__ */ jsx(ScrollArea, { className: "flex-1 min-h-0 [&_[data-radix-scroll-area-viewport]]:!overflow-y-auto [&_[data-radix-scroll-area-viewport]]:scrollbar-none", children: /* @__PURE__ */ jsxs("div", { className: "p-2 space-y-2", children: [
|
|
6594
6695
|
column.tasks.map((task, index) => {
|
|
6595
6696
|
const isDragging = draggedTask?.task.id === task.id;
|
|
6596
6697
|
return /* @__PURE__ */ jsx(
|
|
@@ -6603,7 +6704,8 @@ function Column({
|
|
|
6603
6704
|
isDragging,
|
|
6604
6705
|
externalDnD,
|
|
6605
6706
|
onDragStart,
|
|
6606
|
-
onDragEnd
|
|
6707
|
+
onDragEnd,
|
|
6708
|
+
onTouchDragStart
|
|
6607
6709
|
},
|
|
6608
6710
|
task.id
|
|
6609
6711
|
);
|
|
@@ -6687,16 +6789,40 @@ function KanbanBoard({
|
|
|
6687
6789
|
onAddSubtask,
|
|
6688
6790
|
onToggleSubtask,
|
|
6689
6791
|
onDeleteSubtask,
|
|
6690
|
-
onUpdateSubtask
|
|
6792
|
+
onUpdateSubtask,
|
|
6793
|
+
onTaskClick
|
|
6691
6794
|
}) {
|
|
6692
|
-
const [draggedTask, setDraggedTask] =
|
|
6693
|
-
const [dropTargetColumnId, setDropTargetColumnId] =
|
|
6694
|
-
const [
|
|
6695
|
-
const
|
|
6696
|
-
|
|
6697
|
-
|
|
6698
|
-
const
|
|
6699
|
-
|
|
6795
|
+
const [draggedTask, setDraggedTask] = React5.useState(null);
|
|
6796
|
+
const [dropTargetColumnId, setDropTargetColumnId] = React5.useState(null);
|
|
6797
|
+
const [touchDraggedTask, setTouchDraggedTask] = React5.useState(null);
|
|
6798
|
+
const handleTouchDragStart = React5.useCallback((task, fromColumnId) => {
|
|
6799
|
+
setTouchDraggedTask({ task, fromColumnId });
|
|
6800
|
+
}, []);
|
|
6801
|
+
const handleTouchDrop = React5.useCallback((toColumnId) => {
|
|
6802
|
+
if (!touchDraggedTask) return;
|
|
6803
|
+
const { task, fromColumnId } = touchDraggedTask;
|
|
6804
|
+
if (fromColumnId !== toColumnId) {
|
|
6805
|
+
onTaskMove?.(task.id, fromColumnId, toColumnId, 0);
|
|
6806
|
+
if (onColumnChange) {
|
|
6807
|
+
const newColumns = columns.map((col) => {
|
|
6808
|
+
if (col.id === fromColumnId) return { ...col, tasks: col.tasks.filter((t) => t.id !== task.id) };
|
|
6809
|
+
if (col.id === toColumnId) return { ...col, tasks: [...col.tasks, task] };
|
|
6810
|
+
return col;
|
|
6811
|
+
});
|
|
6812
|
+
onColumnChange(newColumns);
|
|
6813
|
+
}
|
|
6814
|
+
}
|
|
6815
|
+
setTouchDraggedTask(null);
|
|
6816
|
+
}, [touchDraggedTask, columns, onTaskMove, onColumnChange]);
|
|
6817
|
+
const cancelTouchDrag = React5.useCallback(() => setTouchDraggedTask(null), []);
|
|
6818
|
+
const isTouchDragging = touchDraggedTask !== null;
|
|
6819
|
+
const effectiveDraggedTask = draggedTask || touchDraggedTask;
|
|
6820
|
+
const [sheetOpen, setSheetOpen] = React5.useState(false);
|
|
6821
|
+
const [selectedTask, setSelectedTask] = React5.useState(null);
|
|
6822
|
+
const [isAddingColumn, setIsAddingColumn] = React5.useState(false);
|
|
6823
|
+
const [newColumnTitle, setNewColumnTitle] = React5.useState("");
|
|
6824
|
+
const addColumnInputRef = React5.useRef(null);
|
|
6825
|
+
React5.useEffect(() => {
|
|
6700
6826
|
if (isAddingColumn) addColumnInputRef.current?.focus();
|
|
6701
6827
|
}, [isAddingColumn]);
|
|
6702
6828
|
const handleAddColumnSubmit = () => {
|
|
@@ -6717,6 +6843,10 @@ function KanbanBoard({
|
|
|
6717
6843
|
}
|
|
6718
6844
|
};
|
|
6719
6845
|
const handleTaskClick = (task, columnId) => {
|
|
6846
|
+
if (onTaskClick) {
|
|
6847
|
+
onTaskClick(task.id);
|
|
6848
|
+
return;
|
|
6849
|
+
}
|
|
6720
6850
|
setSelectedTask({ task, columnId });
|
|
6721
6851
|
setSheetOpen(true);
|
|
6722
6852
|
};
|
|
@@ -6758,8 +6888,9 @@ function KanbanBoard({
|
|
|
6758
6888
|
"div",
|
|
6759
6889
|
{
|
|
6760
6890
|
className: cn(
|
|
6761
|
-
"flex gap-4 p-4 overflow-x-auto h-full min-h-[400px]",
|
|
6762
|
-
"bg-void",
|
|
6891
|
+
"flex gap-3 sm:gap-4 p-3 sm:p-4 overflow-x-auto h-full min-h-[400px]",
|
|
6892
|
+
"bg-void snap-x snap-mandatory sm:snap-none",
|
|
6893
|
+
"scrollbar-none",
|
|
6763
6894
|
className
|
|
6764
6895
|
),
|
|
6765
6896
|
children: [
|
|
@@ -6771,12 +6902,13 @@ function KanbanBoard({
|
|
|
6771
6902
|
onAddTask,
|
|
6772
6903
|
onRenameColumn,
|
|
6773
6904
|
externalDnD,
|
|
6774
|
-
draggedTask,
|
|
6905
|
+
draggedTask: effectiveDraggedTask,
|
|
6775
6906
|
onDragStart: handleDragStart,
|
|
6776
6907
|
onDragEnd: handleDragEnd,
|
|
6777
6908
|
onDragOver: handleDragOver,
|
|
6778
6909
|
onDrop: handleDrop,
|
|
6779
|
-
isDropTarget: dropTargetColumnId === column.id
|
|
6910
|
+
isDropTarget: dropTargetColumnId === column.id,
|
|
6911
|
+
onTouchDragStart: handleTouchDragStart
|
|
6780
6912
|
},
|
|
6781
6913
|
column.id
|
|
6782
6914
|
)),
|
|
@@ -6837,6 +6969,35 @@ function KanbanBoard({
|
|
|
6837
6969
|
]
|
|
6838
6970
|
}
|
|
6839
6971
|
),
|
|
6972
|
+
isTouchDragging && /* @__PURE__ */ jsxs("div", { className: "fixed inset-x-0 bottom-0 z-50 flex gap-2 p-3 bg-void/90 backdrop-blur-xl border-t border-theme-subtle animate-in slide-in-from-bottom-4 duration-300 sm:hidden", children: [
|
|
6973
|
+
/* @__PURE__ */ jsx("div", { className: "w-full overflow-x-auto scrollbar-none flex gap-2", children: columns.filter((col) => col.id !== touchDraggedTask?.fromColumnId).map((col) => /* @__PURE__ */ jsxs(
|
|
6974
|
+
"button",
|
|
6975
|
+
{
|
|
6976
|
+
onClick: () => handleTouchDrop(col.id),
|
|
6977
|
+
className: cn(
|
|
6978
|
+
"flex-shrink-0 flex items-center gap-2 px-4 py-3 rounded-xl",
|
|
6979
|
+
"bg-theme-glass border border-theme-subtle",
|
|
6980
|
+
"text-sm font-medium text-theme",
|
|
6981
|
+
"active:bg-primary/20 active:border-primary-light/50",
|
|
6982
|
+
"transition-all duration-200"
|
|
6983
|
+
),
|
|
6984
|
+
children: [
|
|
6985
|
+
col.color && /* @__PURE__ */ jsx("div", { className: "w-2.5 h-2.5 rounded-full shrink-0", style: { backgroundColor: col.color } }),
|
|
6986
|
+
col.title,
|
|
6987
|
+
/* @__PURE__ */ jsx(Badge, { className: "text-[10px] bg-theme-highlight text-theme-muted border-theme-subtle", children: col.tasks.length })
|
|
6988
|
+
]
|
|
6989
|
+
},
|
|
6990
|
+
col.id
|
|
6991
|
+
)) }),
|
|
6992
|
+
/* @__PURE__ */ jsx(
|
|
6993
|
+
"button",
|
|
6994
|
+
{
|
|
6995
|
+
onClick: cancelTouchDrag,
|
|
6996
|
+
className: "shrink-0 p-3 rounded-xl bg-rose-500/20 text-rose-400 border border-rose-500/30",
|
|
6997
|
+
children: /* @__PURE__ */ jsx(X, { className: "w-4 h-4" })
|
|
6998
|
+
}
|
|
6999
|
+
)
|
|
7000
|
+
] }),
|
|
6840
7001
|
/* @__PURE__ */ jsx(
|
|
6841
7002
|
TaskDetailSheet,
|
|
6842
7003
|
{
|
|
@@ -7025,7 +7186,7 @@ function PlanBadgeFull({
|
|
|
7025
7186
|
config.bgColor,
|
|
7026
7187
|
config.borderColor
|
|
7027
7188
|
),
|
|
7028
|
-
children: /* @__PURE__ */ jsx("span", { className: config.color, children:
|
|
7189
|
+
children: /* @__PURE__ */ jsx("span", { className: config.color, children: React5.cloneElement(config.icon, {
|
|
7029
7190
|
className: "w-5 h-5"
|
|
7030
7191
|
}) })
|
|
7031
7192
|
}
|
|
@@ -7326,7 +7487,7 @@ function Checkbox({
|
|
|
7326
7487
|
}
|
|
7327
7488
|
);
|
|
7328
7489
|
}
|
|
7329
|
-
var Switch =
|
|
7490
|
+
var Switch = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
7330
7491
|
SwitchPrimitive.Root,
|
|
7331
7492
|
{
|
|
7332
7493
|
className: cn(
|
|
@@ -7744,11 +7905,11 @@ function CreateProjectDialog({
|
|
|
7744
7905
|
const gql = useOrganifyGql();
|
|
7745
7906
|
const { workspace } = useOrganifyWorkspace();
|
|
7746
7907
|
const { navigate } = useOrganifyNavigation();
|
|
7747
|
-
const [name, setName] =
|
|
7748
|
-
const [type, setType] =
|
|
7749
|
-
const [error, setError] =
|
|
7750
|
-
const [loading, setLoading] =
|
|
7751
|
-
|
|
7908
|
+
const [name, setName] = React5.useState("");
|
|
7909
|
+
const [type, setType] = React5.useState("KANBAN");
|
|
7910
|
+
const [error, setError] = React5.useState("");
|
|
7911
|
+
const [loading, setLoading] = React5.useState(false);
|
|
7912
|
+
React5.useEffect(() => {
|
|
7752
7913
|
if (open) {
|
|
7753
7914
|
setName("");
|
|
7754
7915
|
setType("KANBAN");
|
|
@@ -7864,10 +8025,10 @@ function CreateWorkspaceDialog({
|
|
|
7864
8025
|
}) {
|
|
7865
8026
|
const gql = useOrganifyGql();
|
|
7866
8027
|
const { navigate } = useOrganifyNavigation();
|
|
7867
|
-
const [name, setName] =
|
|
7868
|
-
const [error, setError] =
|
|
7869
|
-
const [loading, setLoading] =
|
|
7870
|
-
|
|
8028
|
+
const [name, setName] = React5.useState("");
|
|
8029
|
+
const [error, setError] = React5.useState("");
|
|
8030
|
+
const [loading, setLoading] = React5.useState(false);
|
|
8031
|
+
React5.useEffect(() => {
|
|
7871
8032
|
if (open) {
|
|
7872
8033
|
setName("");
|
|
7873
8034
|
setError("");
|
|
@@ -7957,13 +8118,13 @@ function CreateSprintDialog({
|
|
|
7957
8118
|
const gql = useOrganifyGql();
|
|
7958
8119
|
const { project } = useOrganifyProject();
|
|
7959
8120
|
const effectiveProjectId = propProjectId ?? project?.id;
|
|
7960
|
-
const [name, setName] =
|
|
7961
|
-
const [goal, setGoal] =
|
|
7962
|
-
const [startDate, setStartDate] =
|
|
7963
|
-
const [endDate, setEndDate] =
|
|
7964
|
-
const [error, setError] =
|
|
7965
|
-
const [loading, setLoading] =
|
|
7966
|
-
|
|
8121
|
+
const [name, setName] = React5.useState("");
|
|
8122
|
+
const [goal, setGoal] = React5.useState("");
|
|
8123
|
+
const [startDate, setStartDate] = React5.useState("");
|
|
8124
|
+
const [endDate, setEndDate] = React5.useState("");
|
|
8125
|
+
const [error, setError] = React5.useState("");
|
|
8126
|
+
const [loading, setLoading] = React5.useState(false);
|
|
8127
|
+
React5.useEffect(() => {
|
|
7967
8128
|
if (open) {
|
|
7968
8129
|
setName("");
|
|
7969
8130
|
setGoal("");
|
|
@@ -8104,12 +8265,12 @@ function CreateEpicDialog({
|
|
|
8104
8265
|
const gql = useOrganifyGql();
|
|
8105
8266
|
const { project } = useOrganifyProject();
|
|
8106
8267
|
const effectiveProjectId = propProjectId ?? project?.id;
|
|
8107
|
-
const [name, setName] =
|
|
8108
|
-
const [description, setDescription] =
|
|
8109
|
-
const [color, setColor] =
|
|
8110
|
-
const [error, setError] =
|
|
8111
|
-
const [loading, setLoading] =
|
|
8112
|
-
|
|
8268
|
+
const [name, setName] = React5.useState("");
|
|
8269
|
+
const [description, setDescription] = React5.useState("");
|
|
8270
|
+
const [color, setColor] = React5.useState(EPIC_COLORS[0]);
|
|
8271
|
+
const [error, setError] = React5.useState("");
|
|
8272
|
+
const [loading, setLoading] = React5.useState(false);
|
|
8273
|
+
React5.useEffect(() => {
|
|
8113
8274
|
if (open) {
|
|
8114
8275
|
setName("");
|
|
8115
8276
|
setDescription("");
|
|
@@ -8245,11 +8406,11 @@ function CreateTaskDialog({
|
|
|
8245
8406
|
const gql = useOrganifyGql();
|
|
8246
8407
|
const projectCtx = useOrganifyProject();
|
|
8247
8408
|
const projectId = projectIdProp ?? projectCtx?.project?.id;
|
|
8248
|
-
const [title, setTitle] =
|
|
8249
|
-
const [priority, setPriority] =
|
|
8250
|
-
const [error, setError] =
|
|
8251
|
-
const [loading, setLoading] =
|
|
8252
|
-
|
|
8409
|
+
const [title, setTitle] = React5.useState("");
|
|
8410
|
+
const [priority, setPriority] = React5.useState("NONE");
|
|
8411
|
+
const [error, setError] = React5.useState("");
|
|
8412
|
+
const [loading, setLoading] = React5.useState(false);
|
|
8413
|
+
React5.useEffect(() => {
|
|
8253
8414
|
if (open) {
|
|
8254
8415
|
setTitle("");
|
|
8255
8416
|
setPriority("NONE");
|
|
@@ -8361,11 +8522,11 @@ function InviteMemberDialog({
|
|
|
8361
8522
|
const gql = useOrganifyGql();
|
|
8362
8523
|
const { workspace } = useOrganifyWorkspace();
|
|
8363
8524
|
const effectiveWsId = propWorkspaceId ?? workspace?.id;
|
|
8364
|
-
const [email, setEmail] =
|
|
8365
|
-
const [role, setRole] =
|
|
8366
|
-
const [error, setError] =
|
|
8367
|
-
const [loading, setLoading] =
|
|
8368
|
-
|
|
8525
|
+
const [email, setEmail] = React5.useState("");
|
|
8526
|
+
const [role, setRole] = React5.useState("MEMBER");
|
|
8527
|
+
const [error, setError] = React5.useState("");
|
|
8528
|
+
const [loading, setLoading] = React5.useState(false);
|
|
8529
|
+
React5.useEffect(() => {
|
|
8369
8530
|
if (open) {
|
|
8370
8531
|
setEmail("");
|
|
8371
8532
|
setRole("MEMBER");
|