@checkstack/maintenance-frontend 0.4.29 → 0.5.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,47 @@
1
1
  # @checkstack/maintenance-frontend
2
2
 
3
+ ## 0.5.1
4
+
5
+ ### Patch Changes
6
+
7
+ - @checkstack/dashboard-frontend@0.4.1
8
+
9
+ ## 0.5.0
10
+
11
+ ### Minor Changes
12
+
13
+ - bb1fea0: Redesign system detail page with hero banner, two-column layout, plugin metric tiles, and health check slide-over drawer.
14
+
15
+ ### New Components
16
+
17
+ - **MetricTile** (`@checkstack/ui`): Compact stat tile with icon, label, value, variant coloring
18
+ - **Sheet** (`@checkstack/ui`): Slide-over drawer built on Radix Dialog primitives
19
+
20
+ ### New Extension Slot
21
+
22
+ - **SystemOverviewMetricsSlot** (`@checkstack/catalog-common`): Plugin-contributed at-a-glance metric tiles in the system detail hero banner
23
+
24
+ ### Layout Changes
25
+
26
+ - System detail page now uses a hero banner with breadcrumb, status badges, and metric tile strip
27
+ - Two-column layout: monitoring content (left) and system context (right)
28
+ - Health checks rendered as compact card rows instead of heavy accordions
29
+ - Clicking a health check opens a slide-over drawer with summary tiles, timeline charts, and recent runs
30
+ - Right column uses lightweight borderless sections with dividers instead of heavy Card wrappers
31
+
32
+ ### Plugin Extensions
33
+
34
+ - Health check, SLO, Incident, and Maintenance plugins each contribute a metric tile to the hero banner
35
+
36
+ ### Patch Changes
37
+
38
+ - Updated dependencies [bb1fea0]
39
+ - Updated dependencies [bb1fea0]
40
+ - @checkstack/dashboard-frontend@0.4.0
41
+ - @checkstack/ui@1.4.0
42
+ - @checkstack/catalog-common@1.4.0
43
+ - @checkstack/auth-frontend@0.5.26
44
+
3
45
  ## 0.4.29
4
46
 
5
47
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@checkstack/maintenance-frontend",
3
- "version": "0.4.29",
3
+ "version": "0.5.1",
4
4
  "type": "module",
5
5
  "main": "src/index.tsx",
6
6
  "checkstack": {
@@ -9,17 +9,8 @@ import {
9
9
  maintenanceRoutes,
10
10
  MAINTENANCE_UPDATED,
11
11
  } from "@checkstack/maintenance-common";
12
- import {
13
- Card,
14
- CardHeader,
15
- CardTitle,
16
- CardContent,
17
- Badge,
18
- LoadingSpinner,
19
- Button,
20
- } from "@checkstack/ui";
21
- import { Wrench, Clock, Calendar, History, ChevronRight } from "lucide-react";
22
- import { formatDistanceToNow, format } from "date-fns";
12
+ import { LoadingSpinner, Button } from "@checkstack/ui";
13
+ import { Wrench, History } from "lucide-react";
23
14
 
24
15
  type Props = SlotContext<typeof SystemDetailsSlot>;
25
16
 
@@ -49,118 +40,61 @@ export const SystemMaintenancePanel: React.FC<Props> = ({ system }) => {
49
40
 
50
41
  if (loading) {
51
42
  return (
52
- <Card>
53
- <CardContent className="p-6 flex justify-center">
54
- <LoadingSpinner />
55
- </CardContent>
56
- </Card>
43
+ <div className="flex items-center justify-center rounded-md border border-border/50 bg-card px-3 py-2">
44
+ <LoadingSpinner />
45
+ </div>
57
46
  );
58
47
  }
59
48
 
60
49
  if (maintenances.length === 0) {
61
- // Show a subtle card with just the history button when no active maintenances
62
50
  return (
63
- <Card className="border-border/50">
64
- <CardContent className="p-4">
65
- <div className="flex items-center justify-between">
66
- <div className="flex items-center gap-2 text-muted-foreground">
67
- <Wrench className="h-4 w-4" />
68
- <span className="text-sm">No active maintenances</span>
69
- </div>
70
- <Button variant="ghost" size="sm" asChild>
71
- <Link
72
- to={resolveRoute(maintenanceRoutes.routes.systemHistory, {
73
- systemId: system.id,
74
- })}
75
- >
76
- <History className="h-4 w-4 mr-1" />
77
- View History
78
- </Link>
79
- </Button>
80
- </div>
81
- </CardContent>
82
- </Card>
51
+ <div className="flex items-center justify-between rounded-md border border-border/50 bg-card px-3 py-2">
52
+ <div className="flex items-center gap-2 text-muted-foreground">
53
+ <Wrench className="h-3.5 w-3.5" />
54
+ <span className="text-sm">No planned maintenances</span>
55
+ </div>
56
+ <Button variant="ghost" size="sm" className="h-7 text-xs" asChild>
57
+ <Link
58
+ to={resolveRoute(maintenanceRoutes.routes.systemHistory, {
59
+ systemId: system.id,
60
+ })}
61
+ >
62
+ <History className="h-3 w-3 mr-1" />
63
+ History
64
+ </Link>
65
+ </Button>
66
+ </div>
83
67
  );
84
68
  }
85
69
 
86
- const getStatusBadge = (status: string) => {
87
- switch (status) {
88
- case "in_progress": {
89
- return <Badge variant="warning">In Progress</Badge>;
90
- }
91
- case "scheduled": {
92
- return <Badge variant="info">Scheduled</Badge>;
93
- }
94
- default: {
95
- return <Badge>{status}</Badge>;
96
- }
97
- }
98
- };
70
+ const active = maintenances.filter((m) => m.status === "in_progress");
71
+ const scheduled = maintenances.filter((m) => m.status === "scheduled");
99
72
 
100
73
  return (
101
- <Card className="border-warning/30 bg-warning/5">
102
- <CardHeader className="border-b border-border bg-warning/10">
103
- <div className="flex items-center justify-between">
104
- <div className="flex items-center gap-2">
105
- <Wrench className="h-5 w-5 text-warning" />
106
- <CardTitle className="text-lg font-semibold">
107
- Planned Maintenance
108
- </CardTitle>
109
- </div>
110
- <Button variant="ghost" size="sm" asChild>
111
- <Link
112
- to={resolveRoute(maintenanceRoutes.routes.systemHistory, {
113
- systemId: system.id,
114
- })}
115
- >
116
- <History className="h-4 w-4 mr-1" />
117
- View History
118
- </Link>
119
- </Button>
120
- </div>
121
- </CardHeader>
122
- <CardContent className="p-4 space-y-3">
123
- {maintenances.map((m) => (
124
- <Link
125
- key={m.id}
126
- to={`${resolveRoute(maintenanceRoutes.routes.detail, {
127
- maintenanceId: m.id,
128
- })}?from=${system.id}`}
129
- className="block p-3 rounded-lg border border-border bg-background hover:bg-muted/50 transition-colors"
130
- >
131
- <div className="flex items-start justify-between mb-2">
132
- <div className="flex items-center gap-2">
133
- <h4 className="font-medium text-foreground">{m.title}</h4>
134
- <ChevronRight className="h-4 w-4 text-muted-foreground" />
135
- </div>
136
- {getStatusBadge(m.status)}
137
- </div>
138
- {m.description && (
139
- <p className="text-sm text-muted-foreground mb-2">
140
- {m.description}
141
- </p>
142
- )}
143
- <div className="flex gap-4 text-xs text-muted-foreground">
144
- <div className="flex items-center gap-1">
145
- <Calendar className="h-3 w-3" />
146
- <span>{format(new Date(m.startAt), "MMM d, HH:mm")}</span>
147
- </div>
148
- <div className="flex items-center gap-1">
149
- <Clock className="h-3 w-3" />
150
- <span>
151
- {m.status === "scheduled"
152
- ? `Starts ${formatDistanceToNow(new Date(m.startAt), {
153
- addSuffix: true,
154
- })}`
155
- : `Ends ${formatDistanceToNow(new Date(m.endAt), {
156
- addSuffix: true,
157
- })}`}
158
- </span>
159
- </div>
160
- </div>
161
- </Link>
162
- ))}
163
- </CardContent>
164
- </Card>
74
+ <div className="flex items-center justify-between rounded-md border border-warning/30 bg-warning/5 px-3 py-2">
75
+ <div className="flex items-center gap-2 min-w-0">
76
+ <Wrench className="h-3.5 w-3.5 text-warning shrink-0" />
77
+ <span className="text-sm font-medium truncate">
78
+ {active.length > 0
79
+ ? `${active.length} in progress`
80
+ : `${scheduled.length} scheduled`}
81
+ </span>
82
+ {active.length > 0 && scheduled.length > 0 && (
83
+ <span className="text-xs text-muted-foreground">
84
+ + {scheduled.length} scheduled
85
+ </span>
86
+ )}
87
+ </div>
88
+ <Button variant="ghost" size="sm" className="h-7 text-xs shrink-0" asChild>
89
+ <Link
90
+ to={resolveRoute(maintenanceRoutes.routes.systemHistory, {
91
+ systemId: system.id,
92
+ })}
93
+ >
94
+ <History className="h-3 w-3 mr-1" />
95
+ View
96
+ </Link>
97
+ </Button>
98
+ </div>
165
99
  );
166
100
  };