mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Show active item in hotbar & allow to pin/unpin (#2790)
* show active item in hotbar & allow to pin it Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * cleanup Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * fix styles Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>
This commit is contained in:
parent
d08d5a24d7
commit
752f49821a
@ -20,7 +20,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import mockFs from "mock-fs";
|
import mockFs from "mock-fs";
|
||||||
import { CatalogEntityItem } from "../../renderer/components/+catalog/catalog-entity.store";
|
|
||||||
import { ClusterStore } from "../cluster-store";
|
import { ClusterStore } from "../cluster-store";
|
||||||
import { HotbarStore } from "../hotbar-store";
|
import { HotbarStore } from "../hotbar-store";
|
||||||
|
|
||||||
@ -159,10 +158,9 @@ describe("HotbarStore", () => {
|
|||||||
|
|
||||||
it("adds items", () => {
|
it("adds items", () => {
|
||||||
const hotbarStore = HotbarStore.createInstance();
|
const hotbarStore = HotbarStore.createInstance();
|
||||||
const entity = new CatalogEntityItem(testCluster);
|
|
||||||
|
|
||||||
hotbarStore.load();
|
hotbarStore.load();
|
||||||
hotbarStore.addToHotbar(entity);
|
hotbarStore.addToHotbar(testCluster);
|
||||||
const items = hotbarStore.getActive().items.filter(Boolean);
|
const items = hotbarStore.getActive().items.filter(Boolean);
|
||||||
|
|
||||||
expect(items.length).toEqual(1);
|
expect(items.length).toEqual(1);
|
||||||
@ -170,10 +168,9 @@ describe("HotbarStore", () => {
|
|||||||
|
|
||||||
it("removes items", () => {
|
it("removes items", () => {
|
||||||
const hotbarStore = HotbarStore.createInstance();
|
const hotbarStore = HotbarStore.createInstance();
|
||||||
const entity = new CatalogEntityItem(testCluster);
|
|
||||||
|
|
||||||
hotbarStore.load();
|
hotbarStore.load();
|
||||||
hotbarStore.addToHotbar(entity);
|
hotbarStore.addToHotbar(testCluster);
|
||||||
hotbarStore.removeFromHotbar("test");
|
hotbarStore.removeFromHotbar("test");
|
||||||
const items = hotbarStore.getActive().items.filter(Boolean);
|
const items = hotbarStore.getActive().items.filter(Boolean);
|
||||||
|
|
||||||
@ -182,10 +179,9 @@ describe("HotbarStore", () => {
|
|||||||
|
|
||||||
it("does nothing if removing with invalid uid", () => {
|
it("does nothing if removing with invalid uid", () => {
|
||||||
const hotbarStore = HotbarStore.createInstance();
|
const hotbarStore = HotbarStore.createInstance();
|
||||||
const entity = new CatalogEntityItem(testCluster);
|
|
||||||
|
|
||||||
hotbarStore.load();
|
hotbarStore.load();
|
||||||
hotbarStore.addToHotbar(entity);
|
hotbarStore.addToHotbar(testCluster);
|
||||||
hotbarStore.removeFromHotbar("invalid uid");
|
hotbarStore.removeFromHotbar("invalid uid");
|
||||||
const items = hotbarStore.getActive().items.filter(Boolean);
|
const items = hotbarStore.getActive().items.filter(Boolean);
|
||||||
|
|
||||||
@ -194,14 +190,11 @@ describe("HotbarStore", () => {
|
|||||||
|
|
||||||
it("moves item to empty cell", () => {
|
it("moves item to empty cell", () => {
|
||||||
const hotbarStore = HotbarStore.createInstance();
|
const hotbarStore = HotbarStore.createInstance();
|
||||||
const test = new CatalogEntityItem(testCluster);
|
|
||||||
const minikube = new CatalogEntityItem(minikubeCluster);
|
|
||||||
const aws = new CatalogEntityItem(awsCluster);
|
|
||||||
|
|
||||||
hotbarStore.load();
|
hotbarStore.load();
|
||||||
hotbarStore.addToHotbar(test);
|
hotbarStore.addToHotbar(testCluster);
|
||||||
hotbarStore.addToHotbar(minikube);
|
hotbarStore.addToHotbar(minikubeCluster);
|
||||||
hotbarStore.addToHotbar(aws);
|
hotbarStore.addToHotbar(awsCluster);
|
||||||
|
|
||||||
expect(hotbarStore.getActive().items[5]).toBeNull();
|
expect(hotbarStore.getActive().items[5]).toBeNull();
|
||||||
|
|
||||||
@ -213,14 +206,11 @@ describe("HotbarStore", () => {
|
|||||||
|
|
||||||
it("moves items down", () => {
|
it("moves items down", () => {
|
||||||
const hotbarStore = HotbarStore.createInstance();
|
const hotbarStore = HotbarStore.createInstance();
|
||||||
const test = new CatalogEntityItem(testCluster);
|
|
||||||
const minikube = new CatalogEntityItem(minikubeCluster);
|
|
||||||
const aws = new CatalogEntityItem(awsCluster);
|
|
||||||
|
|
||||||
hotbarStore.load();
|
hotbarStore.load();
|
||||||
hotbarStore.addToHotbar(test);
|
hotbarStore.addToHotbar(testCluster);
|
||||||
hotbarStore.addToHotbar(minikube);
|
hotbarStore.addToHotbar(minikubeCluster);
|
||||||
hotbarStore.addToHotbar(aws);
|
hotbarStore.addToHotbar(awsCluster);
|
||||||
|
|
||||||
// aws -> test
|
// aws -> test
|
||||||
hotbarStore.restackItems(2, 0);
|
hotbarStore.restackItems(2, 0);
|
||||||
@ -232,14 +222,11 @@ describe("HotbarStore", () => {
|
|||||||
|
|
||||||
it("moves items up", () => {
|
it("moves items up", () => {
|
||||||
const hotbarStore = HotbarStore.createInstance();
|
const hotbarStore = HotbarStore.createInstance();
|
||||||
const test = new CatalogEntityItem(testCluster);
|
|
||||||
const minikube = new CatalogEntityItem(minikubeCluster);
|
|
||||||
const aws = new CatalogEntityItem(awsCluster);
|
|
||||||
|
|
||||||
hotbarStore.load();
|
hotbarStore.load();
|
||||||
hotbarStore.addToHotbar(test);
|
hotbarStore.addToHotbar(testCluster);
|
||||||
hotbarStore.addToHotbar(minikube);
|
hotbarStore.addToHotbar(minikubeCluster);
|
||||||
hotbarStore.addToHotbar(aws);
|
hotbarStore.addToHotbar(awsCluster);
|
||||||
|
|
||||||
// test -> aws
|
// test -> aws
|
||||||
hotbarStore.restackItems(0, 2);
|
hotbarStore.restackItems(0, 2);
|
||||||
@ -251,10 +238,9 @@ describe("HotbarStore", () => {
|
|||||||
|
|
||||||
it("does nothing when item moved to same cell", () => {
|
it("does nothing when item moved to same cell", () => {
|
||||||
const hotbarStore = HotbarStore.createInstance();
|
const hotbarStore = HotbarStore.createInstance();
|
||||||
const test = new CatalogEntityItem(testCluster);
|
|
||||||
|
|
||||||
hotbarStore.load();
|
hotbarStore.load();
|
||||||
hotbarStore.addToHotbar(test);
|
hotbarStore.addToHotbar(testCluster);
|
||||||
hotbarStore.restackItems(0, 0);
|
hotbarStore.restackItems(0, 0);
|
||||||
|
|
||||||
expect(hotbarStore.getActive().items[0].entity.uid).toEqual("test");
|
expect(hotbarStore.getActive().items[0].entity.uid).toEqual("test");
|
||||||
@ -262,15 +248,12 @@ describe("HotbarStore", () => {
|
|||||||
|
|
||||||
it("new items takes first empty cell", () => {
|
it("new items takes first empty cell", () => {
|
||||||
const hotbarStore = HotbarStore.createInstance();
|
const hotbarStore = HotbarStore.createInstance();
|
||||||
const test = new CatalogEntityItem(testCluster);
|
|
||||||
const minikube = new CatalogEntityItem(minikubeCluster);
|
|
||||||
const aws = new CatalogEntityItem(awsCluster);
|
|
||||||
|
|
||||||
hotbarStore.load();
|
hotbarStore.load();
|
||||||
hotbarStore.addToHotbar(test);
|
hotbarStore.addToHotbar(testCluster);
|
||||||
hotbarStore.addToHotbar(aws);
|
hotbarStore.addToHotbar(awsCluster);
|
||||||
hotbarStore.restackItems(0, 3);
|
hotbarStore.restackItems(0, 3);
|
||||||
hotbarStore.addToHotbar(minikube);
|
hotbarStore.addToHotbar(minikubeCluster);
|
||||||
|
|
||||||
expect(hotbarStore.getActive().items[0].entity.uid).toEqual("minikube");
|
expect(hotbarStore.getActive().items[0].entity.uid).toEqual("minikube");
|
||||||
});
|
});
|
||||||
@ -282,10 +265,9 @@ describe("HotbarStore", () => {
|
|||||||
console.error = jest.fn();
|
console.error = jest.fn();
|
||||||
|
|
||||||
const hotbarStore = HotbarStore.createInstance();
|
const hotbarStore = HotbarStore.createInstance();
|
||||||
const test = new CatalogEntityItem(testCluster);
|
|
||||||
|
|
||||||
hotbarStore.load();
|
hotbarStore.load();
|
||||||
hotbarStore.addToHotbar(test);
|
hotbarStore.addToHotbar(testCluster);
|
||||||
|
|
||||||
expect(() => hotbarStore.restackItems(-5, 0)).toThrow();
|
expect(() => hotbarStore.restackItems(-5, 0)).toThrow();
|
||||||
expect(() => hotbarStore.restackItems(2, -1)).toThrow();
|
expect(() => hotbarStore.restackItems(2, -1)).toThrow();
|
||||||
|
|||||||
@ -23,8 +23,8 @@ import { action, comparer, observable, toJS } from "mobx";
|
|||||||
import { BaseStore } from "./base-store";
|
import { BaseStore } from "./base-store";
|
||||||
import migrations from "../migrations/hotbar-store";
|
import migrations from "../migrations/hotbar-store";
|
||||||
import * as uuid from "uuid";
|
import * as uuid from "uuid";
|
||||||
import { CatalogEntityItem } from "../renderer/components/+catalog/catalog-entity.store";
|
|
||||||
import isNull from "lodash/isNull";
|
import isNull from "lodash/isNull";
|
||||||
|
import { CatalogEntity } from "./catalog";
|
||||||
|
|
||||||
export interface HotbarItem {
|
export interface HotbarItem {
|
||||||
entity: {
|
entity: {
|
||||||
@ -151,15 +151,15 @@ export class HotbarStore extends BaseStore<HotbarStoreModel> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
addToHotbar(item: CatalogEntityItem, cellIndex = -1) {
|
addToHotbar(item: CatalogEntity, cellIndex = -1) {
|
||||||
const hotbar = this.getActive();
|
const hotbar = this.getActive();
|
||||||
const newItem = { entity: {
|
const newItem = { entity: {
|
||||||
uid: item.id,
|
uid: item.metadata.uid,
|
||||||
name: item.name,
|
name: item.metadata.name,
|
||||||
source: item.source
|
source: item.metadata.source
|
||||||
}};
|
}};
|
||||||
|
|
||||||
if (hotbar.items.find(i => i?.entity.uid === item.id)) {
|
if (hotbar.items.find(i => i?.entity.uid === item.metadata.uid)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -68,7 +68,7 @@ export class Catalog extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
addToHotbar(item: CatalogEntityItem): void {
|
addToHotbar(item: CatalogEntityItem): void {
|
||||||
HotbarStore.getInstance().addToHotbar(item);
|
HotbarStore.getInstance().addToHotbar(item.entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
onDetails(item: CatalogEntityItem) {
|
onDetails(item: CatalogEntityItem) {
|
||||||
@ -137,7 +137,7 @@ export class Catalog extends React.Component {
|
|||||||
return (
|
return (
|
||||||
<MenuActions onOpen={() => item.onContextMenuOpen(this.contextMenu)}>
|
<MenuActions onOpen={() => item.onContextMenuOpen(this.contextMenu)}>
|
||||||
<MenuItem key="add-to-hotbar" onClick={() => this.addToHotbar(item) }>
|
<MenuItem key="add-to-hotbar" onClick={() => this.addToHotbar(item) }>
|
||||||
<Icon material="add" small interactive={true} title="Add to hotbar"/> Add to Hotbar
|
<Icon material="push_pin" small interactive={true} title="Pin to Hotbar"/> Pin to Hotbar
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
{
|
{
|
||||||
menuItems.map((menuItem, index) => (
|
menuItems.map((menuItem, index) => (
|
||||||
|
|||||||
@ -18,26 +18,26 @@
|
|||||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
import "./hotbar-icon.scss";
|
|
||||||
|
|
||||||
import React, { DOMAttributes } from "react";
|
import React, { DOMAttributes } from "react";
|
||||||
import { observable } from "mobx";
|
import { observable } from "mobx";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import randomColor from "randomcolor";
|
|
||||||
|
|
||||||
import { CatalogEntity, CatalogEntityContextMenu, CatalogEntityContextMenuContext } from "../../../common/catalog";
|
import { CatalogEntity, CatalogEntityContextMenuContext } from "../../../common/catalog";
|
||||||
import { catalogCategoryRegistry } from "../../api/catalog-category-registry";
|
import { catalogCategoryRegistry } from "../../api/catalog-category-registry";
|
||||||
import { catalogEntityRegistry } from "../../api/catalog-entity-registry";
|
import { catalogEntityRegistry } from "../../api/catalog-entity-registry";
|
||||||
import { navigate } from "../../navigation";
|
import { navigate } from "../../navigation";
|
||||||
import { cssNames, IClassName } from "../../utils";
|
import { cssNames, IClassName } from "../../utils";
|
||||||
import { ConfirmDialog } from "../confirm-dialog";
|
|
||||||
import { Icon } from "../icon";
|
import { Icon } from "../icon";
|
||||||
import { HotbarIcon } from "./hotbar-icon";
|
import { HotbarIcon } from "./hotbar-icon";
|
||||||
|
import { HotbarStore } from "../../../common/hotbar-store";
|
||||||
|
|
||||||
interface Props extends DOMAttributes<HTMLElement> {
|
interface Props extends DOMAttributes<HTMLElement> {
|
||||||
entity: CatalogEntity;
|
entity: CatalogEntity;
|
||||||
|
index: number;
|
||||||
className?: IClassName;
|
className?: IClassName;
|
||||||
errorClass?: IClassName;
|
errorClass?: IClassName;
|
||||||
|
add: (item: CatalogEntity, index: number) => void;
|
||||||
remove: (uid: string) => void;
|
remove: (uid: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,33 +77,18 @@ export class HotbarEntityIcon extends React.Component<Props> {
|
|||||||
return catalogEntityRegistry.activeEntity?.metadata?.uid == item.getId();
|
return catalogEntityRegistry.activeEntity?.metadata?.uid == item.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
onMenuItemClick(menuItem: CatalogEntityContextMenu) {
|
isPersisted(entity: CatalogEntity) {
|
||||||
if (menuItem.confirm) {
|
return HotbarStore.getInstance().getActive().items.find((item) => item?.entity?.uid === entity.metadata.uid) !== undefined;
|
||||||
ConfirmDialog.open({
|
|
||||||
okButtonProps: {
|
|
||||||
primary: false,
|
|
||||||
accent: true,
|
|
||||||
},
|
|
||||||
ok: () => {
|
|
||||||
menuItem.onClick();
|
|
||||||
},
|
|
||||||
message: menuItem.confirm.message
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
menuItem.onClick();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
generateAvatarStyle(entity: CatalogEntity): React.CSSProperties {
|
|
||||||
return {
|
|
||||||
"backgroundColor": randomColor({ seed: `${entity.metadata.name}-${entity.metadata.source}`, luminosity: "dark" })
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
if (!this.contextMenu) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const {
|
const {
|
||||||
entity, errorClass, remove,
|
entity, errorClass, add, remove,
|
||||||
children, ...elemProps
|
index, children, ...elemProps
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const className = cssNames("HotbarEntityIcon", this.props.className, {
|
const className = cssNames("HotbarEntityIcon", this.props.className, {
|
||||||
interactive: true,
|
interactive: true,
|
||||||
@ -113,16 +98,31 @@ export class HotbarEntityIcon extends React.Component<Props> {
|
|||||||
const onOpen = async () => {
|
const onOpen = async () => {
|
||||||
await entity.onContextMenuOpen(this.contextMenu);
|
await entity.onContextMenuOpen(this.contextMenu);
|
||||||
};
|
};
|
||||||
|
const isActive = this.isActive(entity);
|
||||||
|
const isPersisted = this.isPersisted(entity);
|
||||||
const menuItems = this.contextMenu?.menuItems.filter((menuItem) => !menuItem.onlyVisibleForSource || menuItem.onlyVisibleForSource === entity.metadata.source);
|
const menuItems = this.contextMenu?.menuItems.filter((menuItem) => !menuItem.onlyVisibleForSource || menuItem.onlyVisibleForSource === entity.metadata.source);
|
||||||
|
|
||||||
|
if (!isPersisted) {
|
||||||
|
menuItems.unshift({
|
||||||
|
title: "Pin to Hotbar",
|
||||||
|
icon: "push_pin",
|
||||||
|
onClick: () => add(entity, index)
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
menuItems.unshift({
|
||||||
|
title: "Unpin from Hotbar",
|
||||||
|
icon: "push_pin",
|
||||||
|
onClick: () => remove(entity.metadata.uid)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<HotbarIcon
|
<HotbarIcon
|
||||||
uid={entity.getId()}
|
uid={entity.metadata.uid}
|
||||||
title={entity.getName()}
|
title={entity.metadata.name}
|
||||||
source={`${entity.metadata.source || "local"}`}
|
source={entity.metadata.source}
|
||||||
className={className}
|
className={className}
|
||||||
active={this.isActive(entity)}
|
active={isActive}
|
||||||
remove={remove}
|
|
||||||
onMenuOpen={onOpen}
|
onMenuOpen={onOpen}
|
||||||
menuItems={menuItems}
|
menuItems={menuItems}
|
||||||
{...elemProps}
|
{...elemProps}
|
||||||
|
|||||||
@ -36,11 +36,6 @@
|
|||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.active {
|
|
||||||
box-shadow: 0 0 0px 3px var(--clusterMenuBackground), 0 0 0px 6px var(--textColorAccent);
|
|
||||||
transition: all 0s 0.8s;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.disabled {
|
&.disabled {
|
||||||
opacity: 0.4;
|
opacity: 0.4;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
@ -53,23 +48,24 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.active, &.interactive:hover {
|
|
||||||
img {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
&:not(.active) {
|
|
||||||
box-shadow: 0 0 0px 3px var(--clusterMenuBackground), 0 0 0px 6px #ffffff30;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.isDragging {
|
&.isDragging {
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
> .led {
|
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;
|
position: absolute;
|
||||||
left: 3px;
|
left: 3px;
|
||||||
top: 3px;
|
top: 3px;
|
||||||
|
|||||||
@ -32,12 +32,12 @@ import { ConfirmDialog } from "../confirm-dialog";
|
|||||||
import { Icon } from "../icon";
|
import { Icon } from "../icon";
|
||||||
import { Menu, MenuItem } from "../menu";
|
import { Menu, MenuItem } from "../menu";
|
||||||
import { MaterialTooltip } from "../+catalog/material-tooltip/material-tooltip";
|
import { MaterialTooltip } from "../+catalog/material-tooltip/material-tooltip";
|
||||||
|
import { observer } from "mobx-react";
|
||||||
|
|
||||||
interface Props extends DOMAttributes<HTMLElement> {
|
interface Props extends DOMAttributes<HTMLElement> {
|
||||||
uid: string;
|
uid: string;
|
||||||
title: string;
|
title: string;
|
||||||
source: string;
|
source: string;
|
||||||
remove: (uid: string) => void;
|
|
||||||
onMenuOpen?: () => void;
|
onMenuOpen?: () => void;
|
||||||
className?: IClassName;
|
className?: IClassName;
|
||||||
active?: boolean;
|
active?: boolean;
|
||||||
@ -84,8 +84,8 @@ function getNameParts(name: string): string[] {
|
|||||||
return name.split(/@+/);
|
return name.split(/@+/);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function HotbarIcon(props: Props) {
|
export const HotbarIcon = observer(({menuItems = [], ...props}: Props) => {
|
||||||
const { uid, title, className, source, active, remove, disabled, menuItems, onMenuOpen, children, ...rest } = props;
|
const { uid, title, active, className, source, disabled, onMenuOpen, children, ...rest } = props;
|
||||||
const id = `hotbarIcon-${uid}`;
|
const id = `hotbarIcon-${uid}`;
|
||||||
const [menuOpen, setMenuOpen] = useState(false);
|
const [menuOpen, setMenuOpen] = useState(false);
|
||||||
|
|
||||||
@ -134,12 +134,6 @@ export function HotbarIcon(props: Props) {
|
|||||||
toggleMenu();
|
toggleMenu();
|
||||||
}}
|
}}
|
||||||
close={() => toggleMenu()}>
|
close={() => toggleMenu()}>
|
||||||
<MenuItem key="remove-from-hotbar" onClick={(evt) => {
|
|
||||||
evt.stopPropagation();
|
|
||||||
remove(uid);
|
|
||||||
}}>
|
|
||||||
<Icon material="clear" small interactive={true} title="Remove from hotbar"/> Remove from Hotbar
|
|
||||||
</MenuItem>
|
|
||||||
{ menuItems.map((menuItem) => {
|
{ menuItems.map((menuItem) => {
|
||||||
return (
|
return (
|
||||||
<MenuItem key={menuItem.title} onClick={() => onMenuItemClick(menuItem) }>
|
<MenuItem key={menuItem.title} onClick={() => onMenuItemClick(menuItem) }>
|
||||||
@ -150,8 +144,4 @@ export function HotbarIcon(props: Props) {
|
|||||||
</Menu>
|
</Menu>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
});
|
||||||
|
|
||||||
HotbarIcon.defaultProps = {
|
|
||||||
menuItems: []
|
|
||||||
};
|
|
||||||
|
|||||||
@ -28,11 +28,12 @@ import { HotbarEntityIcon } from "./hotbar-entity-icon";
|
|||||||
import { cssNames, IClassName } from "../../utils";
|
import { cssNames, IClassName } from "../../utils";
|
||||||
import { catalogEntityRegistry } from "../../api/catalog-entity-registry";
|
import { catalogEntityRegistry } from "../../api/catalog-entity-registry";
|
||||||
import { defaultHotbarCells, HotbarItem, HotbarStore } from "../../../common/hotbar-store";
|
import { defaultHotbarCells, HotbarItem, HotbarStore } from "../../../common/hotbar-store";
|
||||||
import { catalogEntityRunContext } from "../../api/catalog-entity";
|
import { CatalogEntity, catalogEntityRunContext } from "../../api/catalog-entity";
|
||||||
import { DragDropContext, Draggable, Droppable, DropResult } from "react-beautiful-dnd";
|
import { DragDropContext, Draggable, Droppable, DropResult } from "react-beautiful-dnd";
|
||||||
import { HotbarSelector } from "./hotbar-selector";
|
import { HotbarSelector } from "./hotbar-selector";
|
||||||
import { HotbarCell } from "./hotbar-cell";
|
import { HotbarCell } from "./hotbar-cell";
|
||||||
import { HotbarIcon } from "./hotbar-icon";
|
import { HotbarIcon } from "./hotbar-icon";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
className?: IClassName;
|
className?: IClassName;
|
||||||
@ -64,6 +65,10 @@ export class HotbarMenu extends React.Component<Props> {
|
|||||||
const from = parseInt(source.droppableId);
|
const from = parseInt(source.droppableId);
|
||||||
const to = parseInt(destination.droppableId);
|
const to = parseInt(destination.droppableId);
|
||||||
|
|
||||||
|
if (!this.hotbar.items[from]) { // Dropped non-persisted item
|
||||||
|
this.hotbar.items[from] = this.items[from];
|
||||||
|
}
|
||||||
|
|
||||||
HotbarStore.getInstance().restackItems(from, to);
|
HotbarStore.getInstance().restackItems(from, to);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,14 +78,38 @@ export class HotbarMenu extends React.Component<Props> {
|
|||||||
hotbar.removeFromHotbar(uid);
|
hotbar.removeFromHotbar(uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addItem(entity: CatalogEntity, index = -1) {
|
||||||
|
const hotbar = HotbarStore.getInstance();
|
||||||
|
|
||||||
|
hotbar.addToHotbar(entity, index);
|
||||||
|
}
|
||||||
|
|
||||||
getMoveAwayDirection(entityId: string, cellIndex: number) {
|
getMoveAwayDirection(entityId: string, cellIndex: number) {
|
||||||
const draggableItemIndex = this.hotbar.items.findIndex(item => item?.entity.uid == entityId);
|
const draggableItemIndex = this.hotbar.items.findIndex(item => item?.entity.uid == entityId);
|
||||||
|
|
||||||
return draggableItemIndex > cellIndex ? "animateDown" : "animateUp";
|
return draggableItemIndex > cellIndex ? "animateDown" : "animateUp";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@computed get items() {
|
||||||
|
const items = this.hotbar.items;
|
||||||
|
const activeEntity = catalogEntityRegistry.activeEntity;
|
||||||
|
|
||||||
|
if (!activeEntity) return items;
|
||||||
|
|
||||||
|
const emptyIndex = items.indexOf(null);
|
||||||
|
|
||||||
|
if (emptyIndex === -1) return items;
|
||||||
|
if (items.find((item) => item?.entity?.uid === activeEntity.metadata.uid)) return items;
|
||||||
|
|
||||||
|
const modifiedItems = [...items];
|
||||||
|
|
||||||
|
modifiedItems.splice(emptyIndex, 1, { entity: { uid: activeEntity.metadata.uid }});
|
||||||
|
|
||||||
|
return modifiedItems;
|
||||||
|
}
|
||||||
|
|
||||||
renderGrid() {
|
renderGrid() {
|
||||||
return this.hotbar.items.map((item, index) => {
|
return this.items.map((item, index) => {
|
||||||
const entity = this.getEntity(item);
|
const entity = this.getEntity(item);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -116,17 +145,18 @@ export class HotbarMenu extends React.Component<Props> {
|
|||||||
{entity ? (
|
{entity ? (
|
||||||
<HotbarEntityIcon
|
<HotbarEntityIcon
|
||||||
key={index}
|
key={index}
|
||||||
|
index={index}
|
||||||
entity={entity}
|
entity={entity}
|
||||||
onClick={() => entity.onRun(catalogEntityRunContext)}
|
onClick={() => entity.onRun(catalogEntityRunContext)}
|
||||||
className={cssNames({ isDragging: snapshot.isDragging })}
|
className={cssNames({ isDragging: snapshot.isDragging })}
|
||||||
remove={this.removeItem}
|
remove={this.removeItem}
|
||||||
|
add={this.addItem}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<HotbarIcon
|
<HotbarIcon
|
||||||
uid={item.entity.uid}
|
uid={item.entity.uid}
|
||||||
title={item.entity.name}
|
title={item.entity.name}
|
||||||
source={item.entity.source}
|
source={item.entity.source}
|
||||||
remove={this.removeItem}
|
|
||||||
disabled
|
disabled
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@ -151,7 +181,7 @@ export class HotbarMenu extends React.Component<Props> {
|
|||||||
return (
|
return (
|
||||||
<div className={cssNames("HotbarMenu flex column", className)}>
|
<div className={cssNames("HotbarMenu flex column", className)}>
|
||||||
<div className="HotbarItems flex column gaps">
|
<div className="HotbarItems flex column gaps">
|
||||||
<DragDropContext onDragEnd={this.onDragEnd}>
|
<DragDropContext onDragEnd={this.onDragEnd.bind(this)}>
|
||||||
{this.renderGrid()}
|
{this.renderGrid()}
|
||||||
</DragDropContext>
|
</DragDropContext>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user