@amiable-dev/docusaurus-plugin-stentorosaur 0.20.0 → 0.21.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/lib/context/StatusDataProvider.d.ts +101 -0
- package/lib/context/StatusDataProvider.d.ts.map +1 -0
- package/lib/context/StatusDataProvider.js +266 -0
- package/lib/options.d.ts.map +1 -1
- package/lib/options.js +1 -0
- package/lib/theme/StatusBadge/index.d.ts +54 -0
- package/lib/theme/StatusBadge/index.d.ts.map +1 -0
- package/lib/theme/StatusBadge/index.js +63 -0
- package/lib/theme/StatusBadge/styles.module.css +120 -0
- package/lib/theme/StatusPage/index.d.ts.map +1 -1
- package/lib/theme/StatusPage/index.js +12 -2
- package/lib/theme/StatusPage/styles.module.css +83 -0
- package/lib/theme/SystemCard/index.d.ts +98 -0
- package/lib/theme/SystemCard/index.d.ts.map +1 -0
- package/lib/theme/SystemCard/index.js +125 -0
- package/lib/theme/SystemCard/styles.module.css +208 -0
- package/lib/theme/SystemCardGroup/index.d.ts +47 -0
- package/lib/theme/SystemCardGroup/index.d.ts.map +1 -0
- package/lib/theme/SystemCardGroup/index.js +113 -0
- package/lib/theme/SystemCardGroup/styles.module.css +180 -0
- package/lib/theme/UptimeBar/index.d.ts +69 -0
- package/lib/theme/UptimeBar/index.d.ts.map +1 -0
- package/lib/theme/UptimeBar/index.js +177 -0
- package/lib/theme/UptimeBar/styles.module.css +217 -0
- package/lib/types.d.ts +15 -0
- package/lib/types.d.ts.map +1 -1
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/package.json +1 -1
|
@@ -3,6 +3,89 @@
|
|
|
3
3
|
padding: 2rem 0;
|
|
4
4
|
}
|
|
5
5
|
|
|
6
|
+
/* Minimal layout styles (ADR-004) */
|
|
7
|
+
.statusBoard {
|
|
8
|
+
max-width: 1200px;
|
|
9
|
+
margin: 0 auto;
|
|
10
|
+
padding: 2rem 1rem;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.header {
|
|
14
|
+
margin-bottom: 2rem;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.header h1 {
|
|
18
|
+
margin: 0 0 0.5rem;
|
|
19
|
+
font-size: 2.5rem;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.description {
|
|
23
|
+
color: var(--ifm-color-emphasis-700);
|
|
24
|
+
font-size: 1.125rem;
|
|
25
|
+
margin: 0.5rem 0 1.5rem;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.overallStatus {
|
|
29
|
+
padding: 1rem 1.5rem;
|
|
30
|
+
border-radius: 8px;
|
|
31
|
+
background: var(--ifm-color-emphasis-100);
|
|
32
|
+
display: inline-flex;
|
|
33
|
+
align-items: center;
|
|
34
|
+
gap: 0.75rem;
|
|
35
|
+
font-weight: 600;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.statusGood {
|
|
39
|
+
display: flex;
|
|
40
|
+
align-items: center;
|
|
41
|
+
gap: 0.75rem;
|
|
42
|
+
color: #10b981;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.statusIssue {
|
|
46
|
+
display: flex;
|
|
47
|
+
align-items: center;
|
|
48
|
+
gap: 0.75rem;
|
|
49
|
+
color: #f59e0b;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.statusDot {
|
|
53
|
+
width: 12px;
|
|
54
|
+
height: 12px;
|
|
55
|
+
border-radius: 50%;
|
|
56
|
+
background-color: currentColor;
|
|
57
|
+
animation: pulse 2s ease-in-out infinite;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
@keyframes pulse {
|
|
61
|
+
0%, 100% {
|
|
62
|
+
opacity: 1;
|
|
63
|
+
}
|
|
64
|
+
50% {
|
|
65
|
+
opacity: 0.5;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.systemCards {
|
|
70
|
+
display: flex;
|
|
71
|
+
flex-direction: column;
|
|
72
|
+
gap: 1rem;
|
|
73
|
+
margin-top: 2rem;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.emptyState {
|
|
77
|
+
text-align: center;
|
|
78
|
+
padding: 3rem 1rem;
|
|
79
|
+
color: var(--ifm-color-emphasis-600);
|
|
80
|
+
background: var(--ifm-color-emphasis-100);
|
|
81
|
+
border-radius: 8px;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.emptyState p {
|
|
85
|
+
margin: 0;
|
|
86
|
+
font-size: 1.125rem;
|
|
87
|
+
}
|
|
88
|
+
|
|
6
89
|
.chartsSection {
|
|
7
90
|
max-width: 1400px;
|
|
8
91
|
margin: 3rem auto;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Your Organization
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* ADR-004: SystemCard Compound Component
|
|
9
|
+
*
|
|
10
|
+
* Collapsible system status card with compound component pattern.
|
|
11
|
+
* Includes Header, UptimeBar, Details, Metrics, and Charts sub-components.
|
|
12
|
+
*
|
|
13
|
+
* @see docs/adrs/ADR-004-simplified-status-card-ux.md
|
|
14
|
+
*/
|
|
15
|
+
import React, { type ReactNode } from 'react';
|
|
16
|
+
import { type UptimeBarProps } from '../UptimeBar';
|
|
17
|
+
/**
|
|
18
|
+
* Status types
|
|
19
|
+
*/
|
|
20
|
+
export type SystemStatus = 'up' | 'degraded' | 'down' | 'maintenance';
|
|
21
|
+
/**
|
|
22
|
+
* Props for SystemCard component
|
|
23
|
+
*/
|
|
24
|
+
export interface SystemCardProps {
|
|
25
|
+
/** System identifier */
|
|
26
|
+
name: string;
|
|
27
|
+
/** Display name (optional) */
|
|
28
|
+
displayName?: string;
|
|
29
|
+
/** Current status */
|
|
30
|
+
status: SystemStatus;
|
|
31
|
+
/** Enable expand on click (default: true) */
|
|
32
|
+
expandable?: boolean;
|
|
33
|
+
/** Initial expanded state */
|
|
34
|
+
defaultExpanded?: boolean;
|
|
35
|
+
/** Controlled expanded state */
|
|
36
|
+
expanded?: boolean;
|
|
37
|
+
/** Callback when expanded/collapsed */
|
|
38
|
+
onExpandChange?: (expanded: boolean) => void;
|
|
39
|
+
/** Semantic heading level (default: 3) */
|
|
40
|
+
headingLevel?: 2 | 3 | 4;
|
|
41
|
+
/** Accessibility label for expand button */
|
|
42
|
+
expandButtonLabel?: string;
|
|
43
|
+
/** Compound component children */
|
|
44
|
+
children?: ReactNode;
|
|
45
|
+
/** Optional additional className */
|
|
46
|
+
className?: string;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* SystemCard Component
|
|
50
|
+
*
|
|
51
|
+
* Main container for system status with expand/collapse functionality.
|
|
52
|
+
*/
|
|
53
|
+
export declare function SystemCard({ name, displayName, status, expandable, defaultExpanded, expanded: controlledExpanded, onExpandChange, headingLevel, expandButtonLabel, children, className, }: SystemCardProps): React.ReactElement;
|
|
54
|
+
export declare namespace SystemCard {
|
|
55
|
+
var Header: typeof SystemCardHeader;
|
|
56
|
+
var UptimeBar: typeof SystemCardUptimeBar;
|
|
57
|
+
var Details: typeof SystemCardDetails;
|
|
58
|
+
var Metrics: typeof SystemCardMetrics;
|
|
59
|
+
var Charts: typeof SystemCardCharts;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* SystemCard.Header - Custom header content
|
|
63
|
+
*/
|
|
64
|
+
export interface SystemCardHeaderProps {
|
|
65
|
+
children?: ReactNode;
|
|
66
|
+
}
|
|
67
|
+
export declare function SystemCardHeader({ children, }: SystemCardHeaderProps): React.ReactElement;
|
|
68
|
+
/**
|
|
69
|
+
* SystemCard.UptimeBar - Embedded UptimeBar
|
|
70
|
+
*/
|
|
71
|
+
export declare function SystemCardUptimeBar(props: Omit<UptimeBarProps, 'serviceName'> & {
|
|
72
|
+
serviceName?: string;
|
|
73
|
+
}): React.ReactElement;
|
|
74
|
+
/**
|
|
75
|
+
* SystemCard.Details - Expandable content container
|
|
76
|
+
*/
|
|
77
|
+
export interface SystemCardDetailsProps {
|
|
78
|
+
children?: ReactNode;
|
|
79
|
+
}
|
|
80
|
+
export declare function SystemCardDetails({ children, }: SystemCardDetailsProps): React.ReactElement;
|
|
81
|
+
/**
|
|
82
|
+
* SystemCard.Metrics - Response time and last checked
|
|
83
|
+
*/
|
|
84
|
+
export interface SystemCardMetricsProps {
|
|
85
|
+
responseTime?: number;
|
|
86
|
+
lastChecked?: string;
|
|
87
|
+
}
|
|
88
|
+
export declare function SystemCardMetrics({ responseTime, lastChecked, }: SystemCardMetricsProps): React.ReactElement;
|
|
89
|
+
/**
|
|
90
|
+
* SystemCard.Charts - Chart container (placeholder)
|
|
91
|
+
*/
|
|
92
|
+
export interface SystemCardChartsProps {
|
|
93
|
+
serviceName?: string;
|
|
94
|
+
children?: ReactNode;
|
|
95
|
+
}
|
|
96
|
+
export declare function SystemCardCharts({ children, }: SystemCardChartsProps): React.ReactElement;
|
|
97
|
+
export default SystemCard;
|
|
98
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/theme/SystemCard/index.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,EAKZ,KAAK,SAAS,EAEf,MAAM,OAAO,CAAC;AAEf,OAAO,EAAa,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAG9D;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,UAAU,GAAG,MAAM,GAAG,aAAa,CAAC;AA0BtE;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,wBAAwB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,8BAA8B;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qBAAqB;IACrB,MAAM,EAAE,YAAY,CAAC;IACrB,6CAA6C;IAC7C,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,6BAA6B;IAC7B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,gCAAgC;IAChC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uCAAuC;IACvC,cAAc,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IAC7C,0CAA0C;IAC1C,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACzB,4CAA4C;IAC5C,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,kCAAkC;IAClC,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,oCAAoC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAYD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,EACzB,IAAI,EACJ,WAAW,EACX,MAAM,EACN,UAAiB,EACjB,eAAuB,EACvB,QAAQ,EAAE,kBAAkB,EAC5B,cAAc,EACd,YAAgB,EAChB,iBAAiB,EACjB,QAAQ,EACR,SAAS,GACV,EAAE,eAAe,GAAG,KAAK,CAAC,YAAY,CA2FtC;yBAvGe,UAAU;;;;;;;AAyG1B;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,QAAQ,GACT,EAAE,qBAAqB,GAAG,KAAK,CAAC,YAAY,CAE5C;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,IAAI,CAAC,cAAc,EAAE,aAAa,CAAC,GAAG;IAAE,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GACpE,KAAK,CAAC,YAAY,CAOpB;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,wBAAgB,iBAAiB,CAAC,EAChC,QAAQ,GACT,EAAE,sBAAsB,GAAG,KAAK,CAAC,YAAY,CAW7C;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,iBAAiB,CAAC,EAChC,YAAY,EACZ,WAAW,GACZ,EAAE,sBAAsB,GAAG,KAAK,CAAC,YAAY,CAsB7C;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,QAAQ,GACT,EAAE,qBAAqB,GAAG,KAAK,CAAC,YAAY,CAE5C;AAUD,eAAe,UAAU,CAAC"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.SystemCard = SystemCard;
|
|
7
|
+
exports.SystemCardHeader = SystemCardHeader;
|
|
8
|
+
exports.SystemCardUptimeBar = SystemCardUptimeBar;
|
|
9
|
+
exports.SystemCardDetails = SystemCardDetails;
|
|
10
|
+
exports.SystemCardMetrics = SystemCardMetrics;
|
|
11
|
+
exports.SystemCardCharts = SystemCardCharts;
|
|
12
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
13
|
+
/**
|
|
14
|
+
* Copyright (c) Your Organization
|
|
15
|
+
*
|
|
16
|
+
* This source code is licensed under the MIT license found in the
|
|
17
|
+
* LICENSE file in the root directory of this source tree.
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* ADR-004: SystemCard Compound Component
|
|
21
|
+
*
|
|
22
|
+
* Collapsible system status card with compound component pattern.
|
|
23
|
+
* Includes Header, UptimeBar, Details, Metrics, and Charts sub-components.
|
|
24
|
+
*
|
|
25
|
+
* @see docs/adrs/ADR-004-simplified-status-card-ux.md
|
|
26
|
+
*/
|
|
27
|
+
const react_1 = require("react");
|
|
28
|
+
const StatusBadge_1 = require("../StatusBadge");
|
|
29
|
+
const UptimeBar_1 = require("../UptimeBar");
|
|
30
|
+
const styles_module_css_1 = __importDefault(require("./styles.module.css"));
|
|
31
|
+
const SystemCardContext = (0, react_1.createContext)(undefined);
|
|
32
|
+
function useSystemCardContext() {
|
|
33
|
+
const context = (0, react_1.useContext)(SystemCardContext);
|
|
34
|
+
if (!context) {
|
|
35
|
+
throw new Error('SystemCard compound components must be used within a SystemCard');
|
|
36
|
+
}
|
|
37
|
+
return context;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Status class mapping
|
|
41
|
+
*/
|
|
42
|
+
const STATUS_CLASS_MAP = {
|
|
43
|
+
up: styles_module_css_1.default.statusUp,
|
|
44
|
+
degraded: styles_module_css_1.default.statusDegraded,
|
|
45
|
+
down: styles_module_css_1.default.statusDown,
|
|
46
|
+
maintenance: styles_module_css_1.default.statusMaintenance,
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* SystemCard Component
|
|
50
|
+
*
|
|
51
|
+
* Main container for system status with expand/collapse functionality.
|
|
52
|
+
*/
|
|
53
|
+
function SystemCard({ name, displayName, status, expandable = true, defaultExpanded = false, expanded: controlledExpanded, onExpandChange, headingLevel = 3, expandButtonLabel, children, className, }) {
|
|
54
|
+
// Uncontrolled state
|
|
55
|
+
const [internalExpanded, setInternalExpanded] = (0, react_1.useState)(defaultExpanded);
|
|
56
|
+
// Use controlled or uncontrolled state
|
|
57
|
+
const isControlled = controlledExpanded !== undefined;
|
|
58
|
+
const expanded = isControlled ? controlledExpanded : internalExpanded;
|
|
59
|
+
const handleToggle = (0, react_1.useCallback)(() => {
|
|
60
|
+
if (!expandable)
|
|
61
|
+
return;
|
|
62
|
+
const newExpanded = !expanded;
|
|
63
|
+
if (!isControlled) {
|
|
64
|
+
setInternalExpanded(newExpanded);
|
|
65
|
+
}
|
|
66
|
+
onExpandChange?.(newExpanded);
|
|
67
|
+
}, [expandable, expanded, isControlled, onExpandChange]);
|
|
68
|
+
const handleKeyDown = (0, react_1.useCallback)((event) => {
|
|
69
|
+
if (!expandable)
|
|
70
|
+
return;
|
|
71
|
+
if (event.key === 'Enter' || event.key === ' ') {
|
|
72
|
+
event.preventDefault();
|
|
73
|
+
handleToggle();
|
|
74
|
+
}
|
|
75
|
+
else if (event.key === 'Escape' && expanded) {
|
|
76
|
+
event.preventDefault();
|
|
77
|
+
if (!isControlled) {
|
|
78
|
+
setInternalExpanded(false);
|
|
79
|
+
}
|
|
80
|
+
onExpandChange?.(false);
|
|
81
|
+
}
|
|
82
|
+
}, [expandable, expanded, isControlled, onExpandChange, handleToggle]);
|
|
83
|
+
const Heading = `h${headingLevel}`;
|
|
84
|
+
const label = displayName || name;
|
|
85
|
+
// Context value for compound components
|
|
86
|
+
const contextValue = {
|
|
87
|
+
name,
|
|
88
|
+
status,
|
|
89
|
+
expanded,
|
|
90
|
+
expandable,
|
|
91
|
+
};
|
|
92
|
+
const statusClass = STATUS_CLASS_MAP[status];
|
|
93
|
+
return ((0, jsx_runtime_1.jsx)(SystemCardContext.Provider, { value: contextValue, children: (0, jsx_runtime_1.jsxs)("article", { className: `${styles_module_css_1.default.systemCard} ${statusClass} ${expanded ? styles_module_css_1.default.expanded : ''} ${className || ''}`, role: "article", "aria-expanded": expanded, tabIndex: expandable ? 0 : undefined, onClick: handleToggle, onKeyDown: handleKeyDown, children: [(0, jsx_runtime_1.jsxs)("div", { className: styles_module_css_1.default.cardHeader, children: [(0, jsx_runtime_1.jsxs)("div", { className: styles_module_css_1.default.cardTitleRow, children: [(0, jsx_runtime_1.jsx)(Heading, { className: styles_module_css_1.default.cardTitle, children: label }), (0, jsx_runtime_1.jsx)(StatusBadge_1.StatusBadge, { status: status, size: "sm" })] }), expandable && ((0, jsx_runtime_1.jsx)("button", { type: "button", className: styles_module_css_1.default.expandButton, "aria-label": expandButtonLabel || `Toggle ${label} details`, "aria-expanded": expanded, onClick: (e) => {
|
|
94
|
+
e.stopPropagation();
|
|
95
|
+
handleToggle();
|
|
96
|
+
}, children: (0, jsx_runtime_1.jsx)("span", { className: `${styles_module_css_1.default.expandIcon} ${expanded ? styles_module_css_1.default.expandIconOpen : ''}`, children: "\u25BC" }) }))] }), children] }) }));
|
|
97
|
+
}
|
|
98
|
+
function SystemCardHeader({ children, }) {
|
|
99
|
+
return (0, jsx_runtime_1.jsx)("div", { className: styles_module_css_1.default.customHeader, children: children });
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* SystemCard.UptimeBar - Embedded UptimeBar
|
|
103
|
+
*/
|
|
104
|
+
function SystemCardUptimeBar(props) {
|
|
105
|
+
const { name } = useSystemCardContext();
|
|
106
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: styles_module_css_1.default.uptimeBarWrapper, children: (0, jsx_runtime_1.jsx)(UptimeBar_1.UptimeBar, { ...props, serviceName: props.serviceName || name }) }));
|
|
107
|
+
}
|
|
108
|
+
function SystemCardDetails({ children, }) {
|
|
109
|
+
const { expanded } = useSystemCardContext();
|
|
110
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: `${styles_module_css_1.default.cardDetails} ${expanded ? styles_module_css_1.default.detailsVisible : ''}`, "aria-hidden": !expanded, children: children }));
|
|
111
|
+
}
|
|
112
|
+
function SystemCardMetrics({ responseTime, lastChecked, }) {
|
|
113
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: styles_module_css_1.default.metricsGrid, children: [responseTime !== undefined && ((0, jsx_runtime_1.jsxs)("div", { className: styles_module_css_1.default.metricItem, children: [(0, jsx_runtime_1.jsx)("span", { className: styles_module_css_1.default.metricLabel, children: "Response Time" }), (0, jsx_runtime_1.jsxs)("span", { className: styles_module_css_1.default.metricValue, children: [responseTime, "ms"] })] })), lastChecked !== undefined && ((0, jsx_runtime_1.jsxs)("div", { className: styles_module_css_1.default.metricItem, children: [(0, jsx_runtime_1.jsx)("span", { className: styles_module_css_1.default.metricLabel, children: "Last Checked" }), (0, jsx_runtime_1.jsx)("span", { className: styles_module_css_1.default.metricValue, children: lastChecked })] })), responseTime === undefined && lastChecked === undefined && ((0, jsx_runtime_1.jsx)("div", { className: styles_module_css_1.default.metricItem, children: (0, jsx_runtime_1.jsx)("span", { className: styles_module_css_1.default.metricValue, children: "N/A" }) }))] }));
|
|
114
|
+
}
|
|
115
|
+
function SystemCardCharts({ children, }) {
|
|
116
|
+
return (0, jsx_runtime_1.jsx)("div", { className: styles_module_css_1.default.chartsContainer, children: children });
|
|
117
|
+
}
|
|
118
|
+
// Attach compound components to SystemCard
|
|
119
|
+
SystemCard.Header = SystemCardHeader;
|
|
120
|
+
SystemCard.UptimeBar = SystemCardUptimeBar;
|
|
121
|
+
SystemCard.Details = SystemCardDetails;
|
|
122
|
+
SystemCard.Metrics = SystemCardMetrics;
|
|
123
|
+
SystemCard.Charts = SystemCardCharts;
|
|
124
|
+
// Default export
|
|
125
|
+
exports.default = SystemCard;
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ADR-004: SystemCard Styles
|
|
3
|
+
*
|
|
4
|
+
* Collapsible system status card with expand/collapse animation.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/* CSS Variables */
|
|
8
|
+
:root {
|
|
9
|
+
--card-border-radius: 8px;
|
|
10
|
+
--card-padding: 1rem;
|
|
11
|
+
--card-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
|
12
|
+
--card-shadow-hover: 0 4px 12px rgba(0, 0, 0, 0.15);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/* Main card container */
|
|
16
|
+
.systemCard {
|
|
17
|
+
background: var(--ifm-card-background-color, #fff);
|
|
18
|
+
border: 1px solid var(--ifm-color-emphasis-200);
|
|
19
|
+
border-radius: var(--card-border-radius);
|
|
20
|
+
padding: var(--card-padding);
|
|
21
|
+
box-shadow: var(--card-shadow);
|
|
22
|
+
cursor: pointer;
|
|
23
|
+
transition: box-shadow 0.2s ease, border-color 0.2s ease;
|
|
24
|
+
outline: none;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.systemCard:hover {
|
|
28
|
+
box-shadow: var(--card-shadow-hover);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.systemCard:focus-visible {
|
|
32
|
+
outline: 2px solid var(--ifm-color-primary);
|
|
33
|
+
outline-offset: 2px;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/* Expanded state */
|
|
37
|
+
.expanded {
|
|
38
|
+
border-color: var(--ifm-color-primary-light);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/* Status indicator border */
|
|
42
|
+
.statusUp {
|
|
43
|
+
border-left: 4px solid var(--status-operational, #22c55e);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.statusDegraded {
|
|
47
|
+
border-left: 4px solid var(--status-degraded, #eab308);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.statusDown {
|
|
51
|
+
border-left: 4px solid var(--status-outage, #ef4444);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.statusMaintenance {
|
|
55
|
+
border-left: 4px solid var(--status-maintenance, #3b82f6);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/* Card header */
|
|
59
|
+
.cardHeader {
|
|
60
|
+
display: flex;
|
|
61
|
+
align-items: center;
|
|
62
|
+
justify-content: space-between;
|
|
63
|
+
gap: 1rem;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.cardTitleRow {
|
|
67
|
+
display: flex;
|
|
68
|
+
align-items: center;
|
|
69
|
+
gap: 0.75rem;
|
|
70
|
+
flex: 1;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.cardTitle {
|
|
74
|
+
margin: 0;
|
|
75
|
+
font-size: 1rem;
|
|
76
|
+
font-weight: 600;
|
|
77
|
+
color: var(--ifm-color-content);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/* Expand button */
|
|
81
|
+
.expandButton {
|
|
82
|
+
display: flex;
|
|
83
|
+
align-items: center;
|
|
84
|
+
justify-content: center;
|
|
85
|
+
width: 32px;
|
|
86
|
+
height: 32px;
|
|
87
|
+
background: transparent;
|
|
88
|
+
border: 1px solid var(--ifm-color-emphasis-300);
|
|
89
|
+
border-radius: 4px;
|
|
90
|
+
cursor: pointer;
|
|
91
|
+
transition: background-color 0.15s ease;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.expandButton:hover {
|
|
95
|
+
background: var(--ifm-color-emphasis-100);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.expandIcon {
|
|
99
|
+
font-size: 0.75rem;
|
|
100
|
+
color: var(--ifm-color-content-secondary);
|
|
101
|
+
transition: transform 0.2s ease;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.expandIconOpen {
|
|
105
|
+
transform: rotate(180deg);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/* Custom header slot */
|
|
109
|
+
.customHeader {
|
|
110
|
+
margin-top: 0.5rem;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/* UptimeBar wrapper */
|
|
114
|
+
.uptimeBarWrapper {
|
|
115
|
+
margin-top: 0.75rem;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/* Card details (expandable content) */
|
|
119
|
+
.cardDetails {
|
|
120
|
+
max-height: 0;
|
|
121
|
+
overflow: hidden;
|
|
122
|
+
opacity: 0;
|
|
123
|
+
transition: max-height 0.3s ease, opacity 0.2s ease, margin-top 0.3s ease;
|
|
124
|
+
margin-top: 0;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.detailsVisible {
|
|
128
|
+
max-height: 500px;
|
|
129
|
+
opacity: 1;
|
|
130
|
+
margin-top: 1rem;
|
|
131
|
+
padding-top: 1rem;
|
|
132
|
+
border-top: 1px solid var(--ifm-color-emphasis-200);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/* Metrics grid */
|
|
136
|
+
.metricsGrid {
|
|
137
|
+
display: grid;
|
|
138
|
+
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
|
|
139
|
+
gap: 1rem;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.metricItem {
|
|
143
|
+
display: flex;
|
|
144
|
+
flex-direction: column;
|
|
145
|
+
gap: 0.25rem;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
.metricLabel {
|
|
149
|
+
font-size: 0.75rem;
|
|
150
|
+
color: var(--ifm-color-content-secondary);
|
|
151
|
+
text-transform: uppercase;
|
|
152
|
+
letter-spacing: 0.05em;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
.metricValue {
|
|
156
|
+
font-size: 1rem;
|
|
157
|
+
font-weight: 600;
|
|
158
|
+
color: var(--ifm-color-content);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/* Charts container */
|
|
162
|
+
.chartsContainer {
|
|
163
|
+
margin-top: 1rem;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/* Dark mode */
|
|
167
|
+
[data-theme='dark'] .systemCard {
|
|
168
|
+
background: var(--ifm-card-background-color, #1a1a1a);
|
|
169
|
+
border-color: var(--ifm-color-emphasis-300);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
[data-theme='dark'] .systemCard:hover {
|
|
173
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/* Reduced motion */
|
|
177
|
+
@media (prefers-reduced-motion: reduce) {
|
|
178
|
+
.systemCard,
|
|
179
|
+
.expandIcon,
|
|
180
|
+
.cardDetails {
|
|
181
|
+
transition: none;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
.cardDetails {
|
|
185
|
+
max-height: none;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
.cardDetails:not(.detailsVisible) {
|
|
189
|
+
display: none;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/* Mobile responsiveness */
|
|
194
|
+
@media (max-width: 600px) {
|
|
195
|
+
.systemCard {
|
|
196
|
+
padding: 0.75rem;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
.cardTitleRow {
|
|
200
|
+
flex-direction: column;
|
|
201
|
+
align-items: flex-start;
|
|
202
|
+
gap: 0.5rem;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
.metricsGrid {
|
|
206
|
+
grid-template-columns: 1fr;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Your Organization
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* ADR-004: SystemCardGroup Component
|
|
9
|
+
*
|
|
10
|
+
* Container for grouping multiple SystemCards with collapsible behavior.
|
|
11
|
+
* Shows aggregate status (worst-of) for the group.
|
|
12
|
+
*
|
|
13
|
+
* @see docs/adrs/ADR-004-simplified-status-card-ux.md
|
|
14
|
+
*/
|
|
15
|
+
import React, { type ReactNode } from 'react';
|
|
16
|
+
/**
|
|
17
|
+
* Status types (matching SystemCard)
|
|
18
|
+
*/
|
|
19
|
+
export type GroupStatus = 'up' | 'degraded' | 'down' | 'maintenance';
|
|
20
|
+
/**
|
|
21
|
+
* Props for SystemCardGroup component
|
|
22
|
+
*/
|
|
23
|
+
export interface SystemCardGroupProps {
|
|
24
|
+
/** Group identifier */
|
|
25
|
+
name: string;
|
|
26
|
+
/** Display name */
|
|
27
|
+
displayName: string;
|
|
28
|
+
/** Initially collapsed (default: false) */
|
|
29
|
+
defaultCollapsed?: boolean;
|
|
30
|
+
/** Group status override (derived from children if not provided) */
|
|
31
|
+
status?: GroupStatus;
|
|
32
|
+
/** Semantic heading level (default: 2) */
|
|
33
|
+
headingLevel?: 2 | 3 | 4;
|
|
34
|
+
/** Children (SystemCard components) */
|
|
35
|
+
children: ReactNode;
|
|
36
|
+
/** Optional additional className */
|
|
37
|
+
className?: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* SystemCardGroup Component
|
|
41
|
+
*
|
|
42
|
+
* Groups multiple SystemCards together with a collapsible header.
|
|
43
|
+
* Displays aggregate status based on worst child status.
|
|
44
|
+
*/
|
|
45
|
+
export declare function SystemCardGroup({ name, displayName, defaultCollapsed, status: explicitStatus, headingLevel, children, className, }: SystemCardGroupProps): React.ReactElement;
|
|
46
|
+
export default SystemCardGroup;
|
|
47
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/theme/SystemCardGroup/index.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,EAMZ,KAAK,SAAS,EAEf,MAAM,OAAO,CAAC;AAGf;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,IAAI,GAAG,UAAU,GAAG,MAAM,GAAG,aAAa,CAAC;AAYrE;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,uBAAuB;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,mBAAmB;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,2CAA2C;IAC3C,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,oEAAoE;IACpE,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,0CAA0C;IAC1C,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACzB,uCAAuC;IACvC,QAAQ,EAAE,SAAS,CAAC;IACpB,oCAAoC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAyDD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,EAC9B,IAAI,EACJ,WAAW,EACX,gBAAwB,EACxB,MAAM,EAAE,cAAc,EACtB,YAAgB,EAChB,QAAQ,EACR,SAAS,GACV,EAAE,oBAAoB,GAAG,KAAK,CAAC,YAAY,CA0E3C;AAGD,eAAe,eAAe,CAAC"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.SystemCardGroup = SystemCardGroup;
|
|
7
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
+
/**
|
|
9
|
+
* Copyright (c) Your Organization
|
|
10
|
+
*
|
|
11
|
+
* This source code is licensed under the MIT license found in the
|
|
12
|
+
* LICENSE file in the root directory of this source tree.
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* ADR-004: SystemCardGroup Component
|
|
16
|
+
*
|
|
17
|
+
* Container for grouping multiple SystemCards with collapsible behavior.
|
|
18
|
+
* Shows aggregate status (worst-of) for the group.
|
|
19
|
+
*
|
|
20
|
+
* @see docs/adrs/ADR-004-simplified-status-card-ux.md
|
|
21
|
+
*/
|
|
22
|
+
const react_1 = require("react");
|
|
23
|
+
const styles_module_css_1 = __importDefault(require("./styles.module.css"));
|
|
24
|
+
/**
|
|
25
|
+
* Status priority for aggregation (higher = worse)
|
|
26
|
+
*/
|
|
27
|
+
const STATUS_PRIORITY = {
|
|
28
|
+
up: 0,
|
|
29
|
+
maintenance: 1,
|
|
30
|
+
degraded: 2,
|
|
31
|
+
down: 3,
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Status labels for group header
|
|
35
|
+
*/
|
|
36
|
+
const GROUP_STATUS_LABELS = {
|
|
37
|
+
up: 'All Operational',
|
|
38
|
+
degraded: 'Partial Issues',
|
|
39
|
+
down: 'Service Outage',
|
|
40
|
+
maintenance: 'Maintenance',
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Status class mapping
|
|
44
|
+
*/
|
|
45
|
+
const GROUP_STATUS_CLASS_MAP = {
|
|
46
|
+
up: styles_module_css_1.default.groupStatusUp,
|
|
47
|
+
degraded: styles_module_css_1.default.groupStatusDegraded,
|
|
48
|
+
down: styles_module_css_1.default.groupStatusDown,
|
|
49
|
+
maintenance: styles_module_css_1.default.groupStatusMaintenance,
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Extract status from SystemCard children
|
|
53
|
+
*/
|
|
54
|
+
function getWorstStatus(children) {
|
|
55
|
+
let worstStatus = 'up';
|
|
56
|
+
let worstPriority = STATUS_PRIORITY.up;
|
|
57
|
+
react_1.Children.forEach(children, (child) => {
|
|
58
|
+
if ((0, react_1.isValidElement)(child) && child.props.status) {
|
|
59
|
+
const childStatus = child.props.status;
|
|
60
|
+
const priority = STATUS_PRIORITY[childStatus] ?? 0;
|
|
61
|
+
if (priority > worstPriority) {
|
|
62
|
+
worstPriority = priority;
|
|
63
|
+
worstStatus = childStatus;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
return worstStatus;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Count valid children
|
|
71
|
+
*/
|
|
72
|
+
function countChildren(children) {
|
|
73
|
+
let count = 0;
|
|
74
|
+
react_1.Children.forEach(children, (child) => {
|
|
75
|
+
if ((0, react_1.isValidElement)(child)) {
|
|
76
|
+
count++;
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
return count;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* SystemCardGroup Component
|
|
83
|
+
*
|
|
84
|
+
* Groups multiple SystemCards together with a collapsible header.
|
|
85
|
+
* Displays aggregate status based on worst child status.
|
|
86
|
+
*/
|
|
87
|
+
function SystemCardGroup({ name, displayName, defaultCollapsed = false, status: explicitStatus, headingLevel = 2, children, className, }) {
|
|
88
|
+
const [collapsed, setCollapsed] = (0, react_1.useState)(defaultCollapsed);
|
|
89
|
+
// Derive status from children or use explicit override
|
|
90
|
+
const aggregatedStatus = (0, react_1.useMemo)(() => {
|
|
91
|
+
if (explicitStatus)
|
|
92
|
+
return explicitStatus;
|
|
93
|
+
return getWorstStatus(children);
|
|
94
|
+
}, [explicitStatus, children]);
|
|
95
|
+
// Count children
|
|
96
|
+
const childCount = (0, react_1.useMemo)(() => countChildren(children), [children]);
|
|
97
|
+
const handleToggle = (0, react_1.useCallback)(() => {
|
|
98
|
+
setCollapsed((prev) => !prev);
|
|
99
|
+
}, []);
|
|
100
|
+
const handleKeyDown = (0, react_1.useCallback)((event) => {
|
|
101
|
+
if (event.key === 'Enter' || event.key === ' ') {
|
|
102
|
+
event.preventDefault();
|
|
103
|
+
handleToggle();
|
|
104
|
+
}
|
|
105
|
+
}, [handleToggle]);
|
|
106
|
+
const Heading = `h${headingLevel}`;
|
|
107
|
+
const statusLabel = GROUP_STATUS_LABELS[aggregatedStatus];
|
|
108
|
+
const statusClass = GROUP_STATUS_CLASS_MAP[aggregatedStatus];
|
|
109
|
+
const serviceWord = childCount === 1 ? 'service' : 'services';
|
|
110
|
+
return ((0, jsx_runtime_1.jsxs)("section", { className: `${styles_module_css_1.default.systemCardGroup} ${collapsed ? styles_module_css_1.default.collapsed : ''} ${statusClass} ${className || ''}`, "data-group": name, children: [(0, jsx_runtime_1.jsxs)("div", { className: styles_module_css_1.default.groupHeader, children: [(0, jsx_runtime_1.jsx)("button", { type: "button", className: styles_module_css_1.default.toggleButton, onClick: handleToggle, onKeyDown: handleKeyDown, "aria-expanded": !collapsed, "aria-label": `Toggle ${displayName} group`, children: (0, jsx_runtime_1.jsx)("span", { className: `${styles_module_css_1.default.expandIcon} ${!collapsed ? styles_module_css_1.default.expandIconOpen : ''}`, children: "\u25BC" }) }), (0, jsx_runtime_1.jsxs)("div", { className: styles_module_css_1.default.groupInfo, children: [(0, jsx_runtime_1.jsx)(Heading, { className: styles_module_css_1.default.groupTitle, children: displayName }), (0, jsx_runtime_1.jsxs)("span", { className: styles_module_css_1.default.groupMeta, children: [(0, jsx_runtime_1.jsxs)("span", { className: styles_module_css_1.default.serviceCount, children: [childCount, " ", serviceWord] }), (0, jsx_runtime_1.jsx)("span", { className: styles_module_css_1.default.statusDot }), (0, jsx_runtime_1.jsx)("span", { className: styles_module_css_1.default.statusLabel, children: statusLabel })] })] })] }), (0, jsx_runtime_1.jsx)("div", { className: `${styles_module_css_1.default.groupContent} ${collapsed ? styles_module_css_1.default.contentHidden : ''}`, "aria-hidden": collapsed, children: children })] }));
|
|
111
|
+
}
|
|
112
|
+
// Default export
|
|
113
|
+
exports.default = SystemCardGroup;
|