@checkstack/announcement-frontend 0.3.3 → 0.3.5
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,57 @@
|
|
|
1
1
|
# @checkstack/announcement-frontend
|
|
2
2
|
|
|
3
|
+
## 0.3.5
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- f23f3c9: Gate decorative motion and blur effects behind
|
|
8
|
+
`usePerformance().isLowPower` on a focused set of high-traffic plugin
|
|
9
|
+
pages (Dashboard, Dependency map, System node, Notification bell,
|
|
10
|
+
Announcement banner / cards, Anomaly field overrides editor, SLO
|
|
11
|
+
attribution chart, Catalog droppable group). Hover scales, backdrop
|
|
12
|
+
blurs, `animate-pulse`/`animate-ping` accents, and entry transitions
|
|
13
|
+
now drop to static states on low-power devices; functional UX
|
|
14
|
+
transitions (Drawer/Dialog open-close, colour transitions) are left
|
|
15
|
+
alone.
|
|
16
|
+
|
|
17
|
+
Standardise the post-mutation error-toast voice on plugin pages by
|
|
18
|
+
migrating multi-clause `toast.error(extractErrorMessage(error, "Failed
|
|
19
|
+
to X"))` call sites onto the `toastError(toast, "Failed to X", error)`
|
|
20
|
+
helper from `@checkstack/ui`. The helper applies the canonical
|
|
21
|
+
`"action: message"` prefix and 100-character truncation in one place,
|
|
22
|
+
and the now-orphaned `extractErrorMessage` imports are dropped from
|
|
23
|
+
the affected files. No business logic or component APIs changed.
|
|
24
|
+
|
|
25
|
+
- f23f3c9: Standardise the empty / loading / error story on key list pages using
|
|
26
|
+
the shared `ListEmptyState`, `QueryErrorState`, and `Skeleton`
|
|
27
|
+
primitives from `@checkstack/ui`. Each affected page now branches
|
|
28
|
+
through the same `isLoading -> isError -> empty -> data` ladder, so
|
|
29
|
+
failed queries surface a retry-able inline error instead of silently
|
|
30
|
+
rendering an empty table, and loading states match the final layout
|
|
31
|
+
rather than flashing a generic spinner. No layout, business logic, or
|
|
32
|
+
query input shapes changed.
|
|
33
|
+
- Updated dependencies [f23f3c9]
|
|
34
|
+
- Updated dependencies [f23f3c9]
|
|
35
|
+
- Updated dependencies [f23f3c9]
|
|
36
|
+
- Updated dependencies [f23f3c9]
|
|
37
|
+
- Updated dependencies [f23f3c9]
|
|
38
|
+
- @checkstack/common@0.11.0
|
|
39
|
+
- @checkstack/auth-frontend@0.6.5
|
|
40
|
+
- @checkstack/frontend-api@0.5.2
|
|
41
|
+
- @checkstack/ui@1.10.0
|
|
42
|
+
- @checkstack/announcement-common@0.4.1
|
|
43
|
+
- @checkstack/tips-frontend@0.2.5
|
|
44
|
+
- @checkstack/signal-frontend@0.1.4
|
|
45
|
+
|
|
46
|
+
## 0.3.4
|
|
47
|
+
|
|
48
|
+
### Patch Changes
|
|
49
|
+
|
|
50
|
+
- Updated dependencies [a06b899]
|
|
51
|
+
- @checkstack/ui@1.9.0
|
|
52
|
+
- @checkstack/auth-frontend@0.6.4
|
|
53
|
+
- @checkstack/tips-frontend@0.2.4
|
|
54
|
+
|
|
3
55
|
## 0.3.3
|
|
4
56
|
|
|
5
57
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@checkstack/announcement-frontend",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.5",
|
|
4
4
|
"license": "Elastic-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.tsx",
|
|
@@ -14,12 +14,12 @@
|
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
16
|
"@checkstack/announcement-common": "0.4.0",
|
|
17
|
-
"@checkstack/auth-frontend": "0.6.
|
|
17
|
+
"@checkstack/auth-frontend": "0.6.4",
|
|
18
18
|
"@checkstack/common": "0.10.0",
|
|
19
19
|
"@checkstack/frontend-api": "0.5.1",
|
|
20
20
|
"@checkstack/signal-frontend": "0.1.3",
|
|
21
|
-
"@checkstack/tips-frontend": "0.2.
|
|
22
|
-
"@checkstack/ui": "1.
|
|
21
|
+
"@checkstack/tips-frontend": "0.2.4",
|
|
22
|
+
"@checkstack/ui": "1.9.0",
|
|
23
23
|
"date-fns": "^4.1.0",
|
|
24
24
|
"lucide-react": "^0.344.0",
|
|
25
25
|
"react": "^18.2.0",
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
AnnouncementApi,
|
|
5
5
|
type Announcement,
|
|
6
6
|
} from "@checkstack/announcement-common";
|
|
7
|
-
import { MarkdownBlock } from "@checkstack/ui";
|
|
7
|
+
import { MarkdownBlock, cn, usePerformance } from "@checkstack/ui";
|
|
8
8
|
import {
|
|
9
9
|
Info,
|
|
10
10
|
AlertTriangle,
|
|
@@ -106,6 +106,7 @@ function BannerItem({
|
|
|
106
106
|
announcement: Announcement;
|
|
107
107
|
onDismiss: (id: string) => void;
|
|
108
108
|
}) {
|
|
109
|
+
const { isLowPower } = usePerformance();
|
|
109
110
|
const [expanded, setExpanded] = useState(false);
|
|
110
111
|
const styles = getSeverityStyles(announcement.severity);
|
|
111
112
|
|
|
@@ -114,7 +115,12 @@ function BannerItem({
|
|
|
114
115
|
|
|
115
116
|
return (
|
|
116
117
|
<div
|
|
117
|
-
className={
|
|
118
|
+
className={cn(
|
|
119
|
+
styles.bg,
|
|
120
|
+
styles.border,
|
|
121
|
+
"border-b px-4 py-2",
|
|
122
|
+
!isLowPower && "transition-all duration-200",
|
|
123
|
+
)}
|
|
118
124
|
>
|
|
119
125
|
<div className="flex items-center gap-3 max-w-7xl mx-auto">
|
|
120
126
|
<SeverityIcon severity={announcement.severity} />
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { useState } from "react";
|
|
2
2
|
import { usePluginClient } from "@checkstack/frontend-api";
|
|
3
3
|
import { AnnouncementApi, type Announcement } from "@checkstack/announcement-common";
|
|
4
|
-
import { MarkdownBlock } from "@checkstack/ui";
|
|
4
|
+
import { MarkdownBlock, cn, usePerformance } from "@checkstack/ui";
|
|
5
5
|
import {
|
|
6
6
|
Info,
|
|
7
7
|
AlertTriangle,
|
|
@@ -55,13 +55,18 @@ function getSeverityColor(severity: Announcement["severity"]): string {
|
|
|
55
55
|
* A single compact announcement card with expand/collapse.
|
|
56
56
|
*/
|
|
57
57
|
function AnnouncementCard({ announcement }: { announcement: Announcement }) {
|
|
58
|
+
const { isLowPower } = usePerformance();
|
|
58
59
|
const [expanded, setExpanded] = useState(false);
|
|
59
60
|
const severityColor = getSeverityColor(announcement.severity);
|
|
60
61
|
const [borderClass, textClass] = severityColor.split(" ");
|
|
61
62
|
|
|
62
63
|
return (
|
|
63
64
|
<div
|
|
64
|
-
className={
|
|
65
|
+
className={cn(
|
|
66
|
+
"bg-card border border-border rounded-lg border-l-4",
|
|
67
|
+
borderClass,
|
|
68
|
+
!isLowPower && "transition-all duration-200",
|
|
69
|
+
)}
|
|
65
70
|
>
|
|
66
71
|
<button
|
|
67
72
|
type="button"
|
|
@@ -83,7 +88,12 @@ function AnnouncementCard({ announcement }: { announcement: Announcement }) {
|
|
|
83
88
|
</button>
|
|
84
89
|
|
|
85
90
|
{expanded && (
|
|
86
|
-
<div
|
|
91
|
+
<div
|
|
92
|
+
className={cn(
|
|
93
|
+
"px-4 pb-3 pl-11",
|
|
94
|
+
!isLowPower && "animate-in slide-in-from-top-1 duration-200",
|
|
95
|
+
)}
|
|
96
|
+
>
|
|
87
97
|
<div className="text-sm text-muted-foreground">
|
|
88
98
|
<MarkdownBlock size="sm">{announcement.message}</MarkdownBlock>
|
|
89
99
|
</div>
|
|
@@ -99,6 +109,7 @@ function AnnouncementCard({ announcement }: { announcement: Announcement }) {
|
|
|
99
109
|
* Only shows when there are active dashboard-mode announcements.
|
|
100
110
|
*/
|
|
101
111
|
export const DashboardAnnouncements: React.FC = () => {
|
|
112
|
+
const { isLowPower } = usePerformance();
|
|
102
113
|
const announcementClient = usePluginClient(AnnouncementApi);
|
|
103
114
|
|
|
104
115
|
// Always refetch on mount so the dashboard shows fresh data when navigated to.
|
|
@@ -121,7 +132,9 @@ export const DashboardAnnouncements: React.FC = () => {
|
|
|
121
132
|
}
|
|
122
133
|
|
|
123
134
|
return (
|
|
124
|
-
<section
|
|
135
|
+
<section
|
|
136
|
+
className={cn(!isLowPower && "animate-in fade-in duration-300")}
|
|
137
|
+
>
|
|
125
138
|
<div className="flex items-center gap-2 mb-3">
|
|
126
139
|
<Megaphone className="w-4 h-4 text-muted-foreground" />
|
|
127
140
|
<h3 className="text-sm font-medium text-muted-foreground">
|
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
Badge,
|
|
26
26
|
LoadingSpinner,
|
|
27
27
|
EmptyState,
|
|
28
|
+
QueryErrorState,
|
|
28
29
|
Table,
|
|
29
30
|
TableHeader,
|
|
30
31
|
TableRow,
|
|
@@ -47,6 +48,7 @@ import {
|
|
|
47
48
|
Input,
|
|
48
49
|
Label,
|
|
49
50
|
Textarea,
|
|
51
|
+
toastError,
|
|
50
52
|
} from "@checkstack/ui";
|
|
51
53
|
import {
|
|
52
54
|
Plus,
|
|
@@ -61,7 +63,6 @@ import {
|
|
|
61
63
|
Columns,
|
|
62
64
|
} from "lucide-react";
|
|
63
65
|
import { formatDistanceToNow, format } from "date-fns";
|
|
64
|
-
import { extractErrorMessage } from "@checkstack/common";
|
|
65
66
|
|
|
66
67
|
// ---------------------------------------------------------------------------
|
|
67
68
|
// Editor Dialog
|
|
@@ -136,7 +137,7 @@ const AnnouncementEditor: React.FC<AnnouncementEditorProps> = ({
|
|
|
136
137
|
onSave();
|
|
137
138
|
},
|
|
138
139
|
onError: (error) => {
|
|
139
|
-
toast
|
|
140
|
+
toastError(toast, "Failed to create announcement", error);
|
|
140
141
|
},
|
|
141
142
|
});
|
|
142
143
|
|
|
@@ -147,7 +148,7 @@ const AnnouncementEditor: React.FC<AnnouncementEditorProps> = ({
|
|
|
147
148
|
onSave();
|
|
148
149
|
},
|
|
149
150
|
onError: (error) => {
|
|
150
|
-
toast
|
|
151
|
+
toastError(toast, "Failed to update announcement", error);
|
|
151
152
|
},
|
|
152
153
|
});
|
|
153
154
|
|
|
@@ -457,11 +458,8 @@ const AnnouncementManageContent: React.FC = () => {
|
|
|
457
458
|
>();
|
|
458
459
|
const [deleteId, setDeleteId] = useState<string | undefined>();
|
|
459
460
|
|
|
460
|
-
const
|
|
461
|
-
|
|
462
|
-
isLoading,
|
|
463
|
-
refetch,
|
|
464
|
-
} = announcementClient.listAllAnnouncements.useQuery();
|
|
461
|
+
const announcementsQuery = announcementClient.listAllAnnouncements.useQuery();
|
|
462
|
+
const { data: announcementsData, isLoading, refetch } = announcementsQuery;
|
|
465
463
|
|
|
466
464
|
const deleteMutation = announcementClient.deleteAnnouncement.useMutation({
|
|
467
465
|
onSuccess: () => {
|
|
@@ -470,7 +468,7 @@ const AnnouncementManageContent: React.FC = () => {
|
|
|
470
468
|
setDeleteId(undefined);
|
|
471
469
|
},
|
|
472
470
|
onError: (error) => {
|
|
473
|
-
toast
|
|
471
|
+
toastError(toast, "Failed to delete announcement", error);
|
|
474
472
|
},
|
|
475
473
|
});
|
|
476
474
|
|
|
@@ -530,6 +528,14 @@ const AnnouncementManageContent: React.FC = () => {
|
|
|
530
528
|
<div className="p-12 flex justify-center">
|
|
531
529
|
<LoadingSpinner />
|
|
532
530
|
</div>
|
|
531
|
+
) : announcementsQuery.isError ? (
|
|
532
|
+
<div className="p-4">
|
|
533
|
+
<QueryErrorState
|
|
534
|
+
error={announcementsQuery.error}
|
|
535
|
+
onRetry={() => void announcementsQuery.refetch()}
|
|
536
|
+
resource="announcements"
|
|
537
|
+
/>
|
|
538
|
+
</div>
|
|
533
539
|
) : announcements.length === 0 ? (
|
|
534
540
|
<EmptyState
|
|
535
541
|
icon={<Megaphone className="size-10" />}
|