@burdenoff/microfe-workspaces 2026.616.1 → 2026.623.1
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.
|
@@ -5,148 +5,171 @@ import { nativeConfirm as r, nativeImpact as i } from "../utils/nativeBridge.js"
|
|
|
5
5
|
import { useArchiveProject as a, useDeleteProject as o, useUnarchiveProject as s } from "../hooks/useProjectMutations.js";
|
|
6
6
|
import { formatDate as c } from "../utils/formatters.js";
|
|
7
7
|
import { getProjectDisplayTags as l } from "../utils/projectTags.js";
|
|
8
|
-
import { Archive as u,
|
|
9
|
-
import { jsx as
|
|
10
|
-
import { Badge as
|
|
11
|
-
import { useNavigate as
|
|
12
|
-
import { TagBadge as
|
|
8
|
+
import { Archive as u, Fingerprint as d, FolderKanban as f, MoreVertical as p } from "lucide-react";
|
|
9
|
+
import { Fragment as m, jsx as h, jsxs as g } from "react/jsx-runtime";
|
|
10
|
+
import { Badge as _, Button as v, Card as y, CardContent as b, CardHeader as x, CardTitle as S, DropdownMenu as C, DropdownMenuContent as w, DropdownMenuItem as T, DropdownMenuTrigger as E, EntityIdModal as D, useEntityIdModal as O } from "@burdenoff/fe-libs/ui";
|
|
11
|
+
import { useNavigate as k } from "react-router-dom";
|
|
12
|
+
import { TagBadge as A } from "@burdenoff/fe-libs/tag";
|
|
13
13
|
//#region src/components/ProjectCard.tsx
|
|
14
|
-
function
|
|
15
|
-
let
|
|
16
|
-
|
|
14
|
+
function j({ project: j, selected: M = !1, onToggleSelect: N, onTagClick: P, canArchive: F = !1, canDelete: I = !1 }) {
|
|
15
|
+
let L = k(), { basePath: R = "/workspaces" } = e(), { withCurrentSearch: z } = n(), { mutate: B } = a(j.workspaceId), { mutate: V } = s(j.workspaceId), { mutate: H } = o(j.workspaceId), U = O(), W = l(j), G = () => {
|
|
16
|
+
L(z(`${R}/${j.workspaceId}/projects/${j.id}`));
|
|
17
17
|
};
|
|
18
|
-
return /* @__PURE__ */ m(
|
|
19
|
-
className: `cursor-pointer relative ${
|
|
20
|
-
onClick:
|
|
18
|
+
return /* @__PURE__ */ g(m, { children: [/* @__PURE__ */ g(y, {
|
|
19
|
+
className: `cursor-pointer relative ${M ? "ring-2 ring-primary/25 border-primary/50" : ""}`,
|
|
20
|
+
onClick: G,
|
|
21
21
|
onKeyDown: (e) => {
|
|
22
|
-
(e.key === "Enter" || e.key === " ") && (e.preventDefault(),
|
|
22
|
+
(e.key === "Enter" || e.key === " ") && (e.preventDefault(), G());
|
|
23
23
|
},
|
|
24
24
|
role: "button",
|
|
25
25
|
tabIndex: 0,
|
|
26
|
-
"aria-label": `Open project ${
|
|
27
|
-
children: [/* @__PURE__ */
|
|
26
|
+
"aria-label": `Open project ${j.name}`,
|
|
27
|
+
children: [/* @__PURE__ */ h(x, { children: /* @__PURE__ */ g("div", {
|
|
28
28
|
className: "flex items-start justify-between",
|
|
29
|
-
children: [/* @__PURE__ */
|
|
29
|
+
children: [/* @__PURE__ */ g("div", {
|
|
30
30
|
className: "flex items-center gap-3 flex-1",
|
|
31
31
|
children: [
|
|
32
|
-
|
|
32
|
+
N && /* @__PURE__ */ h("input", {
|
|
33
33
|
type: "checkbox",
|
|
34
|
-
checked:
|
|
35
|
-
onChange: (e) =>
|
|
34
|
+
checked: M,
|
|
35
|
+
onChange: (e) => N(e.target.checked),
|
|
36
36
|
onClick: (e) => e.stopPropagation(),
|
|
37
|
-
"aria-label": `Select project ${
|
|
37
|
+
"aria-label": `Select project ${j.name}`,
|
|
38
38
|
className: "mt-1 size-4 rounded border-border text-primary"
|
|
39
39
|
}),
|
|
40
|
-
/* @__PURE__ */
|
|
40
|
+
/* @__PURE__ */ h("div", {
|
|
41
41
|
className: "p-3 rounded-lg bg-primary/10 transition-colors",
|
|
42
|
-
children: /* @__PURE__ */
|
|
42
|
+
children: /* @__PURE__ */ h(f, {
|
|
43
43
|
className: "text-primary",
|
|
44
44
|
size: 24
|
|
45
45
|
})
|
|
46
46
|
}),
|
|
47
|
-
/* @__PURE__ */
|
|
47
|
+
/* @__PURE__ */ g("div", {
|
|
48
48
|
className: "flex-1 min-w-0",
|
|
49
|
-
children: [/* @__PURE__ */
|
|
49
|
+
children: [/* @__PURE__ */ h(S, {
|
|
50
50
|
className: "truncate",
|
|
51
|
-
children:
|
|
52
|
-
}), /* @__PURE__ */
|
|
51
|
+
children: j.name
|
|
52
|
+
}), /* @__PURE__ */ h("p", {
|
|
53
53
|
className: "truncate text-sm text-muted-foreground",
|
|
54
|
-
children:
|
|
54
|
+
children: j.key
|
|
55
55
|
})]
|
|
56
56
|
})
|
|
57
57
|
]
|
|
58
|
-
}), /* @__PURE__ */
|
|
58
|
+
}), /* @__PURE__ */ g(C, { children: [/* @__PURE__ */ h(E, {
|
|
59
59
|
asChild: !0,
|
|
60
60
|
onClick: (e) => e.stopPropagation(),
|
|
61
|
-
children: /* @__PURE__ */
|
|
61
|
+
children: /* @__PURE__ */ g(v, {
|
|
62
62
|
variant: "ghost",
|
|
63
63
|
size: "sm",
|
|
64
64
|
className: "size-8 p-0",
|
|
65
|
-
children: [/* @__PURE__ */ p
|
|
65
|
+
children: [/* @__PURE__ */ h(p, { size: 16 }), /* @__PURE__ */ h("span", {
|
|
66
66
|
className: "sr-only",
|
|
67
67
|
children: "Open project actions"
|
|
68
68
|
})]
|
|
69
69
|
})
|
|
70
|
-
}), /* @__PURE__ */
|
|
70
|
+
}), /* @__PURE__ */ g(w, {
|
|
71
71
|
align: "end",
|
|
72
|
-
children: [
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
72
|
+
children: [
|
|
73
|
+
/* @__PURE__ */ g(T, {
|
|
74
|
+
onClick: (e) => {
|
|
75
|
+
e.stopPropagation(), U.show({
|
|
76
|
+
id: j.id,
|
|
77
|
+
name: j.name,
|
|
78
|
+
type: "Project",
|
|
79
|
+
details: [{
|
|
80
|
+
label: "Key",
|
|
81
|
+
value: j.key
|
|
82
|
+
}, {
|
|
83
|
+
label: "Workspace ID",
|
|
84
|
+
value: j.workspaceId
|
|
85
|
+
}]
|
|
86
|
+
});
|
|
87
|
+
},
|
|
88
|
+
children: [/* @__PURE__ */ h(d, {
|
|
89
|
+
size: 16,
|
|
90
|
+
className: "mr-2"
|
|
91
|
+
}), "Get ID"]
|
|
92
|
+
}),
|
|
93
|
+
F && /* @__PURE__ */ g(T, {
|
|
94
|
+
onClick: (e) => {
|
|
95
|
+
e.stopPropagation(), j.archived ? V(j.id) : B(j.id);
|
|
96
|
+
},
|
|
97
|
+
children: [/* @__PURE__ */ h(u, {
|
|
98
|
+
size: 16,
|
|
99
|
+
className: "mr-2"
|
|
100
|
+
}), j.archived ? "Unarchive" : "Archive"]
|
|
101
|
+
}),
|
|
102
|
+
I && /* @__PURE__ */ h(T, {
|
|
103
|
+
onClick: async (e) => {
|
|
104
|
+
e.stopPropagation(), i("medium");
|
|
105
|
+
let t = await r({
|
|
106
|
+
title: "Delete project",
|
|
107
|
+
message: `Are you sure you want to delete "${j.name}"?`,
|
|
108
|
+
okButtonTitle: "Delete",
|
|
109
|
+
cancelButtonTitle: "Cancel"
|
|
110
|
+
});
|
|
111
|
+
(t === null ? confirm(`Are you sure you want to delete "${j.name}"?`) : t) && H(j.id);
|
|
112
|
+
},
|
|
113
|
+
className: "text-destructive",
|
|
114
|
+
children: "Delete"
|
|
115
|
+
})
|
|
116
|
+
]
|
|
94
117
|
})] })]
|
|
95
|
-
}) }), /* @__PURE__ */
|
|
118
|
+
}) }), /* @__PURE__ */ g(b, {
|
|
96
119
|
className: "space-y-3",
|
|
97
120
|
children: [
|
|
98
|
-
/* @__PURE__ */
|
|
121
|
+
/* @__PURE__ */ g("div", {
|
|
99
122
|
className: "flex items-center gap-2",
|
|
100
|
-
children: [/* @__PURE__ */
|
|
101
|
-
className: `border ${t(
|
|
102
|
-
children:
|
|
103
|
-
}),
|
|
123
|
+
children: [/* @__PURE__ */ h(_, {
|
|
124
|
+
className: `border ${t(j.status)}`,
|
|
125
|
+
children: j.status
|
|
126
|
+
}), j.archived && /* @__PURE__ */ g(_, {
|
|
104
127
|
variant: "outline",
|
|
105
128
|
className: "border-workspace-archived-border text-workspace-archived-text",
|
|
106
|
-
children: [/* @__PURE__ */
|
|
129
|
+
children: [/* @__PURE__ */ h(u, {
|
|
107
130
|
size: 12,
|
|
108
131
|
className: "mr-1"
|
|
109
132
|
}), "Archived"]
|
|
110
133
|
})]
|
|
111
134
|
}),
|
|
112
|
-
/* @__PURE__ */
|
|
135
|
+
/* @__PURE__ */ g("div", {
|
|
113
136
|
className: "text-xs text-muted-foreground",
|
|
114
|
-
children: ["Created ", c(
|
|
137
|
+
children: ["Created ", c(j.createdAt)]
|
|
115
138
|
}),
|
|
116
|
-
|
|
139
|
+
W.length > 0 && /* @__PURE__ */ g("div", {
|
|
117
140
|
className: "flex flex-wrap gap-1.5",
|
|
118
141
|
"aria-label": "Project tags",
|
|
119
|
-
children: [
|
|
120
|
-
...
|
|
142
|
+
children: [W.slice(0, 4).map((e) => /* @__PURE__ */ h("span", {
|
|
143
|
+
...P ? {
|
|
121
144
|
role: "button",
|
|
122
145
|
tabIndex: 0,
|
|
123
146
|
onClick: (t) => {
|
|
124
|
-
t.stopPropagation(),
|
|
147
|
+
t.stopPropagation(), P(e);
|
|
125
148
|
},
|
|
126
149
|
onKeyDown: (t) => {
|
|
127
|
-
(t.key === "Enter" || t.key === " ") && (t.preventDefault(), t.stopPropagation(),
|
|
150
|
+
(t.key === "Enter" || t.key === " ") && (t.preventDefault(), t.stopPropagation(), P(e));
|
|
128
151
|
}
|
|
129
152
|
} : {},
|
|
130
|
-
children: /* @__PURE__ */
|
|
153
|
+
children: /* @__PURE__ */ h(A, {
|
|
131
154
|
id: e.tagId,
|
|
132
155
|
label: e.label,
|
|
133
156
|
color: e.color ?? void 0,
|
|
134
157
|
icon: e.icon ?? void 0,
|
|
135
158
|
description: e.description ?? void 0,
|
|
136
159
|
size: "sm",
|
|
137
|
-
className:
|
|
160
|
+
className: P ? "cursor-pointer" : void 0
|
|
138
161
|
})
|
|
139
|
-
}, e.tagId)),
|
|
162
|
+
}, e.tagId)), W.length > 4 && /* @__PURE__ */ g(_, {
|
|
140
163
|
variant: "outline",
|
|
141
164
|
className: "text-xs",
|
|
142
|
-
children: ["+",
|
|
165
|
+
children: ["+", W.length - 4]
|
|
143
166
|
})]
|
|
144
167
|
})
|
|
145
168
|
]
|
|
146
169
|
})]
|
|
147
|
-
});
|
|
170
|
+
}), /* @__PURE__ */ h(D, { control: U })] });
|
|
148
171
|
}
|
|
149
172
|
//#endregion
|
|
150
|
-
export {
|
|
173
|
+
export { j as ProjectCard };
|
|
151
174
|
|
|
152
175
|
//# sourceMappingURL=ProjectCard.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProjectCard.js","names":[],"sources":["../../src/components/ProjectCard.tsx"],"sourcesContent":["import type React from 'react';\nimport { FolderKanban, Archive, MoreVertical } from 'lucide-react';\nimport { useNavigate } from 'react-router-dom';\nimport {\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n Badge,\n Button,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@burdenoff/fe-libs/ui';\nimport { TagBadge } from '@burdenoff/fe-libs/tag';\n\nimport type { Project, ProjectTag } from '../types';\nimport { formatDate } from '../utils/formatters';\nimport { getProjectDisplayTags } from '../utils/projectTags';\nimport { getProjectStatusClasses } from '../utils/tokenHelpers';\nimport {\n useArchiveProject,\n useUnarchiveProject,\n useDeleteProject,\n} from '../hooks/useProjectMutations';\nimport { useWorkspacesContext } from '../providers/WorkspacesProvider';\nimport { useScopedNavigation } from '../hooks/useScopedNavigation';\nimport { nativeConfirm, nativeImpact } from '../utils/nativeBridge';\n\ninterface ProjectCardProps {\n project: Project;\n selected?: boolean;\n onToggleSelect?: (checked: boolean) => void;\n onTagClick?: (tag: ProjectTag) => void;\n canArchive?: boolean;\n canDelete?: boolean;\n}\n\nexport function ProjectCard({\n project,\n selected = false,\n onToggleSelect,\n onTagClick,\n canArchive = false,\n canDelete = false,\n}: ProjectCardProps) {\n const navigate = useNavigate();\n const { basePath = '/workspaces' } = useWorkspacesContext();\n const { withCurrentSearch } = useScopedNavigation();\n const { mutate: archiveProject } = useArchiveProject(project.workspaceId);\n const { mutate: unarchiveProject } = useUnarchiveProject(project.workspaceId);\n const { mutate: deleteProject } = useDeleteProject(project.workspaceId);\n const projectTags = getProjectDisplayTags(project);\n\n const handleCardClick = () => {\n navigate(withCurrentSearch(`${basePath}/${project.workspaceId}/projects/${project.id}`));\n };\n\n const handleArchive = (e: React.MouseEvent) => {\n e.stopPropagation();\n if (project.archived) {\n unarchiveProject(project.id);\n } else {\n archiveProject(project.id);\n }\n };\n\n const handleDelete = async (e: React.MouseEvent) => {\n e.stopPropagation();\n void nativeImpact('medium');\n const native = await nativeConfirm({\n title: 'Delete project',\n message: `Are you sure you want to delete \"${project.name}\"?`,\n okButtonTitle: 'Delete',\n cancelButtonTitle: 'Cancel',\n });\n const ok =\n native === null ? confirm(`Are you sure you want to delete \"${project.name}\"?`) : native;\n if (ok) {\n deleteProject(project.id);\n }\n };\n\n const handleCardKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n handleCardClick();\n }\n };\n\n return (\n <Card\n className={`cursor-pointer relative ${\n selected ? 'ring-2 ring-primary/25 border-primary/50' : ''\n }`}\n onClick={handleCardClick}\n onKeyDown={handleCardKeyDown}\n role=\"button\"\n tabIndex={0}\n aria-label={`Open project ${project.name}`}\n >\n <CardHeader>\n <div className=\"flex items-start justify-between\">\n <div className=\"flex items-center gap-3 flex-1\">\n {onToggleSelect && (\n <input\n type=\"checkbox\"\n checked={selected}\n onChange={(event) => onToggleSelect(event.target.checked)}\n onClick={(event) => event.stopPropagation()}\n aria-label={`Select project ${project.name}`}\n className=\"mt-1 size-4 rounded border-border text-primary\"\n />\n )}\n <div className=\"p-3 rounded-lg bg-primary/10 transition-colors\">\n <FolderKanban className=\"text-primary\" size={24} />\n </div>\n <div className=\"flex-1 min-w-0\">\n <CardTitle className=\"truncate\">{project.name}</CardTitle>\n <p className=\"truncate text-sm text-muted-foreground\">{project.key}</p>\n </div>\n </div>\n <DropdownMenu>\n <DropdownMenuTrigger asChild onClick={(e) => e.stopPropagation()}>\n <Button variant=\"ghost\" size=\"sm\" className=\"size-8 p-0\">\n <MoreVertical size={16} />\n <span className=\"sr-only\">Open project actions</span>\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n {canArchive && (\n <DropdownMenuItem onClick={handleArchive}>\n <Archive size={16} className=\"mr-2\" />\n {project.archived ? 'Unarchive' : 'Archive'}\n </DropdownMenuItem>\n )}\n {canDelete && (\n <DropdownMenuItem onClick={handleDelete} className=\"text-destructive\">\n Delete\n </DropdownMenuItem>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n <div className=\"flex items-center gap-2\">\n <Badge className={`border ${getProjectStatusClasses(project.status)}`}>\n {project.status}\n </Badge>\n {project.archived && (\n <Badge\n variant=\"outline\"\n className=\"border-workspace-archived-border text-workspace-archived-text\"\n >\n <Archive size={12} className=\"mr-1\" />\n Archived\n </Badge>\n )}\n </div>\n <div className=\"text-xs text-muted-foreground\">Created {formatDate(project.createdAt)}</div>\n {projectTags.length > 0 && (\n <div className=\"flex flex-wrap gap-1.5\" aria-label=\"Project tags\">\n {projectTags.slice(0, 4).map((tag) => (\n <span\n key={tag.tagId}\n {...(onTagClick\n ? {\n role: 'button',\n tabIndex: 0,\n onClick: (event: React.MouseEvent<HTMLSpanElement>) => {\n event.stopPropagation();\n onTagClick(tag);\n },\n onKeyDown: (event: React.KeyboardEvent<HTMLSpanElement>) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n event.stopPropagation();\n onTagClick(tag);\n }\n },\n }\n : {})}\n >\n <TagBadge\n id={tag.tagId}\n label={tag.label}\n color={tag.color ?? undefined}\n icon={tag.icon ?? undefined}\n description={tag.description ?? undefined}\n size=\"sm\"\n className={onTagClick ? 'cursor-pointer' : undefined}\n />\n </span>\n ))}\n {projectTags.length > 4 && (\n <Badge variant=\"outline\" className=\"text-xs\">\n +{projectTags.length - 4}\n </Badge>\n )}\n </div>\n )}\n </CardContent>\n </Card>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ProjectCard.js","names":[],"sources":["../../src/components/ProjectCard.tsx"],"sourcesContent":["import type React from 'react';\nimport { FolderKanban, Archive, MoreVertical, Fingerprint } from 'lucide-react';\nimport { useNavigate } from 'react-router-dom';\nimport {\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n Badge,\n Button,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n EntityIdModal,\n useEntityIdModal,\n} from '@burdenoff/fe-libs/ui';\nimport { TagBadge } from '@burdenoff/fe-libs/tag';\n\nimport type { Project, ProjectTag } from '../types';\nimport { formatDate } from '../utils/formatters';\nimport { getProjectDisplayTags } from '../utils/projectTags';\nimport { getProjectStatusClasses } from '../utils/tokenHelpers';\nimport {\n useArchiveProject,\n useUnarchiveProject,\n useDeleteProject,\n} from '../hooks/useProjectMutations';\nimport { useWorkspacesContext } from '../providers/WorkspacesProvider';\nimport { useScopedNavigation } from '../hooks/useScopedNavigation';\nimport { nativeConfirm, nativeImpact } from '../utils/nativeBridge';\n\ninterface ProjectCardProps {\n project: Project;\n selected?: boolean;\n onToggleSelect?: (checked: boolean) => void;\n onTagClick?: (tag: ProjectTag) => void;\n canArchive?: boolean;\n canDelete?: boolean;\n}\n\nexport function ProjectCard({\n project,\n selected = false,\n onToggleSelect,\n onTagClick,\n canArchive = false,\n canDelete = false,\n}: ProjectCardProps) {\n const navigate = useNavigate();\n const { basePath = '/workspaces' } = useWorkspacesContext();\n const { withCurrentSearch } = useScopedNavigation();\n const { mutate: archiveProject } = useArchiveProject(project.workspaceId);\n const { mutate: unarchiveProject } = useUnarchiveProject(project.workspaceId);\n const { mutate: deleteProject } = useDeleteProject(project.workspaceId);\n const idModal = useEntityIdModal();\n const projectTags = getProjectDisplayTags(project);\n\n const handleCardClick = () => {\n navigate(withCurrentSearch(`${basePath}/${project.workspaceId}/projects/${project.id}`));\n };\n\n const handleArchive = (e: React.MouseEvent) => {\n e.stopPropagation();\n if (project.archived) {\n unarchiveProject(project.id);\n } else {\n archiveProject(project.id);\n }\n };\n\n const handleDelete = async (e: React.MouseEvent) => {\n e.stopPropagation();\n void nativeImpact('medium');\n const native = await nativeConfirm({\n title: 'Delete project',\n message: `Are you sure you want to delete \"${project.name}\"?`,\n okButtonTitle: 'Delete',\n cancelButtonTitle: 'Cancel',\n });\n const ok =\n native === null ? confirm(`Are you sure you want to delete \"${project.name}\"?`) : native;\n if (ok) {\n deleteProject(project.id);\n }\n };\n\n const handleCardKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n handleCardClick();\n }\n };\n\n return (\n <>\n <Card\n className={`cursor-pointer relative ${\n selected ? 'ring-2 ring-primary/25 border-primary/50' : ''\n }`}\n onClick={handleCardClick}\n onKeyDown={handleCardKeyDown}\n role=\"button\"\n tabIndex={0}\n aria-label={`Open project ${project.name}`}\n >\n <CardHeader>\n <div className=\"flex items-start justify-between\">\n <div className=\"flex items-center gap-3 flex-1\">\n {onToggleSelect && (\n <input\n type=\"checkbox\"\n checked={selected}\n onChange={(event) => onToggleSelect(event.target.checked)}\n onClick={(event) => event.stopPropagation()}\n aria-label={`Select project ${project.name}`}\n className=\"mt-1 size-4 rounded border-border text-primary\"\n />\n )}\n <div className=\"p-3 rounded-lg bg-primary/10 transition-colors\">\n <FolderKanban className=\"text-primary\" size={24} />\n </div>\n <div className=\"flex-1 min-w-0\">\n <CardTitle className=\"truncate\">{project.name}</CardTitle>\n <p className=\"truncate text-sm text-muted-foreground\">{project.key}</p>\n </div>\n </div>\n <DropdownMenu>\n <DropdownMenuTrigger asChild onClick={(e) => e.stopPropagation()}>\n <Button variant=\"ghost\" size=\"sm\" className=\"size-8 p-0\">\n <MoreVertical size={16} />\n <span className=\"sr-only\">Open project actions</span>\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem\n onClick={(e) => {\n e.stopPropagation();\n idModal.show({\n id: project.id,\n name: project.name,\n type: 'Project',\n details: [\n { label: 'Key', value: project.key },\n { label: 'Workspace ID', value: project.workspaceId },\n ],\n });\n }}\n >\n <Fingerprint size={16} className=\"mr-2\" />\n Get ID\n </DropdownMenuItem>\n {canArchive && (\n <DropdownMenuItem onClick={handleArchive}>\n <Archive size={16} className=\"mr-2\" />\n {project.archived ? 'Unarchive' : 'Archive'}\n </DropdownMenuItem>\n )}\n {canDelete && (\n <DropdownMenuItem onClick={handleDelete} className=\"text-destructive\">\n Delete\n </DropdownMenuItem>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n <div className=\"flex items-center gap-2\">\n <Badge className={`border ${getProjectStatusClasses(project.status)}`}>\n {project.status}\n </Badge>\n {project.archived && (\n <Badge\n variant=\"outline\"\n className=\"border-workspace-archived-border text-workspace-archived-text\"\n >\n <Archive size={12} className=\"mr-1\" />\n Archived\n </Badge>\n )}\n </div>\n <div className=\"text-xs text-muted-foreground\">\n Created {formatDate(project.createdAt)}\n </div>\n {projectTags.length > 0 && (\n <div className=\"flex flex-wrap gap-1.5\" aria-label=\"Project tags\">\n {projectTags.slice(0, 4).map((tag) => (\n <span\n key={tag.tagId}\n {...(onTagClick\n ? {\n role: 'button',\n tabIndex: 0,\n onClick: (event: React.MouseEvent<HTMLSpanElement>) => {\n event.stopPropagation();\n onTagClick(tag);\n },\n onKeyDown: (event: React.KeyboardEvent<HTMLSpanElement>) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n event.stopPropagation();\n onTagClick(tag);\n }\n },\n }\n : {})}\n >\n <TagBadge\n id={tag.tagId}\n label={tag.label}\n color={tag.color ?? undefined}\n icon={tag.icon ?? undefined}\n description={tag.description ?? undefined}\n size=\"sm\"\n className={onTagClick ? 'cursor-pointer' : undefined}\n />\n </span>\n ))}\n {projectTags.length > 4 && (\n <Badge variant=\"outline\" className=\"text-xs\">\n +{projectTags.length - 4}\n </Badge>\n )}\n </div>\n )}\n </CardContent>\n </Card>\n <EntityIdModal control={idModal} />\n </>\n );\n}\n"],"mappings":"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"}
|
|
@@ -9,54 +9,54 @@ import { useProject as re, useProjectMembersCount as ie } from "../hooks/useProj
|
|
|
9
9
|
import { useArchiveProject as ae, useDeleteProject as oe, useTagProject as se, useUnarchiveProject as ce, useUntagProject as le, useUpdateProject as ue } from "../hooks/useProjectMutations.js";
|
|
10
10
|
import { formatDate as a } from "../utils/formatters.js";
|
|
11
11
|
import { getProjectDisplayTags as de, toProjectTag as o } from "../utils/projectTags.js";
|
|
12
|
-
import { useWorkspaceActivity as
|
|
13
|
-
import { ProjectTagsWidget as
|
|
14
|
-
import { ProjectMemberPickerDialog as
|
|
15
|
-
import { useMemo as
|
|
16
|
-
import { Activity as
|
|
17
|
-
import { jsx as
|
|
18
|
-
import { AlertDialog as
|
|
19
|
-
import { useNavigate as
|
|
20
|
-
import { useI18n as
|
|
12
|
+
import { useWorkspaceActivity as fe } from "../hooks/useWorkspaceActivity.js";
|
|
13
|
+
import { ProjectTagsWidget as s } from "../components/tags/ProjectTagsWidget.js";
|
|
14
|
+
import { ProjectMemberPickerDialog as c } from "../components/ProjectMemberPickerDialog.js";
|
|
15
|
+
import { useMemo as l, useState as u } from "react";
|
|
16
|
+
import { Activity as d, Archive as f, ArrowLeft as p, Clock as m, FolderKanban as h, MoreVertical as pe, UserPlus as me, Users as g } from "lucide-react";
|
|
17
|
+
import { jsx as _, jsxs as v } from "react/jsx-runtime";
|
|
18
|
+
import { AlertDialog as he, AlertDialogAction as ge, AlertDialogCancel as _e, AlertDialogContent as ve, AlertDialogDescription as ye, AlertDialogFooter as be, AlertDialogHeader as xe, AlertDialogTitle as Se, Badge as y, Button as b, Card as x, CardContent as S, CardHeader as C, CardTitle as w, DropdownMenu as T, DropdownMenuContent as E, DropdownMenuItem as D, DropdownMenuSeparator as O, DropdownMenuTrigger as k, EntityIdModal as A, Skeleton as j, useEntityIdModal as Ce } from "@burdenoff/fe-libs/ui";
|
|
19
|
+
import { useNavigate as we, useParams as Te } from "react-router-dom";
|
|
20
|
+
import { useI18n as Ee } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
21
21
|
//#region src/pages/ProjectDetailPage.tsx
|
|
22
|
-
function
|
|
23
|
-
let { t:
|
|
22
|
+
function M() {
|
|
23
|
+
let { t: M } = Ee(), N = Ce(), { workspaceId: P, projectId: F } = Te();
|
|
24
24
|
ee("workspaces.project-detail", {
|
|
25
25
|
workspaceId: P,
|
|
26
26
|
projectId: F,
|
|
27
27
|
requireParams: !0
|
|
28
28
|
});
|
|
29
|
-
let I =
|
|
29
|
+
let I = we(), { basePath: L = "/workspaces" } = e(), { withCurrentSearch: R } = n(), { data: z, isLoading: De, error: Oe } = re(F || "", P), [ke, B] = u(!1), [V, H] = u(!1), { mutate: Ae, isPending: U } = ae(P), { mutate: je, isPending: W } = ce(P), { mutate: Me, isPending: G } = oe(P), { mutateAsync: Ne, isPending: Pe } = se(P), { mutateAsync: Fe, isPending: Ie } = le(P), { mutateAsync: Le, isPending: Re } = ue(P), { canViewProject: ze, canDeleteProject: K, canArchiveProject: q, canListProjectMembers: J, canAddProjectMember: Y, isLoading: Be } = ne(), { data: Ve } = ie(F || "", P), X = l(() => de({
|
|
30
30
|
tags: z?.tags ?? [],
|
|
31
31
|
tagAssignments: z?.tagAssignments
|
|
32
|
-
}), [z?.tags, z?.tagAssignments]), { data:
|
|
33
|
-
if (
|
|
32
|
+
}), [z?.tags, z?.tagAssignments]), { data: He } = fe(P), Ue = (He ?? []).filter((e) => e.resourceId === F || e.resourceType?.toLowerCase() === "project").length, We = X;
|
|
33
|
+
if (Be) return /* @__PURE__ */ v("div", {
|
|
34
34
|
className: "space-y-4 p-6",
|
|
35
|
-
children: [/* @__PURE__ */
|
|
35
|
+
children: [/* @__PURE__ */ _(j, { className: "h-10 w-1/3" }), /* @__PURE__ */ _(j, { className: "h-64" })]
|
|
36
36
|
});
|
|
37
|
-
if (!
|
|
37
|
+
if (!ze) return /* @__PURE__ */ _("div", {
|
|
38
38
|
className: "flex items-center justify-center min-h-[400px]",
|
|
39
|
-
children: /* @__PURE__ */
|
|
39
|
+
children: /* @__PURE__ */ v("div", {
|
|
40
40
|
className: "text-center space-y-2",
|
|
41
|
-
children: [/* @__PURE__ */
|
|
41
|
+
children: [/* @__PURE__ */ _("h2", {
|
|
42
42
|
className: "text-lg font-semibold",
|
|
43
|
-
children: r(
|
|
44
|
-
}), /* @__PURE__ */
|
|
43
|
+
children: r(M, "projectDetail.accessDenied", "Access Denied")
|
|
44
|
+
}), /* @__PURE__ */ _("p", {
|
|
45
45
|
className: "text-sm text-muted-foreground",
|
|
46
|
-
children: r(
|
|
46
|
+
children: r(M, "projectDetail.noPermissionToViewProject", "You don't have permission to view this project.")
|
|
47
47
|
})]
|
|
48
48
|
})
|
|
49
49
|
});
|
|
50
50
|
let Z = () => {
|
|
51
51
|
I(R(`${L}/${P}/projects`));
|
|
52
|
-
},
|
|
53
|
-
z && (z.archived ?
|
|
52
|
+
}, Ge = () => {
|
|
53
|
+
z && (z.archived ? je(z.id, { onError: (e) => {
|
|
54
54
|
console.error("Failed to unarchive project:", e);
|
|
55
|
-
} }) :
|
|
55
|
+
} }) : Ae(z.id, { onError: (e) => {
|
|
56
56
|
console.error("Failed to archive project:", e);
|
|
57
57
|
} }));
|
|
58
|
-
},
|
|
59
|
-
z && (te("medium"),
|
|
58
|
+
}, Ke = () => {
|
|
59
|
+
z && (te("medium"), Me(z.id, {
|
|
60
60
|
onSuccess: () => {
|
|
61
61
|
i("success"), B(!1), I(R(`${L}/${P}/projects`));
|
|
62
62
|
},
|
|
@@ -70,7 +70,7 @@ function N() {
|
|
|
70
70
|
if (!z) return;
|
|
71
71
|
let t = e.map((e) => o(e));
|
|
72
72
|
try {
|
|
73
|
-
await
|
|
73
|
+
await Le({
|
|
74
74
|
id: z.id,
|
|
75
75
|
input: { tags: t }
|
|
76
76
|
});
|
|
@@ -78,200 +78,200 @@ function N() {
|
|
|
78
78
|
i("warning"), console.error("Failed to sync legacy project tag mirror after updating structured project tags:", e);
|
|
79
79
|
}
|
|
80
80
|
};
|
|
81
|
-
return
|
|
81
|
+
return De ? /* @__PURE__ */ v("div", {
|
|
82
82
|
className: "space-y-4 sm:space-y-6 p-3 sm:p-6",
|
|
83
83
|
children: [
|
|
84
|
-
/* @__PURE__ */
|
|
85
|
-
/* @__PURE__ */
|
|
86
|
-
/* @__PURE__ */
|
|
84
|
+
/* @__PURE__ */ _(j, { className: "h-10 w-32" }),
|
|
85
|
+
/* @__PURE__ */ _(j, { className: "h-10 w-1/3" }),
|
|
86
|
+
/* @__PURE__ */ v("div", {
|
|
87
87
|
className: "grid grid-cols-1 md:grid-cols-3 gap-4",
|
|
88
88
|
children: [
|
|
89
|
-
/* @__PURE__ */
|
|
90
|
-
/* @__PURE__ */
|
|
91
|
-
/* @__PURE__ */
|
|
89
|
+
/* @__PURE__ */ _(j, { className: "h-32" }),
|
|
90
|
+
/* @__PURE__ */ _(j, { className: "h-32" }),
|
|
91
|
+
/* @__PURE__ */ _(j, { className: "h-32" })
|
|
92
92
|
]
|
|
93
93
|
}),
|
|
94
|
-
/* @__PURE__ */
|
|
94
|
+
/* @__PURE__ */ _(j, { className: "h-48" })
|
|
95
95
|
]
|
|
96
|
-
}) :
|
|
96
|
+
}) : Oe || !z ? /* @__PURE__ */ v("div", {
|
|
97
97
|
className: "space-y-4 p-6",
|
|
98
|
-
children: [/* @__PURE__ */
|
|
98
|
+
children: [/* @__PURE__ */ v(b, {
|
|
99
99
|
variant: "ghost",
|
|
100
100
|
onClick: Z,
|
|
101
101
|
className: "gap-2",
|
|
102
|
-
children: [/* @__PURE__ */
|
|
103
|
-
}), /* @__PURE__ */
|
|
102
|
+
children: [/* @__PURE__ */ _(p, { size: 20 }), r(M, "projectDetail.backToProjects", "Back to Projects")]
|
|
103
|
+
}), /* @__PURE__ */ v("div", {
|
|
104
104
|
className: "text-center py-12",
|
|
105
105
|
children: [
|
|
106
|
-
/* @__PURE__ */
|
|
106
|
+
/* @__PURE__ */ _("div", {
|
|
107
107
|
className: "rounded-full bg-muted p-6 mb-4 inline-block",
|
|
108
|
-
children: /* @__PURE__ */
|
|
108
|
+
children: /* @__PURE__ */ _(h, {
|
|
109
109
|
size: 48,
|
|
110
110
|
className: "text-muted-foreground"
|
|
111
111
|
})
|
|
112
112
|
}),
|
|
113
|
-
/* @__PURE__ */
|
|
113
|
+
/* @__PURE__ */ _("h3", {
|
|
114
114
|
className: "text-lg font-semibold mb-2",
|
|
115
|
-
children: r(
|
|
115
|
+
children: r(M, "projectDetail.projectNotFound", "Project not found")
|
|
116
116
|
}),
|
|
117
|
-
/* @__PURE__ */
|
|
117
|
+
/* @__PURE__ */ _("p", {
|
|
118
118
|
className: "text-muted-foreground max-w-sm mx-auto mb-4",
|
|
119
|
-
children: r(
|
|
119
|
+
children: r(M, "projectDetail.projectNotFoundDescription", "The project you're looking for doesn't exist or you don't have permission to view it.")
|
|
120
120
|
}),
|
|
121
|
-
/* @__PURE__ */
|
|
121
|
+
/* @__PURE__ */ v(b, {
|
|
122
122
|
onClick: Z,
|
|
123
|
-
children: [/* @__PURE__ */
|
|
123
|
+
children: [/* @__PURE__ */ _(p, {
|
|
124
124
|
size: 16,
|
|
125
125
|
className: "mr-2"
|
|
126
|
-
}), r(
|
|
126
|
+
}), r(M, "projectDetail.backToProjects", "Back to Projects")]
|
|
127
127
|
})
|
|
128
128
|
]
|
|
129
129
|
})]
|
|
130
|
-
}) : /* @__PURE__ */
|
|
130
|
+
}) : /* @__PURE__ */ v("div", {
|
|
131
131
|
className: "space-y-4 sm:space-y-6 p-3 sm:p-6",
|
|
132
132
|
children: [
|
|
133
|
-
/* @__PURE__ */
|
|
133
|
+
/* @__PURE__ */ v("div", {
|
|
134
134
|
className: "flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3",
|
|
135
|
-
children: [/* @__PURE__ */
|
|
136
|
-
/* @__PURE__ */
|
|
135
|
+
children: [/* @__PURE__ */ v("div", { children: [
|
|
136
|
+
/* @__PURE__ */ v(b, {
|
|
137
137
|
variant: "ghost",
|
|
138
138
|
onClick: Z,
|
|
139
139
|
className: "gap-2 mb-2 -ml-2",
|
|
140
|
-
children: [/* @__PURE__ */
|
|
140
|
+
children: [/* @__PURE__ */ _(p, { size: 20 }), r(M, "projectDetail.backToProjects", "Back to Projects")]
|
|
141
141
|
}),
|
|
142
|
-
/* @__PURE__ */
|
|
142
|
+
/* @__PURE__ */ v("div", {
|
|
143
143
|
className: "flex items-center gap-3",
|
|
144
|
-
children: [/* @__PURE__ */
|
|
144
|
+
children: [/* @__PURE__ */ _("div", {
|
|
145
145
|
className: "p-3 rounded-lg bg-primary/10",
|
|
146
|
-
children: /* @__PURE__ */
|
|
146
|
+
children: /* @__PURE__ */ _(h, {
|
|
147
147
|
className: "text-primary",
|
|
148
148
|
size: 28
|
|
149
149
|
})
|
|
150
|
-
}), /* @__PURE__ */
|
|
150
|
+
}), /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("h1", {
|
|
151
151
|
className: "text-2xl sm:text-3xl font-bold",
|
|
152
152
|
children: z.name
|
|
153
|
-
}), /* @__PURE__ */
|
|
153
|
+
}), /* @__PURE__ */ _("p", {
|
|
154
154
|
className: "text-sm text-muted-foreground font-mono",
|
|
155
155
|
children: z.key
|
|
156
156
|
})] })]
|
|
157
157
|
}),
|
|
158
|
-
/* @__PURE__ */
|
|
158
|
+
/* @__PURE__ */ v("div", {
|
|
159
159
|
className: "flex items-center gap-2 mt-3",
|
|
160
|
-
children: [/* @__PURE__ */
|
|
160
|
+
children: [/* @__PURE__ */ _(y, {
|
|
161
161
|
className: `border ${t(z.status)}`,
|
|
162
162
|
children: z.status
|
|
163
|
-
}), z.archived && /* @__PURE__ */ y
|
|
163
|
+
}), z.archived && /* @__PURE__ */ v(y, {
|
|
164
164
|
variant: "outline",
|
|
165
165
|
className: "border-workspace-archived-border text-workspace-archived-text",
|
|
166
|
-
children: [/* @__PURE__ */
|
|
166
|
+
children: [/* @__PURE__ */ _(f, {
|
|
167
167
|
size: 12,
|
|
168
168
|
className: "mr-1"
|
|
169
|
-
}), r(
|
|
169
|
+
}), r(M, "projectDetail.archived", "Archived")]
|
|
170
170
|
})]
|
|
171
171
|
})
|
|
172
|
-
] }), /* @__PURE__ */
|
|
172
|
+
] }), /* @__PURE__ */ _("div", {
|
|
173
173
|
className: "flex items-center gap-2",
|
|
174
|
-
children: /* @__PURE__ */
|
|
174
|
+
children: /* @__PURE__ */ v(T, { children: [/* @__PURE__ */ _(k, {
|
|
175
175
|
asChild: !0,
|
|
176
|
-
children: /* @__PURE__ */
|
|
176
|
+
children: /* @__PURE__ */ _(b, {
|
|
177
177
|
variant: "outline",
|
|
178
178
|
size: "icon",
|
|
179
|
-
"aria-label": r(
|
|
180
|
-
children: /* @__PURE__ */
|
|
179
|
+
"aria-label": r(M, "projectDetail.openProjectActionsAriaLabel", "Open project actions"),
|
|
180
|
+
children: /* @__PURE__ */ _(pe, { size: 20 })
|
|
181
181
|
})
|
|
182
|
-
}), /* @__PURE__ */
|
|
182
|
+
}), /* @__PURE__ */ v(E, {
|
|
183
183
|
align: "end",
|
|
184
184
|
children: [
|
|
185
|
-
q && /* @__PURE__ */
|
|
186
|
-
onClick:
|
|
185
|
+
q && /* @__PURE__ */ v(D, {
|
|
186
|
+
onClick: Ge,
|
|
187
187
|
disabled: U || W,
|
|
188
|
-
children: [/* @__PURE__ */
|
|
188
|
+
children: [/* @__PURE__ */ _(f, {
|
|
189
189
|
size: 16,
|
|
190
190
|
className: "mr-2"
|
|
191
|
-
}), U || W ? r(
|
|
191
|
+
}), U || W ? r(M, "projectDetail.processing", "Processing...") : z.archived ? r(M, "projectDetail.unarchive", "Unarchive") : r(M, "projectDetail.archive", "Archive")]
|
|
192
192
|
}),
|
|
193
|
-
q && K && /* @__PURE__ */
|
|
194
|
-
K && /* @__PURE__ */
|
|
193
|
+
q && K && /* @__PURE__ */ _(O, {}),
|
|
194
|
+
K && /* @__PURE__ */ _(D, {
|
|
195
195
|
onClick: () => B(!0),
|
|
196
196
|
className: "text-destructive",
|
|
197
|
-
children: r(
|
|
197
|
+
children: r(M, "projectDetail.deleteProject", "Delete Project")
|
|
198
198
|
})
|
|
199
199
|
]
|
|
200
200
|
})] })
|
|
201
201
|
})]
|
|
202
202
|
}),
|
|
203
|
-
/* @__PURE__ */
|
|
203
|
+
/* @__PURE__ */ v("div", {
|
|
204
204
|
className: "grid grid-cols-1 md:grid-cols-2 gap-4",
|
|
205
|
-
children: [/* @__PURE__ */
|
|
205
|
+
children: [/* @__PURE__ */ v(x, { children: [/* @__PURE__ */ _(C, {
|
|
206
206
|
className: "flex flex-row items-center justify-between pb-2",
|
|
207
|
-
children: /* @__PURE__ */
|
|
207
|
+
children: /* @__PURE__ */ v(w, {
|
|
208
208
|
className: "flex items-center gap-2 text-base",
|
|
209
|
-
children: [/* @__PURE__ */
|
|
209
|
+
children: [/* @__PURE__ */ _(g, {
|
|
210
210
|
size: 20,
|
|
211
211
|
className: "text-muted-foreground"
|
|
212
|
-
}), r(
|
|
212
|
+
}), r(M, "projectDetail.membersCardTitle", "Members")]
|
|
213
213
|
})
|
|
214
|
-
}), /* @__PURE__ */
|
|
214
|
+
}), /* @__PURE__ */ v(S, {
|
|
215
215
|
className: "space-y-4",
|
|
216
216
|
children: [
|
|
217
|
-
/* @__PURE__ */
|
|
217
|
+
/* @__PURE__ */ _("p", {
|
|
218
218
|
className: "text-3xl font-bold",
|
|
219
|
-
children:
|
|
219
|
+
children: Ve ?? 0
|
|
220
220
|
}),
|
|
221
|
-
/* @__PURE__ */
|
|
221
|
+
/* @__PURE__ */ _("p", {
|
|
222
222
|
className: "text-sm text-muted-foreground",
|
|
223
|
-
children: r(
|
|
223
|
+
children: r(M, "projectDetail.projectMembers", "Project members")
|
|
224
224
|
}),
|
|
225
|
-
Y || J ? /* @__PURE__ */
|
|
225
|
+
Y || J ? /* @__PURE__ */ v("div", {
|
|
226
226
|
className: "flex flex-wrap gap-2",
|
|
227
|
-
children: [Y ? /* @__PURE__ */
|
|
227
|
+
children: [Y ? /* @__PURE__ */ v(b, {
|
|
228
228
|
size: "sm",
|
|
229
229
|
onClick: () => H(!0),
|
|
230
|
-
children: [/* @__PURE__ */
|
|
230
|
+
children: [/* @__PURE__ */ _(me, {
|
|
231
231
|
size: 16,
|
|
232
232
|
className: "mr-2"
|
|
233
|
-
}), r(
|
|
234
|
-
}) : null, J ? /* @__PURE__ */
|
|
233
|
+
}), r(M, "projectDetail.addProjectMember", "Add Member")]
|
|
234
|
+
}) : null, J ? /* @__PURE__ */ v(b, {
|
|
235
235
|
variant: "outline",
|
|
236
236
|
size: "sm",
|
|
237
237
|
onClick: Q,
|
|
238
|
-
children: [/* @__PURE__ */
|
|
238
|
+
children: [/* @__PURE__ */ _(g, {
|
|
239
239
|
size: 16,
|
|
240
240
|
className: "mr-2"
|
|
241
|
-
}), r(
|
|
241
|
+
}), r(M, "projectDetail.manageProjectMembers", "Manage Members")]
|
|
242
242
|
}) : null]
|
|
243
243
|
}) : null
|
|
244
244
|
]
|
|
245
|
-
})] }), /* @__PURE__ */
|
|
245
|
+
})] }), /* @__PURE__ */ v(x, { children: [/* @__PURE__ */ _(C, {
|
|
246
246
|
className: "flex flex-row items-center justify-between pb-2",
|
|
247
|
-
children: /* @__PURE__ */
|
|
247
|
+
children: /* @__PURE__ */ v(w, {
|
|
248
248
|
className: "flex items-center gap-2 text-base",
|
|
249
|
-
children: [/* @__PURE__ */
|
|
249
|
+
children: [/* @__PURE__ */ _(d, {
|
|
250
250
|
size: 20,
|
|
251
251
|
className: "text-muted-foreground"
|
|
252
|
-
}), r(
|
|
252
|
+
}), r(M, "projectDetail.activityCardTitle", "Activity")]
|
|
253
253
|
})
|
|
254
|
-
}), /* @__PURE__ */
|
|
254
|
+
}), /* @__PURE__ */ v(S, { children: [/* @__PURE__ */ _("p", {
|
|
255
255
|
className: "text-3xl font-bold",
|
|
256
|
-
children:
|
|
257
|
-
}), /* @__PURE__ */
|
|
256
|
+
children: Ue
|
|
257
|
+
}), /* @__PURE__ */ _("p", {
|
|
258
258
|
className: "text-sm text-muted-foreground",
|
|
259
|
-
children: r(
|
|
259
|
+
children: r(M, "projectDetail.recentActivityItems", "Recent activity items")
|
|
260
260
|
})] })] })]
|
|
261
261
|
}),
|
|
262
|
-
/* @__PURE__ */
|
|
262
|
+
/* @__PURE__ */ v(x, { children: [/* @__PURE__ */ _(C, { children: /* @__PURE__ */ _(w, { children: r(M, "projectDetail.tagsTitle", "Tags") }) }), /* @__PURE__ */ v(S, {
|
|
263
263
|
className: "space-y-3",
|
|
264
|
-
children: [/* @__PURE__ */
|
|
264
|
+
children: [/* @__PURE__ */ _("p", {
|
|
265
265
|
className: "text-sm text-muted-foreground",
|
|
266
|
-
children: r(
|
|
267
|
-
}), /* @__PURE__ */
|
|
266
|
+
children: r(M, "projectDetail.tagsDescription", "Use universal tags to classify and filter this project across the workspace.")
|
|
267
|
+
}), /* @__PURE__ */ _(s, {
|
|
268
268
|
entityType: "Project",
|
|
269
269
|
entityId: z.id,
|
|
270
270
|
workspaceId: P,
|
|
271
|
-
tags:
|
|
271
|
+
tags: We,
|
|
272
272
|
onAdd: async (e) => {
|
|
273
273
|
if (z) try {
|
|
274
|
-
await
|
|
274
|
+
await Ne({
|
|
275
275
|
entityId: z.id,
|
|
276
276
|
tagId: e.id
|
|
277
277
|
}), await $([...X, o(e)]);
|
|
@@ -283,7 +283,7 @@ function N() {
|
|
|
283
283
|
if (!z) return;
|
|
284
284
|
let t = z.tagAssignments?.find((t) => t.tagId === e)?.id;
|
|
285
285
|
try {
|
|
286
|
-
await
|
|
286
|
+
await Fe({
|
|
287
287
|
entityId: z.id,
|
|
288
288
|
tagId: e,
|
|
289
289
|
assignmentId: t
|
|
@@ -292,136 +292,147 @@ function N() {
|
|
|
292
292
|
throw i("error"), e;
|
|
293
293
|
}
|
|
294
294
|
},
|
|
295
|
-
className:
|
|
295
|
+
className: Pe || Ie || Re ? "pointer-events-none opacity-75" : void 0
|
|
296
296
|
})]
|
|
297
297
|
})] }),
|
|
298
|
-
/* @__PURE__ */
|
|
298
|
+
/* @__PURE__ */ v(x, { children: [/* @__PURE__ */ _(C, { children: /* @__PURE__ */ _(w, { children: r(M, "projectDetail.projectInformation", "Project Information") }) }), /* @__PURE__ */ v(S, {
|
|
299
299
|
className: "space-y-4",
|
|
300
|
-
children: [/* @__PURE__ */
|
|
300
|
+
children: [/* @__PURE__ */ v("div", {
|
|
301
301
|
className: "grid grid-cols-1 sm:grid-cols-2 gap-4 text-sm",
|
|
302
302
|
children: [
|
|
303
|
-
/* @__PURE__ */
|
|
303
|
+
/* @__PURE__ */ v("div", {
|
|
304
304
|
className: "space-y-1",
|
|
305
|
-
children: [/* @__PURE__ */
|
|
305
|
+
children: [/* @__PURE__ */ v("span", {
|
|
306
306
|
className: "text-muted-foreground flex items-center gap-2",
|
|
307
|
-
children: [/* @__PURE__ */
|
|
308
|
-
}), /* @__PURE__ */
|
|
309
|
-
|
|
310
|
-
|
|
307
|
+
children: [/* @__PURE__ */ _(h, { size: 14 }), r(M, "projectDetail.projectId", "Project ID")]
|
|
308
|
+
}), /* @__PURE__ */ _("button", {
|
|
309
|
+
type: "button",
|
|
310
|
+
onClick: () => N.show({
|
|
311
|
+
id: z.id,
|
|
312
|
+
name: z.name,
|
|
313
|
+
type: "Project",
|
|
314
|
+
details: z.key ? [{
|
|
315
|
+
label: "Key",
|
|
316
|
+
value: z.key
|
|
317
|
+
}] : void 0
|
|
318
|
+
}),
|
|
319
|
+
className: "inline-flex items-center gap-1.5 text-xs font-medium text-text-link hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)] rounded",
|
|
320
|
+
children: r(M, "projectDetail.getId", "Get ID")
|
|
311
321
|
})]
|
|
312
322
|
}),
|
|
313
|
-
/* @__PURE__ */
|
|
323
|
+
/* @__PURE__ */ v("div", {
|
|
314
324
|
className: "space-y-1",
|
|
315
|
-
children: [/* @__PURE__ */
|
|
325
|
+
children: [/* @__PURE__ */ v("span", {
|
|
316
326
|
className: "text-muted-foreground flex items-center gap-2",
|
|
317
|
-
children: [/* @__PURE__ */
|
|
318
|
-
}), /* @__PURE__ */
|
|
327
|
+
children: [/* @__PURE__ */ _(h, { size: 14 }), r(M, "projectDetail.projectKey", "Project Key")]
|
|
328
|
+
}), /* @__PURE__ */ _("span", {
|
|
319
329
|
className: "font-medium",
|
|
320
330
|
children: z.key
|
|
321
331
|
})]
|
|
322
332
|
}),
|
|
323
|
-
/* @__PURE__ */
|
|
333
|
+
/* @__PURE__ */ v("div", {
|
|
324
334
|
className: "space-y-1",
|
|
325
|
-
children: [/* @__PURE__ */
|
|
335
|
+
children: [/* @__PURE__ */ v("span", {
|
|
326
336
|
className: "text-muted-foreground flex items-center gap-2",
|
|
327
|
-
children: [/* @__PURE__ */
|
|
328
|
-
}), /* @__PURE__ */
|
|
337
|
+
children: [/* @__PURE__ */ _(m, { size: 14 }), r(M, "projectDetail.created", "Created")]
|
|
338
|
+
}), /* @__PURE__ */ _("span", { children: a(z.createdAt) })]
|
|
329
339
|
}),
|
|
330
|
-
/* @__PURE__ */
|
|
340
|
+
/* @__PURE__ */ v("div", {
|
|
331
341
|
className: "space-y-1",
|
|
332
|
-
children: [/* @__PURE__ */
|
|
342
|
+
children: [/* @__PURE__ */ v("span", {
|
|
333
343
|
className: "text-muted-foreground flex items-center gap-2",
|
|
334
|
-
children: [/* @__PURE__ */
|
|
335
|
-
}), /* @__PURE__ */
|
|
344
|
+
children: [/* @__PURE__ */ _(m, { size: 14 }), r(M, "projectDetail.lastUpdated", "Last Updated")]
|
|
345
|
+
}), /* @__PURE__ */ _("span", { children: a(z.updatedAt) })]
|
|
336
346
|
}),
|
|
337
|
-
/* @__PURE__ */
|
|
347
|
+
/* @__PURE__ */ v("div", {
|
|
338
348
|
className: "space-y-1",
|
|
339
|
-
children: [/* @__PURE__ */
|
|
349
|
+
children: [/* @__PURE__ */ v("span", {
|
|
340
350
|
className: "text-muted-foreground flex items-center gap-2",
|
|
341
|
-
children: [/* @__PURE__ */
|
|
342
|
-
}), /* @__PURE__ */
|
|
351
|
+
children: [/* @__PURE__ */ _(g, { size: 14 }), r(M, "projectDetail.workspaceId", "Workspace ID")]
|
|
352
|
+
}), /* @__PURE__ */ _("span", {
|
|
343
353
|
className: "font-mono text-xs block",
|
|
344
354
|
children: z.workspaceId
|
|
345
355
|
})]
|
|
346
356
|
}),
|
|
347
|
-
/* @__PURE__ */
|
|
357
|
+
/* @__PURE__ */ v("div", {
|
|
348
358
|
className: "space-y-1",
|
|
349
|
-
children: [/* @__PURE__ */
|
|
359
|
+
children: [/* @__PURE__ */ v("span", {
|
|
350
360
|
className: "text-muted-foreground flex items-center gap-2",
|
|
351
|
-
children: [/* @__PURE__ */
|
|
352
|
-
}), /* @__PURE__ */
|
|
361
|
+
children: [/* @__PURE__ */ _(g, { size: 14 }), r(M, "projectDetail.creatorId", "Creator ID")]
|
|
362
|
+
}), /* @__PURE__ */ _("span", {
|
|
353
363
|
className: "font-mono text-xs block",
|
|
354
364
|
children: z.creatorId
|
|
355
365
|
})]
|
|
356
366
|
})
|
|
357
367
|
]
|
|
358
|
-
}), z.config && Object.keys(z.config).length > 0 && /* @__PURE__ */
|
|
368
|
+
}), z.config && Object.keys(z.config).length > 0 && /* @__PURE__ */ v("div", {
|
|
359
369
|
className: "pt-4 border-t",
|
|
360
|
-
children: [/* @__PURE__ */
|
|
370
|
+
children: [/* @__PURE__ */ _("h4", {
|
|
361
371
|
className: "text-sm font-medium mb-2",
|
|
362
|
-
children: r(
|
|
363
|
-
}), /* @__PURE__ */
|
|
372
|
+
children: r(M, "projectDetail.configuration", "Configuration")
|
|
373
|
+
}), /* @__PURE__ */ _("pre", {
|
|
364
374
|
className: "text-xs bg-muted p-3 rounded-lg overflow-auto",
|
|
365
375
|
children: JSON.stringify(z.config, null, 2)
|
|
366
376
|
})]
|
|
367
377
|
})]
|
|
368
378
|
})] }),
|
|
369
|
-
/* @__PURE__ */
|
|
379
|
+
/* @__PURE__ */ v(x, { children: [/* @__PURE__ */ _(C, { children: /* @__PURE__ */ _(w, { children: r(M, "projectDetail.quickActions", "Quick Actions") }) }), /* @__PURE__ */ _(S, { children: /* @__PURE__ */ v("div", {
|
|
370
380
|
className: "flex flex-wrap gap-2",
|
|
371
381
|
children: [
|
|
372
|
-
J ? /* @__PURE__ */
|
|
382
|
+
J ? /* @__PURE__ */ v(b, {
|
|
373
383
|
variant: "outline",
|
|
374
384
|
size: "sm",
|
|
375
385
|
onClick: Q,
|
|
376
|
-
children: [/* @__PURE__ */
|
|
386
|
+
children: [/* @__PURE__ */ _(g, {
|
|
377
387
|
size: 16,
|
|
378
388
|
className: "mr-2"
|
|
379
|
-
}), r(
|
|
389
|
+
}), r(M, "projectDetail.projectMembersPage", "Project Members")]
|
|
380
390
|
}) : null,
|
|
381
|
-
/* @__PURE__ */
|
|
391
|
+
/* @__PURE__ */ v(b, {
|
|
382
392
|
variant: "outline",
|
|
383
393
|
size: "sm",
|
|
384
394
|
onClick: () => I(R(`${L}/${P}/members`)),
|
|
385
|
-
children: [/* @__PURE__ */
|
|
395
|
+
children: [/* @__PURE__ */ _(g, {
|
|
386
396
|
size: 16,
|
|
387
397
|
className: "mr-2"
|
|
388
|
-
}), r(
|
|
398
|
+
}), r(M, "projectDetail.workspaceMembers", "Workspace Members")]
|
|
389
399
|
}),
|
|
390
|
-
/* @__PURE__ */
|
|
400
|
+
/* @__PURE__ */ v(b, {
|
|
391
401
|
variant: "outline",
|
|
392
402
|
size: "sm",
|
|
393
403
|
onClick: () => I(R(`${L}/${P}/activity`)),
|
|
394
|
-
children: [/* @__PURE__ */
|
|
404
|
+
children: [/* @__PURE__ */ _(d, {
|
|
395
405
|
size: 16,
|
|
396
406
|
className: "mr-2"
|
|
397
|
-
}), r(
|
|
407
|
+
}), r(M, "projectDetail.workspaceActivity", "Workspace Activity")]
|
|
398
408
|
})
|
|
399
409
|
]
|
|
400
410
|
}) })] }),
|
|
401
|
-
/* @__PURE__ */
|
|
402
|
-
open:
|
|
411
|
+
/* @__PURE__ */ _(he, {
|
|
412
|
+
open: ke,
|
|
403
413
|
onOpenChange: B,
|
|
404
|
-
children: /* @__PURE__ */
|
|
414
|
+
children: /* @__PURE__ */ v(ve, { children: [/* @__PURE__ */ v(xe, { children: [/* @__PURE__ */ _(Se, { children: r(M, "projectDetail.deleteDialogTitle", "Delete Project") }), /* @__PURE__ */ _(ye, { children: r(M, "projectDetail.deleteConfirmPrefix", "Are you sure you want to delete \"") + z.name + r(M, "projectDetail.deleteConfirmSuffix", "\"? This action cannot be undone and all project data will be permanently removed.") })] }), /* @__PURE__ */ v(be, { children: [/* @__PURE__ */ _(_e, {
|
|
405
415
|
disabled: G,
|
|
406
|
-
children: r(
|
|
407
|
-
}), /* @__PURE__ */
|
|
408
|
-
onClick:
|
|
416
|
+
children: r(M, "projectDetail.cancel", "Cancel")
|
|
417
|
+
}), /* @__PURE__ */ _(ge, {
|
|
418
|
+
onClick: Ke,
|
|
409
419
|
disabled: G,
|
|
410
420
|
className: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
|
411
|
-
children: G ? r(
|
|
421
|
+
children: G ? r(M, "projectDetail.deleting", "Deleting...") : r(M, "projectDetail.deleteProject", "Delete Project")
|
|
412
422
|
})] })] })
|
|
413
423
|
}),
|
|
414
|
-
P && F && V ? /* @__PURE__ */
|
|
424
|
+
P && F && V ? /* @__PURE__ */ _(c, {
|
|
415
425
|
open: V,
|
|
416
426
|
onOpenChange: H,
|
|
417
427
|
workspaceId: P,
|
|
418
428
|
projectId: F,
|
|
419
429
|
projectName: z.name
|
|
420
|
-
}) : null
|
|
430
|
+
}) : null,
|
|
431
|
+
/* @__PURE__ */ _(A, { control: N })
|
|
421
432
|
]
|
|
422
433
|
});
|
|
423
434
|
}
|
|
424
435
|
//#endregion
|
|
425
|
-
export {
|
|
436
|
+
export { M as ProjectDetailPage };
|
|
426
437
|
|
|
427
438
|
//# sourceMappingURL=ProjectDetailPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProjectDetailPage.js","names":[],"sources":["../../src/pages/ProjectDetailPage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport { useParams, useNavigate } from 'react-router-dom';\nimport {\n ArrowLeft,\n FolderKanban,\n Users,\n UserPlus,\n Activity,\n Archive,\n MoreVertical,\n Clock,\n} from 'lucide-react';\nimport {\n Button,\n Card,\n CardHeader,\n CardTitle,\n CardContent,\n Badge,\n Skeleton,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n DropdownMenuSeparator,\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n} from '@burdenoff/fe-libs/ui';\nimport { type TagItem } from '@burdenoff/fe-libs/tag';\nimport { ProjectTagsWidget } from '../components/tags/ProjectTagsWidget';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { tWithFallback } from '../utils/i18n';\nimport { useProject, useProjectMembersCount } from '../hooks/useProjects';\nimport { useWorkspacesContext } from '../providers/WorkspacesProvider';\nimport {\n useArchiveProject,\n useUnarchiveProject,\n useDeleteProject,\n useTagProject,\n useUntagProject,\n useUpdateProject,\n} from '../hooks/useProjectMutations';\nimport { formatDate } from '../utils/formatters';\nimport { nativeImpact, nativeNotify } from '../utils/nativeBridge';\nimport { getProjectDisplayTags, toProjectTag } from '../utils/projectTags';\nimport { getProjectStatusClasses } from '../utils/tokenHelpers';\nimport { useWorkspaceActivity } from '../hooks/useWorkspaceActivity';\nimport { useScopedNavigation } from '../hooks/useScopedNavigation';\nimport { useWorkspacePermissions } from '../hooks/useWorkspacePermissions';\nimport { useWorkspacesPageView } from '../hooks/useWorkspacesPageView';\nimport { ProjectMemberPickerDialog } from '../components/ProjectMemberPickerDialog';\n\nexport function ProjectDetailPage() {\n const { t } = useI18n();\n\n const { workspaceId, projectId } = useParams<{ workspaceId: string; projectId: string }>();\n useWorkspacesPageView('workspaces.project-detail', {\n workspaceId,\n projectId,\n requireParams: true,\n });\n const navigate = useNavigate();\n const { basePath = '/workspaces' } = useWorkspacesContext();\n const { withCurrentSearch } = useScopedNavigation();\n const { data: project, isLoading, error } = useProject(projectId || '', workspaceId);\n const [showDeleteDialog, setShowDeleteDialog] = useState(false);\n const [showAddMemberDialog, setShowAddMemberDialog] = useState(false);\n\n const { mutate: archiveProject, isPending: isArchiving } = useArchiveProject(workspaceId);\n const { mutate: unarchiveProject, isPending: isUnarchiving } = useUnarchiveProject(workspaceId);\n const { mutate: deleteProject, isPending: isDeleting } = useDeleteProject(workspaceId);\n const { mutateAsync: tagProject, isPending: isTaggingProject } = useTagProject(workspaceId);\n const { mutateAsync: untagProject, isPending: isUntaggingProject } = useUntagProject(workspaceId);\n const { mutateAsync: updateProject, isPending: isUpdatingProject } =\n useUpdateProject(workspaceId);\n const {\n canViewProject,\n canDeleteProject,\n canArchiveProject,\n canListProjectMembers,\n canAddProjectMember,\n isLoading: permissionsLoading,\n } = useWorkspacePermissions();\n const { data: projectMemberCount } = useProjectMembersCount(projectId || '', workspaceId);\n const displayTags = useMemo(\n () =>\n getProjectDisplayTags({\n tags: project?.tags ?? [],\n tagAssignments: project?.tagAssignments,\n }),\n [project?.tags, project?.tagAssignments]\n );\n const { data: workspaceActivity } = useWorkspaceActivity(workspaceId);\n const relatedActivityCount = (workspaceActivity ?? []).filter(\n (item) => item.resourceId === projectId || item.resourceType?.toLowerCase() === 'project'\n ).length;\n const widgetTags: TagItem[] = displayTags;\n\n if (permissionsLoading) {\n return (\n <div className=\"space-y-4 p-6\">\n <Skeleton className=\"h-10 w-1/3\" />\n <Skeleton className=\"h-64\" />\n </div>\n );\n }\n\n if (!canViewProject) {\n return (\n <div className=\"flex items-center justify-center min-h-[400px]\">\n <div className=\"text-center space-y-2\">\n <h2 className=\"text-lg font-semibold\">\n {tWithFallback(t, 'projectDetail.accessDenied', 'Access Denied')}\n </h2>\n <p className=\"text-sm text-muted-foreground\">\n {tWithFallback(\n t,\n 'projectDetail.noPermissionToViewProject',\n \"You don't have permission to view this project.\"\n )}\n </p>\n </div>\n </div>\n );\n }\n\n const handleBack = () => {\n navigate(withCurrentSearch(`${basePath}/${workspaceId}/projects`));\n };\n\n const handleArchive = () => {\n if (!project) return;\n if (project.archived) {\n unarchiveProject(project.id, {\n onError: (err) => {\n console.error('Failed to unarchive project:', err);\n },\n });\n } else {\n archiveProject(project.id, {\n onError: (err) => {\n console.error('Failed to archive project:', err);\n },\n });\n }\n };\n\n const handleDelete = () => {\n if (!project) return;\n void nativeImpact('medium');\n deleteProject(project.id, {\n onSuccess: () => {\n void nativeNotify('success');\n setShowDeleteDialog(false);\n navigate(withCurrentSearch(`${basePath}/${workspaceId}/projects`));\n },\n onError: (err) => {\n void nativeNotify('error');\n console.error('Failed to delete project:', err);\n },\n });\n };\n\n const handleViewProjectMembers = () => {\n navigate(withCurrentSearch(`${basePath}/${workspaceId}/projects/${projectId}/members`));\n };\n\n const syncLegacyProjectTags = async (nextTags: TagItem[]) => {\n if (!project) {\n return;\n }\n\n const normalizedNextTags = nextTags.map((tag) => toProjectTag(tag));\n\n try {\n await updateProject({\n id: project.id,\n input: {\n tags: normalizedNextTags,\n },\n });\n } catch (err) {\n void nativeNotify('warning');\n console.error(\n 'Failed to sync legacy project tag mirror after updating structured project tags:',\n err\n );\n }\n };\n\n const handleAddTag = async (tag: TagItem) => {\n if (!project) {\n return;\n }\n\n try {\n await tagProject({\n entityId: project.id,\n tagId: tag.id,\n });\n\n await syncLegacyProjectTags([...displayTags, toProjectTag(tag)]);\n } catch (err) {\n void nativeNotify('error');\n throw err;\n }\n };\n\n const handleRemoveTag = async (tagId: string) => {\n if (!project) {\n return;\n }\n\n const assignmentId = project.tagAssignments?.find(\n (assignment) => assignment.tagId === tagId\n )?.id;\n try {\n await untagProject({\n entityId: project.id,\n tagId,\n assignmentId,\n });\n\n await syncLegacyProjectTags(\n displayTags.filter((tag) => tag.tagId !== tagId && tag.id !== tagId)\n );\n } catch (err) {\n void nativeNotify('error');\n throw err;\n }\n };\n\n if (isLoading) {\n return (\n <div className=\"space-y-4 sm:space-y-6 p-3 sm:p-6\">\n <Skeleton className=\"h-10 w-32\" />\n <Skeleton className=\"h-10 w-1/3\" />\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\n <Skeleton className=\"h-32\" />\n <Skeleton className=\"h-32\" />\n <Skeleton className=\"h-32\" />\n </div>\n <Skeleton className=\"h-48\" />\n </div>\n );\n }\n\n if (error || !project) {\n return (\n <div className=\"space-y-4 p-6\">\n <Button variant=\"ghost\" onClick={handleBack} className=\"gap-2\">\n <ArrowLeft size={20} />\n {tWithFallback(t, 'projectDetail.backToProjects', 'Back to Projects')}\n </Button>\n <div className=\"text-center py-12\">\n <div className=\"rounded-full bg-muted p-6 mb-4 inline-block\">\n <FolderKanban size={48} className=\"text-muted-foreground\" />\n </div>\n <h3 className=\"text-lg font-semibold mb-2\">\n {tWithFallback(t, 'projectDetail.projectNotFound', 'Project not found')}\n </h3>\n <p className=\"text-muted-foreground max-w-sm mx-auto mb-4\">\n {tWithFallback(\n t,\n 'projectDetail.projectNotFoundDescription',\n \"The project you're looking for doesn't exist or you don't have permission to view it.\"\n )}\n </p>\n <Button onClick={handleBack}>\n <ArrowLeft size={16} className=\"mr-2\" />\n {tWithFallback(t, 'projectDetail.backToProjects', 'Back to Projects')}\n </Button>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"space-y-4 sm:space-y-6 p-3 sm:p-6\">\n {/* Header */}\n <div className=\"flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3\">\n <div>\n <Button variant=\"ghost\" onClick={handleBack} className=\"gap-2 mb-2 -ml-2\">\n <ArrowLeft size={20} />\n {tWithFallback(t, 'projectDetail.backToProjects', 'Back to Projects')}\n </Button>\n <div className=\"flex items-center gap-3\">\n <div className=\"p-3 rounded-lg bg-primary/10\">\n <FolderKanban className=\"text-primary\" size={28} />\n </div>\n <div>\n <h1 className=\"text-2xl sm:text-3xl font-bold\">{project.name}</h1>\n <p className=\"text-sm text-muted-foreground font-mono\">{project.key}</p>\n </div>\n </div>\n <div className=\"flex items-center gap-2 mt-3\">\n <Badge className={`border ${getProjectStatusClasses(project.status)}`}>\n {project.status}\n </Badge>\n {project.archived && (\n <Badge\n variant=\"outline\"\n className=\"border-workspace-archived-border text-workspace-archived-text\"\n >\n <Archive size={12} className=\"mr-1\" />\n {tWithFallback(t, 'projectDetail.archived', 'Archived')}\n </Badge>\n )}\n </div>\n </div>\n <div className=\"flex items-center gap-2\">\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"outline\"\n size=\"icon\"\n aria-label={tWithFallback(\n t,\n 'projectDetail.openProjectActionsAriaLabel',\n 'Open project actions'\n )}\n >\n <MoreVertical size={20} />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n {canArchiveProject && (\n <DropdownMenuItem onClick={handleArchive} disabled={isArchiving || isUnarchiving}>\n <Archive size={16} className=\"mr-2\" />\n {isArchiving || isUnarchiving\n ? tWithFallback(t, 'projectDetail.processing', 'Processing...')\n : project.archived\n ? tWithFallback(t, 'projectDetail.unarchive', 'Unarchive')\n : tWithFallback(t, 'projectDetail.archive', 'Archive')}\n </DropdownMenuItem>\n )}\n {canArchiveProject && canDeleteProject && <DropdownMenuSeparator />}\n {canDeleteProject && (\n <DropdownMenuItem\n onClick={() => setShowDeleteDialog(true)}\n className=\"text-destructive\"\n >\n {tWithFallback(t, 'projectDetail.deleteProject', 'Delete Project')}\n </DropdownMenuItem>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n </div>\n\n {/* Stats Cards */}\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between pb-2\">\n <CardTitle className=\"flex items-center gap-2 text-base\">\n <Users size={20} className=\"text-muted-foreground\" />\n {tWithFallback(t, 'projectDetail.membersCardTitle', 'Members')}\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <p className=\"text-3xl font-bold\">{projectMemberCount ?? 0}</p>\n <p className=\"text-sm text-muted-foreground\">\n {tWithFallback(t, 'projectDetail.projectMembers', 'Project members')}\n </p>\n\n {canAddProjectMember || canListProjectMembers ? (\n <div className=\"flex flex-wrap gap-2\">\n {canAddProjectMember ? (\n <Button size=\"sm\" onClick={() => setShowAddMemberDialog(true)}>\n <UserPlus size={16} className=\"mr-2\" />\n {tWithFallback(t, 'projectDetail.addProjectMember', 'Add Member')}\n </Button>\n ) : null}\n\n {canListProjectMembers ? (\n <Button variant=\"outline\" size=\"sm\" onClick={handleViewProjectMembers}>\n <Users size={16} className=\"mr-2\" />\n {tWithFallback(t, 'projectDetail.manageProjectMembers', 'Manage Members')}\n </Button>\n ) : null}\n </div>\n ) : null}\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between pb-2\">\n <CardTitle className=\"flex items-center gap-2 text-base\">\n <Activity size={20} className=\"text-muted-foreground\" />\n {tWithFallback(t, 'projectDetail.activityCardTitle', 'Activity')}\n </CardTitle>\n </CardHeader>\n <CardContent>\n <p className=\"text-3xl font-bold\">{relatedActivityCount}</p>\n <p className=\"text-sm text-muted-foreground\">\n {tWithFallback(t, 'projectDetail.recentActivityItems', 'Recent activity items')}\n </p>\n </CardContent>\n </Card>\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle>{tWithFallback(t, 'projectDetail.tagsTitle', 'Tags')}</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n <p className=\"text-sm text-muted-foreground\">\n {tWithFallback(\n t,\n 'projectDetail.tagsDescription',\n 'Use universal tags to classify and filter this project across the workspace.'\n )}\n </p>\n <ProjectTagsWidget\n entityType=\"Project\"\n entityId={project.id}\n workspaceId={workspaceId}\n tags={widgetTags}\n onAdd={handleAddTag}\n onRemove={handleRemoveTag}\n className={\n isTaggingProject || isUntaggingProject || isUpdatingProject\n ? 'pointer-events-none opacity-75'\n : undefined\n }\n />\n </CardContent>\n </Card>\n\n {/* Project Information */}\n <Card>\n <CardHeader>\n <CardTitle>\n {tWithFallback(t, 'projectDetail.projectInformation', 'Project Information')}\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4 text-sm\">\n <div className=\"space-y-1\">\n <span className=\"text-muted-foreground flex items-center gap-2\">\n <FolderKanban size={14} />\n {tWithFallback(t, 'projectDetail.projectId', 'Project ID')}\n </span>\n <span className=\"font-mono text-xs block\">{project.id}</span>\n </div>\n\n <div className=\"space-y-1\">\n <span className=\"text-muted-foreground flex items-center gap-2\">\n <FolderKanban size={14} />\n {tWithFallback(t, 'projectDetail.projectKey', 'Project Key')}\n </span>\n <span className=\"font-medium\">{project.key}</span>\n </div>\n\n <div className=\"space-y-1\">\n <span className=\"text-muted-foreground flex items-center gap-2\">\n <Clock size={14} />\n {tWithFallback(t, 'projectDetail.created', 'Created')}\n </span>\n <span>{formatDate(project.createdAt)}</span>\n </div>\n\n <div className=\"space-y-1\">\n <span className=\"text-muted-foreground flex items-center gap-2\">\n <Clock size={14} />\n {tWithFallback(t, 'projectDetail.lastUpdated', 'Last Updated')}\n </span>\n <span>{formatDate(project.updatedAt)}</span>\n </div>\n\n <div className=\"space-y-1\">\n <span className=\"text-muted-foreground flex items-center gap-2\">\n <Users size={14} />\n {tWithFallback(t, 'projectDetail.workspaceId', 'Workspace ID')}\n </span>\n <span className=\"font-mono text-xs block\">{project.workspaceId}</span>\n </div>\n\n <div className=\"space-y-1\">\n <span className=\"text-muted-foreground flex items-center gap-2\">\n <Users size={14} />\n {tWithFallback(t, 'projectDetail.creatorId', 'Creator ID')}\n </span>\n <span className=\"font-mono text-xs block\">{project.creatorId}</span>\n </div>\n </div>\n\n {project.config && Object.keys(project.config).length > 0 && (\n <div className=\"pt-4 border-t\">\n <h4 className=\"text-sm font-medium mb-2\">\n {tWithFallback(t, 'projectDetail.configuration', 'Configuration')}\n </h4>\n <pre className=\"text-xs bg-muted p-3 rounded-lg overflow-auto\">\n {JSON.stringify(project.config, null, 2)}\n </pre>\n </div>\n )}\n </CardContent>\n </Card>\n\n {/* Quick Actions */}\n <Card>\n <CardHeader>\n <CardTitle>{tWithFallback(t, 'projectDetail.quickActions', 'Quick Actions')}</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"flex flex-wrap gap-2\">\n {canListProjectMembers ? (\n <Button variant=\"outline\" size=\"sm\" onClick={handleViewProjectMembers}>\n <Users size={16} className=\"mr-2\" />\n {tWithFallback(t, 'projectDetail.projectMembersPage', 'Project Members')}\n </Button>\n ) : null}\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => navigate(withCurrentSearch(`${basePath}/${workspaceId}/members`))}\n >\n <Users size={16} className=\"mr-2\" />\n {tWithFallback(t, 'projectDetail.workspaceMembers', 'Workspace Members')}\n </Button>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => navigate(withCurrentSearch(`${basePath}/${workspaceId}/activity`))}\n >\n <Activity size={16} className=\"mr-2\" />\n {tWithFallback(t, 'projectDetail.workspaceActivity', 'Workspace Activity')}\n </Button>\n </div>\n </CardContent>\n </Card>\n\n {/* Delete Confirmation Dialog */}\n <AlertDialog open={showDeleteDialog} onOpenChange={setShowDeleteDialog}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>\n {tWithFallback(t, 'projectDetail.deleteDialogTitle', 'Delete Project')}\n </AlertDialogTitle>\n <AlertDialogDescription>\n {tWithFallback(\n t,\n 'projectDetail.deleteConfirmPrefix',\n 'Are you sure you want to delete \"'\n ) +\n project.name +\n tWithFallback(\n t,\n 'projectDetail.deleteConfirmSuffix',\n '\"? This action cannot be undone and all project data will be permanently removed.'\n )}\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel disabled={isDeleting}>\n {tWithFallback(t, 'projectDetail.cancel', 'Cancel')}\n </AlertDialogCancel>\n <AlertDialogAction\n onClick={handleDelete}\n disabled={isDeleting}\n className=\"bg-destructive text-destructive-foreground hover:bg-destructive/90\"\n >\n {isDeleting\n ? tWithFallback(t, 'projectDetail.deleting', 'Deleting...')\n : tWithFallback(t, 'projectDetail.deleteProject', 'Delete Project')}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n\n {workspaceId && projectId && showAddMemberDialog ? (\n <ProjectMemberPickerDialog\n open={showAddMemberDialog}\n onOpenChange={setShowAddMemberDialog}\n workspaceId={workspaceId}\n projectId={projectId}\n projectName={project.name}\n />\n ) : null}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ProjectDetailPage.js","names":[],"sources":["../../src/pages/ProjectDetailPage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport { useParams, useNavigate } from 'react-router-dom';\nimport {\n ArrowLeft,\n FolderKanban,\n Users,\n UserPlus,\n Activity,\n Archive,\n MoreVertical,\n Clock,\n} from 'lucide-react';\nimport {\n Button,\n Card,\n CardHeader,\n CardTitle,\n CardContent,\n Badge,\n Skeleton,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n DropdownMenuSeparator,\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n EntityIdModal,\n useEntityIdModal,\n} from '@burdenoff/fe-libs/ui';\nimport { type TagItem } from '@burdenoff/fe-libs/tag';\nimport { ProjectTagsWidget } from '../components/tags/ProjectTagsWidget';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { tWithFallback } from '../utils/i18n';\nimport { useProject, useProjectMembersCount } from '../hooks/useProjects';\nimport { useWorkspacesContext } from '../providers/WorkspacesProvider';\nimport {\n useArchiveProject,\n useUnarchiveProject,\n useDeleteProject,\n useTagProject,\n useUntagProject,\n useUpdateProject,\n} from '../hooks/useProjectMutations';\nimport { formatDate } from '../utils/formatters';\nimport { nativeImpact, nativeNotify } from '../utils/nativeBridge';\nimport { getProjectDisplayTags, toProjectTag } from '../utils/projectTags';\nimport { getProjectStatusClasses } from '../utils/tokenHelpers';\nimport { useWorkspaceActivity } from '../hooks/useWorkspaceActivity';\nimport { useScopedNavigation } from '../hooks/useScopedNavigation';\nimport { useWorkspacePermissions } from '../hooks/useWorkspacePermissions';\nimport { useWorkspacesPageView } from '../hooks/useWorkspacesPageView';\nimport { ProjectMemberPickerDialog } from '../components/ProjectMemberPickerDialog';\n\nexport function ProjectDetailPage() {\n const { t } = useI18n();\n const idModal = useEntityIdModal();\n\n const { workspaceId, projectId } = useParams<{ workspaceId: string; projectId: string }>();\n useWorkspacesPageView('workspaces.project-detail', {\n workspaceId,\n projectId,\n requireParams: true,\n });\n const navigate = useNavigate();\n const { basePath = '/workspaces' } = useWorkspacesContext();\n const { withCurrentSearch } = useScopedNavigation();\n const { data: project, isLoading, error } = useProject(projectId || '', workspaceId);\n const [showDeleteDialog, setShowDeleteDialog] = useState(false);\n const [showAddMemberDialog, setShowAddMemberDialog] = useState(false);\n\n const { mutate: archiveProject, isPending: isArchiving } = useArchiveProject(workspaceId);\n const { mutate: unarchiveProject, isPending: isUnarchiving } = useUnarchiveProject(workspaceId);\n const { mutate: deleteProject, isPending: isDeleting } = useDeleteProject(workspaceId);\n const { mutateAsync: tagProject, isPending: isTaggingProject } = useTagProject(workspaceId);\n const { mutateAsync: untagProject, isPending: isUntaggingProject } = useUntagProject(workspaceId);\n const { mutateAsync: updateProject, isPending: isUpdatingProject } =\n useUpdateProject(workspaceId);\n const {\n canViewProject,\n canDeleteProject,\n canArchiveProject,\n canListProjectMembers,\n canAddProjectMember,\n isLoading: permissionsLoading,\n } = useWorkspacePermissions();\n const { data: projectMemberCount } = useProjectMembersCount(projectId || '', workspaceId);\n const displayTags = useMemo(\n () =>\n getProjectDisplayTags({\n tags: project?.tags ?? [],\n tagAssignments: project?.tagAssignments,\n }),\n [project?.tags, project?.tagAssignments]\n );\n const { data: workspaceActivity } = useWorkspaceActivity(workspaceId);\n const relatedActivityCount = (workspaceActivity ?? []).filter(\n (item) => item.resourceId === projectId || item.resourceType?.toLowerCase() === 'project'\n ).length;\n const widgetTags: TagItem[] = displayTags;\n\n if (permissionsLoading) {\n return (\n <div className=\"space-y-4 p-6\">\n <Skeleton className=\"h-10 w-1/3\" />\n <Skeleton className=\"h-64\" />\n </div>\n );\n }\n\n if (!canViewProject) {\n return (\n <div className=\"flex items-center justify-center min-h-[400px]\">\n <div className=\"text-center space-y-2\">\n <h2 className=\"text-lg font-semibold\">\n {tWithFallback(t, 'projectDetail.accessDenied', 'Access Denied')}\n </h2>\n <p className=\"text-sm text-muted-foreground\">\n {tWithFallback(\n t,\n 'projectDetail.noPermissionToViewProject',\n \"You don't have permission to view this project.\"\n )}\n </p>\n </div>\n </div>\n );\n }\n\n const handleBack = () => {\n navigate(withCurrentSearch(`${basePath}/${workspaceId}/projects`));\n };\n\n const handleArchive = () => {\n if (!project) return;\n if (project.archived) {\n unarchiveProject(project.id, {\n onError: (err) => {\n console.error('Failed to unarchive project:', err);\n },\n });\n } else {\n archiveProject(project.id, {\n onError: (err) => {\n console.error('Failed to archive project:', err);\n },\n });\n }\n };\n\n const handleDelete = () => {\n if (!project) return;\n void nativeImpact('medium');\n deleteProject(project.id, {\n onSuccess: () => {\n void nativeNotify('success');\n setShowDeleteDialog(false);\n navigate(withCurrentSearch(`${basePath}/${workspaceId}/projects`));\n },\n onError: (err) => {\n void nativeNotify('error');\n console.error('Failed to delete project:', err);\n },\n });\n };\n\n const handleViewProjectMembers = () => {\n navigate(withCurrentSearch(`${basePath}/${workspaceId}/projects/${projectId}/members`));\n };\n\n const syncLegacyProjectTags = async (nextTags: TagItem[]) => {\n if (!project) {\n return;\n }\n\n const normalizedNextTags = nextTags.map((tag) => toProjectTag(tag));\n\n try {\n await updateProject({\n id: project.id,\n input: {\n tags: normalizedNextTags,\n },\n });\n } catch (err) {\n void nativeNotify('warning');\n console.error(\n 'Failed to sync legacy project tag mirror after updating structured project tags:',\n err\n );\n }\n };\n\n const handleAddTag = async (tag: TagItem) => {\n if (!project) {\n return;\n }\n\n try {\n await tagProject({\n entityId: project.id,\n tagId: tag.id,\n });\n\n await syncLegacyProjectTags([...displayTags, toProjectTag(tag)]);\n } catch (err) {\n void nativeNotify('error');\n throw err;\n }\n };\n\n const handleRemoveTag = async (tagId: string) => {\n if (!project) {\n return;\n }\n\n const assignmentId = project.tagAssignments?.find(\n (assignment) => assignment.tagId === tagId\n )?.id;\n try {\n await untagProject({\n entityId: project.id,\n tagId,\n assignmentId,\n });\n\n await syncLegacyProjectTags(\n displayTags.filter((tag) => tag.tagId !== tagId && tag.id !== tagId)\n );\n } catch (err) {\n void nativeNotify('error');\n throw err;\n }\n };\n\n if (isLoading) {\n return (\n <div className=\"space-y-4 sm:space-y-6 p-3 sm:p-6\">\n <Skeleton className=\"h-10 w-32\" />\n <Skeleton className=\"h-10 w-1/3\" />\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\n <Skeleton className=\"h-32\" />\n <Skeleton className=\"h-32\" />\n <Skeleton className=\"h-32\" />\n </div>\n <Skeleton className=\"h-48\" />\n </div>\n );\n }\n\n if (error || !project) {\n return (\n <div className=\"space-y-4 p-6\">\n <Button variant=\"ghost\" onClick={handleBack} className=\"gap-2\">\n <ArrowLeft size={20} />\n {tWithFallback(t, 'projectDetail.backToProjects', 'Back to Projects')}\n </Button>\n <div className=\"text-center py-12\">\n <div className=\"rounded-full bg-muted p-6 mb-4 inline-block\">\n <FolderKanban size={48} className=\"text-muted-foreground\" />\n </div>\n <h3 className=\"text-lg font-semibold mb-2\">\n {tWithFallback(t, 'projectDetail.projectNotFound', 'Project not found')}\n </h3>\n <p className=\"text-muted-foreground max-w-sm mx-auto mb-4\">\n {tWithFallback(\n t,\n 'projectDetail.projectNotFoundDescription',\n \"The project you're looking for doesn't exist or you don't have permission to view it.\"\n )}\n </p>\n <Button onClick={handleBack}>\n <ArrowLeft size={16} className=\"mr-2\" />\n {tWithFallback(t, 'projectDetail.backToProjects', 'Back to Projects')}\n </Button>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"space-y-4 sm:space-y-6 p-3 sm:p-6\">\n {/* Header */}\n <div className=\"flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3\">\n <div>\n <Button variant=\"ghost\" onClick={handleBack} className=\"gap-2 mb-2 -ml-2\">\n <ArrowLeft size={20} />\n {tWithFallback(t, 'projectDetail.backToProjects', 'Back to Projects')}\n </Button>\n <div className=\"flex items-center gap-3\">\n <div className=\"p-3 rounded-lg bg-primary/10\">\n <FolderKanban className=\"text-primary\" size={28} />\n </div>\n <div>\n <h1 className=\"text-2xl sm:text-3xl font-bold\">{project.name}</h1>\n <p className=\"text-sm text-muted-foreground font-mono\">{project.key}</p>\n </div>\n </div>\n <div className=\"flex items-center gap-2 mt-3\">\n <Badge className={`border ${getProjectStatusClasses(project.status)}`}>\n {project.status}\n </Badge>\n {project.archived && (\n <Badge\n variant=\"outline\"\n className=\"border-workspace-archived-border text-workspace-archived-text\"\n >\n <Archive size={12} className=\"mr-1\" />\n {tWithFallback(t, 'projectDetail.archived', 'Archived')}\n </Badge>\n )}\n </div>\n </div>\n <div className=\"flex items-center gap-2\">\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"outline\"\n size=\"icon\"\n aria-label={tWithFallback(\n t,\n 'projectDetail.openProjectActionsAriaLabel',\n 'Open project actions'\n )}\n >\n <MoreVertical size={20} />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n {canArchiveProject && (\n <DropdownMenuItem onClick={handleArchive} disabled={isArchiving || isUnarchiving}>\n <Archive size={16} className=\"mr-2\" />\n {isArchiving || isUnarchiving\n ? tWithFallback(t, 'projectDetail.processing', 'Processing...')\n : project.archived\n ? tWithFallback(t, 'projectDetail.unarchive', 'Unarchive')\n : tWithFallback(t, 'projectDetail.archive', 'Archive')}\n </DropdownMenuItem>\n )}\n {canArchiveProject && canDeleteProject && <DropdownMenuSeparator />}\n {canDeleteProject && (\n <DropdownMenuItem\n onClick={() => setShowDeleteDialog(true)}\n className=\"text-destructive\"\n >\n {tWithFallback(t, 'projectDetail.deleteProject', 'Delete Project')}\n </DropdownMenuItem>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n </div>\n\n {/* Stats Cards */}\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between pb-2\">\n <CardTitle className=\"flex items-center gap-2 text-base\">\n <Users size={20} className=\"text-muted-foreground\" />\n {tWithFallback(t, 'projectDetail.membersCardTitle', 'Members')}\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <p className=\"text-3xl font-bold\">{projectMemberCount ?? 0}</p>\n <p className=\"text-sm text-muted-foreground\">\n {tWithFallback(t, 'projectDetail.projectMembers', 'Project members')}\n </p>\n\n {canAddProjectMember || canListProjectMembers ? (\n <div className=\"flex flex-wrap gap-2\">\n {canAddProjectMember ? (\n <Button size=\"sm\" onClick={() => setShowAddMemberDialog(true)}>\n <UserPlus size={16} className=\"mr-2\" />\n {tWithFallback(t, 'projectDetail.addProjectMember', 'Add Member')}\n </Button>\n ) : null}\n\n {canListProjectMembers ? (\n <Button variant=\"outline\" size=\"sm\" onClick={handleViewProjectMembers}>\n <Users size={16} className=\"mr-2\" />\n {tWithFallback(t, 'projectDetail.manageProjectMembers', 'Manage Members')}\n </Button>\n ) : null}\n </div>\n ) : null}\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between pb-2\">\n <CardTitle className=\"flex items-center gap-2 text-base\">\n <Activity size={20} className=\"text-muted-foreground\" />\n {tWithFallback(t, 'projectDetail.activityCardTitle', 'Activity')}\n </CardTitle>\n </CardHeader>\n <CardContent>\n <p className=\"text-3xl font-bold\">{relatedActivityCount}</p>\n <p className=\"text-sm text-muted-foreground\">\n {tWithFallback(t, 'projectDetail.recentActivityItems', 'Recent activity items')}\n </p>\n </CardContent>\n </Card>\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle>{tWithFallback(t, 'projectDetail.tagsTitle', 'Tags')}</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n <p className=\"text-sm text-muted-foreground\">\n {tWithFallback(\n t,\n 'projectDetail.tagsDescription',\n 'Use universal tags to classify and filter this project across the workspace.'\n )}\n </p>\n <ProjectTagsWidget\n entityType=\"Project\"\n entityId={project.id}\n workspaceId={workspaceId}\n tags={widgetTags}\n onAdd={handleAddTag}\n onRemove={handleRemoveTag}\n className={\n isTaggingProject || isUntaggingProject || isUpdatingProject\n ? 'pointer-events-none opacity-75'\n : undefined\n }\n />\n </CardContent>\n </Card>\n\n {/* Project Information */}\n <Card>\n <CardHeader>\n <CardTitle>\n {tWithFallback(t, 'projectDetail.projectInformation', 'Project Information')}\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4 text-sm\">\n <div className=\"space-y-1\">\n <span className=\"text-muted-foreground flex items-center gap-2\">\n <FolderKanban size={14} />\n {tWithFallback(t, 'projectDetail.projectId', 'Project ID')}\n </span>\n <button\n type=\"button\"\n onClick={() =>\n idModal.show({\n id: project.id,\n name: project.name,\n type: 'Project',\n details: project.key ? [{ label: 'Key', value: project.key }] : undefined,\n })\n }\n className=\"inline-flex items-center gap-1.5 text-xs font-medium text-text-link hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)] rounded\"\n >\n {tWithFallback(t, 'projectDetail.getId', 'Get ID')}\n </button>\n </div>\n\n <div className=\"space-y-1\">\n <span className=\"text-muted-foreground flex items-center gap-2\">\n <FolderKanban size={14} />\n {tWithFallback(t, 'projectDetail.projectKey', 'Project Key')}\n </span>\n <span className=\"font-medium\">{project.key}</span>\n </div>\n\n <div className=\"space-y-1\">\n <span className=\"text-muted-foreground flex items-center gap-2\">\n <Clock size={14} />\n {tWithFallback(t, 'projectDetail.created', 'Created')}\n </span>\n <span>{formatDate(project.createdAt)}</span>\n </div>\n\n <div className=\"space-y-1\">\n <span className=\"text-muted-foreground flex items-center gap-2\">\n <Clock size={14} />\n {tWithFallback(t, 'projectDetail.lastUpdated', 'Last Updated')}\n </span>\n <span>{formatDate(project.updatedAt)}</span>\n </div>\n\n <div className=\"space-y-1\">\n <span className=\"text-muted-foreground flex items-center gap-2\">\n <Users size={14} />\n {tWithFallback(t, 'projectDetail.workspaceId', 'Workspace ID')}\n </span>\n <span className=\"font-mono text-xs block\">{project.workspaceId}</span>\n </div>\n\n <div className=\"space-y-1\">\n <span className=\"text-muted-foreground flex items-center gap-2\">\n <Users size={14} />\n {tWithFallback(t, 'projectDetail.creatorId', 'Creator ID')}\n </span>\n <span className=\"font-mono text-xs block\">{project.creatorId}</span>\n </div>\n </div>\n\n {project.config && Object.keys(project.config).length > 0 && (\n <div className=\"pt-4 border-t\">\n <h4 className=\"text-sm font-medium mb-2\">\n {tWithFallback(t, 'projectDetail.configuration', 'Configuration')}\n </h4>\n <pre className=\"text-xs bg-muted p-3 rounded-lg overflow-auto\">\n {JSON.stringify(project.config, null, 2)}\n </pre>\n </div>\n )}\n </CardContent>\n </Card>\n\n {/* Quick Actions */}\n <Card>\n <CardHeader>\n <CardTitle>{tWithFallback(t, 'projectDetail.quickActions', 'Quick Actions')}</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"flex flex-wrap gap-2\">\n {canListProjectMembers ? (\n <Button variant=\"outline\" size=\"sm\" onClick={handleViewProjectMembers}>\n <Users size={16} className=\"mr-2\" />\n {tWithFallback(t, 'projectDetail.projectMembersPage', 'Project Members')}\n </Button>\n ) : null}\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => navigate(withCurrentSearch(`${basePath}/${workspaceId}/members`))}\n >\n <Users size={16} className=\"mr-2\" />\n {tWithFallback(t, 'projectDetail.workspaceMembers', 'Workspace Members')}\n </Button>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => navigate(withCurrentSearch(`${basePath}/${workspaceId}/activity`))}\n >\n <Activity size={16} className=\"mr-2\" />\n {tWithFallback(t, 'projectDetail.workspaceActivity', 'Workspace Activity')}\n </Button>\n </div>\n </CardContent>\n </Card>\n\n {/* Delete Confirmation Dialog */}\n <AlertDialog open={showDeleteDialog} onOpenChange={setShowDeleteDialog}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>\n {tWithFallback(t, 'projectDetail.deleteDialogTitle', 'Delete Project')}\n </AlertDialogTitle>\n <AlertDialogDescription>\n {tWithFallback(\n t,\n 'projectDetail.deleteConfirmPrefix',\n 'Are you sure you want to delete \"'\n ) +\n project.name +\n tWithFallback(\n t,\n 'projectDetail.deleteConfirmSuffix',\n '\"? This action cannot be undone and all project data will be permanently removed.'\n )}\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel disabled={isDeleting}>\n {tWithFallback(t, 'projectDetail.cancel', 'Cancel')}\n </AlertDialogCancel>\n <AlertDialogAction\n onClick={handleDelete}\n disabled={isDeleting}\n className=\"bg-destructive text-destructive-foreground hover:bg-destructive/90\"\n >\n {isDeleting\n ? tWithFallback(t, 'projectDetail.deleting', 'Deleting...')\n : tWithFallback(t, 'projectDetail.deleteProject', 'Delete Project')}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n\n {workspaceId && projectId && showAddMemberDialog ? (\n <ProjectMemberPickerDialog\n open={showAddMemberDialog}\n onOpenChange={setShowAddMemberDialog}\n workspaceId={workspaceId}\n projectId={projectId}\n projectName={project.name}\n />\n ) : null}\n <EntityIdModal control={idModal} />\n </div>\n );\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@burdenoff/microfe-workspaces",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.623.1",
|
|
4
4
|
"description": "Workspaces microfrontend for Burdenoff products",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"@apollo/client": "^4.0.11",
|
|
47
|
-
"@burdenoff/fe-libs": "2026.
|
|
47
|
+
"@burdenoff/fe-libs": "2026.623.6",
|
|
48
48
|
"@radix-ui/react-icons": "^1.3.2",
|
|
49
49
|
"@tanstack/react-query": "^5.62.13",
|
|
50
50
|
"axios": "^1.15.2",
|