mirror of
https://github.com/turbot/steampipe.git
synced 2025-12-19 18:12:43 -05:00
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -26,9 +26,10 @@
|
|||||||
/ui/dashboard/.vscode
|
/ui/dashboard/.vscode
|
||||||
/ui/dashboard/build
|
/ui/dashboard/build
|
||||||
/ui/dashboard/node_modules
|
/ui/dashboard/node_modules
|
||||||
|
/ui/dashboard/src/icons/materialSymbols.ts
|
||||||
/ui/dashboard/output
|
/ui/dashboard/output
|
||||||
/ui/dashboard/yarn-debug.log*
|
/ui/dashboard/yarn-debug.log*
|
||||||
/ui/dashboard/yarn-error.log*
|
/ui/dashboard/yarn-error.log*
|
||||||
|
|
||||||
# Dist directory is created by goreleaser
|
# Dist directory is created by goreleaser
|
||||||
/dist
|
/dist
|
||||||
|
|||||||
@@ -4,18 +4,22 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
"prestart": "node scripts/setupMaterialSymbols.js",
|
||||||
"start": "if-node-version '>= 17' && craco --openssl-legacy-provider start || craco start",
|
"start": "if-node-version '>= 17' && craco --openssl-legacy-provider start || craco start",
|
||||||
|
"prebuid": "node scripts/setupMaterialSymbols.js",
|
||||||
"build": "GENERATE_SOURCEMAP=false if-node-version '>= 17' && craco --openssl-legacy-provider build || craco build",
|
"build": "GENERATE_SOURCEMAP=false if-node-version '>= 17' && craco --openssl-legacy-provider build || craco build",
|
||||||
"test": "craco test",
|
"test": "craco test",
|
||||||
"eject": "react-scripts eject",
|
"eject": "react-scripts eject",
|
||||||
"prettify": "prettier --write \"src/**/*.{js,jsx,ts,tsx,json,css,scss,md}\"",
|
"prettify": "prettier --write \"src/**/*.{js,jsx,ts,tsx,json,css,scss,md}\"",
|
||||||
"analyze": "source-map-explorer 'build/static/js/*.js'",
|
"analyze": "source-map-explorer 'build/static/js/*.js'",
|
||||||
"storybook": "start-storybook -p 6006 -s public",
|
"prestorybook": "node scripts/setupMaterialSymbols.js",
|
||||||
|
"storybook": "NODE_OPTIONS=--openssl-legacy-provider start-storybook -p 6006 -s public",
|
||||||
"build-storybook": "build-storybook -s public"
|
"build-storybook": "build-storybook -s public"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@headlessui/react": "1.7.4",
|
"@headlessui/react": "1.7.4",
|
||||||
"@heroicons/react": "2.0.13",
|
"@heroicons/react": "2.0.13",
|
||||||
|
"@material-symbols/svg-200": "0.4.1",
|
||||||
"@popperjs/core": "2.11.6",
|
"@popperjs/core": "2.11.6",
|
||||||
"@supabase/sql-formatter": "4.0.3",
|
"@supabase/sql-formatter": "4.0.3",
|
||||||
"color-convert": "2.0.1",
|
"color-convert": "2.0.1",
|
||||||
@@ -51,16 +55,16 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@craco/craco": "7.0.0",
|
"@craco/craco": "7.0.0",
|
||||||
"@storybook/addon-actions": "6.5.13",
|
"@storybook/addon-actions": "6.5.14",
|
||||||
"@storybook/addon-essentials": "6.5.13",
|
"@storybook/addon-essentials": "6.5.14",
|
||||||
"@storybook/addon-links": "6.5.13",
|
"@storybook/addon-links": "6.5.14",
|
||||||
"@storybook/addons": "6.5.13",
|
"@storybook/addons": "6.5.14",
|
||||||
"@storybook/builder-webpack5": "6.5.13",
|
"@storybook/builder-webpack5": "6.5.14",
|
||||||
"@storybook/manager-webpack5": "6.5.13",
|
"@storybook/manager-webpack5": "6.5.14",
|
||||||
"@storybook/node-logger": "6.5.13",
|
"@storybook/node-logger": "6.5.14",
|
||||||
"@storybook/preset-create-react-app": "4.1.2",
|
"@storybook/preset-create-react-app": "4.1.2",
|
||||||
"@storybook/react": "6.5.13",
|
"@storybook/react": "6.5.14",
|
||||||
"@storybook/theming": "6.5.13",
|
"@storybook/theming": "6.5.14",
|
||||||
"@tailwindcss/forms": "0.5.3",
|
"@tailwindcss/forms": "0.5.3",
|
||||||
"@tailwindcss/line-clamp": "0.4.2",
|
"@tailwindcss/line-clamp": "0.4.2",
|
||||||
"@tailwindcss/typography": "0.5.8",
|
"@tailwindcss/typography": "0.5.8",
|
||||||
@@ -68,15 +72,15 @@
|
|||||||
"@testing-library/react": "13.4.0",
|
"@testing-library/react": "13.4.0",
|
||||||
"@tsconfig/create-react-app": "1.0.3",
|
"@tsconfig/create-react-app": "1.0.3",
|
||||||
"@types/echarts": "4.9.16",
|
"@types/echarts": "4.9.16",
|
||||||
"@types/jest": "29.2.3",
|
"@types/jest": "29.2.4",
|
||||||
"@types/lodash": "4.14.191",
|
"@types/lodash": "4.14.191",
|
||||||
"@types/node": "18.11.10",
|
"@types/node": "18.11.11",
|
||||||
"@types/react": "18.0.25",
|
"@types/react": "18.0.26",
|
||||||
"@types/react-dom": "18.0.9",
|
"@types/react-dom": "18.0.9",
|
||||||
"autoprefixer": "10.4.13",
|
"autoprefixer": "10.4.13",
|
||||||
"circular-dependency-plugin": "5.2.2",
|
"circular-dependency-plugin": "5.2.2",
|
||||||
"if-node-version": "1.1.1",
|
"if-node-version": "1.1.1",
|
||||||
"lint-staged": "13.0.4",
|
"lint-staged": "13.1.0",
|
||||||
"npm-run-all": "4.1.5",
|
"npm-run-all": "4.1.5",
|
||||||
"prettier": "2.8.0",
|
"prettier": "2.8.0",
|
||||||
"process": "0.11.10",
|
"process": "0.11.10",
|
||||||
@@ -84,7 +88,7 @@
|
|||||||
"react-scripts": "5.0.1",
|
"react-scripts": "5.0.1",
|
||||||
"source-map-explorer": "2.5.3",
|
"source-map-explorer": "2.5.3",
|
||||||
"storybook-addon-react-router-v6": "0.2.1",
|
"storybook-addon-react-router-v6": "0.2.1",
|
||||||
"storybook-dark-mode": "1.1.2",
|
"storybook-dark-mode": "2.0.3",
|
||||||
"tailwindcss": "3.2.4",
|
"tailwindcss": "3.2.4",
|
||||||
"typescript": "4.5.5"
|
"typescript": "4.5.5"
|
||||||
},
|
},
|
||||||
|
|||||||
49
ui/dashboard/scripts/setupMaterialSymbols.js
Normal file
49
ui/dashboard/scripts/setupMaterialSymbols.js
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
const camelCase = require("lodash/camelCase");
|
||||||
|
const fs = require("fs-extra");
|
||||||
|
const upperFirst = require("lodash/upperFirst");
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
const nodeModulesPath = "@material-symbols/svg-200/rounded";
|
||||||
|
const dir = await fs.readdir("./node_modules/" + nodeModulesPath);
|
||||||
|
let generatedFile = "// @ts-nocheck\n";
|
||||||
|
const outlineIcons = {};
|
||||||
|
const solidIcons = {};
|
||||||
|
for (const file of dir) {
|
||||||
|
const fileNameParts = file.split(".");
|
||||||
|
let importName = upperFirst(camelCase(fileNameParts[0]));
|
||||||
|
if (/^\d/.test(importName)) {
|
||||||
|
importName = "_" + importName;
|
||||||
|
}
|
||||||
|
const nameAndStyleParts = fileNameParts[0].split("-");
|
||||||
|
const nameKebab = nameAndStyleParts[0].replaceAll("_", "-");
|
||||||
|
const isFillIcon =
|
||||||
|
nameAndStyleParts.length === 2 && nameAndStyleParts[1] === "fill";
|
||||||
|
|
||||||
|
if (isFillIcon) {
|
||||||
|
solidIcons[nameKebab] = {
|
||||||
|
component: importName,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
outlineIcons[nameKebab] = {
|
||||||
|
component: importName,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
generatedFile += `import { ReactComponent as ${importName} } from "${nodeModulesPath}/${file}";\n`;
|
||||||
|
}
|
||||||
|
generatedFile += "\n";
|
||||||
|
generatedFile += "const icons = {\n";
|
||||||
|
for (const [name, definition] of Object.entries(outlineIcons)) {
|
||||||
|
generatedFile += ` "${name}": ${definition.component},\n`;
|
||||||
|
generatedFile += ` "materialsymbols-outline:${name}": ${definition.component},\n`;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [name, definition] of Object.entries(solidIcons)) {
|
||||||
|
generatedFile += ` "materialsymbols-solid:${name}": ${definition.component},\n`;
|
||||||
|
}
|
||||||
|
generatedFile += "}\n\n";
|
||||||
|
generatedFile += "export {\n";
|
||||||
|
generatedFile += " icons,\n";
|
||||||
|
generatedFile += "}";
|
||||||
|
|
||||||
|
await fs.writeFile("./src/icons/materialSymbols.ts", generatedFile);
|
||||||
|
})();
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
import { getDashboardIconName } from "./";
|
|
||||||
|
|
||||||
describe("common.adjustMinValue", () => {
|
|
||||||
test("null returns null", () => {
|
|
||||||
expect(getDashboardIconName(null)).toEqual(null);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("undefined returns null", () => {
|
|
||||||
expect(getDashboardIconName(undefined)).toEqual(null);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("existing icon not mapped", () => {
|
|
||||||
expect(getDashboardIconName("bell")).toEqual("bell");
|
|
||||||
});
|
|
||||||
|
|
||||||
test("existing namespaced icon not mapped", () => {
|
|
||||||
expect(getDashboardIconName("heroicons-outline:bell")).toEqual(
|
|
||||||
"heroicons-outline:bell"
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("migrated icon mapped", () => {
|
|
||||||
expect(getDashboardIconName("search")).toEqual("magnifying-glass");
|
|
||||||
});
|
|
||||||
|
|
||||||
test("prefixed migrated icon mapped", () => {
|
|
||||||
expect(getDashboardIconName("heroicons-solid:search")).toEqual(
|
|
||||||
"heroicons-solid:magnifying-glass"
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,179 +1,4 @@
|
|||||||
import kebabCase from "lodash/kebabCase";
|
import useDashboardIcons from "../../hooks/useDashboardIcons";
|
||||||
import * as outlineIconExports from "@heroicons/react/24/outline";
|
|
||||||
import * as solidIconExports from "@heroicons/react/24/solid";
|
|
||||||
|
|
||||||
const icons = {};
|
|
||||||
|
|
||||||
const migratedV2IconNames = {
|
|
||||||
adjustments: "adjustments-vertical",
|
|
||||||
annotation: "chat-bubble-bottom-center-text",
|
|
||||||
archive: "archive-box",
|
|
||||||
"arrow-circle-down": "arrow-down-circle",
|
|
||||||
"arrow-circle-left": "arrow-left-circle",
|
|
||||||
"arrow-circle-right": "arrow-right-circle",
|
|
||||||
"arrow-circle-up": "arrow-up-circle",
|
|
||||||
"arrow-narrow-down": "arrow-long-down",
|
|
||||||
"arrow-narrow-left": "arrow-long-left",
|
|
||||||
"arrow-narrow-right": "arrow-long-right",
|
|
||||||
"arrow-narrow-up": "arrow-long-up",
|
|
||||||
"arrow-sm-left": "arrow-small-left",
|
|
||||||
"arrow-sm-right": "arrow-small-right",
|
|
||||||
"arrow-sm-up": "arrow-small-up",
|
|
||||||
"arrow-sm-down": "arrow-small-down",
|
|
||||||
"arrows-expand": "arrows-pointing-out",
|
|
||||||
"badge-check": "check-badge",
|
|
||||||
ban: "no-symbol",
|
|
||||||
"bookmark-alt": "bookmark-square",
|
|
||||||
cash: "banknotes",
|
|
||||||
"chart-square-bar": "chart-bar-square",
|
|
||||||
"chat-alt-2": "chat-bubble-left-right",
|
|
||||||
"chat-alt": "chat-bubble-left-ellipsis",
|
|
||||||
chat: "chat-bubble-oval-left-ellipsis",
|
|
||||||
chip: "cpu-chip",
|
|
||||||
"clipboard-check": "clipboard-document-check",
|
|
||||||
"clipboard-copy": "clipboard-document",
|
|
||||||
"clipboard-list": "clipboard-document-list",
|
|
||||||
"cloud-download": "cloud-arrow-down",
|
|
||||||
"cloud-upload": "cloud-arrow-up",
|
|
||||||
code: "code-bracket",
|
|
||||||
collection: "rectangle-stack",
|
|
||||||
"color-swatch": "swatch",
|
|
||||||
"cursor-click": "cursor-arrow-rays",
|
|
||||||
database: "circle-stack",
|
|
||||||
"desktop-computer": "computer-desktop",
|
|
||||||
"device-mobile": "device-phone-mobile",
|
|
||||||
"document-add": "document-plus",
|
|
||||||
"document-download": "document-arrow-down",
|
|
||||||
"document-remove": "document-minus",
|
|
||||||
"document-report": "document-chart-bar",
|
|
||||||
"document-search": "document-magnifying-glass",
|
|
||||||
"dots-circle-horizontal": "ellipsis-horizontal-circle",
|
|
||||||
"dots-horizontal": "ellipsis-horizontal",
|
|
||||||
"dots-vertical": "ellipsis-vertical",
|
|
||||||
download: "arrow-down-tray",
|
|
||||||
duplicate: "square-2-stack",
|
|
||||||
"emoji-happy": "face-smile",
|
|
||||||
"emoji-sad": "face-frown",
|
|
||||||
exclamation: "exclamation-triangle",
|
|
||||||
"external-link": "arrow-top-right-on-square",
|
|
||||||
"eye-off": "eye-slash",
|
|
||||||
"fast-forward": "forward",
|
|
||||||
filter: "funnel",
|
|
||||||
"folder-add": "folder-plus",
|
|
||||||
"folder-download": "folder-arrow-down",
|
|
||||||
"folder-remove": "folder-minus",
|
|
||||||
globe: "globe-americas",
|
|
||||||
hand: "hand-raised",
|
|
||||||
"inbox-in": "inbox-arrow-down",
|
|
||||||
library: "building-library",
|
|
||||||
"lightning-bolt": "bolt",
|
|
||||||
"location-marker": "map-pin",
|
|
||||||
login: "arrow-left-on-rectangle",
|
|
||||||
logout: "arrow-right-on-rectangle",
|
|
||||||
"mail-open": "envelope-open",
|
|
||||||
mail: "envelope",
|
|
||||||
"menu-alt-1": "bars-3-center-left",
|
|
||||||
"menu-alt-2": "bars-3-bottom-left",
|
|
||||||
"menu-alt-3": "bars-3-bottom-right",
|
|
||||||
"menu-alt-4": "bars-2",
|
|
||||||
menu: "bars-3",
|
|
||||||
"minus-sm": "minus-small",
|
|
||||||
"music-note": "musical-note",
|
|
||||||
"office-building": "building-office",
|
|
||||||
"pencil-alt": "pencil-square",
|
|
||||||
"phone-incoming": "phone-arrow-down-left",
|
|
||||||
"phone-missed-call": "phone-x-mark",
|
|
||||||
"phone-outgoing": "phone-arrow-up-right",
|
|
||||||
photograph: "photo",
|
|
||||||
"plus-sm": "plus-small",
|
|
||||||
puzzle: "puzzle-piece",
|
|
||||||
qrcode: "qr-code",
|
|
||||||
"receipt-tax": "receipt-percent",
|
|
||||||
refresh: "arrow-path",
|
|
||||||
reply: "arrow-uturn-left",
|
|
||||||
rewind: "backward",
|
|
||||||
"save-as": "arrow-down-on-square-stack",
|
|
||||||
save: "arrow-down-on-square",
|
|
||||||
"search-circle": "magnifying-glass-circle",
|
|
||||||
search: "magnifying-glass",
|
|
||||||
selector: "chevron-up-down",
|
|
||||||
"sort-ascending": "bars-arrow-up",
|
|
||||||
"sort-descending": "bars-arrow-down",
|
|
||||||
speakerphone: "megaphone",
|
|
||||||
"status-offline": "signal-slash",
|
|
||||||
"status-online": "signal",
|
|
||||||
support: "lifebuoy",
|
|
||||||
"switch-horizontal": "arrow-right-left",
|
|
||||||
"switch-vertical": "arrow-up-down",
|
|
||||||
table: "table-cells",
|
|
||||||
template: "rectangle-group",
|
|
||||||
terminal: "command-line",
|
|
||||||
"thumb-down": "hand-thumb-down",
|
|
||||||
"thumb-up": "hand-thumb-up",
|
|
||||||
translate: "language",
|
|
||||||
"trending-down": "arrow-trending-down",
|
|
||||||
"trending-up": "arrow-trending-up",
|
|
||||||
upload: "arrow-up-tray",
|
|
||||||
"user-add": "user-plus",
|
|
||||||
"user-remove": "user-minus",
|
|
||||||
"view-boards": "view-columns",
|
|
||||||
"view-grid-add": "squares-plus",
|
|
||||||
"view-grid": "squares-2x2",
|
|
||||||
"view-list": "bars-4",
|
|
||||||
"volume-off": "speaker-x-mark",
|
|
||||||
"volume-up": "speaker-wave",
|
|
||||||
x: "x-mark",
|
|
||||||
"zoom-in": "magnifying-glass-plus",
|
|
||||||
"zoom-out": "magnifying-glass-minus",
|
|
||||||
};
|
|
||||||
|
|
||||||
const kebabCaseExceptions = {
|
|
||||||
Square3Stack3D: "square-3-stack-3d",
|
|
||||||
Squares2X2: "squares-2x2",
|
|
||||||
};
|
|
||||||
|
|
||||||
const convertIconName = (name) => {
|
|
||||||
let condensedName = name;
|
|
||||||
const iconOccurrence = name.lastIndexOf("Icon");
|
|
||||||
if (iconOccurrence >= 0) {
|
|
||||||
condensedName = condensedName.substring(0, iconOccurrence);
|
|
||||||
}
|
|
||||||
return kebabCaseExceptions[condensedName] || kebabCase(condensedName);
|
|
||||||
};
|
|
||||||
|
|
||||||
const getDashboardIconName = (name?: string | null) => {
|
|
||||||
if (!name) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const parts = name.split(":");
|
|
||||||
if (parts.length === 1) {
|
|
||||||
const migratedV2IconName = migratedV2IconNames[parts[0]];
|
|
||||||
if (migratedV2IconName) {
|
|
||||||
return migratedV2IconName;
|
|
||||||
}
|
|
||||||
return name;
|
|
||||||
} else if (parts.length === 2) {
|
|
||||||
const migratedV2IconName = migratedV2IconNames[parts[1]];
|
|
||||||
if (migratedV2IconName) {
|
|
||||||
return [parts[0], migratedV2IconName].join(":");
|
|
||||||
}
|
|
||||||
return name;
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Object.entries(outlineIconExports).forEach(([name, exported]) => {
|
|
||||||
const iconName = convertIconName(name);
|
|
||||||
icons[iconName] = exported;
|
|
||||||
icons[`heroicons-outline:${iconName}`] = exported;
|
|
||||||
});
|
|
||||||
|
|
||||||
Object.entries(solidIconExports).forEach(([name, exported]) => {
|
|
||||||
const iconName = convertIconName(name);
|
|
||||||
icons[`heroicons-solid:${iconName}`] = exported;
|
|
||||||
});
|
|
||||||
|
|
||||||
interface IconProps {
|
interface IconProps {
|
||||||
className?: string;
|
className?: string;
|
||||||
@@ -183,13 +8,29 @@ interface IconProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const Icon = ({ className = "h-6 w-6", icon, style, title }: IconProps) => {
|
const Icon = ({ className = "h-6 w-6", icon, style, title }: IconProps) => {
|
||||||
const MatchingIcon = icons[getDashboardIconName(icon)];
|
const icons = useDashboardIcons();
|
||||||
|
let MatchingIcon = icons.materialSymbols[icon];
|
||||||
|
|
||||||
|
if (MatchingIcon) {
|
||||||
|
return (
|
||||||
|
<MatchingIcon
|
||||||
|
className={className}
|
||||||
|
style={{
|
||||||
|
fill: "currentColor",
|
||||||
|
color: style ? style.color : undefined,
|
||||||
|
}}
|
||||||
|
title={title}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
MatchingIcon = icons.heroIcons[icon];
|
||||||
|
}
|
||||||
|
|
||||||
if (!MatchingIcon) {
|
if (!MatchingIcon) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return <MatchingIcon className={className} style={style} title={title} />;
|
return <MatchingIcon className={className} style={style} title={title} />;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Icon;
|
export default Icon;
|
||||||
|
|
||||||
export { getDashboardIconName };
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ const SaveSnapshotButton = () => {
|
|||||||
<>
|
<>
|
||||||
<Icon
|
<Icon
|
||||||
className="inline-block text-foreground-lighter w-5 -mt-0.5"
|
className="inline-block text-foreground-lighter w-5 -mt-0.5"
|
||||||
icon="camera"
|
icon="heroicons-outline:camera"
|
||||||
/>
|
/>
|
||||||
<span className="hidden lg:block">Snap</span>
|
<span className="hidden lg:block">Snap</span>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import DashboardIcon from "../dashboards/common/DashboardIcon";
|
import DashboardIcon from "../dashboards/common/DashboardIcon";
|
||||||
|
import { classNames } from "../../utils/styles";
|
||||||
import { ThemeNames } from "../../hooks/useTheme";
|
import { ThemeNames } from "../../hooks/useTheme";
|
||||||
import { useDashboard } from "../../hooks/useDashboard";
|
import { useDashboard } from "../../hooks/useDashboard";
|
||||||
|
|
||||||
@@ -9,12 +10,12 @@ const ThemeToggle = () => {
|
|||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className={
|
className={classNames(
|
||||||
(theme.name === ThemeNames.STEAMPIPE_DEFAULT
|
theme.name === ThemeNames.STEAMPIPE_DEFAULT
|
||||||
? "bg-gray-200"
|
? "bg-gray-200"
|
||||||
: "bg-gray-500") +
|
: "bg-gray-500",
|
||||||
" relative inline-flex flex-shrink-0 h-6 w-11 border-2 border-transparent rounded-full cursor-pointer transition-colors ease-in-out duration-200 focus:outline-none focus:ring-1 focus:ring-offset-2 focus:ring-indigo-500"
|
"relative inline-flex flex-shrink-0 h-6 w-11 border-2 border-transparent rounded-full cursor-pointer transition-colors ease-in-out duration-200 focus:outline-none focus:ring-1 focus:ring-offset-2 focus:ring-indigo-500"
|
||||||
}
|
)}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
setTheme(
|
setTheme(
|
||||||
theme.name === ThemeNames.STEAMPIPE_DEFAULT
|
theme.name === ThemeNames.STEAMPIPE_DEFAULT
|
||||||
@@ -26,34 +27,40 @@ const ThemeToggle = () => {
|
|||||||
>
|
>
|
||||||
<span className="sr-only">Use setting</span>
|
<span className="sr-only">Use setting</span>
|
||||||
<span
|
<span
|
||||||
className={
|
className={classNames(
|
||||||
(theme.name === ThemeNames.STEAMPIPE_DEFAULT
|
theme.name === ThemeNames.STEAMPIPE_DEFAULT
|
||||||
? "translate-x-0"
|
? "translate-x-0"
|
||||||
: "translate-x-5") +
|
: "translate-x-5",
|
||||||
" pointer-events-none relative inline-block h-5 w-5 rounded-full bg-dashboard-panel shadow transform ring-0 transition ease-in-out duration-200"
|
"pointer-events-none relative inline-block h-5 w-5 rounded-full bg-dashboard-panel shadow transform ring-0 transition ease-in-out duration-200"
|
||||||
}
|
)}
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
className={
|
className={classNames(
|
||||||
(theme.name === ThemeNames.STEAMPIPE_DEFAULT
|
theme.name === ThemeNames.STEAMPIPE_DEFAULT
|
||||||
? "opacity-100 ease-in duration-200"
|
? "opacity-100 ease-in duration-200"
|
||||||
: "opacity-0 ease-out duration-100") +
|
: "opacity-0 ease-out duration-100",
|
||||||
" absolute inset-0 h-full w-full flex items-center justify-center transition-opacity text-gray-500"
|
"absolute inset-0 h-full w-full flex items-center justify-center transition-opacity"
|
||||||
}
|
)}
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
>
|
>
|
||||||
<DashboardIcon icon="heroicons-solid:sun" />
|
<DashboardIcon
|
||||||
|
className="text-gray-500"
|
||||||
|
icon="materialsymbols-solid:light-mode"
|
||||||
|
/>
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
className={
|
className={classNames(
|
||||||
(theme.name === ThemeNames.STEAMPIPE_DEFAULT
|
theme.name === ThemeNames.STEAMPIPE_DEFAULT
|
||||||
? "opacity-0 ease-out duration-100"
|
? "opacity-0 ease-out duration-100"
|
||||||
: "opacity-100 ease-in duration-200") +
|
: "opacity-100 ease-in duration-200",
|
||||||
" absolute inset-0 h-full w-full flex items-center justify-center transition-opacity text-gray-500"
|
"absolute inset-0 h-full w-full flex items-center justify-center transition-opacity"
|
||||||
}
|
)}
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
>
|
>
|
||||||
<DashboardIcon icon="heroicons-solid:moon" />
|
<DashboardIcon
|
||||||
|
className="text-gray-500"
|
||||||
|
icon="materialsymbols-solid:dark-mode"
|
||||||
|
/>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -27,40 +27,43 @@ LoadingCustomIcon.args = {
|
|||||||
export const LoadingOK = Template.bind({});
|
export const LoadingOK = Template.bind({});
|
||||||
LoadingOK.args = {
|
LoadingOK.args = {
|
||||||
data: null,
|
data: null,
|
||||||
properties: { type: "ok" },
|
display_type: "ok",
|
||||||
};
|
};
|
||||||
|
|
||||||
export const LoadingOKCustomIcon = Template.bind({});
|
export const LoadingOKCustomIcon = Template.bind({});
|
||||||
LoadingOKCustomIcon.storyName = "Loading OK (Custom Icon)";
|
LoadingOKCustomIcon.storyName = "Loading OK (Custom Icon)";
|
||||||
LoadingOKCustomIcon.args = {
|
LoadingOKCustomIcon.args = {
|
||||||
data: null,
|
data: null,
|
||||||
properties: { type: "ok", icon: "check-circle" },
|
display_type: "ok",
|
||||||
|
properties: { icon: "check-circle" },
|
||||||
};
|
};
|
||||||
|
|
||||||
export const LoadingAlert = Template.bind({});
|
export const LoadingAlert = Template.bind({});
|
||||||
LoadingAlert.args = {
|
LoadingAlert.args = {
|
||||||
data: null,
|
data: null,
|
||||||
properties: { type: "alert" },
|
display_type: "alert",
|
||||||
};
|
};
|
||||||
|
|
||||||
export const LoadingAlertCustomIcon = Template.bind({});
|
export const LoadingAlertCustomIcon = Template.bind({});
|
||||||
LoadingAlertCustomIcon.storyName = "Loading Alert (Custom Icon)";
|
LoadingAlertCustomIcon.storyName = "Loading Alert (Custom Icon)";
|
||||||
LoadingAlertCustomIcon.args = {
|
LoadingAlertCustomIcon.args = {
|
||||||
data: null,
|
data: null,
|
||||||
properties: { type: "alert", icon: "shield-exclamation" },
|
display_type: "alert",
|
||||||
|
properties: { icon: "shield-exclamation" },
|
||||||
};
|
};
|
||||||
|
|
||||||
export const LoadingInfo = Template.bind({});
|
export const LoadingInfo = Template.bind({});
|
||||||
LoadingInfo.args = {
|
LoadingInfo.args = {
|
||||||
data: null,
|
data: null,
|
||||||
properties: { type: "info" },
|
display_type: "info",
|
||||||
};
|
};
|
||||||
|
|
||||||
export const LoadingInfoCustomIcon = Template.bind({});
|
export const LoadingInfoCustomIcon = Template.bind({});
|
||||||
LoadingInfoCustomIcon.storyName = "Loading Info (Custom Icon)";
|
LoadingInfoCustomIcon.storyName = "Loading Info (Custom Icon)";
|
||||||
LoadingInfoCustomIcon.args = {
|
LoadingInfoCustomIcon.args = {
|
||||||
data: null,
|
data: null,
|
||||||
properties: { type: "info", icon: "light-bulb" },
|
display_type: "info",
|
||||||
|
properties: { icon: "light-bulb" },
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Error = Template.bind({});
|
export const Error = Template.bind({});
|
||||||
@@ -77,19 +80,19 @@ Empty.args = {
|
|||||||
export const EmptyOK = Template.bind({});
|
export const EmptyOK = Template.bind({});
|
||||||
EmptyOK.args = {
|
EmptyOK.args = {
|
||||||
data: [],
|
data: [],
|
||||||
properties: { type: "ok" },
|
display_type: "ok",
|
||||||
};
|
};
|
||||||
|
|
||||||
export const EmptyAlert = Template.bind({});
|
export const EmptyAlert = Template.bind({});
|
||||||
EmptyAlert.args = {
|
EmptyAlert.args = {
|
||||||
data: [],
|
data: [],
|
||||||
properties: { type: "alert" },
|
display_type: "alert",
|
||||||
};
|
};
|
||||||
|
|
||||||
export const EmptyInfo = Template.bind({});
|
export const EmptyInfo = Template.bind({});
|
||||||
EmptyInfo.args = {
|
EmptyInfo.args = {
|
||||||
data: [],
|
data: [],
|
||||||
properties: { type: "info" },
|
display_type: "info",
|
||||||
};
|
};
|
||||||
|
|
||||||
export const StringValue = Template.bind({});
|
export const StringValue = Template.bind({});
|
||||||
@@ -122,7 +125,7 @@ SimpleDataFormatOK.args = {
|
|||||||
columns: [{ name: "Encrypted EC2 Instances", data_type: "INT8" }],
|
columns: [{ name: "Encrypted EC2 Instances", data_type: "INT8" }],
|
||||||
rows: [{ "Encrypted EC2 Instances": 5 }],
|
rows: [{ "Encrypted EC2 Instances": 5 }],
|
||||||
},
|
},
|
||||||
properties: { type: "ok" },
|
display_type: "ok",
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SimpleDataFormatOKCustomIcon = Template.bind({});
|
export const SimpleDataFormatOKCustomIcon = Template.bind({});
|
||||||
@@ -132,7 +135,8 @@ SimpleDataFormatOKCustomIcon.args = {
|
|||||||
columns: [{ name: "Encrypted EC2 Instances", data_type: "INT8" }],
|
columns: [{ name: "Encrypted EC2 Instances", data_type: "INT8" }],
|
||||||
rows: [{ "Encrypted EC2 Instances": 5 }],
|
rows: [{ "Encrypted EC2 Instances": 5 }],
|
||||||
},
|
},
|
||||||
properties: { type: "ok", icon: "check-circle" },
|
display_type: "ok",
|
||||||
|
properties: { icon: "check-circle" },
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SimpleDataFormatAlert = Template.bind({});
|
export const SimpleDataFormatAlert = Template.bind({});
|
||||||
@@ -141,7 +145,7 @@ SimpleDataFormatAlert.args = {
|
|||||||
columns: [{ name: "Public Buckets", data_type: "INT8" }],
|
columns: [{ name: "Public Buckets", data_type: "INT8" }],
|
||||||
rows: [{ "Public Buckets": 5 }],
|
rows: [{ "Public Buckets": 5 }],
|
||||||
},
|
},
|
||||||
properties: { type: "alert" },
|
display_type: "alert",
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SimpleDataFormatAlertCustomIcon = Template.bind({});
|
export const SimpleDataFormatAlertCustomIcon = Template.bind({});
|
||||||
@@ -152,7 +156,8 @@ SimpleDataFormatAlertCustomIcon.args = {
|
|||||||
columns: [{ name: "Public Buckets", data_type: "INT8" }],
|
columns: [{ name: "Public Buckets", data_type: "INT8" }],
|
||||||
rows: [{ "Public Buckets": 5 }],
|
rows: [{ "Public Buckets": 5 }],
|
||||||
},
|
},
|
||||||
properties: { type: "alert", icon: "shield-exclamation" },
|
display_type: "alert",
|
||||||
|
properties: { icon: "shield-exclamation" },
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SimpleDataFormatInfo = Template.bind({});
|
export const SimpleDataFormatInfo = Template.bind({});
|
||||||
@@ -161,7 +166,7 @@ SimpleDataFormatInfo.args = {
|
|||||||
columns: [{ name: "EC2 Instances", data_type: "INT8" }],
|
columns: [{ name: "EC2 Instances", data_type: "INT8" }],
|
||||||
rows: [{ "EC2 Instances": 106 }],
|
rows: [{ "EC2 Instances": 106 }],
|
||||||
},
|
},
|
||||||
properties: { type: "info" },
|
display_type: "info",
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SimpleDataFormatInfoCustomIcon = Template.bind({});
|
export const SimpleDataFormatInfoCustomIcon = Template.bind({});
|
||||||
@@ -172,7 +177,8 @@ SimpleDataFormatInfoCustomIcon.args = {
|
|||||||
columns: [{ name: "EC2 Instances", data_type: "INT8" }],
|
columns: [{ name: "EC2 Instances", data_type: "INT8" }],
|
||||||
rows: [{ "EC2 Instances": 106 }],
|
rows: [{ "EC2 Instances": 106 }],
|
||||||
},
|
},
|
||||||
properties: { type: "info", icon: "light-bulb" },
|
display_type: "info",
|
||||||
|
properties: { icon: "light-bulb" },
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SimpleDataFormatThousands = Template.bind({});
|
export const SimpleDataFormatThousands = Template.bind({});
|
||||||
@@ -182,7 +188,7 @@ SimpleDataFormatThousands.args = {
|
|||||||
columns: [{ name: "EC2 Instances", data_type: "INT8" }],
|
columns: [{ name: "EC2 Instances", data_type: "INT8" }],
|
||||||
rows: [{ "EC2 Instances": 1236 }],
|
rows: [{ "EC2 Instances": 1236 }],
|
||||||
},
|
},
|
||||||
properties: { type: "info" },
|
display_type: "info",
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SimpleDataFormatMillions = Template.bind({});
|
export const SimpleDataFormatMillions = Template.bind({});
|
||||||
@@ -192,7 +198,7 @@ SimpleDataFormatMillions.args = {
|
|||||||
columns: [{ name: "Log Lines", data_type: "INT8" }],
|
columns: [{ name: "Log Lines", data_type: "INT8" }],
|
||||||
rows: [{ "Log Lines": 5236174 }],
|
rows: [{ "Log Lines": 5236174 }],
|
||||||
},
|
},
|
||||||
properties: { type: "info" },
|
display_type: "info",
|
||||||
};
|
};
|
||||||
|
|
||||||
export const FormalDataFormat = Template.bind({});
|
export const FormalDataFormat = Template.bind({});
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import { DashboardDataModeLive } from "../../../types";
|
|||||||
import { getComponent, registerComponent } from "../index";
|
import { getComponent, registerComponent } from "../index";
|
||||||
import {
|
import {
|
||||||
getIconClasses,
|
getIconClasses,
|
||||||
|
getIconForType,
|
||||||
getTextClasses,
|
getTextClasses,
|
||||||
getWrapperClasses,
|
getWrapperClasses,
|
||||||
} from "../../../utils/card";
|
} from "../../../utils/card";
|
||||||
@@ -58,29 +59,6 @@ const getDataFormat = (data: LeafNodeData): CardDataFormat => {
|
|||||||
return "simple";
|
return "simple";
|
||||||
};
|
};
|
||||||
|
|
||||||
const getIconForType = (type, icon) => {
|
|
||||||
if (!type && !icon) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (icon) {
|
|
||||||
return icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case "alert":
|
|
||||||
return "heroicons-solid:exclamation-circle";
|
|
||||||
case "ok":
|
|
||||||
return "heroicons-solid:check-circle";
|
|
||||||
case "info":
|
|
||||||
return "heroicons-solid:information-circle";
|
|
||||||
case "severity":
|
|
||||||
return "heroicons-solid:exclamation";
|
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const useCardState = ({ data, sql, display_type, properties }: CardProps) => {
|
const useCardState = ({ data, sql, display_type, properties }: CardProps) => {
|
||||||
const [calculatedProperties, setCalculatedProperties] = useState<CardState>({
|
const [calculatedProperties, setCalculatedProperties] = useState<CardState>({
|
||||||
loading: !!sql,
|
loading: !!sql,
|
||||||
@@ -233,12 +211,6 @@ const Card = (props: CardProps) => {
|
|||||||
doRender();
|
doRender();
|
||||||
}, [state, props.data]);
|
}, [state, props.data]);
|
||||||
|
|
||||||
// return (
|
|
||||||
// <div className="bg-alert text-alert print:bg-white print:border-2 print:border-alert">
|
|
||||||
// Hello
|
|
||||||
// </div>
|
|
||||||
// );
|
|
||||||
|
|
||||||
const card = (
|
const card = (
|
||||||
<div
|
<div
|
||||||
className={classNames(
|
className={classNames(
|
||||||
@@ -263,7 +235,10 @@ const Card = (props: CardProps) => {
|
|||||||
>
|
>
|
||||||
{state.loading && "Loading..."}
|
{state.loading && "Loading..."}
|
||||||
{!state.loading && !state.label && (
|
{!state.loading && !state.label && (
|
||||||
<DashboardIcon className="h-5 w-5" icon="heroicons-solid:minus" />
|
<DashboardIcon
|
||||||
|
className="h-5 w-5"
|
||||||
|
icon="materialsymbols-outline:remove"
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
{!state.loading && state.label}
|
{!state.loading && state.label}
|
||||||
</p>
|
</p>
|
||||||
@@ -295,7 +270,7 @@ const Card = (props: CardProps) => {
|
|||||||
(state.value === null || state.value === undefined) && (
|
(state.value === null || state.value === undefined) && (
|
||||||
<DashboardIcon
|
<DashboardIcon
|
||||||
className="h-10 w-10"
|
className="h-10 w-10"
|
||||||
icon="heroicons-solid:minus"
|
icon="materialsymbols-outline:remove"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{state.value !== null &&
|
{state.value !== null &&
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ const Benchmark = (props: InnerCheckProps) => {
|
|||||||
properties: {
|
properties: {
|
||||||
label: "OK",
|
label: "OK",
|
||||||
value: totalSummary.ok.toString(),
|
value: totalSummary.ok.toString(),
|
||||||
icon: "heroicons-solid:check-circle",
|
icon: "materialsymbols-solid:check-circle",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -100,7 +100,7 @@ const Benchmark = (props: InnerCheckProps) => {
|
|||||||
properties: {
|
properties: {
|
||||||
label: "Alarm",
|
label: "Alarm",
|
||||||
value: totalSummary.alarm.toString(),
|
value: totalSummary.alarm.toString(),
|
||||||
icon: "heroicons-solid:bell",
|
icon: "materialsymbols-solid:notifications",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -110,7 +110,7 @@ const Benchmark = (props: InnerCheckProps) => {
|
|||||||
properties: {
|
properties: {
|
||||||
label: "Error",
|
label: "Error",
|
||||||
value: totalSummary.error.toString(),
|
value: totalSummary.error.toString(),
|
||||||
icon: "heroicons-solid:exclamation-circle",
|
icon: "materialsymbols-solid:error",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -120,7 +120,7 @@ const Benchmark = (props: InnerCheckProps) => {
|
|||||||
properties: {
|
properties: {
|
||||||
label: "Info",
|
label: "Info",
|
||||||
value: totalSummary.info.toString(),
|
value: totalSummary.info.toString(),
|
||||||
icon: "heroicons-solid:information-circle",
|
icon: "materialsymbols-solid:info",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -129,7 +129,7 @@ const Benchmark = (props: InnerCheckProps) => {
|
|||||||
properties: {
|
properties: {
|
||||||
label: "Skipped",
|
label: "Skipped",
|
||||||
value: totalSummary.skip.toString(),
|
value: totalSummary.skip.toString(),
|
||||||
icon: "heroicons-solid:arrow-circle-right",
|
icon: "materialsymbols-solid:arrow-circle-right",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@@ -150,7 +150,7 @@ const Benchmark = (props: InnerCheckProps) => {
|
|||||||
properties: {
|
properties: {
|
||||||
label: "Critical / High",
|
label: "Critical / High",
|
||||||
value: total.toString(),
|
value: total.toString(),
|
||||||
icon: "heroicons-solid:exclamation",
|
icon: "materialsymbols-solid:exclamation",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,13 +18,11 @@ const CheckGrouping = ({ node }: CheckGroupingProps) => {
|
|||||||
useState<CheckGroupNodeStates | null>(null);
|
useState<CheckGroupNodeStates | null>(null);
|
||||||
|
|
||||||
const expand = useCallback(() => {
|
const expand = useCallback(() => {
|
||||||
// console.log("Capturing and expanding", nodeStates);
|
|
||||||
setRestoreNodeStates(nodeStates);
|
setRestoreNodeStates(nodeStates);
|
||||||
dispatch({ type: CheckGroupingActions.EXPAND_ALL_NODES });
|
dispatch({ type: CheckGroupingActions.EXPAND_ALL_NODES });
|
||||||
}, [dispatch, nodeStates]);
|
}, [dispatch, nodeStates]);
|
||||||
|
|
||||||
const restore = useCallback(() => {
|
const restore = useCallback(() => {
|
||||||
// console.log("Restoring", restoreNodeStates);
|
|
||||||
if (restoreNodeStates) {
|
if (restoreNodeStates) {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: CheckGroupingActions.UPDATE_NODES,
|
type: CheckGroupingActions.UPDATE_NODES,
|
||||||
|
|||||||
@@ -111,118 +111,6 @@ const ProgressBarGroup = ({ children, className }: ProgressBarGroupProps) => (
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
// interface ValueWithIndex {
|
|
||||||
// value: number;
|
|
||||||
// percent: number;
|
|
||||||
// index: number;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// const ensureMinPercentages = (
|
|
||||||
// name,
|
|
||||||
// values: number[] = [],
|
|
||||||
// minPercentage = 2
|
|
||||||
// ) => {
|
|
||||||
// // Summary here is I want to ensure each percent is >= 2% and a round number, so I'll adjust
|
|
||||||
// // all other values accordingly to ensure we total 100%
|
|
||||||
// const total = values.reduce((partial, v) => partial + v, 0);
|
|
||||||
// const valuesWithPercentAndIndex: ValueWithIndex[] = [];
|
|
||||||
// for (let i = 0; i < values.length; i++) {
|
|
||||||
// const value = values[i];
|
|
||||||
// valuesWithPercentAndIndex.push({
|
|
||||||
// value,
|
|
||||||
// percent: (value / total) * 100,
|
|
||||||
// index: i,
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// const withMinPercentages = valuesWithPercentAndIndex.map((p) => ({
|
|
||||||
// ...p,
|
|
||||||
// percent:
|
|
||||||
// p.percent > 0 && p.percent < minPercentage ? minPercentage : p.percent,
|
|
||||||
// }));
|
|
||||||
// const flooredPercentages = withMinPercentages.map((p) => ({
|
|
||||||
// ...p,
|
|
||||||
// percent: p.percent > 0 ? Math.floor(p.percent) : p.percent,
|
|
||||||
// }));
|
|
||||||
// let diff =
|
|
||||||
// flooredPercentages.reduce((partial, v) => partial + v.percent, 0) - 100;
|
|
||||||
// const numberOfValuesToDistributeAcross = flooredPercentages.filter((p) => {
|
|
||||||
// if (diff < 0) {
|
|
||||||
// return p.percent > minPercentage && 100 - p.percent + 4 > 0;
|
|
||||||
// } else {
|
|
||||||
// return p.percent > minPercentage && p.percent - 4 > minPercentage;
|
|
||||||
// }
|
|
||||||
// }).length;
|
|
||||||
// const perItem = diff / numberOfValuesToDistributeAcross;
|
|
||||||
// // if (name === "aws_compliance.control.cis_v140_1_12") {
|
|
||||||
// // console.log({
|
|
||||||
// // values,
|
|
||||||
// // total,
|
|
||||||
// // valuesWithPercentAndIndex,
|
|
||||||
// // withMinPercentages,
|
|
||||||
// // flooredPercentages,
|
|
||||||
// // numberOfValuesToDistributeAcross,
|
|
||||||
// // perItem,
|
|
||||||
// // diff,
|
|
||||||
// // });
|
|
||||||
// // }
|
|
||||||
// let adjusted;
|
|
||||||
// if (diff < 0) {
|
|
||||||
// const ascending = [...flooredPercentages]
|
|
||||||
// .sort((a, b) =>
|
|
||||||
// a.percent < b.percent ? -1 : a.percent > b.percent ? 1 : 0
|
|
||||||
// )
|
|
||||||
// .map((p) => ({ ...p }));
|
|
||||||
// for (const percentageItem of ascending) {
|
|
||||||
// if (
|
|
||||||
// diff === 0 ||
|
|
||||||
// percentageItem.percent < minPercentage ||
|
|
||||||
// percentageItem.percent - 4 <= minPercentage
|
|
||||||
// ) {
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
// if (perItem < 0 && perItem > -1) {
|
|
||||||
// percentageItem.percent += 1;
|
|
||||||
// diff += 1;
|
|
||||||
// } else {
|
|
||||||
// percentageItem.percent -= perItem;
|
|
||||||
// diff -= perItem;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// adjusted = ascending
|
|
||||||
// .sort((a, b) => (a.index < b.index ? -1 : a.index > b.index ? 1 : 0))
|
|
||||||
// .map((p) => p.percent);
|
|
||||||
// } else {
|
|
||||||
// const descending = [...flooredPercentages]
|
|
||||||
// .sort((a, b) =>
|
|
||||||
// b.percent < a.percent ? -1 : b.percent > a.percent ? 1 : 0
|
|
||||||
// )
|
|
||||||
// .map((p) => ({ ...p }));
|
|
||||||
// for (const percentageItem of descending) {
|
|
||||||
// if (
|
|
||||||
// diff === 0 ||
|
|
||||||
// percentageItem.percent < minPercentage ||
|
|
||||||
// percentageItem.percent - 4 <= minPercentage
|
|
||||||
// ) {
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
// if (perItem > 0 && perItem < 1) {
|
|
||||||
// percentageItem.percent -= 1;
|
|
||||||
// diff -= 1;
|
|
||||||
// } else {
|
|
||||||
// percentageItem.percent -= perItem;
|
|
||||||
// diff -= perItem;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// adjusted = descending
|
|
||||||
// .sort((a, b) => (a.index < b.index ? -1 : a.index > b.index ? 1 : 0))
|
|
||||||
// .map((p) => p.percent);
|
|
||||||
// }
|
|
||||||
// // if (name === "aws_compliance.control.cis_v140_1_12") {
|
|
||||||
// // console.log(adjusted);
|
|
||||||
// // }
|
|
||||||
// return adjusted;
|
|
||||||
// };
|
|
||||||
|
|
||||||
const ProgressBar = ({ className, percent }: ProgressBarProps) => {
|
const ProgressBar = ({ className, percent }: ProgressBarProps) => {
|
||||||
if (!percent) {
|
if (!percent) {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -17,16 +17,67 @@ heroIconDefaultOutline.args = {
|
|||||||
icon: "arrow-up-circle",
|
icon: "arrow-up-circle",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const heroIconDefaultOutlineWithColor = Template.bind({});
|
||||||
|
heroIconDefaultOutlineWithColor.args = {
|
||||||
|
icon: "arrow-up-circle",
|
||||||
|
style: { color: "red" },
|
||||||
|
};
|
||||||
|
|
||||||
export const heroIconOutlineFullyNamespaced = Template.bind({});
|
export const heroIconOutlineFullyNamespaced = Template.bind({});
|
||||||
heroIconOutlineFullyNamespaced.args = {
|
heroIconOutlineFullyNamespaced.args = {
|
||||||
icon: "heroicons-outline:arrow-up-circle",
|
icon: "heroicons-outline:arrow-up-circle",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const heroIconOutlineFullyNamespacedWithColor = Template.bind({});
|
||||||
|
heroIconOutlineFullyNamespacedWithColor.args = {
|
||||||
|
icon: "heroicons-outline:arrow-up-circle",
|
||||||
|
style: { color: "red" },
|
||||||
|
};
|
||||||
|
|
||||||
export const heroIconSolid = Template.bind({});
|
export const heroIconSolid = Template.bind({});
|
||||||
heroIconSolid.args = {
|
heroIconSolid.args = {
|
||||||
icon: "heroicons-solid:arrow-up-circle",
|
icon: "heroicons-solid:arrow-up-circle",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const heroIconSolidWithColor = Template.bind({});
|
||||||
|
heroIconSolidWithColor.args = {
|
||||||
|
icon: "heroicons-solid:arrow-up-circle",
|
||||||
|
style: { color: "red" },
|
||||||
|
};
|
||||||
|
|
||||||
|
export const materialSymbolDefaultOutline = Template.bind({});
|
||||||
|
materialSymbolDefaultOutline.args = {
|
||||||
|
icon: "cloud",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const materialSymbolDefaultOutlineWithColor = Template.bind({});
|
||||||
|
materialSymbolDefaultOutlineWithColor.args = {
|
||||||
|
icon: "cloud",
|
||||||
|
style: { color: "red" },
|
||||||
|
};
|
||||||
|
|
||||||
|
export const materialSymbolOutlineFullyNamespaced = Template.bind({});
|
||||||
|
materialSymbolOutlineFullyNamespaced.args = {
|
||||||
|
icon: "materialsymbols-outline:cloud",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const materialSymbolOutlineFullyNamespacedWithColor = Template.bind({});
|
||||||
|
materialSymbolOutlineFullyNamespacedWithColor.args = {
|
||||||
|
icon: "materialsymbols-outline:cloud",
|
||||||
|
style: { color: "red" },
|
||||||
|
};
|
||||||
|
|
||||||
|
export const materialSymbolSolid = Template.bind({});
|
||||||
|
materialSymbolSolid.args = {
|
||||||
|
icon: "materialsymbols-solid:cloud",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const materialSymbolSolidWithColor = Template.bind({});
|
||||||
|
materialSymbolSolidWithColor.args = {
|
||||||
|
icon: "materialsymbols-solid:cloud",
|
||||||
|
style: { color: "red" },
|
||||||
|
};
|
||||||
|
|
||||||
export const text1Letter = Template.bind({});
|
export const text1Letter = Template.bind({});
|
||||||
text1Letter.args = {
|
text1Letter.args = {
|
||||||
icon: "text:A",
|
icon: "text:A",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import Icon from "../../Icon";
|
import Icon from "../../Icon";
|
||||||
import { classNames } from "../../../utils/styles";
|
import { classNames } from "../../../utils/styles";
|
||||||
import { memo, useMemo } from "react";
|
import { useMemo } from "react";
|
||||||
|
|
||||||
interface DashboardIconProps {
|
interface DashboardIconProps {
|
||||||
className?: string;
|
className?: string;
|
||||||
@@ -9,14 +9,12 @@ interface DashboardIconProps {
|
|||||||
title?: string;
|
title?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface DashboardHeroIconProps extends DashboardIconProps {
|
interface DashboardTextIconProps extends DashboardIconProps {
|
||||||
icon: string;
|
icon: string;
|
||||||
style?: any;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface DashboardImageIconProps extends DashboardIconProps {
|
interface DashboardImageIconProps extends DashboardIconProps {
|
||||||
icon: string;
|
icon: string;
|
||||||
style?: any;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const useDashboardIconType = (icon) =>
|
const useDashboardIconType = (icon) =>
|
||||||
@@ -28,7 +26,9 @@ const useDashboardIconType = (icon) =>
|
|||||||
// This gets parsed as a URL if we don't check first
|
// This gets parsed as a URL if we don't check first
|
||||||
if (
|
if (
|
||||||
icon.startsWith("heroicons-outline:") ||
|
icon.startsWith("heroicons-outline:") ||
|
||||||
icon.startsWith("heroicons-solid:")
|
icon.startsWith("heroicons-solid:") ||
|
||||||
|
icon.startsWith("materialsymbols-outline:") ||
|
||||||
|
icon.startsWith("materialsymbols-solid:")
|
||||||
) {
|
) {
|
||||||
return "icon";
|
return "icon";
|
||||||
}
|
}
|
||||||
@@ -57,21 +57,12 @@ const DashboardImageIcon = ({
|
|||||||
<img className={className} src={icon} alt="" style={style} title={title} />
|
<img className={className} src={icon} alt="" style={style} title={title} />
|
||||||
);
|
);
|
||||||
|
|
||||||
const DashboardHeroIcon = ({
|
|
||||||
className,
|
|
||||||
icon,
|
|
||||||
style,
|
|
||||||
title,
|
|
||||||
}: DashboardHeroIconProps) => (
|
|
||||||
<Icon className={className} icon={icon} style={style} title={title} />
|
|
||||||
);
|
|
||||||
|
|
||||||
const DashboardTextIcon = ({
|
const DashboardTextIcon = ({
|
||||||
className,
|
className,
|
||||||
icon,
|
icon,
|
||||||
style,
|
style,
|
||||||
title,
|
title,
|
||||||
}: DashboardHeroIconProps) => {
|
}: DashboardTextIconProps) => {
|
||||||
const text = useMemo(() => {
|
const text = useMemo(() => {
|
||||||
if (!icon) {
|
if (!icon) {
|
||||||
return "";
|
return "";
|
||||||
@@ -104,12 +95,7 @@ const DashboardIcon = ({
|
|||||||
switch (iconType) {
|
switch (iconType) {
|
||||||
case "icon":
|
case "icon":
|
||||||
return (
|
return (
|
||||||
<DashboardHeroIcon
|
<Icon className={className} icon={icon} style={style} title={title} />
|
||||||
className={className}
|
|
||||||
icon={icon}
|
|
||||||
style={style}
|
|
||||||
title={title}
|
|
||||||
/>
|
|
||||||
);
|
);
|
||||||
case "text":
|
case "text":
|
||||||
return (
|
return (
|
||||||
@@ -134,6 +120,6 @@ const DashboardIcon = ({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default memo(DashboardIcon);
|
export default DashboardIcon;
|
||||||
|
|
||||||
export { useDashboardIconType };
|
export { useDashboardIconType };
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ const NodeAndEdgePanelInformation = ({
|
|||||||
<div className="flex items-center space-x-1">
|
<div className="flex items-center space-x-1">
|
||||||
<Icon
|
<Icon
|
||||||
className="w-3.5 h-3.5 text-alert"
|
className="w-3.5 h-3.5 text-alert"
|
||||||
icon="heroicons-solid:exclamation-circle"
|
icon="materialsymbols-solid:error"
|
||||||
/>
|
/>
|
||||||
<span key={category.id} className="block">
|
<span key={category.id} className="block">
|
||||||
{category.title || category.id}
|
{category.title || category.id}
|
||||||
|
|||||||
22
ui/dashboard/src/hooks/useDashboardIcons.ts
Normal file
22
ui/dashboard/src/hooks/useDashboardIcons.ts
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import { useMemo } from "react";
|
||||||
|
|
||||||
|
let heroIcons = {};
|
||||||
|
let materialSymbols = {};
|
||||||
|
import("../icons/heroIcons").then((m) => {
|
||||||
|
heroIcons = m.icons;
|
||||||
|
});
|
||||||
|
import("../icons/materialSymbols").then((m) => {
|
||||||
|
materialSymbols = m.icons;
|
||||||
|
});
|
||||||
|
|
||||||
|
const useDashboardIcons = () => {
|
||||||
|
return useMemo(
|
||||||
|
() => ({
|
||||||
|
heroIcons,
|
||||||
|
materialSymbols,
|
||||||
|
}),
|
||||||
|
[heroIcons, materialSymbols]
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useDashboardIcons;
|
||||||
23
ui/dashboard/src/icons/heroIcons.test.ts
Normal file
23
ui/dashboard/src/icons/heroIcons.test.ts
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import { icons } from "./heroIcons";
|
||||||
|
|
||||||
|
describe("hero icons", () => {
|
||||||
|
test("unknown returns null", () => {
|
||||||
|
expect(icons["hjdfghskhgskfdjg"]).toEqual(undefined);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("existing icon not mapped", () => {
|
||||||
|
expect(icons["bell"]).not.toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("existing namespaced icon not mapped", () => {
|
||||||
|
expect(icons["heroicons-outline:bell"]).not.toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("migrated icon mapped", () => {
|
||||||
|
expect(icons["search"]).not.toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("prefixed migrated icon mapped", () => {
|
||||||
|
expect(icons["heroicons-solid:search"]).not.toBeNull();
|
||||||
|
});
|
||||||
|
});
|
||||||
162
ui/dashboard/src/icons/heroIcons.ts
Normal file
162
ui/dashboard/src/icons/heroIcons.ts
Normal file
@@ -0,0 +1,162 @@
|
|||||||
|
import kebabCase from "lodash/kebabCase";
|
||||||
|
import * as outline from "@heroicons/react/24/outline";
|
||||||
|
import * as solid from "@heroicons/react/24/solid";
|
||||||
|
|
||||||
|
const migratedV2IconNames = {
|
||||||
|
adjustments: "adjustments-vertical",
|
||||||
|
annotation: "chat-bubble-bottom-center-text",
|
||||||
|
archive: "archive-box",
|
||||||
|
"arrow-circle-down": "arrow-down-circle",
|
||||||
|
"arrow-circle-left": "arrow-left-circle",
|
||||||
|
"arrow-circle-right": "arrow-right-circle",
|
||||||
|
"arrow-circle-up": "arrow-up-circle",
|
||||||
|
"arrow-narrow-down": "arrow-long-down",
|
||||||
|
"arrow-narrow-left": "arrow-long-left",
|
||||||
|
"arrow-narrow-right": "arrow-long-right",
|
||||||
|
"arrow-narrow-up": "arrow-long-up",
|
||||||
|
"arrow-sm-left": "arrow-small-left",
|
||||||
|
"arrow-sm-right": "arrow-small-right",
|
||||||
|
"arrow-sm-up": "arrow-small-up",
|
||||||
|
"arrow-sm-down": "arrow-small-down",
|
||||||
|
"arrows-expand": "arrows-pointing-out",
|
||||||
|
"badge-check": "check-badge",
|
||||||
|
ban: "no-symbol",
|
||||||
|
"bookmark-alt": "bookmark-square",
|
||||||
|
cash: "banknotes",
|
||||||
|
"chart-square-bar": "chart-bar-square",
|
||||||
|
"chat-alt-2": "chat-bubble-left-right",
|
||||||
|
"chat-alt": "chat-bubble-left-ellipsis",
|
||||||
|
chat: "chat-bubble-oval-left-ellipsis",
|
||||||
|
chip: "cpu-chip",
|
||||||
|
"clipboard-check": "clipboard-document-check",
|
||||||
|
"clipboard-copy": "clipboard-document",
|
||||||
|
"clipboard-list": "clipboard-document-list",
|
||||||
|
"cloud-download": "cloud-arrow-down",
|
||||||
|
"cloud-upload": "cloud-arrow-up",
|
||||||
|
code: "code-bracket",
|
||||||
|
collection: "rectangle-stack",
|
||||||
|
"color-swatch": "swatch",
|
||||||
|
"cursor-click": "cursor-arrow-rays",
|
||||||
|
database: "circle-stack",
|
||||||
|
"desktop-computer": "computer-desktop",
|
||||||
|
"device-mobile": "device-phone-mobile",
|
||||||
|
"document-add": "document-plus",
|
||||||
|
"document-download": "document-arrow-down",
|
||||||
|
"document-remove": "document-minus",
|
||||||
|
"document-report": "document-chart-bar",
|
||||||
|
"document-search": "document-magnifying-glass",
|
||||||
|
"dots-circle-horizontal": "ellipsis-horizontal-circle",
|
||||||
|
"dots-horizontal": "ellipsis-horizontal",
|
||||||
|
"dots-vertical": "ellipsis-vertical",
|
||||||
|
download: "arrow-down-tray",
|
||||||
|
duplicate: "square-2-stack",
|
||||||
|
"emoji-happy": "face-smile",
|
||||||
|
"emoji-sad": "face-frown",
|
||||||
|
exclamation: "exclamation-triangle",
|
||||||
|
"external-link": "arrow-top-right-on-square",
|
||||||
|
"eye-off": "eye-slash",
|
||||||
|
"fast-forward": "forward",
|
||||||
|
filter: "funnel",
|
||||||
|
"folder-add": "folder-plus",
|
||||||
|
"folder-download": "folder-arrow-down",
|
||||||
|
"folder-remove": "folder-minus",
|
||||||
|
globe: "globe-americas",
|
||||||
|
hand: "hand-raised",
|
||||||
|
"inbox-in": "inbox-arrow-down",
|
||||||
|
library: "building-library",
|
||||||
|
"lightning-bolt": "bolt",
|
||||||
|
"location-marker": "map-pin",
|
||||||
|
login: "arrow-left-on-rectangle",
|
||||||
|
logout: "arrow-right-on-rectangle",
|
||||||
|
"mail-open": "envelope-open",
|
||||||
|
mail: "envelope",
|
||||||
|
"menu-alt-1": "bars-3-center-left",
|
||||||
|
"menu-alt-2": "bars-3-bottom-left",
|
||||||
|
"menu-alt-3": "bars-3-bottom-right",
|
||||||
|
"menu-alt-4": "bars-2",
|
||||||
|
menu: "bars-3",
|
||||||
|
"minus-sm": "minus-small",
|
||||||
|
"music-note": "musical-note",
|
||||||
|
"office-building": "building-office",
|
||||||
|
"pencil-alt": "pencil-square",
|
||||||
|
"phone-incoming": "phone-arrow-down-left",
|
||||||
|
"phone-missed-call": "phone-x-mark",
|
||||||
|
"phone-outgoing": "phone-arrow-up-right",
|
||||||
|
photograph: "photo",
|
||||||
|
"plus-sm": "plus-small",
|
||||||
|
puzzle: "puzzle-piece",
|
||||||
|
qrcode: "qr-code",
|
||||||
|
"receipt-tax": "receipt-percent",
|
||||||
|
refresh: "arrow-path",
|
||||||
|
reply: "arrow-uturn-left",
|
||||||
|
rewind: "backward",
|
||||||
|
"save-as": "arrow-down-on-square-stack",
|
||||||
|
save: "arrow-down-on-square",
|
||||||
|
"search-circle": "magnifying-glass-circle",
|
||||||
|
search: "magnifying-glass",
|
||||||
|
selector: "chevron-up-down",
|
||||||
|
"sort-ascending": "bars-arrow-up",
|
||||||
|
"sort-descending": "bars-arrow-down",
|
||||||
|
speakerphone: "megaphone",
|
||||||
|
"status-offline": "signal-slash",
|
||||||
|
"status-online": "signal",
|
||||||
|
support: "lifebuoy",
|
||||||
|
"switch-horizontal": "arrow-right-left",
|
||||||
|
"switch-vertical": "arrow-up-down",
|
||||||
|
table: "table-cells",
|
||||||
|
template: "rectangle-group",
|
||||||
|
terminal: "command-line",
|
||||||
|
"thumb-down": "hand-thumb-down",
|
||||||
|
"thumb-up": "hand-thumb-up",
|
||||||
|
translate: "language",
|
||||||
|
"trending-down": "arrow-trending-down",
|
||||||
|
"trending-up": "arrow-trending-up",
|
||||||
|
upload: "arrow-up-tray",
|
||||||
|
"user-add": "user-plus",
|
||||||
|
"user-remove": "user-minus",
|
||||||
|
"view-boards": "view-columns",
|
||||||
|
"view-grid-add": "squares-plus",
|
||||||
|
"view-grid": "squares-2x2",
|
||||||
|
"view-list": "bars-4",
|
||||||
|
"volume-off": "speaker-x-mark",
|
||||||
|
"volume-up": "speaker-wave",
|
||||||
|
x: "x-mark",
|
||||||
|
"zoom-in": "magnifying-glass-plus",
|
||||||
|
"zoom-out": "magnifying-glass-minus",
|
||||||
|
};
|
||||||
|
|
||||||
|
const kebabCaseExceptions = {
|
||||||
|
Square3Stack3D: "square-3-stack-3d",
|
||||||
|
Squares2X2: "squares-2x2",
|
||||||
|
};
|
||||||
|
|
||||||
|
const convertIconName = (name) => {
|
||||||
|
let condensedName = name;
|
||||||
|
const iconOccurrence = name.lastIndexOf("Icon");
|
||||||
|
if (iconOccurrence >= 0) {
|
||||||
|
condensedName = condensedName.substring(0, iconOccurrence);
|
||||||
|
}
|
||||||
|
return kebabCaseExceptions[condensedName] || kebabCase(condensedName);
|
||||||
|
};
|
||||||
|
|
||||||
|
const icons = {};
|
||||||
|
|
||||||
|
Object.entries(outline).forEach(([name, exported]) => {
|
||||||
|
const iconName = convertIconName(name);
|
||||||
|
icons[iconName] = exported;
|
||||||
|
icons[`heroicons-outline:${iconName}`] = exported;
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.entries(solid).forEach(([name, exported]) => {
|
||||||
|
const iconName = convertIconName(name);
|
||||||
|
icons[`heroicons-solid:${iconName}`] = exported;
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.entries(migratedV2IconNames).forEach(([name, mappedName]) => {
|
||||||
|
const mappedIcon = icons[mappedName];
|
||||||
|
icons[name] = mappedIcon;
|
||||||
|
icons[`heroicons-outline:${name}`] = mappedIcon;
|
||||||
|
icons[`heroicons-solid:${name}`] = mappedIcon;
|
||||||
|
});
|
||||||
|
|
||||||
|
export { icons };
|
||||||
@@ -16,6 +16,29 @@ const getIconClasses = (type) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getIconForType = (type, icon) => {
|
||||||
|
if (!type && !icon) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (icon) {
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case "alert":
|
||||||
|
return "materialsymbols-solid:error";
|
||||||
|
case "ok":
|
||||||
|
return "materialsymbols-solid:check-circle";
|
||||||
|
case "info":
|
||||||
|
return "materialsymbols-solid:info";
|
||||||
|
case "severity":
|
||||||
|
return "materialsymbols-solid:exclamation";
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const getTextClasses = (type) => {
|
const getTextClasses = (type) => {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case "alert":
|
case "alert":
|
||||||
@@ -46,4 +69,4 @@ const getWrapperClasses = (type) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export { getIconClasses, getTextClasses, getWrapperClasses };
|
export { getIconClasses, getIconForType, getTextClasses, getWrapperClasses };
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user