mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Technical requirements for behavioural unit tests (#5084)
* Implement a lot of technical requirements for behavioural unit tests Note: the crux of this was to make routing env-agnostic, and not based on URLs as magic strings, but instead something type-enforced. Note: extension-based routes comply to same exact interface by "late-registering" their routes when installed. Routes are just injectables. Note: another chunk of global shared state is no more. Note: a lot of explicit side effects have been cornered to injectables. Note: a lot of stuff has become reactive as part if this. Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Make a directory commonly available Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Require id for <Select /> to prevent non-deterministic renders This was caused by global state in a 3rd party lib: "react-select". Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Specify id for all <Select /> to satisfy previous commit Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Prevent explicit side effect in component by using existing dependency instead Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Extract instantiation of "conf" as injectables for causing side effects Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Introduce a legacy-helper to make gradual refactoring of inheritors of Singleton easier Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Make legacy unit tests for hotbar green and more simple by using the new legacy helper Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Temporarily kludge all unit tests green with a disclaimer about allowing side-effects Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Remove kludge in previous commit by explicitly permitting specific side effects where old unit tests require it Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Prevent old unit test with side effects from accessing file system Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Migrate to actual typing for di.permitSideEffects Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Prevent unit tests from failing because of non-standard method of HTML-element not present in js-dom Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Adapt integration tests to recent changes Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Fix code style Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Fix artifact from bad rebase Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Add a deprecation from a review comment Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Remove change that is not required Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Remove redundant comment Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Fix code style Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Remove redundant file Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Fix bad merge Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Improve variable name Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Tweak logger interface to be more descriptive Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Make injecting legacy singleton always provide new instance Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Remove conditional typing when not needed Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Improve naming of variable Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Remove unnecessary code style changes Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Remove flag for causing side effects from too broad scope Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Override side-effects in unit test using injectable instead of monkey patching Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Flag some side-effects and add general overrides Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Fix unit tests in CI by removing explicit side-effect Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Remove explicit side-effect from getting default shell Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Introduce abstraction for getting absolute paths Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Switch to using abstraction for getting absolute path to control explicit side effect Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Introduce abstraction for joining paths Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Switch to using abstraction for joining paths to control explicit side effect Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Fix fake implementation for join paths Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Fix test after removing explicit side effect Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Remove explicit side effects from kubeconfig-syncs Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Fix arguments after removing explicit side effect Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Make registrators not async for not being needed anymore Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Make generalCatalogEntities non-observable, as there is no requirement Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Remove redundant code Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Simplify logic for registering general catalog entity sources Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Add TODO Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Replace function for getting application menu items with reactive solution Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Fix typo in interface name Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Remove global shared state usages of hot bar store Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Remove redundant enum Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> Co-authored-by: Janne Savolainen <janne.savolainen@live.fi>
This commit is contained in:
1 parent
ab2cd27a27
commit
a277cfcf02
583 files changed
+13073
-6556
No files matched your search
@@ -10,13 +10,15 @@ import React from "react";
|
||||
import type { DiContainer } from "@ogre-tools/injectable";
|
||||
import { getDiForUnitTesting } from "../../../getDiForUnitTesting";
|
||||
import { DiRender, renderFor } from "../../test-utils/renderFor";
|
||||
import hotbarManagerInjectable from "../../../../common/hotbar-store.injectable";
|
||||
import hotbarStoreInjectable from "../../../../common/hotbar-store.injectable";
|
||||
import { ThemeStore } from "../../../theme.store";
|
||||
import { ConfirmDialog } from "../../confirm-dialog";
|
||||
import type { HotbarStore } from "../../../../common/hotbar-store";
|
||||
import { UserStore } from "../../../../common/user-store";
|
||||
import mockFs from "mock-fs";
|
||||
import directoryForUserDataInjectable from "../../../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable";
|
||||
import getConfigurationFileModelInjectable from "../../../../common/get-configuration-file-model/get-configuration-file-model.injectable";
|
||||
import appVersionInjectable from "../../../../common/get-configuration-file-model/app-version/app-version.injectable";
|
||||
import type { HotbarStore } from "../../../../common/hotbar-store";
|
||||
|
||||
const mockHotbars: { [id: string]: any } = {
|
||||
"1": {
|
||||
@@ -44,6 +46,10 @@ describe("<HotbarRemoveCommand />", () => {
|
||||
|
||||
di.override(directoryForUserDataInjectable, () => "some-directory-for-user-data");
|
||||
|
||||
di.permitSideEffects(hotbarStoreInjectable);
|
||||
di.permitSideEffects(getConfigurationFileModelInjectable);
|
||||
di.permitSideEffects(appVersionInjectable);
|
||||
|
||||
render = renderFor(di);
|
||||
|
||||
UserStore.createInstance();
|
||||
@@ -57,7 +63,7 @@ describe("<HotbarRemoveCommand />", () => {
|
||||
});
|
||||
|
||||
it("renders w/o errors", async () => {
|
||||
di.override(hotbarManagerInjectable, () => ({
|
||||
di.override(hotbarStoreInjectable, () => ({
|
||||
hotbars: [mockHotbars["1"]],
|
||||
getById: (id: string) => mockHotbars[id],
|
||||
remove: () => {
|
||||
@@ -76,7 +82,7 @@ describe("<HotbarRemoveCommand />", () => {
|
||||
it("calls remove if you click on the entry", async () => {
|
||||
const removeMock = jest.fn();
|
||||
|
||||
di.override(hotbarManagerInjectable, () => ({
|
||||
di.override(hotbarStoreInjectable, () => ({
|
||||
hotbars: [mockHotbars["1"]],
|
||||
getById: (id: string) => mockHotbars[id],
|
||||
remove: removeMock,
|
||||
|
||||
@@ -9,7 +9,7 @@ import { Input, InputValidator } from "../input";
|
||||
import type { CreateHotbarData, CreateHotbarOptions } from "../../../common/hotbar-types";
|
||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import commandOverlayInjectable from "../command-palette/command-overlay.injectable";
|
||||
import hotbarManagerInjectable from "../../../common/hotbar-store.injectable";
|
||||
import hotbarStoreInjectable from "../../../common/hotbar-store.injectable";
|
||||
import uniqueHotbarNameInjectable from "../input/validators/unique-hotbar-name.injectable";
|
||||
|
||||
interface Dependencies {
|
||||
@@ -50,7 +50,7 @@ const NonInjectedHotbarAddCommand = observer(({ closeCommandOverlay, addHotbar,
|
||||
export const HotbarAddCommand = withInjectables<Dependencies>(NonInjectedHotbarAddCommand, {
|
||||
getProps: (di, props) => ({
|
||||
closeCommandOverlay: di.inject(commandOverlayInjectable).close,
|
||||
addHotbar: di.inject(hotbarManagerInjectable).add,
|
||||
addHotbar: di.inject(hotbarStoreInjectable).add,
|
||||
uniqueHotbarName: di.inject(uniqueHotbarNameInjectable),
|
||||
...props,
|
||||
}),
|
||||
|
||||
@@ -10,7 +10,6 @@ import { observer } from "mobx-react";
|
||||
import { HotbarEntityIcon } from "./hotbar-entity-icon";
|
||||
import { cssNames, IClassName } from "../../utils";
|
||||
import { catalogEntityRegistry } from "../../api/catalog-entity-registry";
|
||||
import { HotbarStore } from "../../../common/hotbar-store";
|
||||
import type { CatalogEntity } from "../../api/catalog-entity";
|
||||
import { DragDropContext, Draggable, Droppable, type DropResult } from "react-beautiful-dnd";
|
||||
import { HotbarSelector } from "./hotbar-selector";
|
||||
@@ -18,26 +17,33 @@ import { HotbarCell } from "./hotbar-cell";
|
||||
import { HotbarIcon } from "./hotbar-icon";
|
||||
import { defaultHotbarCells, HotbarItem } from "../../../common/hotbar-types";
|
||||
import { action, makeObservable, observable } from "mobx";
|
||||
import hotbarStoreInjectable from "../../../common/hotbar-store.injectable";
|
||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import type { HotbarStore } from "../../../common/hotbar-store";
|
||||
|
||||
export interface HotbarMenuProps {
|
||||
className?: IClassName;
|
||||
}
|
||||
|
||||
interface Dependencies {
|
||||
hotbarStore: HotbarStore;
|
||||
}
|
||||
|
||||
@observer
|
||||
export class HotbarMenu extends React.Component<HotbarMenuProps> {
|
||||
class NonInjectedHotbarMenu extends React.Component<Dependencies & HotbarMenuProps> {
|
||||
@observable draggingOver = false;
|
||||
|
||||
constructor(props: HotbarMenuProps) {
|
||||
constructor(props: Dependencies & HotbarMenuProps) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
get hotbar() {
|
||||
return HotbarStore.getInstance().getActive();
|
||||
return this.props.hotbarStore.getActive();
|
||||
}
|
||||
|
||||
getEntity(item: HotbarItem) {
|
||||
const hotbar = HotbarStore.getInstance().getActive();
|
||||
const hotbar = this.props.hotbarStore.getActive();
|
||||
|
||||
if (!hotbar) {
|
||||
return null;
|
||||
@@ -64,17 +70,17 @@ export class HotbarMenu extends React.Component<HotbarMenuProps> {
|
||||
const from = parseInt(source.droppableId);
|
||||
const to = parseInt(destination.droppableId);
|
||||
|
||||
HotbarStore.getInstance().restackItems(from, to);
|
||||
this.props.hotbarStore.restackItems(from, to);
|
||||
}
|
||||
|
||||
removeItem(uid: string) {
|
||||
const hotbar = HotbarStore.getInstance();
|
||||
const hotbar = this.props.hotbarStore;
|
||||
|
||||
hotbar.removeFromHotbar(uid);
|
||||
}
|
||||
|
||||
addItem(entity: CatalogEntity, index = -1) {
|
||||
const hotbar = HotbarStore.getInstance();
|
||||
const hotbar = this.props.hotbarStore;
|
||||
|
||||
hotbar.addToHotbar(entity, index);
|
||||
}
|
||||
@@ -160,8 +166,7 @@ export class HotbarMenu extends React.Component<HotbarMenuProps> {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { className } = this.props;
|
||||
const hotbarStore = HotbarStore.getInstance();
|
||||
const { className, hotbarStore } = this.props;
|
||||
const hotbar = hotbarStore.getActive();
|
||||
|
||||
return (
|
||||
@@ -176,3 +181,14 @@ export class HotbarMenu extends React.Component<HotbarMenuProps> {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const HotbarMenu = withInjectables<Dependencies, HotbarMenuProps>(
|
||||
NonInjectedHotbarMenu,
|
||||
|
||||
{
|
||||
getProps: (di, props) => ({
|
||||
hotbarStore: di.inject(hotbarStoreInjectable),
|
||||
...props,
|
||||
}),
|
||||
},
|
||||
);
|
||||
@@ -6,7 +6,7 @@
|
||||
import React from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { Select } from "../select";
|
||||
import hotbarManagerInjectable from "../../../common/hotbar-store.injectable";
|
||||
import hotbarStoreInjectable from "../../../common/hotbar-store.injectable";
|
||||
import { ConfirmDialog } from "../confirm-dialog";
|
||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import commandOverlayInjectable from "../command-palette/command-overlay.injectable";
|
||||
@@ -14,7 +14,7 @@ import type { Hotbar } from "../../../common/hotbar-types";
|
||||
|
||||
interface Dependencies {
|
||||
closeCommandOverlay: () => void;
|
||||
hotbarManager: {
|
||||
hotbarStore: {
|
||||
hotbars: Hotbar[];
|
||||
getById: (id: string) => Hotbar | undefined;
|
||||
remove: (hotbar: Hotbar) => void;
|
||||
@@ -22,14 +22,14 @@ interface Dependencies {
|
||||
};
|
||||
}
|
||||
|
||||
const NonInjectedHotbarRemoveCommand = observer(({ closeCommandOverlay, hotbarManager }: Dependencies) => {
|
||||
const options = hotbarManager.hotbars.map(hotbar => ({
|
||||
const NonInjectedHotbarRemoveCommand = observer(({ closeCommandOverlay, hotbarStore }: Dependencies) => {
|
||||
const options = hotbarStore.hotbars.map(hotbar => ({
|
||||
value: hotbar.id,
|
||||
label: hotbarManager.getDisplayLabel(hotbar),
|
||||
label: hotbarStore.getDisplayLabel(hotbar),
|
||||
}));
|
||||
|
||||
const onChange = (id: string): void => {
|
||||
const hotbar = hotbarManager.getById(id);
|
||||
const hotbar = hotbarStore.getById(id);
|
||||
|
||||
if (!hotbar) {
|
||||
return;
|
||||
@@ -43,7 +43,7 @@ const NonInjectedHotbarRemoveCommand = observer(({ closeCommandOverlay, hotbarMa
|
||||
primary: false,
|
||||
accent: true,
|
||||
},
|
||||
ok: () => hotbarManager.remove(hotbar),
|
||||
ok: () => hotbarStore.remove(hotbar),
|
||||
message: (
|
||||
<div className="confirm flex column gaps">
|
||||
<p>
|
||||
@@ -56,6 +56,7 @@ const NonInjectedHotbarRemoveCommand = observer(({ closeCommandOverlay, hotbarMa
|
||||
|
||||
return (
|
||||
<Select
|
||||
id="remove-hotbar-input"
|
||||
menuPortalTarget={null}
|
||||
onChange={(v) => onChange(v.value)}
|
||||
components={{ DropdownIndicator: null, IndicatorSeparator: null }}
|
||||
@@ -71,7 +72,7 @@ const NonInjectedHotbarRemoveCommand = observer(({ closeCommandOverlay, hotbarMa
|
||||
export const HotbarRemoveCommand = withInjectables<Dependencies>(NonInjectedHotbarRemoveCommand, {
|
||||
getProps: (di, props) => ({
|
||||
closeCommandOverlay: di.inject(commandOverlayInjectable).close,
|
||||
hotbarManager: di.inject(hotbarManagerInjectable),
|
||||
hotbarStore: di.inject(hotbarStoreInjectable),
|
||||
...props,
|
||||
}),
|
||||
});
|
||||
@@ -6,7 +6,7 @@
|
||||
import React, { useState } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { Select } from "../select";
|
||||
import hotbarManagerInjectable from "../../../common/hotbar-store.injectable";
|
||||
import hotbarStoreInjectable from "../../../common/hotbar-store.injectable";
|
||||
import { Input, InputValidator } from "../input";
|
||||
import type { Hotbar } from "../../../common/hotbar-types";
|
||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
@@ -15,7 +15,7 @@ import uniqueHotbarNameInjectable from "../input/validators/unique-hotbar-name.i
|
||||
|
||||
interface Dependencies {
|
||||
closeCommandOverlay: () => void;
|
||||
hotbarManager: {
|
||||
hotbarStore: {
|
||||
hotbars: Hotbar[];
|
||||
getById: (id: string) => Hotbar | undefined;
|
||||
setHotbarName: (id: string, name: string) => void;
|
||||
@@ -24,25 +24,25 @@ interface Dependencies {
|
||||
uniqueHotbarName: InputValidator;
|
||||
}
|
||||
|
||||
const NonInjectedHotbarRenameCommand = observer(({ closeCommandOverlay, hotbarManager, uniqueHotbarName }: Dependencies) => {
|
||||
const NonInjectedHotbarRenameCommand = observer(({ closeCommandOverlay, hotbarStore, uniqueHotbarName }: Dependencies) => {
|
||||
const [hotbarId, setHotbarId] = useState("");
|
||||
const [hotbarName, setHotbarName] = useState("");
|
||||
|
||||
const options = hotbarManager.hotbars.map(hotbar => ({
|
||||
const options = hotbarStore.hotbars.map(hotbar => ({
|
||||
value: hotbar.id,
|
||||
label: hotbarManager.getDisplayLabel(hotbar),
|
||||
label: hotbarStore.getDisplayLabel(hotbar),
|
||||
}));
|
||||
|
||||
const onSelect = (id: string) => {
|
||||
setHotbarId(id);
|
||||
setHotbarName(hotbarManager.getById(id).name);
|
||||
setHotbarName(hotbarStore.getById(id).name);
|
||||
};
|
||||
const onSubmit = (name: string) => {
|
||||
if (!name.trim()) {
|
||||
return;
|
||||
}
|
||||
|
||||
hotbarManager.setHotbarName(hotbarId, name);
|
||||
hotbarStore.setHotbarName(hotbarId, name);
|
||||
closeCommandOverlay();
|
||||
};
|
||||
|
||||
@@ -69,6 +69,7 @@ const NonInjectedHotbarRenameCommand = observer(({ closeCommandOverlay, hotbarMa
|
||||
|
||||
return (
|
||||
<Select
|
||||
id="rename-hotbar-input"
|
||||
menuPortalTarget={null}
|
||||
onChange={(v) => onSelect(v.value)}
|
||||
components={{ DropdownIndicator: null, IndicatorSeparator: null }}
|
||||
@@ -84,7 +85,7 @@ const NonInjectedHotbarRenameCommand = observer(({ closeCommandOverlay, hotbarMa
|
||||
export const HotbarRenameCommand = withInjectables<Dependencies>(NonInjectedHotbarRenameCommand, {
|
||||
getProps: (di, props) => ({
|
||||
closeCommandOverlay: di.inject(commandOverlayInjectable).close,
|
||||
hotbarManager: di.inject(hotbarManagerInjectable),
|
||||
hotbarStore: di.inject(hotbarStoreInjectable),
|
||||
uniqueHotbarName: di.inject(uniqueHotbarNameInjectable),
|
||||
...props,
|
||||
}),
|
||||
|
||||
@@ -7,7 +7,7 @@ import styles from "./hotbar-selector.module.scss";
|
||||
import React, { useRef, useState } from "react";
|
||||
import { Icon } from "../icon";
|
||||
import { Badge } from "../badge";
|
||||
import hotbarManagerInjectable from "../../../common/hotbar-store.injectable";
|
||||
import hotbarStoreInjectable from "../../../common/hotbar-store.injectable";
|
||||
import { HotbarSwitchCommand } from "./hotbar-switch-command";
|
||||
import { Tooltip, TooltipPosition } from "../tooltip";
|
||||
import { observer } from "mobx-react";
|
||||
@@ -17,7 +17,7 @@ import commandOverlayInjectable from "../command-palette/command-overlay.injecta
|
||||
import { cssNames } from "../../utils";
|
||||
|
||||
interface Dependencies {
|
||||
hotbarManager: {
|
||||
hotbarStore: {
|
||||
switchToPrevious: () => void;
|
||||
switchToNext: () => void;
|
||||
getActive: () => Hotbar;
|
||||
@@ -30,7 +30,7 @@ export interface HotbarSelectorProps extends Partial<Dependencies> {
|
||||
hotbar: Hotbar;
|
||||
}
|
||||
|
||||
const NonInjectedHotbarSelector = observer(({ hotbar, hotbarManager, openCommandOverlay }: HotbarSelectorProps & Dependencies) => {
|
||||
const NonInjectedHotbarSelector = observer(({ hotbar, hotbarStore, openCommandOverlay }: HotbarSelectorProps & Dependencies) => {
|
||||
const [tooltipVisible, setTooltipVisible] = useState(false);
|
||||
const tooltipTimeout = useRef<NodeJS.Timeout>();
|
||||
|
||||
@@ -59,13 +59,13 @@ const NonInjectedHotbarSelector = observer(({ hotbar, hotbarManager, openCommand
|
||||
<Icon
|
||||
material="play_arrow"
|
||||
className={cssNames(styles.Icon, styles.previous)}
|
||||
onClick={() => onArrowClick(hotbarManager.switchToPrevious)}
|
||||
onClick={() => onArrowClick(hotbarStore.switchToPrevious)}
|
||||
/>
|
||||
<div className={styles.HotbarIndex}>
|
||||
<Badge
|
||||
id="hotbarIndex"
|
||||
small
|
||||
label={hotbarManager.getDisplayIndex(hotbarManager.getActive())}
|
||||
label={hotbarStore.getDisplayIndex(hotbarStore.getActive())}
|
||||
onClick={() => openCommandOverlay(<HotbarSwitchCommand />)}
|
||||
className={styles.Badge}
|
||||
onMouseEnter={onMouseEvent}
|
||||
@@ -79,14 +79,14 @@ const NonInjectedHotbarSelector = observer(({ hotbar, hotbarManager, openCommand
|
||||
{hotbar.name}
|
||||
</Tooltip>
|
||||
</div>
|
||||
<Icon material="play_arrow" className={styles.Icon} onClick={() => onArrowClick(hotbarManager.switchToNext)} />
|
||||
<Icon material="play_arrow" className={styles.Icon} onClick={() => onArrowClick(hotbarStore.switchToNext)} />
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
export const HotbarSelector = withInjectables<Dependencies, HotbarSelectorProps>(NonInjectedHotbarSelector, {
|
||||
getProps: (di, props) => ({
|
||||
hotbarManager: di.inject(hotbarManagerInjectable),
|
||||
hotbarStore: di.inject(hotbarStoreInjectable),
|
||||
openCommandOverlay: di.inject(commandOverlayInjectable).open,
|
||||
...props,
|
||||
}),
|
||||
|
||||
@@ -6,39 +6,33 @@
|
||||
import React from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { Select } from "../select";
|
||||
import hotbarManagerInjectable from "../../../common/hotbar-store.injectable";
|
||||
import hotbarStoreInjectable from "../../../common/hotbar-store.injectable";
|
||||
import type { CommandOverlay } from "../command-palette";
|
||||
import { HotbarAddCommand } from "./hotbar-add-command";
|
||||
import { HotbarRemoveCommand } from "./hotbar-remove-command";
|
||||
import { HotbarRenameCommand } from "./hotbar-rename-command";
|
||||
import type { Hotbar } from "../../../common/hotbar-types";
|
||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import commandOverlayInjectable from "../command-palette/command-overlay.injectable";
|
||||
import type { HotbarStore } from "../../../common/hotbar-store";
|
||||
|
||||
const addActionId = "__add__";
|
||||
const removeActionId = "__remove__";
|
||||
const renameActionId = "__rename__";
|
||||
|
||||
interface HotbarManager {
|
||||
hotbars: Hotbar[];
|
||||
setActiveHotbar: (id: string) => void;
|
||||
getDisplayLabel: (hotbar: Hotbar) => string;
|
||||
}
|
||||
|
||||
interface Dependencies {
|
||||
hotbarManager: HotbarManager;
|
||||
hotbarStore: HotbarStore;
|
||||
commandOverlay: CommandOverlay;
|
||||
}
|
||||
|
||||
function getHotbarSwitchOptions(hotbarManager: HotbarManager) {
|
||||
const options = hotbarManager.hotbars.map(hotbar => ({
|
||||
function getHotbarSwitchOptions(hotbarStore: HotbarStore) {
|
||||
const options = hotbarStore.hotbars.map(hotbar => ({
|
||||
value: hotbar.id,
|
||||
label: hotbarManager.getDisplayLabel(hotbar),
|
||||
label: hotbarStore.getDisplayLabel(hotbar),
|
||||
}));
|
||||
|
||||
options.push({ value: addActionId, label: "Add hotbar ..." });
|
||||
|
||||
if (hotbarManager.hotbars.length > 1) {
|
||||
if (hotbarStore.hotbars.length > 1) {
|
||||
options.push({ value: removeActionId, label: "Remove hotbar ..." });
|
||||
}
|
||||
|
||||
@@ -47,8 +41,8 @@ function getHotbarSwitchOptions(hotbarManager: HotbarManager) {
|
||||
return options;
|
||||
}
|
||||
|
||||
const NonInjectedHotbarSwitchCommand = observer(({ hotbarManager, commandOverlay }: Dependencies) => {
|
||||
const options = getHotbarSwitchOptions(hotbarManager);
|
||||
const NonInjectedHotbarSwitchCommand = observer(({ hotbarStore, commandOverlay }: Dependencies) => {
|
||||
const options = getHotbarSwitchOptions(hotbarStore);
|
||||
|
||||
const onChange = (idOrAction: string): void => {
|
||||
switch (idOrAction) {
|
||||
@@ -59,13 +53,14 @@ const NonInjectedHotbarSwitchCommand = observer(({ hotbarManager, commandOverlay
|
||||
case renameActionId:
|
||||
return commandOverlay.open(<HotbarRenameCommand />);
|
||||
default:
|
||||
hotbarManager.setActiveHotbar(idOrAction);
|
||||
hotbarStore.setActiveHotbar(idOrAction);
|
||||
commandOverlay.close();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Select
|
||||
id="switch-to-hotbar-input"
|
||||
menuPortalTarget={null}
|
||||
onChange={(v) => onChange(v.value)}
|
||||
components={{ DropdownIndicator: null, IndicatorSeparator: null }}
|
||||
@@ -80,7 +75,7 @@ const NonInjectedHotbarSwitchCommand = observer(({ hotbarManager, commandOverlay
|
||||
|
||||
export const HotbarSwitchCommand = withInjectables<Dependencies>(NonInjectedHotbarSwitchCommand, {
|
||||
getProps: (di, props) => ({
|
||||
hotbarManager: di.inject(hotbarManagerInjectable),
|
||||
hotbarStore: di.inject(hotbarStoreInjectable),
|
||||
commandOverlay: di.inject(commandOverlayInjectable),
|
||||
...props,
|
||||
}),
|
||||
|
||||
Reference in new issue
Block a user