@burdenoff/microfe-planmagnet 2026.829.2 → 2026.923.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.
@@ -1,12 +1,13 @@
1
- import { usePlanMagnet as e } from "../providers/PlanMagnetProvider.js";
2
- import { useState as t } from "react";
3
- import { Calendar as n, GitBranch as r, Loader2 as i, Package as a } from "lucide-react";
4
- import { gql as o } from "@apollo/client";
5
- import { useQuery as s } from "@apollo/client/react";
6
- import { jsx as c, jsxs as l } from "react/jsx-runtime";
7
- import { Badge as u, Button as d, Card as f, CardContent as p, CardHeader as m, CardTitle as h } from "@burdenoff/fe-libs/ui";
1
+ import { usePlanMagnet as e, usePlanMagnetNavigate as t } from "../providers/PlanMagnetProvider.js";
2
+ import { detailPath as n, rowLinkProps as r } from "../utils/rowNavigation.js";
3
+ import { useState as i } from "react";
4
+ import { Calendar as a, GitBranch as o, Loader2 as s, Package as c } from "lucide-react";
5
+ import { gql as l } from "@apollo/client";
6
+ import { useQuery as u } from "@apollo/client/react";
7
+ import { jsx as d, jsxs as f } from "react/jsx-runtime";
8
+ import { Badge as p, Button as m, Card as h, CardContent as g, CardHeader as _, CardTitle as v } from "@burdenoff/fe-libs/ui";
8
9
  //#region src/planmagnet/pages/ProductsReleasesPagePage.tsx
9
- var g = o`
10
+ var y = l`
10
11
  query ListReleases(
11
12
  $workspaceId: ID!
12
13
  $filter: PlanmagnetReleaseFilter
@@ -32,7 +33,7 @@ var g = o`
32
33
  totalCount
33
34
  }
34
35
  }
35
- `, _ = [
36
+ `, b = [
36
37
  "all",
37
38
  "DRAFT",
38
39
  "PLANNING",
@@ -40,7 +41,7 @@ var g = o`
40
41
  "READY",
41
42
  "RELEASED",
42
43
  "CANCELLED"
43
- ], v = {
44
+ ], x = {
44
45
  DRAFT: "bg-gray-100 text-gray-800",
45
46
  PLANNING: "bg-yellow-100 text-yellow-800",
46
47
  IN_PROGRESS: "bg-blue-100 text-blue-800",
@@ -49,111 +50,114 @@ var g = o`
49
50
  CANCELLED: "bg-red-100 text-red-800",
50
51
  ROLLED_BACK: "bg-red-100 text-red-800"
51
52
  };
52
- function y() {
53
- let { workspaceId: o } = e(), [y, b] = t("all"), { data: x, loading: S, error: C } = s(g, {
53
+ function S() {
54
+ let { workspaceId: l } = e(), S = t(), [C, w] = i("all"), { data: T, loading: E, error: D } = u(y, {
54
55
  variables: {
55
- workspaceId: o,
56
- filter: y === "all" ? void 0 : { status: y },
56
+ workspaceId: l,
57
+ filter: C === "all" ? void 0 : { status: C },
57
58
  pagination: { first: 50 }
58
59
  },
59
- skip: !o
60
+ skip: !l
60
61
  });
61
- if (S) return /* @__PURE__ */ c("div", {
62
+ if (E) return /* @__PURE__ */ d("div", {
62
63
  className: "flex items-center justify-center p-12",
63
- children: /* @__PURE__ */ c(i, { className: "h-8 w-8 animate-spin text-muted-foreground" })
64
+ children: /* @__PURE__ */ d(s, { className: "h-8 w-8 animate-spin text-muted-foreground" })
64
65
  });
65
- if (C) return /* @__PURE__ */ l("div", {
66
+ if (D) return /* @__PURE__ */ f("div", {
66
67
  className: "p-6 text-destructive",
67
- children: ["Failed to load releases: ", C.message]
68
+ children: ["Failed to load releases: ", D.message]
68
69
  });
69
- let w = x?.planmagnetReleases?.items ?? [], T = x?.planmagnetReleases?.totalCount ?? 0;
70
- return /* @__PURE__ */ l("div", {
70
+ let O = T?.planmagnetReleases?.items ?? [], k = T?.planmagnetReleases?.totalCount ?? 0;
71
+ return /* @__PURE__ */ f("div", {
71
72
  className: "space-y-6 p-6",
72
73
  children: [
73
- /* @__PURE__ */ l("div", {
74
+ /* @__PURE__ */ f("div", {
74
75
  className: "flex items-center justify-between",
75
- children: [/* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("h1", {
76
+ children: [/* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("h1", {
76
77
  className: "text-2xl font-semibold",
77
78
  children: "Releases"
78
- }), /* @__PURE__ */ l("p", {
79
+ }), /* @__PURE__ */ f("p", {
79
80
  className: "text-sm text-muted-foreground",
80
- children: [T, " releases across all products"]
81
- })] }), /* @__PURE__ */ l(d, {
81
+ children: [k, " releases across all products"]
82
+ })] }), /* @__PURE__ */ f(m, {
82
83
  size: "sm",
83
- children: [/* @__PURE__ */ c(r, { className: "mr-1 h-4 w-4" }), "New Release"]
84
+ children: [/* @__PURE__ */ d(o, { className: "mr-1 h-4 w-4" }), "New Release"]
84
85
  })]
85
86
  }),
86
- /* @__PURE__ */ c("div", {
87
+ /* @__PURE__ */ d("div", {
87
88
  className: "flex gap-1 border-b pb-1",
88
- children: _.map((e) => /* @__PURE__ */ c("button", {
89
- onClick: () => b(e),
90
- className: `px-3 py-1.5 text-sm rounded-md capitalize ${y === e ? "bg-primary text-primary-foreground" : "text-muted-foreground hover:bg-muted"}`,
89
+ children: b.map((e) => /* @__PURE__ */ d("button", {
90
+ onClick: () => w(e),
91
+ className: `px-3 py-1.5 text-sm rounded-md capitalize ${C === e ? "bg-primary text-primary-foreground" : "text-muted-foreground hover:bg-muted"}`,
91
92
  children: e === "all" ? "All" : e.toLowerCase().replace("_", " ")
92
93
  }, e))
93
94
  }),
94
- /* @__PURE__ */ c("div", {
95
+ /* @__PURE__ */ d("div", {
95
96
  className: "grid grid-cols-1 md:grid-cols-2 gap-4",
96
- children: w.map((e) => /* @__PURE__ */ l(f, { children: [/* @__PURE__ */ l(m, {
97
- className: "pb-2",
98
- children: [/* @__PURE__ */ l("div", {
99
- className: "flex items-center justify-between",
100
- children: [/* @__PURE__ */ c("div", {
101
- className: "flex items-center gap-2",
102
- children: /* @__PURE__ */ c("span", {
103
- className: "text-lg font-semibold",
104
- children: e.version
105
- })
106
- }), /* @__PURE__ */ c("span", {
107
- className: `text-xs px-2 py-0.5 rounded-full capitalize ${v[e.status] ?? "bg-gray-100"}`,
108
- children: e.status.toLowerCase().replace("_", " ")
97
+ children: O.map((e) => /* @__PURE__ */ f(h, {
98
+ ...r(() => S(n("/products/release-detail-page", e.id)), e.name),
99
+ children: [/* @__PURE__ */ f(_, {
100
+ className: "pb-2",
101
+ children: [/* @__PURE__ */ f("div", {
102
+ className: "flex items-center justify-between",
103
+ children: [/* @__PURE__ */ d("div", {
104
+ className: "flex items-center gap-2",
105
+ children: /* @__PURE__ */ d("span", {
106
+ className: "text-lg font-semibold",
107
+ children: e.version
108
+ })
109
+ }), /* @__PURE__ */ d("span", {
110
+ className: `text-xs px-2 py-0.5 rounded-full capitalize ${x[e.status] ?? "bg-gray-100"}`,
111
+ children: e.status.toLowerCase().replace("_", " ")
112
+ })]
113
+ }), /* @__PURE__ */ d(v, {
114
+ className: "text-sm font-medium",
115
+ children: e.name
109
116
  })]
110
- }), /* @__PURE__ */ c(h, {
111
- className: "text-sm font-medium",
112
- children: e.name
117
+ }), /* @__PURE__ */ f(g, {
118
+ className: "space-y-3",
119
+ children: [
120
+ /* @__PURE__ */ d("p", {
121
+ className: "text-sm text-muted-foreground",
122
+ children: e.description ?? "No description"
123
+ }),
124
+ /* @__PURE__ */ f("div", {
125
+ className: "flex items-center gap-4 text-sm",
126
+ children: [/* @__PURE__ */ f("div", {
127
+ className: "flex items-center gap-1 text-muted-foreground",
128
+ children: [
129
+ /* @__PURE__ */ d(c, { className: "h-3.5 w-3.5" }),
130
+ "Owner: ",
131
+ e.ownerId
132
+ ]
133
+ }), /* @__PURE__ */ f("div", {
134
+ className: "flex items-center gap-1 text-muted-foreground",
135
+ children: [/* @__PURE__ */ d(a, { className: "h-3.5 w-3.5" }), e.plannedDate ? new Date(e.plannedDate).toLocaleDateString() : "No date"]
136
+ })]
137
+ }),
138
+ e.tags.length > 0 && /* @__PURE__ */ d("div", {
139
+ className: "flex gap-1 flex-wrap",
140
+ children: e.tags.map((e) => /* @__PURE__ */ d(p, {
141
+ variant: "outline",
142
+ className: "text-xs",
143
+ children: e
144
+ }, e))
145
+ }),
146
+ e.releaseNotes && /* @__PURE__ */ f("div", {
147
+ className: "border-t pt-2",
148
+ children: [/* @__PURE__ */ d("p", {
149
+ className: "text-xs font-medium text-muted-foreground mb-1",
150
+ children: "Release Notes Preview"
151
+ }), /* @__PURE__ */ d("p", {
152
+ className: "text-xs text-muted-foreground line-clamp-3",
153
+ children: e.releaseNotes
154
+ })]
155
+ })
156
+ ]
113
157
  })]
114
- }), /* @__PURE__ */ l(p, {
115
- className: "space-y-3",
116
- children: [
117
- /* @__PURE__ */ c("p", {
118
- className: "text-sm text-muted-foreground",
119
- children: e.description ?? "No description"
120
- }),
121
- /* @__PURE__ */ l("div", {
122
- className: "flex items-center gap-4 text-sm",
123
- children: [/* @__PURE__ */ l("div", {
124
- className: "flex items-center gap-1 text-muted-foreground",
125
- children: [
126
- /* @__PURE__ */ c(a, { className: "h-3.5 w-3.5" }),
127
- "Owner: ",
128
- e.ownerId
129
- ]
130
- }), /* @__PURE__ */ l("div", {
131
- className: "flex items-center gap-1 text-muted-foreground",
132
- children: [/* @__PURE__ */ c(n, { className: "h-3.5 w-3.5" }), e.plannedDate ? new Date(e.plannedDate).toLocaleDateString() : "No date"]
133
- })]
134
- }),
135
- e.tags.length > 0 && /* @__PURE__ */ c("div", {
136
- className: "flex gap-1 flex-wrap",
137
- children: e.tags.map((e) => /* @__PURE__ */ c(u, {
138
- variant: "outline",
139
- className: "text-xs",
140
- children: e
141
- }, e))
142
- }),
143
- e.releaseNotes && /* @__PURE__ */ l("div", {
144
- className: "border-t pt-2",
145
- children: [/* @__PURE__ */ c("p", {
146
- className: "text-xs font-medium text-muted-foreground mb-1",
147
- children: "Release Notes Preview"
148
- }), /* @__PURE__ */ c("p", {
149
- className: "text-xs text-muted-foreground line-clamp-3",
150
- children: e.releaseNotes
151
- })]
152
- })
153
- ]
154
- })] }, e.id))
158
+ }, e.id))
155
159
  }),
156
- w.length === 0 && /* @__PURE__ */ c("p", {
160
+ O.length === 0 && /* @__PURE__ */ d("p", {
157
161
  className: "text-center text-muted-foreground py-8",
158
162
  children: "No releases match this filter."
159
163
  })
@@ -161,6 +165,6 @@ function y() {
161
165
  });
162
166
  }
163
167
  //#endregion
164
- export { y as ProductsReleasesPagePage };
168
+ export { S as ProductsReleasesPagePage };
165
169
 
166
170
  //# sourceMappingURL=ProductsReleasesPagePage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ProductsReleasesPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/ProductsReleasesPagePage.tsx"],"sourcesContent":["// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-nocheck\nimport { useState } from 'react';\nimport { gql } from '@apollo/client';\nimport { useQuery } from '@apollo/client/react';\nimport { Card, CardContent, CardHeader, CardTitle, Badge, Button } from '@burdenoff/fe-libs/ui';\nimport { GitBranch, Calendar, Package, Loader2 } from 'lucide-react';\nimport { usePlanMagnet } from '../providers/PlanMagnetProvider';\n\nconst LIST_RELEASES = gql`\n query ListReleases(\n $workspaceId: ID!\n $filter: PlanmagnetReleaseFilter\n $pagination: PlanmagnetPaginationInput\n ) {\n planmagnetReleases(workspaceId: $workspaceId, filter: $filter, pagination: $pagination) {\n items {\n id\n workspaceId\n projectId\n name\n description\n version\n status\n plannedDate\n releasedAt\n releaseNotes\n ownerId\n tags\n createdAt\n updatedAt\n }\n totalCount\n }\n }\n`;\n\ninterface ReleaseNode {\n id: string;\n name: string;\n description: string | null;\n version: string;\n status: string;\n plannedDate: string | null;\n releasedAt: string | null;\n releaseNotes: string | null;\n ownerId: string;\n tags: string[];\n createdAt: string;\n updatedAt: string;\n}\n\nconst statusTabs = [\n 'all',\n 'DRAFT',\n 'PLANNING',\n 'IN_PROGRESS',\n 'READY',\n 'RELEASED',\n 'CANCELLED',\n] as const;\nconst statusColor: Record<string, string> = {\n DRAFT: 'bg-gray-100 text-gray-800',\n PLANNING: 'bg-yellow-100 text-yellow-800',\n IN_PROGRESS: 'bg-blue-100 text-blue-800',\n READY: 'bg-orange-100 text-orange-800',\n RELEASED: 'bg-green-100 text-green-800',\n CANCELLED: 'bg-red-100 text-red-800',\n ROLLED_BACK: 'bg-red-100 text-red-800',\n};\n\nexport function ProductsReleasesPagePage() {\n const { workspaceId } = usePlanMagnet();\n const [activeTab, setActiveTab] = useState<string>('all');\n\n const {\n data,\n loading,\n error,\n } = // eslint-disable-next-line @typescript-eslint/no-explicit-any\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n useQuery<Record<string, any>>(LIST_RELEASES, {\n variables: {\n workspaceId,\n filter: activeTab !== 'all' ? { status: activeTab } : undefined,\n pagination: { first: 50 },\n },\n skip: !workspaceId,\n });\n\n if (loading) {\n return (\n <div className=\"flex items-center justify-center p-12\">\n <Loader2 className=\"h-8 w-8 animate-spin text-muted-foreground\" />\n </div>\n );\n }\n\n if (error) {\n return <div className=\"p-6 text-destructive\">Failed to load releases: {error.message}</div>;\n }\n\n const releases: ReleaseNode[] = data?.planmagnetReleases?.items ?? [];\n const totalCount = data?.planmagnetReleases?.totalCount ?? 0;\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">Releases</h1>\n <p className=\"text-sm text-muted-foreground\">{totalCount} releases across all products</p>\n </div>\n <Button size=\"sm\">\n <GitBranch className=\"mr-1 h-4 w-4\" />\n New Release\n </Button>\n </div>\n\n <div className=\"flex gap-1 border-b pb-1\">\n {statusTabs.map((tab) => (\n <button\n key={tab}\n onClick={() => setActiveTab(tab)}\n className={`px-3 py-1.5 text-sm rounded-md capitalize ${activeTab === tab ? 'bg-primary text-primary-foreground' : 'text-muted-foreground hover:bg-muted'}`}\n >\n {tab === 'all' ? 'All' : tab.toLowerCase().replace('_', ' ')}\n </button>\n ))}\n </div>\n\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n {releases.map((release) => (\n <Card key={release.id}>\n <CardHeader className=\"pb-2\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-lg font-semibold\">{release.version}</span>\n </div>\n <span\n className={`text-xs px-2 py-0.5 rounded-full capitalize ${statusColor[release.status] ?? 'bg-gray-100'}`}\n >\n {release.status.toLowerCase().replace('_', ' ')}\n </span>\n </div>\n <CardTitle className=\"text-sm font-medium\">{release.name}</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n <p className=\"text-sm text-muted-foreground\">\n {release.description ?? 'No description'}\n </p>\n\n <div className=\"flex items-center gap-4 text-sm\">\n <div className=\"flex items-center gap-1 text-muted-foreground\">\n <Package className=\"h-3.5 w-3.5\" />\n Owner: {release.ownerId}\n </div>\n <div className=\"flex items-center gap-1 text-muted-foreground\">\n <Calendar className=\"h-3.5 w-3.5\" />\n {release.plannedDate\n ? new Date(release.plannedDate).toLocaleDateString()\n : 'No date'}\n </div>\n </div>\n\n {release.tags.length > 0 && (\n <div className=\"flex gap-1 flex-wrap\">\n {release.tags.map((tag) => (\n <Badge key={tag} variant=\"outline\" className=\"text-xs\">\n {tag}\n </Badge>\n ))}\n </div>\n )}\n\n {release.releaseNotes && (\n <div className=\"border-t pt-2\">\n <p className=\"text-xs font-medium text-muted-foreground mb-1\">\n Release Notes Preview\n </p>\n <p className=\"text-xs text-muted-foreground line-clamp-3\">\n {release.releaseNotes}\n </p>\n </div>\n )}\n </CardContent>\n </Card>\n ))}\n </div>\n {releases.length === 0 && (\n <p className=\"text-center text-muted-foreground py-8\">No releases match this filter.</p>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ProductsReleasesPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/ProductsReleasesPagePage.tsx"],"sourcesContent":["// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-nocheck\nimport { useState } from 'react';\nimport { gql } from '@apollo/client';\nimport { useQuery } from '@apollo/client/react';\nimport { Card, CardContent, CardHeader, CardTitle, Badge, Button } from '@burdenoff/fe-libs/ui';\nimport { GitBranch, Calendar, Package, Loader2 } from 'lucide-react';\nimport { usePlanMagnet, usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { rowLinkProps, detailPath } from '../utils/rowNavigation';\n\nconst LIST_RELEASES = gql`\n query ListReleases(\n $workspaceId: ID!\n $filter: PlanmagnetReleaseFilter\n $pagination: PlanmagnetPaginationInput\n ) {\n planmagnetReleases(workspaceId: $workspaceId, filter: $filter, pagination: $pagination) {\n items {\n id\n workspaceId\n projectId\n name\n description\n version\n status\n plannedDate\n releasedAt\n releaseNotes\n ownerId\n tags\n createdAt\n updatedAt\n }\n totalCount\n }\n }\n`;\n\ninterface ReleaseNode {\n id: string;\n name: string;\n description: string | null;\n version: string;\n status: string;\n plannedDate: string | null;\n releasedAt: string | null;\n releaseNotes: string | null;\n ownerId: string;\n tags: string[];\n createdAt: string;\n updatedAt: string;\n}\n\nconst statusTabs = [\n 'all',\n 'DRAFT',\n 'PLANNING',\n 'IN_PROGRESS',\n 'READY',\n 'RELEASED',\n 'CANCELLED',\n] as const;\nconst statusColor: Record<string, string> = {\n DRAFT: 'bg-gray-100 text-gray-800',\n PLANNING: 'bg-yellow-100 text-yellow-800',\n IN_PROGRESS: 'bg-blue-100 text-blue-800',\n READY: 'bg-orange-100 text-orange-800',\n RELEASED: 'bg-green-100 text-green-800',\n CANCELLED: 'bg-red-100 text-red-800',\n ROLLED_BACK: 'bg-red-100 text-red-800',\n};\n\nexport function ProductsReleasesPagePage() {\n const { workspaceId } = usePlanMagnet();\n const navigate = usePlanMagnetNavigate();\n const [activeTab, setActiveTab] = useState<string>('all');\n\n const {\n data,\n loading,\n error,\n } = // eslint-disable-next-line @typescript-eslint/no-explicit-any\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n useQuery<Record<string, any>>(LIST_RELEASES, {\n variables: {\n workspaceId,\n filter: activeTab !== 'all' ? { status: activeTab } : undefined,\n pagination: { first: 50 },\n },\n skip: !workspaceId,\n });\n\n if (loading) {\n return (\n <div className=\"flex items-center justify-center p-12\">\n <Loader2 className=\"h-8 w-8 animate-spin text-muted-foreground\" />\n </div>\n );\n }\n\n if (error) {\n return <div className=\"p-6 text-destructive\">Failed to load releases: {error.message}</div>;\n }\n\n const releases: ReleaseNode[] = data?.planmagnetReleases?.items ?? [];\n const totalCount = data?.planmagnetReleases?.totalCount ?? 0;\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">Releases</h1>\n <p className=\"text-sm text-muted-foreground\">{totalCount} releases across all products</p>\n </div>\n <Button size=\"sm\">\n <GitBranch className=\"mr-1 h-4 w-4\" />\n New Release\n </Button>\n </div>\n\n <div className=\"flex gap-1 border-b pb-1\">\n {statusTabs.map((tab) => (\n <button\n key={tab}\n onClick={() => setActiveTab(tab)}\n className={`px-3 py-1.5 text-sm rounded-md capitalize ${activeTab === tab ? 'bg-primary text-primary-foreground' : 'text-muted-foreground hover:bg-muted'}`}\n >\n {tab === 'all' ? 'All' : tab.toLowerCase().replace('_', ' ')}\n </button>\n ))}\n </div>\n\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n {releases.map((release) => (\n <Card\n key={release.id}\n {...rowLinkProps(\n () => navigate(detailPath('/products/release-detail-page', release.id)),\n release.name\n )}\n >\n <CardHeader className=\"pb-2\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-lg font-semibold\">{release.version}</span>\n </div>\n <span\n className={`text-xs px-2 py-0.5 rounded-full capitalize ${statusColor[release.status] ?? 'bg-gray-100'}`}\n >\n {release.status.toLowerCase().replace('_', ' ')}\n </span>\n </div>\n <CardTitle className=\"text-sm font-medium\">{release.name}</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n <p className=\"text-sm text-muted-foreground\">\n {release.description ?? 'No description'}\n </p>\n\n <div className=\"flex items-center gap-4 text-sm\">\n <div className=\"flex items-center gap-1 text-muted-foreground\">\n <Package className=\"h-3.5 w-3.5\" />\n Owner: {release.ownerId}\n </div>\n <div className=\"flex items-center gap-1 text-muted-foreground\">\n <Calendar className=\"h-3.5 w-3.5\" />\n {release.plannedDate\n ? new Date(release.plannedDate).toLocaleDateString()\n : 'No date'}\n </div>\n </div>\n\n {release.tags.length > 0 && (\n <div className=\"flex gap-1 flex-wrap\">\n {release.tags.map((tag) => (\n <Badge key={tag} variant=\"outline\" className=\"text-xs\">\n {tag}\n </Badge>\n ))}\n </div>\n )}\n\n {release.releaseNotes && (\n <div className=\"border-t pt-2\">\n <p className=\"text-xs font-medium text-muted-foreground mb-1\">\n Release Notes Preview\n </p>\n <p className=\"text-xs text-muted-foreground line-clamp-3\">\n {release.releaseNotes}\n </p>\n </div>\n )}\n </CardContent>\n </Card>\n ))}\n </div>\n {releases.length === 0 && (\n <p className=\"text-center text-muted-foreground py-8\">No releases match this filter.</p>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;AAUA,IAAM,IAAgB,CAAG;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CnB,IAAa;CACjB;CACA;CACA;CACA;CACA;CACA;CACA;CACD,EACK,IAAsC;CAC1C,OAAO;CACP,UAAU;CACV,aAAa;CACb,OAAO;CACP,UAAU;CACV,WAAW;CACX,aAAa;CACd;AAED,SAAgB,IAA2B;CACzC,IAAM,EAAE,mBAAgB,GAAe,EACjC,IAAW,GAAuB,EAClC,CAAC,GAAW,KAAgB,EAAiB,MAAM,EAEnD,EACJ,SACA,YACA,aAGA,EAA8B,GAAe;EAC3C,WAAW;GACT;GACA,QAAQ,MAAc,QAAgC,KAAA,IAAxB,EAAE,QAAQ,GAAW;GACnD,YAAY,EAAE,OAAO,IAAI;GAC1B;EACD,MAAM,CAAC;EACR,CAAC;AAEJ,KAAI,EACF,QACE,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,GAAD,EAAS,WAAU,8CAA+C,CAAA;EAC9D,CAAA;AAIV,KAAI,EACF,QAAO,kBAAC,OAAD;EAAK,WAAU;YAAf,CAAsC,6BAA0B,EAAM,QAAc;;CAG7F,IAAM,IAA0B,GAAM,oBAAoB,SAAS,EAAE,EAC/D,IAAa,GAAM,oBAAoB,cAAc;AAE3D,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;KAAI,WAAU;eAAyB;KAAa,CAAA,EACpD,kBAAC,KAAD;KAAG,WAAU;eAAb,CAA8C,GAAW,gCAAiC;OACtF,EAAA,CAAA,EACN,kBAAC,GAAD;KAAQ,MAAK;eAAb,CACE,kBAAC,GAAD,EAAW,WAAU,gBAAiB,CAAA,EAAA,cAE/B;OACL;;GAEN,kBAAC,OAAD;IAAK,WAAU;cACZ,EAAW,KAAK,MACf,kBAAC,UAAD;KAEE,eAAe,EAAa,EAAI;KAChC,WAAW,6CAA6C,MAAc,IAAM,uCAAuC;eAElH,MAAQ,QAAQ,QAAQ,EAAI,aAAa,CAAC,QAAQ,KAAK,IAAI;KACrD,EALF,EAKE,CACT;IACE,CAAA;GAEN,kBAAC,OAAD;IAAK,WAAU;cACZ,EAAS,KAAK,MACb,kBAAC,GAAD;KAEE,GAAI,QACI,EAAS,EAAW,iCAAiC,EAAQ,GAAG,CAAC,EACvE,EAAQ,KACT;eALH,CAOE,kBAAC,GAAD;MAAY,WAAU;gBAAtB,CACE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,OAAD;QAAK,WAAU;kBACb,kBAAC,QAAD;SAAM,WAAU;mBAAyB,EAAQ;SAAe,CAAA;QAC5D,CAAA,EACN,kBAAC,QAAD;QACE,WAAW,+CAA+C,EAAY,EAAQ,WAAW;kBAExF,EAAQ,OAAO,aAAa,CAAC,QAAQ,KAAK,IAAI;QAC1C,CAAA,CACH;UACN,kBAAC,GAAD;OAAW,WAAU;iBAAuB,EAAQ;OAAiB,CAAA,CAC1D;SACb,kBAAC,GAAD;MAAa,WAAU;gBAAvB;OACE,kBAAC,KAAD;QAAG,WAAU;kBACV,EAAQ,eAAe;QACtB,CAAA;OAEJ,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,OAAD;SAAK,WAAU;mBAAf;UACE,kBAAC,GAAD,EAAS,WAAU,eAAgB,CAAA;;UAC3B,EAAQ;UACZ;YACN,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,GAAD,EAAU,WAAU,eAAgB,CAAA,EACnC,EAAQ,cACL,IAAI,KAAK,EAAQ,YAAY,CAAC,oBAAoB,GAClD,UACA;WACF;;OAEL,EAAQ,KAAK,SAAS,KACrB,kBAAC,OAAD;QAAK,WAAU;kBACZ,EAAQ,KAAK,KAAK,MACjB,kBAAC,GAAD;SAAiB,SAAQ;SAAU,WAAU;mBAC1C;SACK,EAFI,EAEJ,CACR;QACE,CAAA;OAGP,EAAQ,gBACP,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,KAAD;SAAG,WAAU;mBAAiD;SAE1D,CAAA,EACJ,kBAAC,KAAD;SAAG,WAAU;mBACV,EAAQ;SACP,CAAA,CACA;;OAEI;QACT;OA1DA,EAAQ,GA0DR,CACP;IACE,CAAA;GACL,EAAS,WAAW,KACnB,kBAAC,KAAD;IAAG,WAAU;cAAyC;IAAkC,CAAA;GAEtF"}
@@ -1 +1 @@
1
- {"version":3,"file":"ProductsRoadmapsPagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/ProductsRoadmapsPagePage.tsx"],"names":[],"mappings":"AAkEA,wBAAgB,wBAAwB,4CAkKvC"}
1
+ {"version":3,"file":"ProductsRoadmapsPagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/ProductsRoadmapsPagePage.tsx"],"names":[],"mappings":"AAmEA,wBAAgB,wBAAwB,4CAwKvC"}
@@ -1,12 +1,13 @@
1
1
  import { usePlanMagnet as e, usePlanMagnetNavigate as t } from "../providers/PlanMagnetProvider.js";
2
- import { useState as n } from "react";
3
- import { Calendar as r, Filter as i, Loader2 as a, Map as o, Plus as s } from "lucide-react";
4
- import { gql as c } from "@apollo/client";
5
- import { useQuery as l } from "@apollo/client/react";
6
- import { jsx as u, jsxs as d } from "react/jsx-runtime";
7
- import { Badge as f, Button as p, Card as m, CardContent as h, CardHeader as g, CardTitle as _ } from "@burdenoff/fe-libs/ui";
2
+ import { detailPath as n, rowLinkProps as r } from "../utils/rowNavigation.js";
3
+ import { useState as i } from "react";
4
+ import { Calendar as a, Filter as o, Loader2 as s, Map as c, Plus as l } from "lucide-react";
5
+ import { gql as u } from "@apollo/client";
6
+ import { useQuery as d } from "@apollo/client/react";
7
+ import { jsx as f, jsxs as p } from "react/jsx-runtime";
8
+ import { Badge as m, Button as h, Card as g, CardContent as _, CardHeader as v, CardTitle as y } from "@burdenoff/fe-libs/ui";
8
9
  //#region src/planmagnet/pages/ProductsRoadmapsPagePage.tsx
9
- var v = c`
10
+ var b = u`
10
11
  query ListRoadmapsPage(
11
12
  $workspaceId: ID!
12
13
  $filter: PlanmagnetRoadmapFilter
@@ -34,158 +35,161 @@ var v = c`
34
35
  totalCount
35
36
  }
36
37
  }
37
- `, y = {
38
+ `, x = {
38
39
  TIMELINE: "bg-purple-100 text-purple-800",
39
40
  GANTT: "bg-orange-100 text-orange-800",
40
41
  SWIMLANE: "bg-green-100 text-green-800",
41
42
  CUSTOM: "bg-blue-100 text-blue-800"
42
43
  };
43
- function b() {
44
- let c = t(), { workspaceId: b } = e(), [x, S] = n("all"), [C, w] = n("all"), { data: T, loading: E, error: D } = l(v, {
44
+ function S() {
45
+ let u = t(), { workspaceId: S } = e(), [C, w] = i("all"), [T, E] = i("all"), { data: D, loading: O, error: k } = d(b, {
45
46
  variables: {
46
- workspaceId: b,
47
+ workspaceId: S,
47
48
  pagination: { first: 50 }
48
49
  },
49
- skip: !b
50
+ skip: !S
50
51
  });
51
- if (E) return /* @__PURE__ */ u("div", {
52
+ if (O) return /* @__PURE__ */ f("div", {
52
53
  className: "flex items-center justify-center p-12",
53
- children: /* @__PURE__ */ u(a, { className: "h-8 w-8 animate-spin text-muted-foreground" })
54
+ children: /* @__PURE__ */ f(s, { className: "h-8 w-8 animate-spin text-muted-foreground" })
54
55
  });
55
- if (D) return /* @__PURE__ */ d("div", {
56
+ if (k) return /* @__PURE__ */ p("div", {
56
57
  className: "p-6 text-destructive",
57
- children: ["Failed to load roadmaps: ", D.message]
58
+ children: ["Failed to load roadmaps: ", k.message]
58
59
  });
59
- let O = T?.planmagnetRoadmaps?.items ?? [], k = T?.planmagnetRoadmaps?.totalCount ?? 0, A = ["all", ...new Set(O.map((e) => e.type))], j = [
60
+ let A = D?.planmagnetRoadmaps?.items ?? [], j = D?.planmagnetRoadmaps?.totalCount ?? 0, M = ["all", ...new Set(A.map((e) => e.type))], N = [
60
61
  "all",
61
62
  "public",
62
63
  "private"
63
- ], M = O.filter((e) => (x === "all" || e.type === x) && (C === "all" || C === "public" && e.isPublic || C === "private" && !e.isPublic));
64
- return /* @__PURE__ */ d("div", {
64
+ ], P = A.filter((e) => (C === "all" || e.type === C) && (T === "all" || T === "public" && e.isPublic || T === "private" && !e.isPublic));
65
+ return /* @__PURE__ */ p("div", {
65
66
  className: "space-y-6 p-6",
66
67
  children: [
67
- /* @__PURE__ */ d("div", {
68
+ /* @__PURE__ */ p("div", {
68
69
  className: "flex items-center justify-between",
69
- children: [/* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("h1", {
70
+ children: [/* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("h1", {
70
71
  className: "text-2xl font-semibold",
71
72
  children: "Roadmaps"
72
- }), /* @__PURE__ */ d("p", {
73
+ }), /* @__PURE__ */ p("p", {
73
74
  className: "text-sm text-muted-foreground",
74
- children: [k, " roadmaps across all products"]
75
- })] }), /* @__PURE__ */ d(p, {
75
+ children: [j, " roadmaps across all products"]
76
+ })] }), /* @__PURE__ */ p(h, {
76
77
  size: "sm",
77
- onClick: () => c("/products/create-roadmap-page"),
78
- children: [/* @__PURE__ */ u(s, { className: "mr-1 h-4 w-4" }), "New Roadmap"]
78
+ onClick: () => u("/products/create-roadmap-page"),
79
+ children: [/* @__PURE__ */ f(l, { className: "mr-1 h-4 w-4" }), "New Roadmap"]
79
80
  })]
80
81
  }),
81
- /* @__PURE__ */ d("div", {
82
+ /* @__PURE__ */ p("div", {
82
83
  className: "flex gap-4 flex-wrap",
83
- children: [/* @__PURE__ */ d("div", {
84
+ children: [/* @__PURE__ */ p("div", {
84
85
  className: "flex items-center gap-2",
85
86
  children: [
86
- /* @__PURE__ */ u(i, { className: "h-4 w-4 text-muted-foreground" }),
87
- /* @__PURE__ */ u("span", {
87
+ /* @__PURE__ */ f(o, { className: "h-4 w-4 text-muted-foreground" }),
88
+ /* @__PURE__ */ f("span", {
88
89
  className: "text-sm text-muted-foreground",
89
90
  children: "Type:"
90
91
  }),
91
- A.map((e) => /* @__PURE__ */ u("button", {
92
- onClick: () => S(e),
93
- className: `px-2 py-1 text-xs rounded-md capitalize ${x === e ? "bg-primary text-primary-foreground" : "bg-muted text-muted-foreground"}`,
92
+ M.map((e) => /* @__PURE__ */ f("button", {
93
+ onClick: () => w(e),
94
+ className: `px-2 py-1 text-xs rounded-md capitalize ${C === e ? "bg-primary text-primary-foreground" : "bg-muted text-muted-foreground"}`,
94
95
  children: e === "all" ? "All" : e.toLowerCase()
95
96
  }, e))
96
97
  ]
97
- }), /* @__PURE__ */ d("div", {
98
+ }), /* @__PURE__ */ p("div", {
98
99
  className: "flex items-center gap-2",
99
- children: [/* @__PURE__ */ u("span", {
100
+ children: [/* @__PURE__ */ f("span", {
100
101
  className: "text-sm text-muted-foreground",
101
102
  children: "Visibility:"
102
- }), j.map((e) => /* @__PURE__ */ u("button", {
103
- onClick: () => w(e),
104
- className: `px-2 py-1 text-xs rounded-md capitalize ${C === e ? "bg-primary text-primary-foreground" : "bg-muted text-muted-foreground"}`,
103
+ }), N.map((e) => /* @__PURE__ */ f("button", {
104
+ onClick: () => E(e),
105
+ className: `px-2 py-1 text-xs rounded-md capitalize ${T === e ? "bg-primary text-primary-foreground" : "bg-muted text-muted-foreground"}`,
105
106
  children: e
106
107
  }, e))]
107
108
  })]
108
109
  }),
109
- /* @__PURE__ */ u("div", {
110
+ /* @__PURE__ */ f("div", {
110
111
  className: "grid grid-cols-1 md:grid-cols-2 gap-4",
111
- children: M.map((e) => {
112
- let t = e.items?.length ?? 0, n = e.items?.filter((e) => e.status === "COMPLETED" || e.status === "DONE").length ?? 0, i = t > 0 ? Math.round(n / t * 100) : 0, a = e.items?.map((e) => e.startDate).filter(Boolean) ?? [], s = e.items?.map((e) => e.endDate).filter(Boolean) ?? [], c = a.length > 0 ? a.sort()[0] : null, l = s.length > 0 ? s.sort().reverse()[0] : null;
113
- return /* @__PURE__ */ d(m, { children: [/* @__PURE__ */ u(g, {
114
- className: "pb-2",
115
- children: /* @__PURE__ */ d("div", {
116
- className: "flex items-center justify-between",
117
- children: [/* @__PURE__ */ u(_, {
118
- className: "text-base",
119
- children: e.name
120
- }), /* @__PURE__ */ u(f, {
121
- variant: e.isPublic ? "default" : "secondary",
122
- className: "capitalize",
123
- children: e.isPublic ? "public" : "private"
124
- })]
125
- })
126
- }), /* @__PURE__ */ d(h, {
127
- className: "space-y-3",
128
- children: [
129
- /* @__PURE__ */ u("p", {
130
- className: "text-sm text-muted-foreground",
131
- children: e.description ?? "No description"
132
- }),
133
- /* @__PURE__ */ d("div", {
134
- className: "flex items-center gap-2",
135
- children: [/* @__PURE__ */ u("span", {
136
- className: `text-xs px-2 py-0.5 rounded-full capitalize ${y[e.type] ?? "bg-gray-100"}`,
137
- children: e.type.toLowerCase()
138
- }), /* @__PURE__ */ u(f, {
139
- variant: "outline",
140
- className: "text-xs capitalize",
112
+ children: P.map((e) => {
113
+ let t = e.items?.length ?? 0, i = e.items?.filter((e) => e.status === "COMPLETED" || e.status === "DONE").length ?? 0, o = t > 0 ? Math.round(i / t * 100) : 0, s = e.items?.map((e) => e.startDate).filter(Boolean) ?? [], l = e.items?.map((e) => e.endDate).filter(Boolean) ?? [], d = s.length > 0 ? s.sort()[0] : null, h = l.length > 0 ? l.sort().reverse()[0] : null;
114
+ return /* @__PURE__ */ p(g, {
115
+ ...r(() => u(n("/products/roadmap-detail-page", e.id)), e.name),
116
+ children: [/* @__PURE__ */ f(v, {
117
+ className: "pb-2",
118
+ children: /* @__PURE__ */ p("div", {
119
+ className: "flex items-center justify-between",
120
+ children: [/* @__PURE__ */ f(y, {
121
+ className: "text-base",
122
+ children: e.name
123
+ }), /* @__PURE__ */ f(m, {
124
+ variant: e.isPublic ? "default" : "secondary",
125
+ className: "capitalize",
141
126
  children: e.isPublic ? "public" : "private"
142
127
  })]
143
- }),
144
- /* @__PURE__ */ d("div", { children: [/* @__PURE__ */ d("div", {
145
- className: "flex justify-between text-xs mb-1",
146
- children: [/* @__PURE__ */ u("span", {
147
- className: "text-muted-foreground",
148
- children: "Progress"
149
- }), /* @__PURE__ */ d("span", {
150
- className: "font-medium",
151
- children: [i, "%"]
152
- })]
153
- }), /* @__PURE__ */ u("div", {
154
- className: "w-full h-2 rounded-full bg-muted overflow-hidden",
155
- children: /* @__PURE__ */ u("div", {
156
- className: "h-full bg-primary rounded-full",
157
- style: { width: `${i}%` }
158
- })
159
- })] }),
160
- /* @__PURE__ */ u("div", {
161
- className: "flex gap-4 text-xs text-muted-foreground",
162
- children: /* @__PURE__ */ d("span", {
163
- className: "flex items-center gap-1",
164
- children: [
165
- /* @__PURE__ */ u(o, { className: "h-3 w-3" }),
166
- t,
167
- " items"
168
- ]
169
- })
170
- }),
171
- /* @__PURE__ */ d("div", {
172
- className: "flex items-center justify-between text-xs text-muted-foreground border-t pt-2",
173
- children: [/* @__PURE__ */ d("span", { children: ["Owner: ", e.ownerId] }), c && l && /* @__PURE__ */ d("span", {
174
- className: "flex items-center gap-1",
175
- children: [
176
- /* @__PURE__ */ u(r, { className: "h-3 w-3" }),
177
- new Date(c).toLocaleDateString(),
178
- " -",
179
- " ",
180
- new Date(l).toLocaleDateString()
181
- ]
182
- })]
183
128
  })
184
- ]
185
- })] }, e.id);
129
+ }), /* @__PURE__ */ p(_, {
130
+ className: "space-y-3",
131
+ children: [
132
+ /* @__PURE__ */ f("p", {
133
+ className: "text-sm text-muted-foreground",
134
+ children: e.description ?? "No description"
135
+ }),
136
+ /* @__PURE__ */ p("div", {
137
+ className: "flex items-center gap-2",
138
+ children: [/* @__PURE__ */ f("span", {
139
+ className: `text-xs px-2 py-0.5 rounded-full capitalize ${x[e.type] ?? "bg-gray-100"}`,
140
+ children: e.type.toLowerCase()
141
+ }), /* @__PURE__ */ f(m, {
142
+ variant: "outline",
143
+ className: "text-xs capitalize",
144
+ children: e.isPublic ? "public" : "private"
145
+ })]
146
+ }),
147
+ /* @__PURE__ */ p("div", { children: [/* @__PURE__ */ p("div", {
148
+ className: "flex justify-between text-xs mb-1",
149
+ children: [/* @__PURE__ */ f("span", {
150
+ className: "text-muted-foreground",
151
+ children: "Progress"
152
+ }), /* @__PURE__ */ p("span", {
153
+ className: "font-medium",
154
+ children: [o, "%"]
155
+ })]
156
+ }), /* @__PURE__ */ f("div", {
157
+ className: "w-full h-2 rounded-full bg-muted overflow-hidden",
158
+ children: /* @__PURE__ */ f("div", {
159
+ className: "h-full bg-primary rounded-full",
160
+ style: { width: `${o}%` }
161
+ })
162
+ })] }),
163
+ /* @__PURE__ */ f("div", {
164
+ className: "flex gap-4 text-xs text-muted-foreground",
165
+ children: /* @__PURE__ */ p("span", {
166
+ className: "flex items-center gap-1",
167
+ children: [
168
+ /* @__PURE__ */ f(c, { className: "h-3 w-3" }),
169
+ t,
170
+ " items"
171
+ ]
172
+ })
173
+ }),
174
+ /* @__PURE__ */ p("div", {
175
+ className: "flex items-center justify-between text-xs text-muted-foreground border-t pt-2",
176
+ children: [/* @__PURE__ */ p("span", { children: ["Owner: ", e.ownerId] }), d && h && /* @__PURE__ */ p("span", {
177
+ className: "flex items-center gap-1",
178
+ children: [
179
+ /* @__PURE__ */ f(a, { className: "h-3 w-3" }),
180
+ new Date(d).toLocaleDateString(),
181
+ " -",
182
+ " ",
183
+ new Date(h).toLocaleDateString()
184
+ ]
185
+ })]
186
+ })
187
+ ]
188
+ })]
189
+ }, e.id);
186
190
  })
187
191
  }),
188
- M.length === 0 && /* @__PURE__ */ u("p", {
192
+ P.length === 0 && /* @__PURE__ */ f("p", {
189
193
  className: "text-center text-muted-foreground py-8",
190
194
  children: "No roadmaps match the selected filters."
191
195
  })
@@ -193,6 +197,6 @@ function b() {
193
197
  });
194
198
  }
195
199
  //#endregion
196
- export { b as ProductsRoadmapsPagePage };
200
+ export { S as ProductsRoadmapsPagePage };
197
201
 
198
202
  //# sourceMappingURL=ProductsRoadmapsPagePage.js.map