mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Support non-ascii characters in entity names (#2610)
Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
339502cf4f
commit
bcdc0243f4
@ -186,6 +186,7 @@
|
||||
"filehound": "^1.17.4",
|
||||
"filenamify": "^4.1.0",
|
||||
"fs-extra": "^9.0.1",
|
||||
"grapheme-splitter": "^1.0.4",
|
||||
"handlebars": "^4.7.6",
|
||||
"http-proxy": "^1.18.1",
|
||||
"immer": "^8.0.1",
|
||||
|
||||
@ -19,3 +19,6 @@ export * from "./downloadFile";
|
||||
export * from "./escapeRegExp";
|
||||
export * from "./tar";
|
||||
export * from "./type-narrowing";
|
||||
import * as iter from "./iter";
|
||||
|
||||
export { iter };
|
||||
|
||||
25
src/common/utils/iter.ts
Normal file
25
src/common/utils/iter.ts
Normal file
@ -0,0 +1,25 @@
|
||||
/**
|
||||
* Create a new type safe empty Iterable
|
||||
* @returns An `Iterable` that yields 0 items
|
||||
*/
|
||||
export function* newEmpty<T>(): Iterable<T> {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new `Iterable` that yields at most n items from src.
|
||||
* Does not modify `src` which can be used later.
|
||||
* @param src An initial iterator
|
||||
* @param n The maximum number of elements to take from src. Yields up to the floor of `n` and 0 items if n < 0
|
||||
*/
|
||||
export function* take<T>(src: Iterable<T>, n: number): Iterable<T> {
|
||||
outer: for (let i = 0; i < n; i += 1) {
|
||||
for (const item of src) {
|
||||
yield item;
|
||||
continue outer;
|
||||
}
|
||||
|
||||
// if we are here that means that `src` has been exhausted. Don't bother trying again.
|
||||
break outer;
|
||||
}
|
||||
}
|
||||
@ -2,18 +2,19 @@ import "./hotbar-icon.scss";
|
||||
|
||||
import React, { DOMAttributes } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { cssNames, IClassName } from "../../utils";
|
||||
import { cssNames, IClassName, iter } from "../../utils";
|
||||
import { Tooltip } from "../tooltip";
|
||||
import { Avatar } from "@material-ui/core";
|
||||
import { CatalogEntity, CatalogEntityContextMenu, CatalogEntityContextMenuContext } from "../../../common/catalog";
|
||||
import { Menu, MenuItem } from "../menu";
|
||||
import { Icon } from "../icon";
|
||||
import { observable } from "mobx";
|
||||
import { computed, observable } from "mobx";
|
||||
import { navigate } from "../../navigation";
|
||||
import { HotbarStore } from "../../../common/hotbar-store";
|
||||
import { ConfirmDialog } from "../confirm-dialog";
|
||||
import randomColor from "randomcolor";
|
||||
import { catalogCategoryRegistry } from "../../api/catalog-category-registry";
|
||||
import GraphemeSplitter from "grapheme-splitter";
|
||||
|
||||
interface Props extends DOMAttributes<HTMLElement> {
|
||||
entity: CatalogEntity;
|
||||
@ -23,6 +24,22 @@ interface Props extends DOMAttributes<HTMLElement> {
|
||||
isActive?: boolean;
|
||||
}
|
||||
|
||||
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(/@+/);
|
||||
}
|
||||
|
||||
@observer
|
||||
export class HotbarIcon extends React.Component<Props> {
|
||||
@observable.deep private contextMenu: CatalogEntityContextMenuContext;
|
||||
@ -35,26 +52,18 @@ export class HotbarIcon extends React.Component<Props> {
|
||||
};
|
||||
}
|
||||
|
||||
get iconString() {
|
||||
let splittedName = this.props.entity.metadata.name.split(" ");
|
||||
@computed get iconString() {
|
||||
const [rawFirst, rawSecond, rawThird] = getNameParts(this.props.entity.metadata.name);
|
||||
const splitter = new GraphemeSplitter();
|
||||
const first = splitter.iterateGraphemes(rawFirst);
|
||||
const second = rawSecond ? splitter.iterateGraphemes(rawSecond): first;
|
||||
const third = rawThird ? splitter.iterateGraphemes(rawThird) : iter.newEmpty();
|
||||
|
||||
if (splittedName.length === 1) {
|
||||
splittedName = splittedName[0].split("-");
|
||||
}
|
||||
|
||||
if (splittedName.length === 1) {
|
||||
splittedName = splittedName[0].split("@");
|
||||
}
|
||||
|
||||
splittedName = splittedName.map((part) => part.replace(/\W/g, ""));
|
||||
|
||||
if (splittedName.length === 1) {
|
||||
return splittedName[0].substring(0, 2);
|
||||
} else if (splittedName.length === 2) {
|
||||
return splittedName[0].substring(0, 1) + splittedName[1].substring(0, 1);
|
||||
} else {
|
||||
return splittedName[0].substring(0, 1) + splittedName[1].substring(0, 1) + splittedName[2].substring(0, 1);
|
||||
}
|
||||
return [
|
||||
...iter.take(first, 1),
|
||||
...iter.take(second, 1),
|
||||
...iter.take(third, 1),
|
||||
].filter(Boolean).join("");
|
||||
}
|
||||
|
||||
get badgeIcon() {
|
||||
|
||||
@ -6583,7 +6583,7 @@ graceful-fs@^4.1.0, graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2
|
||||
resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725"
|
||||
integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=
|
||||
|
||||
grapheme-splitter@^1.0.2:
|
||||
grapheme-splitter@^1.0.2, grapheme-splitter@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e"
|
||||
integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==
|
||||
|
||||
Loading…
Reference in New Issue
Block a user