@redocly/theme 0.24.0 → 0.25.0-beta.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/components/Catalog/CatalogCard.d.ts +2 -2
- package/lib/components/Catalog/useCatalog.js +7 -5
- package/lib/components/OpenApiDocs/ScorecardBadges.js +1 -3
- package/lib/components/Scorecard/Card.d.ts +4 -0
- package/lib/components/Scorecard/Card.js +28 -0
- package/lib/components/Scorecard/Gauge.d.ts +11 -0
- package/lib/components/Scorecard/Gauge.js +62 -0
- package/lib/components/Scorecard/StatusByLevelWidget.d.ts +12 -0
- package/lib/components/Scorecard/StatusByLevelWidget.js +83 -0
- package/lib/config.d.ts +6 -0
- package/lib/config.js +1 -0
- package/lib/globalStyle.js +13 -8
- package/package.json +1 -1
- package/src/components/Catalog/useCatalog.ts +6 -3
- package/src/components/OpenApiDocs/ScorecardBadges.tsx +1 -1
- package/src/components/Scorecard/Card.tsx +23 -0
- package/src/components/Scorecard/Gauge.tsx +53 -0
- package/src/components/Scorecard/StatusByLevelWidget.tsx +71 -0
- package/src/config.ts +1 -0
- package/src/globalStyle.ts +24 -18
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
import type { CatalogItem } from '
|
|
2
|
+
import type { CatalogItem } from '@theme/types/portal/src/shared/types/catalog';
|
|
3
3
|
export declare function CatalogCard({ item }: {
|
|
4
4
|
item: CatalogItem;
|
|
5
5
|
}): JSX.Element;
|
|
6
|
-
export declare function statusToColor(status: string): "
|
|
6
|
+
export declare function statusToColor(status: string): "" | "error" | "warning" | "success";
|
|
@@ -26,9 +26,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
26
26
|
exports.useCatalog = void 0;
|
|
27
27
|
const React = __importStar(require("react"));
|
|
28
28
|
const react_router_dom_1 = require("react-router-dom");
|
|
29
|
-
const telemetry_1 = require("
|
|
30
|
-
const usePageData_1 = require("
|
|
31
|
-
const utils_1 = require("
|
|
29
|
+
const telemetry_1 = require("@portal/telemetry");
|
|
30
|
+
const usePageData_1 = require("@portal/hooks/usePageData");
|
|
31
|
+
const utils_1 = require("@theme/utils");
|
|
32
32
|
function useCatalog(items, config) {
|
|
33
33
|
var _a;
|
|
34
34
|
const location = (0, react_router_dom_1.useLocation)();
|
|
@@ -257,8 +257,10 @@ function collectFilterOptions(items, filters) {
|
|
|
257
257
|
}
|
|
258
258
|
}
|
|
259
259
|
const options = Object.entries(usedOptions)
|
|
260
|
-
.map(([value, count]) => ({ value, count }))
|
|
261
|
-
|
|
260
|
+
.map(([value, count]) => ({ value, count }));
|
|
261
|
+
if (!staticOptions) {
|
|
262
|
+
options.sort((a, b) => b.value.localeCompare(a.value));
|
|
263
|
+
}
|
|
262
264
|
if (othersCount) {
|
|
263
265
|
options.push({
|
|
264
266
|
value: filter.missingCategoryNameTranslationKey || filter.missingCategoryName || 'Others',
|
|
@@ -29,8 +29,6 @@ const ScorecardBadgesWrapper = styled_components_1.default.div `
|
|
|
29
29
|
function ComplianceTag(props) {
|
|
30
30
|
const { level, status, slug } = props;
|
|
31
31
|
return (react_1.default.createElement(Link_1.Link, { to: slug },
|
|
32
|
-
react_1.default.createElement(Tag_1.Tag, { color: (0, CatalogCard_1.statusToColor)(status), size: "large", onClick: () => telemetry_1.telemetry.send('scorecard_link_clicked', { action: 'click' }) },
|
|
33
|
-
level,
|
|
34
|
-
" oops")));
|
|
32
|
+
react_1.default.createElement(Tag_1.Tag, { color: (0, CatalogCard_1.statusToColor)(status), size: "large", onClick: () => telemetry_1.telemetry.send('scorecard_link_clicked', { action: 'click' }) }, level)));
|
|
35
33
|
}
|
|
36
34
|
//# sourceMappingURL=ScorecardBadges.js.map
|
|
@@ -0,0 +1,28 @@
|
|
|
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.ScorecardCardTitle = exports.ScorecardCard = void 0;
|
|
7
|
+
const styled_components_1 = __importDefault(require("styled-components"));
|
|
8
|
+
exports.ScorecardCard = styled_components_1.default.div.attrs({
|
|
9
|
+
'data-component-name': 'Scorecard/ScorecardCard',
|
|
10
|
+
}) `
|
|
11
|
+
color: var(--text-primary);
|
|
12
|
+
background-color: var(--bg-raised);
|
|
13
|
+
border-radius: 4px;
|
|
14
|
+
|
|
15
|
+
border: 1px solid var(--border-primary);
|
|
16
|
+
box-shadow: 0 0 10px 0 rgba(35, 35, 35, 0.05);
|
|
17
|
+
|
|
18
|
+
flex: 1;
|
|
19
|
+
min-width: 300px;
|
|
20
|
+
padding: 20px;
|
|
21
|
+
`;
|
|
22
|
+
exports.ScorecardCardTitle = styled_components_1.default.h3 `
|
|
23
|
+
font-size: 1.2rem;
|
|
24
|
+
font-weight: bold;
|
|
25
|
+
margin-bottom: 10px;
|
|
26
|
+
margin-top: 0;
|
|
27
|
+
`;
|
|
28
|
+
//# sourceMappingURL=Card.js.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
export interface GaugeProps {
|
|
3
|
+
chunks: {
|
|
4
|
+
share: number;
|
|
5
|
+
color: string;
|
|
6
|
+
title?: string;
|
|
7
|
+
}[];
|
|
8
|
+
className?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function Gauge({ chunks, className }: GaugeProps): JSX.Element;
|
|
11
|
+
export declare const GaugeValue: import("styled-components").StyledComponent<"span", any, {}, never>;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
exports.GaugeValue = exports.Gauge = void 0;
|
|
30
|
+
const React = __importStar(require("react"));
|
|
31
|
+
const styled_components_1 = __importDefault(require("styled-components"));
|
|
32
|
+
function Gauge({ chunks, className }) {
|
|
33
|
+
const title = chunks
|
|
34
|
+
.map((chunk) => chunk.title)
|
|
35
|
+
.filter(Boolean)
|
|
36
|
+
.join(', ');
|
|
37
|
+
return (React.createElement(GaugeWrapper, { "data-component-name": "Scorecard/StatusByLevelWidget", className: className, title: title }, chunks.map((chunk, i) => (React.createElement(GaugeChunk, { key: i, share: chunk.share, color: chunk.color })))));
|
|
38
|
+
}
|
|
39
|
+
exports.Gauge = Gauge;
|
|
40
|
+
exports.GaugeValue = styled_components_1.default.span `
|
|
41
|
+
font-size: var(--font-size-lg);
|
|
42
|
+
line-height: var(line-height-regular);
|
|
43
|
+
|
|
44
|
+
margin-right: 5px;
|
|
45
|
+
vertical-align: middle;
|
|
46
|
+
display: inline-block;
|
|
47
|
+
margin-right: 0;
|
|
48
|
+
text-align: right;
|
|
49
|
+
width: 70px;
|
|
50
|
+
`;
|
|
51
|
+
const GaugeWrapper = styled_components_1.default.div `
|
|
52
|
+
display: flex;
|
|
53
|
+
flex-direction: row;
|
|
54
|
+
height: 10px;
|
|
55
|
+
width: 100%;
|
|
56
|
+
`;
|
|
57
|
+
const GaugeChunk = styled_components_1.default.div `
|
|
58
|
+
width: ${(props) => props.share}%;
|
|
59
|
+
background-color: ${(props) => props.color};
|
|
60
|
+
height: 10px;
|
|
61
|
+
`;
|
|
62
|
+
//# sourceMappingURL=Gauge.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
export interface StatusByLevelWidgetProps {
|
|
3
|
+
title: string;
|
|
4
|
+
levels: {
|
|
5
|
+
name: string;
|
|
6
|
+
errors: number;
|
|
7
|
+
warnings: number;
|
|
8
|
+
total: number;
|
|
9
|
+
}[];
|
|
10
|
+
className?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function StatusByLevelWidget(props: StatusByLevelWidgetProps): JSX.Element;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
exports.StatusByLevelWidget = void 0;
|
|
30
|
+
const React = __importStar(require("react"));
|
|
31
|
+
const styled_components_1 = __importDefault(require("styled-components"));
|
|
32
|
+
const Gauge_1 = require("../../components/Scorecard/Gauge");
|
|
33
|
+
const Card_1 = require("../../components/Scorecard/Card");
|
|
34
|
+
function StatusByLevelWidget(props) {
|
|
35
|
+
const { levels, title, className } = props;
|
|
36
|
+
return (React.createElement(Card_1.ScorecardCard, { "data-component-name": "Scorecard/StatusByLevelWidget", className: className },
|
|
37
|
+
React.createElement(Card_1.ScorecardCardTitle, null, title),
|
|
38
|
+
React.createElement(CardBody, null, levels.map((level) => {
|
|
39
|
+
const success = level.total - level.errors - level.warnings;
|
|
40
|
+
return (React.createElement(CardRow, { key: level.name },
|
|
41
|
+
React.createElement("span", null, level.name),
|
|
42
|
+
React.createElement(Gauge_1.Gauge, { chunks: [
|
|
43
|
+
{
|
|
44
|
+
share: (success / level.total) * 100,
|
|
45
|
+
color: 'var(--scorecard-color-success)',
|
|
46
|
+
title: `${success} passed`,
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
share: (level.warnings / level.total) * 100,
|
|
50
|
+
color: 'var(--scorecard-color-warning)',
|
|
51
|
+
title: `${level.warnings} ${level.warnings === 1 ? 'warning' : 'warnings'}`,
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
share: (level.errors / level.total) * 100,
|
|
55
|
+
color: 'var(--scorecard-color-error)',
|
|
56
|
+
title: `${level.errors} ${level.errors === 1 ? 'error' : 'errors'}`,
|
|
57
|
+
},
|
|
58
|
+
] }),
|
|
59
|
+
React.createElement(Gauge_1.GaugeValue, null,
|
|
60
|
+
success,
|
|
61
|
+
"/",
|
|
62
|
+
level.total)));
|
|
63
|
+
}))));
|
|
64
|
+
}
|
|
65
|
+
exports.StatusByLevelWidget = StatusByLevelWidget;
|
|
66
|
+
const CardBody = styled_components_1.default.div `
|
|
67
|
+
display: flex;
|
|
68
|
+
flex-direction: column;
|
|
69
|
+
gap: 5px;
|
|
70
|
+
`;
|
|
71
|
+
const CardRow = styled_components_1.default.div `
|
|
72
|
+
display: flex;
|
|
73
|
+
flex-direction: row;
|
|
74
|
+
gap: 10px;
|
|
75
|
+
|
|
76
|
+
align-items: center;
|
|
77
|
+
|
|
78
|
+
> span:first-child {
|
|
79
|
+
text-align: right;
|
|
80
|
+
width: 100px;
|
|
81
|
+
}
|
|
82
|
+
`;
|
|
83
|
+
//# sourceMappingURL=StatusByLevelWidget.js.map
|
package/lib/config.d.ts
CHANGED
|
@@ -309,6 +309,9 @@ declare const scorecardConfigSchema: {
|
|
|
309
309
|
readonly name: {
|
|
310
310
|
readonly type: "string";
|
|
311
311
|
};
|
|
312
|
+
readonly color: {
|
|
313
|
+
readonly type: "string";
|
|
314
|
+
};
|
|
312
315
|
readonly extends: {
|
|
313
316
|
readonly type: "array";
|
|
314
317
|
readonly items: {
|
|
@@ -1862,6 +1865,9 @@ export declare const themeConfigSchema: {
|
|
|
1862
1865
|
readonly name: {
|
|
1863
1866
|
readonly type: "string";
|
|
1864
1867
|
};
|
|
1868
|
+
readonly color: {
|
|
1869
|
+
readonly type: "string";
|
|
1870
|
+
};
|
|
1865
1871
|
readonly extends: {
|
|
1866
1872
|
readonly type: "array";
|
|
1867
1873
|
readonly items: {
|
package/lib/config.js
CHANGED
package/lib/globalStyle.js
CHANGED
|
@@ -27,7 +27,7 @@ const Tooltip_1 = require("./components/Tooltip");
|
|
|
27
27
|
const LastUpdated_1 = require("./components/LastUpdated");
|
|
28
28
|
const NavbarLogo_1 = require("./components/NavbarLogo");
|
|
29
29
|
const themeColors = (0, styled_components_1.css) `
|
|
30
|
-
/* === Palette === */
|
|
30
|
+
/* === Palette === */
|
|
31
31
|
/**
|
|
32
32
|
* @tokens Base Colors
|
|
33
33
|
* @presenter Color
|
|
@@ -290,8 +290,8 @@ const typography = (0, styled_components_1.css) `
|
|
|
290
290
|
* @tokens Font Rendering
|
|
291
291
|
*/
|
|
292
292
|
|
|
293
|
-
|
|
294
|
-
|
|
293
|
+
--text-smoothing: antialiased; // text-smoothing
|
|
294
|
+
--text-rendering: optimizeSpeed; // text-rendering
|
|
295
295
|
|
|
296
296
|
// @tokens End
|
|
297
297
|
`;
|
|
@@ -385,7 +385,6 @@ const headingsTypography = (0, styled_components_1.css) `
|
|
|
385
385
|
--heading-anchor-color: var(--color-primary); // @presenter Color
|
|
386
386
|
--heading-anchor-icon: none;
|
|
387
387
|
|
|
388
|
-
|
|
389
388
|
/**
|
|
390
389
|
* @tokens Heading level 1
|
|
391
390
|
*/
|
|
@@ -702,7 +701,6 @@ const badges = (0, styled_components_1.css) `
|
|
|
702
701
|
--badge-deprecated-border: 1px solid var(--badge-deprecated-border-color); // @presenter Border
|
|
703
702
|
--badge-deprecated-border-radius: var(--border-radius); // @presenter BorderRadius
|
|
704
703
|
|
|
705
|
-
|
|
706
704
|
// @tokens End
|
|
707
705
|
`;
|
|
708
706
|
const loadProgressBar = (0, styled_components_1.css) `
|
|
@@ -788,7 +786,8 @@ const docsDropdown = (0, styled_components_1.css) `
|
|
|
788
786
|
--docs-dropdown-padding-vertical: 6px;
|
|
789
787
|
--docs-dropdown-padding-left: 10px;
|
|
790
788
|
--docs-dropdown-padding-right: 26px;
|
|
791
|
-
--docs-dropdown-padding: var(--docs-dropdown-padding-vertical) var(--docs-dropdown-padding-right)
|
|
789
|
+
--docs-dropdown-padding: var(--docs-dropdown-padding-vertical) var(--docs-dropdown-padding-right)
|
|
790
|
+
var(--docs-dropdown-padding-vertical) var(--docs-dropdown-padding-left);
|
|
792
791
|
--docs-dropdown-border: 1px solid var(--border-primary);
|
|
793
792
|
`;
|
|
794
793
|
const tile = (0, styled_components_1.css) `
|
|
@@ -839,11 +838,11 @@ const pages = (0, styled_components_1.css) `
|
|
|
839
838
|
--page-403-description-margin: 0; // @presenter Spacing
|
|
840
839
|
|
|
841
840
|
--page-403-button-margin: 4em; // @presenter Spacing
|
|
842
|
-
|
|
841
|
+
|
|
843
842
|
--page-403-oidc-description-font-size: var(--font-size-lg);
|
|
844
843
|
--page-403-oidc-description-margin: var(--spacing-md) var(--spacing-sm);
|
|
845
844
|
|
|
846
|
-
|
|
845
|
+
// @tokens End
|
|
847
846
|
`;
|
|
848
847
|
const error = (0, styled_components_1.css) `
|
|
849
848
|
--error-bubble-padding: var(--spacing-md);
|
|
@@ -914,6 +913,11 @@ const zIndexDepth = (0, styled_components_1.css) `
|
|
|
914
913
|
--z-index-popover: 200;
|
|
915
914
|
--z-index-overlay: 1000;
|
|
916
915
|
`;
|
|
916
|
+
const scorecardColors = (0, styled_components_1.css) `
|
|
917
|
+
--scorecard-color-error: var(--color-error);
|
|
918
|
+
--scorecard-color-warning: var(--color-warning);
|
|
919
|
+
--scorecard-color-success: var(--color-green-7);
|
|
920
|
+
`;
|
|
917
921
|
exports.styles = (0, styled_components_1.css) `
|
|
918
922
|
:root {
|
|
919
923
|
${Markdown_1.admonition}
|
|
@@ -961,6 +965,7 @@ exports.styles = (0, styled_components_1.css) `
|
|
|
961
965
|
${Profile_1.userProfileDropdown}
|
|
962
966
|
${Sidebar_1.versionPicker}
|
|
963
967
|
${zIndexDepth}
|
|
968
|
+
${scorecardColors}
|
|
964
969
|
|
|
965
970
|
--api-catalog-card-min-width: 250px;
|
|
966
971
|
|
package/package.json
CHANGED
|
@@ -299,9 +299,12 @@ function collectFilterOptions(
|
|
|
299
299
|
}
|
|
300
300
|
}
|
|
301
301
|
|
|
302
|
-
const options = Object.entries(usedOptions)
|
|
303
|
-
|
|
304
|
-
|
|
302
|
+
const options = Object.entries(usedOptions).map(([value, count]) => ({ value, count }));
|
|
303
|
+
|
|
304
|
+
if (!staticOptions) {
|
|
305
|
+
options.sort((a, b) => b.value.localeCompare(a.value));
|
|
306
|
+
}
|
|
307
|
+
|
|
305
308
|
if (othersCount) {
|
|
306
309
|
options.push({
|
|
307
310
|
value: filter.missingCategoryNameTranslationKey || filter.missingCategoryName || 'Others',
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import styled from 'styled-components';
|
|
2
|
+
|
|
3
|
+
export const ScorecardCard = styled.div.attrs({
|
|
4
|
+
'data-component-name': 'Scorecard/ScorecardCard',
|
|
5
|
+
})`
|
|
6
|
+
color: var(--text-primary);
|
|
7
|
+
background-color: var(--bg-raised);
|
|
8
|
+
border-radius: 4px;
|
|
9
|
+
|
|
10
|
+
border: 1px solid var(--border-primary);
|
|
11
|
+
box-shadow: 0 0 10px 0 rgba(35, 35, 35, 0.05);
|
|
12
|
+
|
|
13
|
+
flex: 1;
|
|
14
|
+
min-width: 300px;
|
|
15
|
+
padding: 20px;
|
|
16
|
+
`;
|
|
17
|
+
|
|
18
|
+
export const ScorecardCardTitle = styled.h3`
|
|
19
|
+
font-size: 1.2rem;
|
|
20
|
+
font-weight: bold;
|
|
21
|
+
margin-bottom: 10px;
|
|
22
|
+
margin-top: 0;
|
|
23
|
+
`;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import styled from 'styled-components';
|
|
3
|
+
export interface GaugeProps {
|
|
4
|
+
chunks: {
|
|
5
|
+
share: number;
|
|
6
|
+
color: string;
|
|
7
|
+
title?: string;
|
|
8
|
+
}[];
|
|
9
|
+
className?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function Gauge({ chunks, className }: GaugeProps) {
|
|
13
|
+
const title = chunks
|
|
14
|
+
.map((chunk) => chunk.title)
|
|
15
|
+
.filter(Boolean)
|
|
16
|
+
.join(', ');
|
|
17
|
+
return (
|
|
18
|
+
<GaugeWrapper
|
|
19
|
+
data-component-name="Scorecard/StatusByLevelWidget"
|
|
20
|
+
className={className}
|
|
21
|
+
title={title}
|
|
22
|
+
>
|
|
23
|
+
{chunks.map((chunk, i) => (
|
|
24
|
+
<GaugeChunk key={i} share={chunk.share} color={chunk.color} />
|
|
25
|
+
))}
|
|
26
|
+
</GaugeWrapper>
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export const GaugeValue = styled.span`
|
|
31
|
+
font-size: var(--font-size-lg);
|
|
32
|
+
line-height: var(line-height-regular);
|
|
33
|
+
|
|
34
|
+
margin-right: 5px;
|
|
35
|
+
vertical-align: middle;
|
|
36
|
+
display: inline-block;
|
|
37
|
+
margin-right: 0;
|
|
38
|
+
text-align: right;
|
|
39
|
+
width: 70px;
|
|
40
|
+
`;
|
|
41
|
+
|
|
42
|
+
const GaugeWrapper = styled.div`
|
|
43
|
+
display: flex;
|
|
44
|
+
flex-direction: row;
|
|
45
|
+
height: 10px;
|
|
46
|
+
width: 100%;
|
|
47
|
+
`;
|
|
48
|
+
|
|
49
|
+
const GaugeChunk = styled.div<{ share: number; color: string }>`
|
|
50
|
+
width: ${(props) => props.share}%;
|
|
51
|
+
background-color: ${(props) => props.color};
|
|
52
|
+
height: 10px;
|
|
53
|
+
`;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import styled from 'styled-components';
|
|
3
|
+
|
|
4
|
+
import { Gauge, GaugeValue } from '@theme/components/Scorecard/Gauge';
|
|
5
|
+
import { ScorecardCard, ScorecardCardTitle } from '@theme/components/Scorecard/Card';
|
|
6
|
+
|
|
7
|
+
export interface StatusByLevelWidgetProps {
|
|
8
|
+
title: string;
|
|
9
|
+
levels: { name: string; errors: number; warnings: number; total: number }[];
|
|
10
|
+
className?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function StatusByLevelWidget(props: StatusByLevelWidgetProps) {
|
|
14
|
+
const { levels, title, className } = props;
|
|
15
|
+
return (
|
|
16
|
+
<ScorecardCard data-component-name="Scorecard/StatusByLevelWidget" className={className}>
|
|
17
|
+
<ScorecardCardTitle>{title}</ScorecardCardTitle>
|
|
18
|
+
<CardBody>
|
|
19
|
+
{levels.map((level) => {
|
|
20
|
+
const success = level.total - level.errors - level.warnings;
|
|
21
|
+
return (
|
|
22
|
+
<CardRow key={level.name}>
|
|
23
|
+
<span>{level.name}</span>
|
|
24
|
+
<Gauge
|
|
25
|
+
chunks={[
|
|
26
|
+
{
|
|
27
|
+
share: (success / level.total) * 100,
|
|
28
|
+
color: 'var(--scorecard-color-success)',
|
|
29
|
+
title: `${success} passed`,
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
share: (level.warnings / level.total) * 100,
|
|
33
|
+
color: 'var(--scorecard-color-warning)',
|
|
34
|
+
title: `${level.warnings} ${level.warnings === 1 ? 'warning' : 'warnings'}`,
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
share: (level.errors / level.total) * 100,
|
|
38
|
+
color: 'var(--scorecard-color-error)',
|
|
39
|
+
title: `${level.errors} ${level.errors === 1 ? 'error' : 'errors'}`,
|
|
40
|
+
},
|
|
41
|
+
]}
|
|
42
|
+
/>
|
|
43
|
+
<GaugeValue>
|
|
44
|
+
{success}/{level.total}
|
|
45
|
+
</GaugeValue>
|
|
46
|
+
</CardRow>
|
|
47
|
+
);
|
|
48
|
+
})}
|
|
49
|
+
</CardBody>
|
|
50
|
+
</ScorecardCard>
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const CardBody = styled.div`
|
|
55
|
+
display: flex;
|
|
56
|
+
flex-direction: column;
|
|
57
|
+
gap: 5px;
|
|
58
|
+
`;
|
|
59
|
+
|
|
60
|
+
const CardRow = styled.div`
|
|
61
|
+
display: flex;
|
|
62
|
+
flex-direction: row;
|
|
63
|
+
gap: 10px;
|
|
64
|
+
|
|
65
|
+
align-items: center;
|
|
66
|
+
|
|
67
|
+
> span:first-child {
|
|
68
|
+
text-align: right;
|
|
69
|
+
width: 100px;
|
|
70
|
+
}
|
|
71
|
+
`;
|
package/src/config.ts
CHANGED
package/src/globalStyle.ts
CHANGED
|
@@ -2,17 +2,17 @@ import { createGlobalStyle, css } from 'styled-components';
|
|
|
2
2
|
|
|
3
3
|
import { darkMode } from '@theme/ui/darkColors';
|
|
4
4
|
import { breakpoints } from '@portal/media-css';
|
|
5
|
-
import { footer } from
|
|
6
|
-
import { sidebar, versionPicker } from
|
|
7
|
-
import { breadcrumbs } from
|
|
5
|
+
import { footer } from '@theme/components/Footer';
|
|
6
|
+
import { sidebar, versionPicker } from '@theme/components/Sidebar';
|
|
7
|
+
import { breadcrumbs } from '@theme/components/Breadcrumbs';
|
|
8
8
|
import { button } from '@theme/components/Button';
|
|
9
9
|
import { tag } from '@theme/components/Tag';
|
|
10
10
|
import { toc } from '@theme/components/TableOfContent';
|
|
11
|
-
import { navbar } from
|
|
12
|
-
import { search } from
|
|
13
|
-
import { catalog } from
|
|
14
|
-
import { filter } from
|
|
15
|
-
import { menu, mobileMenu } from
|
|
11
|
+
import { navbar } from '@theme/components/Navbar';
|
|
12
|
+
import { search } from '@theme/components/Search';
|
|
13
|
+
import { catalog } from '@theme/components/Catalog';
|
|
14
|
+
import { filter } from '@theme/components/Filter';
|
|
15
|
+
import { menu, mobileMenu } from '@theme/components/Menu';
|
|
16
16
|
import { apiReferencePanels, responsePanelColors } from '@theme/components/Panel';
|
|
17
17
|
import { code } from '@theme/components/CodeBlock';
|
|
18
18
|
import { product, productPicker } from '@theme/components/Product';
|
|
@@ -26,7 +26,7 @@ import { lastUpdated } from '@theme/components/LastUpdated';
|
|
|
26
26
|
import { logo } from '@theme/components/NavbarLogo';
|
|
27
27
|
|
|
28
28
|
const themeColors = css`
|
|
29
|
-
/* === Palette === */
|
|
29
|
+
/* === Palette === */
|
|
30
30
|
/**
|
|
31
31
|
* @tokens Base Colors
|
|
32
32
|
* @presenter Color
|
|
@@ -290,8 +290,8 @@ const typography = css`
|
|
|
290
290
|
* @tokens Font Rendering
|
|
291
291
|
*/
|
|
292
292
|
|
|
293
|
-
|
|
294
|
-
|
|
293
|
+
--text-smoothing: antialiased; // text-smoothing
|
|
294
|
+
--text-rendering: optimizeSpeed; // text-rendering
|
|
295
295
|
|
|
296
296
|
// @tokens End
|
|
297
297
|
`;
|
|
@@ -363,7 +363,7 @@ const borders = css`
|
|
|
363
363
|
--border-radius-md: calc(var(--border-radius) * 1.5);
|
|
364
364
|
--border-radius-lg: calc(var(--border-radius) * 2);
|
|
365
365
|
--border-radius-xlg: calc(var(--border-radius) * 3);
|
|
366
|
-
|
|
366
|
+
`;
|
|
367
367
|
|
|
368
368
|
const headingsTypography = css`
|
|
369
369
|
* {
|
|
@@ -388,7 +388,6 @@ const headingsTypography = css`
|
|
|
388
388
|
--heading-anchor-color: var(--color-primary); // @presenter Color
|
|
389
389
|
--heading-anchor-icon: none;
|
|
390
390
|
|
|
391
|
-
|
|
392
391
|
/**
|
|
393
392
|
* @tokens Heading level 1
|
|
394
393
|
*/
|
|
@@ -708,7 +707,6 @@ const badges = css`
|
|
|
708
707
|
--badge-deprecated-border: 1px solid var(--badge-deprecated-border-color); // @presenter Border
|
|
709
708
|
--badge-deprecated-border-radius: var(--border-radius); // @presenter BorderRadius
|
|
710
709
|
|
|
711
|
-
|
|
712
710
|
// @tokens End
|
|
713
711
|
`;
|
|
714
712
|
|
|
@@ -797,7 +795,8 @@ const docsDropdown = css`
|
|
|
797
795
|
--docs-dropdown-padding-vertical: 6px;
|
|
798
796
|
--docs-dropdown-padding-left: 10px;
|
|
799
797
|
--docs-dropdown-padding-right: 26px;
|
|
800
|
-
--docs-dropdown-padding: var(--docs-dropdown-padding-vertical) var(--docs-dropdown-padding-right)
|
|
798
|
+
--docs-dropdown-padding: var(--docs-dropdown-padding-vertical) var(--docs-dropdown-padding-right)
|
|
799
|
+
var(--docs-dropdown-padding-vertical) var(--docs-dropdown-padding-left);
|
|
801
800
|
--docs-dropdown-border: 1px solid var(--border-primary);
|
|
802
801
|
`;
|
|
803
802
|
|
|
@@ -850,12 +849,12 @@ const pages = css`
|
|
|
850
849
|
--page-403-description-margin: 0; // @presenter Spacing
|
|
851
850
|
|
|
852
851
|
--page-403-button-margin: 4em; // @presenter Spacing
|
|
853
|
-
|
|
852
|
+
|
|
854
853
|
--page-403-oidc-description-font-size: var(--font-size-lg);
|
|
855
854
|
--page-403-oidc-description-margin: var(--spacing-md) var(--spacing-sm);
|
|
856
855
|
|
|
857
|
-
|
|
858
|
-
|
|
856
|
+
// @tokens End
|
|
857
|
+
`;
|
|
859
858
|
|
|
860
859
|
const error = css`
|
|
861
860
|
--error-bubble-padding: var(--spacing-md);
|
|
@@ -929,6 +928,12 @@ const zIndexDepth = css`
|
|
|
929
928
|
--z-index-overlay: 1000;
|
|
930
929
|
`;
|
|
931
930
|
|
|
931
|
+
const scorecardColors = css`
|
|
932
|
+
--scorecard-color-error: var(--color-error);
|
|
933
|
+
--scorecard-color-warning: var(--color-warning);
|
|
934
|
+
--scorecard-color-success: var(--color-green-7);
|
|
935
|
+
`;
|
|
936
|
+
|
|
932
937
|
export const styles = css`
|
|
933
938
|
:root {
|
|
934
939
|
${admonition}
|
|
@@ -976,6 +981,7 @@ export const styles = css`
|
|
|
976
981
|
${userProfileDropdown}
|
|
977
982
|
${versionPicker}
|
|
978
983
|
${zIndexDepth}
|
|
984
|
+
${scorecardColors}
|
|
979
985
|
|
|
980
986
|
--api-catalog-card-min-width: 250px;
|
|
981
987
|
|