mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Add icon column to catalog list (#2852)
* add icon column to catalog list Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * Create generic Avatar component Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com> Co-authored-by: Alex Andreev <alex.andreev.email@gmail.com>
This commit is contained in:
1 parent
5372e3617e
commit
e033122baf
5 files changed
+223
-135
No files matched your search
@@ -20,92 +20,6 @@
|
||||
*/
|
||||
|
||||
.HotbarMenu {
|
||||
.HotbarIcon {
|
||||
--size: 37px;
|
||||
|
||||
border-radius: 6px;
|
||||
user-select: none;
|
||||
cursor: pointer;
|
||||
transition: none;
|
||||
text-shadow: 0 0 4px #0000008f;
|
||||
position: relative;
|
||||
|
||||
div.MuiAvatar-colorDefault {
|
||||
font-weight:500;
|
||||
text-transform: uppercase;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
opacity: 0.4;
|
||||
cursor: default;
|
||||
filter: grayscale(0.7);
|
||||
|
||||
&:hover {
|
||||
&:not(.active) {
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.isDragging {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
div.MuiAvatar-root {
|
||||
&.active {
|
||||
box-shadow: 0 0 0px 3px var(--clusterMenuBackground), 0 0 0px 6px var(--textColorAccent);
|
||||
transition: all 0s 0.8s;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
&:not(.active) {
|
||||
box-shadow: 0 0 0px 3px var(--clusterMenuBackground), 0 0 0px 6px #ffffff30;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.led {
|
||||
position: absolute;
|
||||
left: 3px;
|
||||
top: 3px;
|
||||
background-color: var(--layoutBackground);
|
||||
border: 1px solid var(--clusterMenuBackground);
|
||||
border-radius: 50%;
|
||||
padding: 0px;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
|
||||
&.online {
|
||||
background-color: var(--primary);
|
||||
box-shadow: 0 0 5px var(--clusterMenuBackground), 0 0 5px var(--primary);
|
||||
}
|
||||
}
|
||||
|
||||
.badge {
|
||||
position: absolute;
|
||||
right: -2px;
|
||||
bottom: -3px;
|
||||
margin: -8px;
|
||||
font-size: var(--font-size-small);
|
||||
background: var(--clusterMenuBackground);
|
||||
color: var(--textColorAccent);
|
||||
padding: 0px;
|
||||
border-radius: 50%;
|
||||
border: 2px solid var(--clusterMenuBackground);
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
|
||||
svg {
|
||||
width: 13px;
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
width: var(--size);
|
||||
height: var(--size);
|
||||
}
|
||||
}
|
||||
|
||||
.HotbarIconMenu {
|
||||
left: 30px;
|
||||
@@ -116,3 +30,90 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.HotbarIcon {
|
||||
border-radius: 6px;
|
||||
user-select: none;
|
||||
cursor: pointer;
|
||||
transition: none;
|
||||
text-shadow: 0 0 4px #0000008f;
|
||||
position: relative;
|
||||
|
||||
div.MuiAvatar-colorDefault {
|
||||
font-weight:500;
|
||||
text-transform: uppercase;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
opacity: 0.4;
|
||||
cursor: default;
|
||||
filter: grayscale(0.7);
|
||||
|
||||
&:hover {
|
||||
&:not(.active) {
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.isDragging {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
div.MuiAvatar-root {
|
||||
width: var(--size);
|
||||
height: var(--size);
|
||||
|
||||
&.active {
|
||||
box-shadow: 0 0 0px 3px var(--clusterMenuBackground), 0 0 0px 6px var(--textColorAccent);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
&:not(.active) {
|
||||
box-shadow: 0 0 0px 3px var(--clusterMenuBackground), 0 0 0px 6px #ffffff30;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.led {
|
||||
position: absolute;
|
||||
left: 3px;
|
||||
top: 3px;
|
||||
background-color: var(--layoutBackground);
|
||||
border: 1px solid var(--clusterMenuBackground);
|
||||
border-radius: 50%;
|
||||
padding: 0px;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
|
||||
&.online {
|
||||
background-color: var(--primary);
|
||||
box-shadow: 0 0 5px var(--clusterMenuBackground), 0 0 5px var(--primary);
|
||||
}
|
||||
}
|
||||
|
||||
.badge {
|
||||
position: absolute;
|
||||
right: -2px;
|
||||
bottom: -3px;
|
||||
margin: -8px;
|
||||
font-size: var(--font-size-small);
|
||||
background: var(--clusterMenuBackground);
|
||||
color: var(--textColorAccent);
|
||||
padding: 0px;
|
||||
border-radius: 50%;
|
||||
border: 2px solid var(--clusterMenuBackground);
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
|
||||
svg {
|
||||
width: 13px;
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
width: var(--size);
|
||||
height: var(--size);
|
||||
}
|
||||
}
|
||||
@@ -22,16 +22,14 @@
|
||||
import "./hotbar-icon.scss";
|
||||
|
||||
import React, { DOMAttributes, useState } from "react";
|
||||
import { Avatar } from "@material-ui/core";
|
||||
import randomColor from "randomcolor";
|
||||
import GraphemeSplitter from "grapheme-splitter";
|
||||
|
||||
import type { CatalogEntityContextMenu } from "../../../common/catalog";
|
||||
import { cssNames, IClassName, iter } from "../../utils";
|
||||
import { cssNames, IClassName } from "../../utils";
|
||||
import { ConfirmDialog } from "../confirm-dialog";
|
||||
import { Menu, MenuItem } from "../menu";
|
||||
import { MaterialTooltip } from "../+catalog/material-tooltip/material-tooltip";
|
||||
import { observer } from "mobx-react";
|
||||
import { Avatar } from "../avatar/avatar";
|
||||
|
||||
interface Props extends DOMAttributes<HTMLElement> {
|
||||
uid: string;
|
||||
@@ -44,12 +42,6 @@ interface Props extends DOMAttributes<HTMLElement> {
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
function generateAvatarStyle(seed: string): React.CSSProperties {
|
||||
return {
|
||||
"backgroundColor": randomColor({ seed, luminosity: "dark" })
|
||||
};
|
||||
}
|
||||
|
||||
function onMenuItemClick(menuItem: CatalogEntityContextMenu) {
|
||||
if (menuItem.confirm) {
|
||||
ConfirmDialog.open({
|
||||
@@ -67,22 +59,6 @@ function onMenuItemClick(menuItem: CatalogEntityContextMenu) {
|
||||
}
|
||||
}
|
||||
|
||||
function getNameParts(name: string): string[] {
|
||||
const byWhitespace = name.split(/\s+/);
|
||||
|
||||
if (byWhitespace.length > 1) {
|
||||
return byWhitespace;
|
||||
}
|
||||
|
||||
const byDashes = name.split(/[-_]+/);
|
||||
|
||||
if (byDashes.length > 1) {
|
||||
return byDashes;
|
||||
}
|
||||
|
||||
return name.split(/@+/);
|
||||
}
|
||||
|
||||
export const HotbarIcon = observer(({menuItems = [], ...props}: Props) => {
|
||||
const { uid, title, active, className, source, disabled, onMenuOpen, children, ...rest } = props;
|
||||
const id = `hotbarIcon-${uid}`;
|
||||
@@ -92,36 +68,18 @@ export const HotbarIcon = observer(({menuItems = [], ...props}: Props) => {
|
||||
setMenuOpen(!menuOpen);
|
||||
};
|
||||
|
||||
const getIconString = () => {
|
||||
if (!title) {
|
||||
return "??";
|
||||
}
|
||||
|
||||
const [rawFirst, rawSecond, rawThird] = getNameParts(title);
|
||||
const splitter = new GraphemeSplitter();
|
||||
const first = splitter.iterateGraphemes(rawFirst);
|
||||
const second = rawSecond ? splitter.iterateGraphemes(rawSecond): first;
|
||||
const third = rawThird ? splitter.iterateGraphemes(rawThird) : iter.newEmpty();
|
||||
|
||||
return [
|
||||
...iter.take(first, 1),
|
||||
...iter.take(second, 1),
|
||||
...iter.take(third, 1),
|
||||
].filter(Boolean).join("");
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={cssNames("HotbarIcon flex inline", className, { disabled })}>
|
||||
<MaterialTooltip title={`${title || "unknown"} (${source || "unknown"})`} placement="right">
|
||||
<div id={id}>
|
||||
<Avatar
|
||||
{...rest}
|
||||
variant="square"
|
||||
title={title}
|
||||
colorHash={`${title}-${source}`}
|
||||
className={active ? "active" : "default"}
|
||||
style={generateAvatarStyle(`${title}-${source}`)}
|
||||
>
|
||||
{getIconString()}
|
||||
</Avatar>
|
||||
width={40}
|
||||
height={40}
|
||||
/>
|
||||
{children}
|
||||
</div>
|
||||
</MaterialTooltip>
|
||||
|
||||
Reference in new issue
Block a user