mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Turn on strict mode in tsconfig.json, some helpful lints, and required cleanup where strictness necessitates it (#5195)
* Turn on strict mode in tsconfig.json - Add route, clusterRoute, and payloadValidatedClusterRoute helper functions to improve types with backend routes - Turn on the following new lints: - react/jsx-first-prop-new-line - react/jsx-wrap-multilines - react/jsx-one-expression-per-line - react/jsx-max-props-per-line - react/jsx-indent - react/jsx-indent-props Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix build Signed-off-by: Sebastian Malton <sebastian@malton.name> * Replace KubeObject scope strings with enum Signed-off-by: Sebastian Malton <sebastian@malton.name> * Revert package.json version changes Signed-off-by: Sebastian Malton <sebastian@malton.name> * revert move hostedCluster(Id) Signed-off-by: Sebastian Malton <sebastian@malton.name> * change some type param names to be not single letters Signed-off-by: Sebastian Malton <sebastian@malton.name> * remove copy-extension-themes Signed-off-by: Sebastian Malton <sebastian@malton.name> * add new make clean action Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix build to not use webpack for generating types Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix kube-object-menu.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix select.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix catalog.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * revert move fileNameMigration to index Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix ref logic error Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix log-resource-selector.test.tsx tests Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix dock-store.test.ts test by overriding createStorage to not touch file system Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix cluster.test.ts tests Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix kube=api.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fixed hotbar-store.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix kubeconfig-manager.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix cluster-role-bindings/__tests__/dialog.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix role-bindings/__tests__/dialog.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix pods.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix delete-cluster-dialog.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix daemonset.store.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix replicaset.store.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix statefulsets/dialog/dialog.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix replicasets/scale-dialog/dialog.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix deployments.store.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix deployments/scale/dialog.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix cronjob.store.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix stateful-set.api.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix deployment.api.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix api-manager.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix statefulset.store.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix job.store.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix pods.store.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix scroll-spy.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix hotbar-remove-command.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix catalog-entity-registry.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix welcome.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix verify-that-all-routes-have-route-component.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix pod-tolerations.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * better fix for previous 3 fixes, plus also select.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix kube-object-menu.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix app-paths.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix dock-tabs.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix isReactNode typing Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix sub-title.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix drawer.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix list-layout.tsx and header.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix error-boundary.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix upgrade-chart/store.ts and dock-tab.store.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix install-chart/store.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix edit-resource/store.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix create-resource/store.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix namespace-select.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix namespace-select-filter.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix crd-list.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix wrong types for extensions Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix circular dependency Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix circular dependency on catalogCategoryRegistry Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix api-kube Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix type errors, most <Select /> errors Signed-off-by: Sebastian Malton <sebastian@malton.name> * fixing more type errors Signed-off-by: Sebastian Malton <sebastian@malton.name> * some more fixing type errors Signed-off-by: Sebastian Malton <sebastian@malton.name> * convert all KubeApis to injectable with legacy global backups Signed-off-by: Sebastian Malton <sebastian@malton.name> * factor out into a common file all the exports Signed-off-by: Sebastian Malton <sebastian@malton.name> * convert all KubeObjectStores to injectable with legacy global backups Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix lint Signed-off-by: Sebastian Malton <sebastian@malton.name> * remove unused legacy KubeApi globals Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix bad previous commit Signed-off-by: Sebastian Malton <sebastian@malton.name> * more crash fixing Signed-off-by: Sebastian Malton <sebastian@malton.name> * try and fix behavioural tests Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix sidebar-and-tab-navigation-for-core.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix sidebar-and-tab-navigation-for-extensions.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix navigation-using-application-menu.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix catalog.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * Make ThemeStore non-singleton and fix navigation-to-terminal-preferences.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * extensions.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix catalog-entity-registry.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix navigation-using-application-menu.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix log-resource-selector.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix dock-tabs.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix delete-cluster-dialog.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix navigation-to-kubernetes-preferences.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix navigation-to-editor-preferences.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix navigation-to-proxy-preferences.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix navigation-using-application-menu.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix navigation-to-application-preferences.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix dock-store.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix select.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix role-bindings/__tests__/dialog.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix hotbar-remove-command.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix cluster-role-bindings/__tests__/dialog.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix navigation-to-extension-specific-preferences.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix navigation-to-telemetry-preferences.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix closing-preferences.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix navigation-to-editor-preferences.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix navigation-to-proxy-preferences.test.ts - Fix other type errors too Signed-off-by: Sebastian Malton <sebastian@malton.name> * final tweaks Signed-off-by: Sebastian Malton <sebastian@malton.name> * Add more tsconfig files, fix bug in <Catalog> - Make all of history, navigation injectable Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix type errors Signed-off-by: Sebastian Malton <sebastian@malton.name> * Convert all of kube-details-params/ and navigate/ to injectable - This fixes a runtime error that was encountered during testing Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix runtime errors on renderer - remove all static uses of `createPageParam` (and then removed the legacy global) - Made LensRendererExtension and LensMainExtension just used dependencies and not the getLegacyDi - Fixed circular dep in extension-loader Signed-off-by: Sebastian Malton <sebastian@malton.name> * Move registerStore calls to after injectMany Signed-off-by: Sebastian Malton <sebastian@malton.name> * replace all the rest of the legacy uses of apiManager Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix stack overflow and cycles in DI Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix NamespaceSelectFilter not opening Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix WizardStep and AddNamespaceDialog Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix KubeApi's not being registered Signed-off-by: Sebastian Malton <sebastian@malton.name> * cleanup WindowManager Signed-off-by: Sebastian Malton <sebastian@malton.name> * Proper fix for Wizard, fix NamespaceStore.subscribe Signed-off-by: Sebastian Malton <sebastian@malton.name> * Rewrite withTooltip to be more type correct - Fixes mobx related "too many recursive actions" error - Change all the uses of withTooltips to be functional components Signed-off-by: Sebastian Malton <sebastian@malton.name> * Add e2e test to cover kube api registration Signed-off-by: Sebastian Malton <sebastian@malton.name> * cleanup internal-commands Signed-off-by: Sebastian Malton <sebastian@malton.name> * remove cast in <Animate> Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix command-palette e2e test Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix type error after rebase Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix test name Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix lint Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix code to help CodeQL scanner Signed-off-by: Sebastian Malton <sebastian@malton.name> * update intree extension lock files Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix build-extensions picking wrong @types/react Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix tests from rebase Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix type error Signed-off-by: Sebastian Malton <sebastian@malton.name> * Make KubeconfigSyncManager more injectable Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix crash in test mode for Dialog Signed-off-by: Sebastian Malton <sebastian@malton.name> * make Select snapshots deterministic Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix new type error Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix kube-object.store.test.ts typing Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix merge build issues Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix snapshots after merge Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix lint after merge Signed-off-by: Sebastian Malton <sebastian@malton.name> * reexport BaseKubeJsonApiObjectMetadata Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix typo in terminalSpawningPool Signed-off-by: Sebastian Malton <sebastian@malton.name> * remove duplicate license header Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix typo to waitUntilDefined Signed-off-by: Sebastian Malton <sebastian@malton.name> * remove iter use from getLegacyGlobalDiForExtensionApi Signed-off-by: Sebastian Malton <sebastian@malton.name> * remove complex createStorage override Signed-off-by: Sebastian Malton <sebastian@malton.name> * override logger with mocks only when needed for tests Signed-off-by: Sebastian Malton <sebastian@malton.name> * remove specialized overrideStore flags for getDiForUnitTesting Signed-off-by: Sebastian Malton <sebastian@malton.name> * remove unnecessary | undefined types from the exactOptionalFieldTypes experiment Signed-off-by: Sebastian Malton <sebastian@malton.name> * use more descriptive name for local test mocks Signed-off-by: Sebastian Malton <sebastian@malton.name> * remove unnecessary addition to 'make clean' target Signed-off-by: Sebastian Malton <sebastian@malton.name> * remove oddity of KubeObjectStore.getById(undefined) being allowed Signed-off-by: Sebastian Malton <sebastian@malton.name> * rename KubeObject.getDescriptor in favour of name without fundemental JS meaning Signed-off-by: Sebastian Malton <sebastian@malton.name> * Simplify legacyRegisterApi when working in behaviour unit tests - Don't emit within main environment as there should be no auto registering there Signed-off-by: Sebastian Malton <sebastian@malton.name> * change confusing variable name in ReactiveDuration Signed-off-by: Sebastian Malton <sebastian@malton.name> * make visitor pattern more explicit for Entity contextMenuOpen Signed-off-by: Sebastian Malton <sebastian@malton.name> * toggleDetails -> toggleKubeDetailsPane is more specific Signed-off-by: Sebastian Malton <sebastian@malton.name> * remove outdated comment Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix bug where LensExtension dependencies are not set Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix tests from the revert of react 18 Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix more tests from merge Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix typings with new is-compatible-extension tests Signed-off-by: Sebastian Malton <sebastian@malton.name> * more type fixing Signed-off-by: Sebastian Malton <sebastian@malton.name> * Revert in-tree extension versions Signed-off-by: Sebastian Malton <sebastian@malton.name> * Improve name of guarding injectable for stores and apis - New name better implies that it is just a guard state and does not do anything Signed-off-by: Sebastian Malton <sebastian@malton.name> * Add helper for <Select>.isMulti for storing in a Set<Value> Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix is-compatible-extension.test.ts types Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
1 parent
381d77c633
commit
dfcb7c3330
1062 files changed
+26512
-28689
No files matched your search
@@ -11,21 +11,21 @@ import type { DiContainer } from "@ogre-tools/injectable";
|
||||
import { getDiForUnitTesting } from "../../../getDiForUnitTesting";
|
||||
import type { DiRender } from "../../test-utils/renderFor";
|
||||
import { renderFor } from "../../test-utils/renderFor";
|
||||
import hotbarStoreInjectable from "../../../../common/hotbar-store.injectable";
|
||||
import { ThemeStore } from "../../../theme.store";
|
||||
import hotbarStoreInjectable from "../../../../common/hotbars/store.injectable";
|
||||
import { ConfirmDialog } from "../../confirm-dialog";
|
||||
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";
|
||||
import type { HotbarStore } from "../../../../common/hotbars/store";
|
||||
import storesAndApisCanBeCreatedInjectable from "../../../stores-apis-can-be-created.injectable";
|
||||
import ipcRendererInjectable from "../../../app-paths/get-value-from-registered-channel/ipc-renderer/ipc-renderer.injectable";
|
||||
|
||||
const mockHotbars: { [id: string]: any } = {
|
||||
const mockHotbars: Partial<Record<string, any>> = {
|
||||
"1": {
|
||||
id: "1",
|
||||
name: "Default",
|
||||
items: [] as any,
|
||||
items: [],
|
||||
},
|
||||
};
|
||||
|
||||
@@ -45,22 +45,22 @@ describe("<HotbarRemoveCommand />", () => {
|
||||
|
||||
mockFs();
|
||||
|
||||
di.override(storesAndApisCanBeCreatedInjectable, () => true);
|
||||
di.override(directoryForUserDataInjectable, () => "some-directory-for-user-data");
|
||||
di.override(ipcRendererInjectable, () => ({
|
||||
on: jest.fn(),
|
||||
invoke: jest.fn(), // TODO: replace with proper mocking via the IPC bridge
|
||||
} as never));
|
||||
|
||||
di.permitSideEffects(hotbarStoreInjectable);
|
||||
di.permitSideEffects(getConfigurationFileModelInjectable);
|
||||
di.permitSideEffects(appVersionInjectable);
|
||||
|
||||
render = renderFor(di);
|
||||
|
||||
UserStore.createInstance();
|
||||
ThemeStore.createInstance();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
mockFs.restore();
|
||||
ThemeStore.resetInstance();
|
||||
UserStore.resetInstance();
|
||||
});
|
||||
|
||||
it("renders w/o errors", async () => {
|
||||
@@ -71,7 +71,7 @@ describe("<HotbarRemoveCommand />", () => {
|
||||
},
|
||||
hotbarIndex: () => 0,
|
||||
getDisplayLabel: () => "1: Default",
|
||||
}) as any as HotbarStore);
|
||||
}) as unknown as HotbarStore);
|
||||
|
||||
await di.runSetups();
|
||||
|
||||
@@ -89,7 +89,7 @@ describe("<HotbarRemoveCommand />", () => {
|
||||
remove: removeMock,
|
||||
hotbarIndex: () => 0,
|
||||
getDisplayLabel: () => "1: Default",
|
||||
}) as any as HotbarStore);
|
||||
}) as unknown as HotbarStore);
|
||||
|
||||
await di.runSetups();
|
||||
|
||||
|
||||
@@ -7,16 +7,16 @@ import React from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import type { InputValidator } from "../input";
|
||||
import { Input } from "../input";
|
||||
import type { CreateHotbarData, CreateHotbarOptions } from "../../../common/hotbar-types";
|
||||
import type { CreateHotbarData, CreateHotbarOptions } from "../../../common/hotbars/types";
|
||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import commandOverlayInjectable from "../command-palette/command-overlay.injectable";
|
||||
import hotbarStoreInjectable from "../../../common/hotbar-store.injectable";
|
||||
import uniqueHotbarNameInjectable from "../input/validators/unique-hotbar-name.injectable";
|
||||
import addHotbarInjectable from "../../../common/hotbars/add-hotbar.injectable";
|
||||
|
||||
interface Dependencies {
|
||||
closeCommandOverlay: () => void;
|
||||
addHotbar: (data: CreateHotbarData, { setActive }?: CreateHotbarOptions) => void;
|
||||
uniqueHotbarName: InputValidator;
|
||||
addHotbar: (data: CreateHotbarData, opts: CreateHotbarOptions) => void;
|
||||
uniqueHotbarName: InputValidator<boolean>;
|
||||
}
|
||||
|
||||
const NonInjectedHotbarAddCommand = observer(({ closeCommandOverlay, addHotbar, uniqueHotbarName }: Dependencies) => {
|
||||
@@ -51,7 +51,7 @@ const NonInjectedHotbarAddCommand = observer(({ closeCommandOverlay, addHotbar,
|
||||
export const HotbarAddCommand = withInjectables<Dependencies>(NonInjectedHotbarAddCommand, {
|
||||
getProps: (di, props) => ({
|
||||
closeCommandOverlay: di.inject(commandOverlayInjectable).close,
|
||||
addHotbar: di.inject(hotbarStoreInjectable).add,
|
||||
addHotbar: di.inject(addHotbarInjectable),
|
||||
uniqueHotbarName: di.inject(uniqueHotbarNameInjectable),
|
||||
...props,
|
||||
}),
|
||||
|
||||
@@ -19,7 +19,7 @@ export function HotbarCell({ innerRef, children, className, ...rest }: HotbarCel
|
||||
const [animating, setAnimating] = useState(false);
|
||||
const onAnimationEnd = () => { setAnimating(false); };
|
||||
const onClick = () => {
|
||||
setAnimating(!className.includes("isDraggingOver"));
|
||||
setAnimating(!className?.includes("isDraggingOver"));
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -5,45 +5,48 @@
|
||||
|
||||
import styles from "./hotbar-entity-icon.module.scss";
|
||||
|
||||
import type { HTMLAttributes } from "react";
|
||||
import React from "react";
|
||||
import { makeObservable, observable } from "mobx";
|
||||
import type { IComputedValue } from "mobx";
|
||||
import { observable } from "mobx";
|
||||
import { observer } from "mobx-react";
|
||||
|
||||
import type { CatalogEntity, CatalogEntityContextMenu, CatalogEntityContextMenuContext } from "../../../common/catalog";
|
||||
import { catalogCategoryRegistry } from "../../api/catalog-category-registry";
|
||||
import { catalogEntityRegistry } from "../../api/catalog-entity-registry";
|
||||
import { navigate } from "../../navigation";
|
||||
import type { CatalogCategoryRegistry, CatalogEntity, CatalogEntityContextMenu } from "../../../common/catalog";
|
||||
import type { IClassName } from "../../utils";
|
||||
import { cssNames } from "../../utils";
|
||||
import { Icon } from "../icon";
|
||||
import { HotbarIcon } from "./hotbar-icon";
|
||||
import { LensKubernetesClusterStatus } from "../../../common/catalog-entities/kubernetes-cluster";
|
||||
import type { VisitEntityContextMenu } from "../../../common/catalog/visit-entity-context-menu.injectable";
|
||||
import { navigate } from "../../navigation";
|
||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import catalogCategoryRegistryInjectable from "../../../common/catalog/category-registry.injectable";
|
||||
import visitEntityContextMenuInjectable from "../../../common/catalog/visit-entity-context-menu.injectable";
|
||||
import activeEntityInjectable from "../../api/catalog/entity/active.injectable";
|
||||
|
||||
export interface HotbarEntityIconProps extends HTMLAttributes<HTMLElement> {
|
||||
export interface HotbarEntityIconProps {
|
||||
entity: CatalogEntity;
|
||||
index: number;
|
||||
errorClass?: IClassName;
|
||||
add: (item: CatalogEntity, index: number) => void;
|
||||
remove: (uid: string) => void;
|
||||
size?: number;
|
||||
onClick?: () => void;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
interface Dependencies {
|
||||
visitEntityContextMenu: VisitEntityContextMenu;
|
||||
catalogCategoryRegistry: CatalogCategoryRegistry;
|
||||
activeEntity: IComputedValue<CatalogEntity | undefined>;
|
||||
}
|
||||
|
||||
@observer
|
||||
export class HotbarEntityIcon extends React.Component<HotbarEntityIconProps> {
|
||||
@observable private contextMenu: CatalogEntityContextMenuContext = {
|
||||
menuItems: [],
|
||||
navigate: (url: string) => navigate(url),
|
||||
};
|
||||
|
||||
constructor(props: HotbarEntityIconProps) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
class NonInjectedHotbarEntityIcon extends React.Component<HotbarEntityIconProps & Dependencies> {
|
||||
private readonly menuItems = observable.array<CatalogEntityContextMenu>();
|
||||
|
||||
get kindIcon() {
|
||||
const className = styles.badge;
|
||||
const category = catalogCategoryRegistry.getCategoryForEntity(this.props.entity);
|
||||
const category = this.props.catalogCategoryRegistry.getCategoryForEntity(this.props.entity);
|
||||
|
||||
if (!category) {
|
||||
return <Icon material="bug_report" className={className} />;
|
||||
@@ -51,9 +54,9 @@ export class HotbarEntityIcon extends React.Component<HotbarEntityIconProps> {
|
||||
|
||||
if (Icon.isSvg(category.metadata.icon)) {
|
||||
return <Icon svg={category.metadata.icon} className={className} />;
|
||||
} else {
|
||||
return <Icon material={category.metadata.icon} className={className} />;
|
||||
}
|
||||
|
||||
return <Icon material={category.metadata.icon} className={className} />;
|
||||
}
|
||||
|
||||
get ledIcon() {
|
||||
@@ -61,34 +64,34 @@ export class HotbarEntityIcon extends React.Component<HotbarEntityIconProps> {
|
||||
return null;
|
||||
}
|
||||
|
||||
const className = cssNames(styles.led, { [styles.online]: this.props.entity.status.phase === LensKubernetesClusterStatus.CONNECTED }); // TODO: make it more generic
|
||||
|
||||
return <div className={className} />;
|
||||
return (
|
||||
<div
|
||||
className={cssNames(styles.led, {
|
||||
// TODO: make it more generic
|
||||
[styles.online]: this.props.entity.status.phase === LensKubernetesClusterStatus.CONNECTED,
|
||||
})}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
isActive(item: CatalogEntity) {
|
||||
return catalogEntityRegistry.activeEntity?.metadata?.uid == item.getId();
|
||||
return this.props.activeEntity.get()?.metadata?.uid == item.getId();
|
||||
}
|
||||
|
||||
async onMenuOpen() {
|
||||
const menuItems: CatalogEntityContextMenu[] = [];
|
||||
|
||||
menuItems.unshift({
|
||||
onMenuOpen() {
|
||||
this.menuItems.replace([{
|
||||
title: "Remove from Hotbar",
|
||||
onClick: () => this.props.remove(this.props.entity.getId()),
|
||||
}]);
|
||||
|
||||
this.props.visitEntityContextMenu(this.props.entity, {
|
||||
menuItems: this.menuItems,
|
||||
navigate,
|
||||
});
|
||||
|
||||
this.contextMenu.menuItems = menuItems;
|
||||
|
||||
await this.props.entity.onContextMenuOpen(this.contextMenu);
|
||||
}
|
||||
|
||||
render() {
|
||||
if (!this.contextMenu) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { entity, errorClass, add, remove, index, children, ...elemProps } = this.props;
|
||||
const { entity, className, onClick } = this.props;
|
||||
|
||||
return (
|
||||
<HotbarIcon
|
||||
@@ -98,13 +101,17 @@ export class HotbarEntityIcon extends React.Component<HotbarEntityIconProps> {
|
||||
src={entity.spec.icon?.src}
|
||||
material={entity.spec.icon?.material}
|
||||
background={entity.spec.icon?.background}
|
||||
className={this.props.className}
|
||||
className={className}
|
||||
active={this.isActive(entity)}
|
||||
onMenuOpen={() => this.onMenuOpen()}
|
||||
disabled={!entity}
|
||||
menuItems={this.contextMenu.menuItems}
|
||||
tooltip={`${entity.getName()} (${entity.metadata.source})`}
|
||||
{...elemProps}
|
||||
menuItems={this.menuItems}
|
||||
tooltip={(
|
||||
entity.metadata.source
|
||||
? `${entity.getName()} (${entity.metadata.source})`
|
||||
: entity.getName()
|
||||
)}
|
||||
onClick={onClick}
|
||||
>
|
||||
{ this.ledIcon }
|
||||
{ this.kindIcon }
|
||||
@@ -112,3 +119,12 @@ export class HotbarEntityIcon extends React.Component<HotbarEntityIconProps> {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const HotbarEntityIcon = withInjectables<Dependencies, HotbarEntityIconProps>(NonInjectedHotbarEntityIcon, {
|
||||
getProps: (di, props) => ({
|
||||
...props,
|
||||
catalogCategoryRegistry: di.inject(catalogCategoryRegistryInjectable),
|
||||
visitEntityContextMenu: di.inject(visitEntityContextMenuInjectable),
|
||||
activeEntity: di.inject(activeEntityInjectable),
|
||||
}),
|
||||
});
|
||||
@@ -21,7 +21,7 @@ import normalizeCatalogEntityContextMenuInjectable from "../../catalog/normalize
|
||||
|
||||
export interface HotbarIconProps extends AvatarProps {
|
||||
uid: string;
|
||||
source: string;
|
||||
source?: string;
|
||||
material?: string;
|
||||
onMenuOpen?: () => void;
|
||||
active?: boolean;
|
||||
@@ -51,12 +51,16 @@ const NonInjectedHotbarIcon = observer(({
|
||||
|
||||
return (
|
||||
<div className={cssNames(styles.HotbarIcon, className, { [styles.contextMenuAvailable]: menuItems.length > 0 })}>
|
||||
{tooltip && <Tooltip targetId={id}>{tooltip}</Tooltip>}
|
||||
{tooltip && (
|
||||
<Tooltip targetId={id}>
|
||||
{tooltip}
|
||||
</Tooltip>
|
||||
)}
|
||||
<Avatar
|
||||
{...rest}
|
||||
id={id}
|
||||
title={title}
|
||||
colorHash={`${title}-${source}`}
|
||||
colorHash={source ? `${title}-${source}` : title}
|
||||
className={cssNames(styles.avatar, { [styles.active]: active, [styles.hasImage]: !!src })}
|
||||
disabled={disabled}
|
||||
size={size}
|
||||
@@ -76,7 +80,8 @@ const NonInjectedHotbarIcon = observer(({
|
||||
onMenuOpen?.();
|
||||
toggleMenu();
|
||||
}}
|
||||
close={() => toggleMenu()}>
|
||||
close={() => toggleMenu()}
|
||||
>
|
||||
{
|
||||
menuItems
|
||||
.map(normalizeMenuItem)
|
||||
|
||||
@@ -10,18 +10,19 @@ import { observer } from "mobx-react";
|
||||
import { HotbarEntityIcon } from "./hotbar-entity-icon";
|
||||
import type { IClassName } from "../../utils";
|
||||
import { cssNames } from "../../utils";
|
||||
import { catalogEntityRegistry } from "../../api/catalog-entity-registry";
|
||||
import type { CatalogEntityRegistry } from "../../api/catalog/entity/registry";
|
||||
import type { CatalogEntity } from "../../api/catalog-entity";
|
||||
import { DragDropContext, Draggable, Droppable, type DropResult } from "react-beautiful-dnd";
|
||||
import { HotbarSelector } from "./hotbar-selector";
|
||||
import { HotbarCell } from "./hotbar-cell";
|
||||
import { HotbarIcon } from "./hotbar-icon";
|
||||
import type { HotbarItem } from "../../../common/hotbar-types";
|
||||
import { defaultHotbarCells } from "../../../common/hotbar-types";
|
||||
import type { HotbarItem } from "../../../common/hotbars/types";
|
||||
import { defaultHotbarCells } from "../../../common/hotbars/types";
|
||||
import { action, makeObservable, observable } from "mobx";
|
||||
import hotbarStoreInjectable from "../../../common/hotbar-store.injectable";
|
||||
import hotbarStoreInjectable from "../../../common/hotbars/store.injectable";
|
||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import type { HotbarStore } from "../../../common/hotbar-store";
|
||||
import type { HotbarStore } from "../../../common/hotbars/store";
|
||||
import catalogEntityRegistryInjectable from "../../api/catalog/entity/registry.injectable";
|
||||
|
||||
export interface HotbarMenuProps {
|
||||
className?: IClassName;
|
||||
@@ -29,6 +30,7 @@ export interface HotbarMenuProps {
|
||||
|
||||
interface Dependencies {
|
||||
hotbarStore: HotbarStore;
|
||||
entityRegistry: CatalogEntityRegistry;
|
||||
}
|
||||
|
||||
@observer
|
||||
@@ -44,14 +46,14 @@ class NonInjectedHotbarMenu extends React.Component<Dependencies & HotbarMenuPro
|
||||
return this.props.hotbarStore.getActive();
|
||||
}
|
||||
|
||||
getEntity(item: HotbarItem) {
|
||||
getEntity(item: HotbarItem | null) {
|
||||
const hotbar = this.props.hotbarStore.getActive();
|
||||
|
||||
if (!hotbar) {
|
||||
if (!hotbar || !item) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return catalogEntityRegistry.getById(item?.entity.uid) ?? null;
|
||||
return this.props.entityRegistry.getById(item.entity.uid) ?? null;
|
||||
}
|
||||
|
||||
@action
|
||||
@@ -87,7 +89,11 @@ class NonInjectedHotbarMenu extends React.Component<Dependencies & HotbarMenuPro
|
||||
hotbar.addToHotbar(entity, index);
|
||||
};
|
||||
|
||||
getMoveAwayDirection(entityId: string, cellIndex: number) {
|
||||
getMoveAwayDirection(entityId: string | undefined, cellIndex: number) {
|
||||
if (!entityId) {
|
||||
return "animateDown";
|
||||
}
|
||||
|
||||
const draggableItemIndex = this.hotbar.items.findIndex(item => item?.entity.uid == entityId);
|
||||
|
||||
return draggableItemIndex > cellIndex ? "animateDown" : "animateUp";
|
||||
@@ -111,7 +117,11 @@ class NonInjectedHotbarMenu extends React.Component<Dependencies & HotbarMenuPro
|
||||
{...provided.droppableProps}
|
||||
>
|
||||
{item && (
|
||||
<Draggable draggableId={item.entity.uid} key={item.entity.uid} index={0} >
|
||||
<Draggable
|
||||
draggableId={item.entity.uid}
|
||||
key={item.entity.uid}
|
||||
index={0}
|
||||
>
|
||||
{(provided, snapshot) => {
|
||||
const style = {
|
||||
zIndex: defaultHotbarCells - index,
|
||||
@@ -132,7 +142,7 @@ class NonInjectedHotbarMenu extends React.Component<Dependencies & HotbarMenuPro
|
||||
key={index}
|
||||
index={index}
|
||||
entity={entity}
|
||||
onClick={() => catalogEntityRegistry.onRun(entity)}
|
||||
onClick={() => this.props.entityRegistry.onRun(entity)}
|
||||
className={cssNames({ isDragging: snapshot.isDragging })}
|
||||
remove={this.removeItem}
|
||||
add={this.addItem}
|
||||
@@ -142,7 +152,7 @@ class NonInjectedHotbarMenu extends React.Component<Dependencies & HotbarMenuPro
|
||||
<HotbarIcon
|
||||
uid={`hotbar-icon-${item.entity.uid}`}
|
||||
title={item.entity.name}
|
||||
source={item.entity.source}
|
||||
source={item.entity.source ?? "local"}
|
||||
tooltip={`${item.entity.name} (${item.entity.source})`}
|
||||
menuItems={[
|
||||
{
|
||||
@@ -178,19 +188,16 @@ class NonInjectedHotbarMenu extends React.Component<Dependencies & HotbarMenuPro
|
||||
{this.renderGrid()}
|
||||
</DragDropContext>
|
||||
</div>
|
||||
<HotbarSelector hotbar={hotbar}/>
|
||||
<HotbarSelector hotbar={hotbar} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const HotbarMenu = withInjectables<Dependencies, HotbarMenuProps>(
|
||||
NonInjectedHotbarMenu,
|
||||
|
||||
{
|
||||
getProps: (di, props) => ({
|
||||
hotbarStore: di.inject(hotbarStoreInjectable),
|
||||
...props,
|
||||
}),
|
||||
},
|
||||
);
|
||||
export const HotbarMenu = withInjectables<Dependencies, HotbarMenuProps>(NonInjectedHotbarMenu, {
|
||||
getProps: (di, props) => ({
|
||||
...props,
|
||||
hotbarStore: di.inject(hotbarStoreInjectable),
|
||||
entityRegistry: di.inject(catalogEntityRegistryInjectable),
|
||||
}),
|
||||
});
|
||||
@@ -6,73 +6,67 @@
|
||||
import React from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { Select } from "../select";
|
||||
import hotbarStoreInjectable from "../../../common/hotbar-store.injectable";
|
||||
import hotbarStoreInjectable from "../../../common/hotbars/store.injectable";
|
||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import commandOverlayInjectable from "../command-palette/command-overlay.injectable";
|
||||
import type { Hotbar } from "../../../common/hotbar-types";
|
||||
import type { HotbarStore } from "../../../common/hotbars/store";
|
||||
import type { OpenConfirmDialog } from "../confirm-dialog/open.injectable";
|
||||
import openConfirmDialogInjectable from "../confirm-dialog/open.injectable";
|
||||
|
||||
interface Dependencies {
|
||||
closeCommandOverlay: () => void;
|
||||
openConfirmDialog: OpenConfirmDialog;
|
||||
hotbarStore: {
|
||||
hotbars: Hotbar[];
|
||||
getById: (id: string) => Hotbar | undefined;
|
||||
remove: (hotbar: Hotbar) => void;
|
||||
getDisplayLabel: (hotbar: Hotbar) => string;
|
||||
};
|
||||
hotbarStore: HotbarStore;
|
||||
}
|
||||
|
||||
const NonInjectedHotbarRemoveCommand = observer(({
|
||||
closeCommandOverlay,
|
||||
hotbarStore,
|
||||
openConfirmDialog,
|
||||
}: Dependencies) => {
|
||||
const options = hotbarStore.hotbars.map(hotbar => ({
|
||||
value: hotbar.id,
|
||||
label: hotbarStore.getDisplayLabel(hotbar),
|
||||
}));
|
||||
}: Dependencies) => (
|
||||
<Select
|
||||
menuPortalTarget={null}
|
||||
onChange={option => {
|
||||
if (!option) {
|
||||
return;
|
||||
}
|
||||
|
||||
const onChange = (id: string): void => {
|
||||
const hotbar = hotbarStore.getById(id);
|
||||
|
||||
if (!hotbar) {
|
||||
return;
|
||||
}
|
||||
|
||||
closeCommandOverlay();
|
||||
openConfirmDialog({
|
||||
okButtonProps: {
|
||||
label: "Remove Hotbar",
|
||||
primary: false,
|
||||
accent: true,
|
||||
},
|
||||
ok: () => hotbarStore.remove(hotbar),
|
||||
message: (
|
||||
<div className="confirm flex column gaps">
|
||||
<p>
|
||||
Are you sure you want remove hotbar <b>{hotbar.name}</b>?
|
||||
</p>
|
||||
</div>
|
||||
),
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Select
|
||||
id="remove-hotbar-input"
|
||||
menuPortalTarget={null}
|
||||
onChange={(v) => onChange(v.value)}
|
||||
components={{ DropdownIndicator: null, IndicatorSeparator: null }}
|
||||
menuIsOpen={true}
|
||||
options={options}
|
||||
autoFocus={true}
|
||||
escapeClearsValue={false}
|
||||
placeholder="Remove hotbar"
|
||||
/>
|
||||
);
|
||||
});
|
||||
closeCommandOverlay();
|
||||
openConfirmDialog({
|
||||
okButtonProps: {
|
||||
label: "Remove Hotbar",
|
||||
primary: false,
|
||||
accent: true,
|
||||
},
|
||||
ok: () => hotbarStore.remove(option.value),
|
||||
message: (
|
||||
<div className="confirm flex column gaps">
|
||||
<p>
|
||||
Are you sure you want remove hotbar
|
||||
{" "}
|
||||
<b>
|
||||
{option.value.name}
|
||||
</b>
|
||||
?
|
||||
</p>
|
||||
</div>
|
||||
),
|
||||
});
|
||||
} }
|
||||
components={{ DropdownIndicator: null, IndicatorSeparator: null }}
|
||||
menuIsOpen={true}
|
||||
options={(
|
||||
hotbarStore.hotbars
|
||||
.map(hotbar => ({
|
||||
value: hotbar,
|
||||
label: hotbarStore.getDisplayLabel(hotbar),
|
||||
}))
|
||||
)}
|
||||
autoFocus={true}
|
||||
escapeClearsValue={false}
|
||||
placeholder="Remove hotbar"
|
||||
/>
|
||||
));
|
||||
|
||||
export const HotbarRemoveCommand = withInjectables<Dependencies>(NonInjectedHotbarRemoveCommand, {
|
||||
getProps: (di, props) => ({
|
||||
|
||||
@@ -6,38 +6,28 @@
|
||||
import React, { useState } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { Select } from "../select";
|
||||
import hotbarStoreInjectable from "../../../common/hotbar-store.injectable";
|
||||
import hotbarStoreInjectable from "../../../common/hotbars/store.injectable";
|
||||
import type { InputValidator } from "../input";
|
||||
import { Input } from "../input";
|
||||
import type { Hotbar } from "../../../common/hotbar-types";
|
||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import commandOverlayInjectable from "../command-palette/command-overlay.injectable";
|
||||
import uniqueHotbarNameInjectable from "../input/validators/unique-hotbar-name.injectable";
|
||||
import type { HotbarStore } from "../../../common/hotbars/store";
|
||||
|
||||
interface Dependencies {
|
||||
closeCommandOverlay: () => void;
|
||||
hotbarStore: {
|
||||
hotbars: Hotbar[];
|
||||
getById: (id: string) => Hotbar | undefined;
|
||||
setHotbarName: (id: string, name: string) => void;
|
||||
getDisplayLabel: (hotbar: Hotbar) => string;
|
||||
};
|
||||
uniqueHotbarName: InputValidator;
|
||||
hotbarStore: HotbarStore;
|
||||
uniqueHotbarName: InputValidator<false>;
|
||||
}
|
||||
|
||||
const NonInjectedHotbarRenameCommand = observer(({ closeCommandOverlay, hotbarStore, uniqueHotbarName }: Dependencies) => {
|
||||
const NonInjectedHotbarRenameCommand = observer(({
|
||||
closeCommandOverlay,
|
||||
hotbarStore,
|
||||
uniqueHotbarName,
|
||||
}: Dependencies) => {
|
||||
const [hotbarId, setHotbarId] = useState("");
|
||||
const [hotbarName, setHotbarName] = useState("");
|
||||
|
||||
const options = hotbarStore.hotbars.map(hotbar => ({
|
||||
value: hotbar.id,
|
||||
label: hotbarStore.getDisplayLabel(hotbar),
|
||||
}));
|
||||
|
||||
const onSelect = (id: string) => {
|
||||
setHotbarId(id);
|
||||
setHotbarName(hotbarStore.getById(id).name);
|
||||
};
|
||||
const onSubmit = (name: string) => {
|
||||
if (!name.trim()) {
|
||||
return;
|
||||
@@ -72,10 +62,21 @@ const NonInjectedHotbarRenameCommand = observer(({ closeCommandOverlay, hotbarSt
|
||||
<Select
|
||||
id="rename-hotbar-input"
|
||||
menuPortalTarget={null}
|
||||
onChange={(v) => onSelect(v.value)}
|
||||
onChange={(option) => {
|
||||
if (option) {
|
||||
setHotbarId(option.value.id);
|
||||
setHotbarName(option.value.name);
|
||||
}
|
||||
}}
|
||||
components={{ DropdownIndicator: null, IndicatorSeparator: null }}
|
||||
menuIsOpen={true}
|
||||
options={options}
|
||||
options={(
|
||||
hotbarStore.hotbars
|
||||
.map(hotbar => ({
|
||||
value: hotbar,
|
||||
label: hotbarStore.getDisplayLabel(hotbar),
|
||||
}))
|
||||
)}
|
||||
autoFocus={true}
|
||||
escapeClearsValue={false}
|
||||
placeholder="Rename hotbar"
|
||||
|
||||
@@ -7,22 +7,18 @@ import styles from "./hotbar-selector.module.scss";
|
||||
import React, { useRef, useState } from "react";
|
||||
import { Icon } from "../icon";
|
||||
import { Badge } from "../badge";
|
||||
import hotbarStoreInjectable from "../../../common/hotbar-store.injectable";
|
||||
import hotbarStoreInjectable from "../../../common/hotbars/store.injectable";
|
||||
import { HotbarSwitchCommand } from "./hotbar-switch-command";
|
||||
import { Tooltip, TooltipPosition } from "../tooltip";
|
||||
import { observer } from "mobx-react";
|
||||
import type { Hotbar } from "../../../common/hotbar-types";
|
||||
import type { Hotbar } from "../../../common/hotbars/types";
|
||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import commandOverlayInjectable from "../command-palette/command-overlay.injectable";
|
||||
import { cssNames } from "../../utils";
|
||||
import type { HotbarStore } from "../../../common/hotbars/store";
|
||||
|
||||
interface Dependencies {
|
||||
hotbarStore: {
|
||||
switchToPrevious: () => void;
|
||||
switchToNext: () => void;
|
||||
getActive: () => Hotbar;
|
||||
getDisplayIndex: (hotbar: Hotbar) => string;
|
||||
};
|
||||
hotbarStore: HotbarStore;
|
||||
openCommandOverlay: (component: React.ReactElement) => void;
|
||||
}
|
||||
|
||||
@@ -32,7 +28,7 @@ export interface HotbarSelectorProps extends Partial<Dependencies> {
|
||||
|
||||
const NonInjectedHotbarSelector = observer(({ hotbar, hotbarStore, openCommandOverlay }: HotbarSelectorProps & Dependencies) => {
|
||||
const [tooltipVisible, setTooltipVisible] = useState(false);
|
||||
const tooltipTimeout = useRef<NodeJS.Timeout>();
|
||||
const tooltipTimeout = useRef<number>();
|
||||
|
||||
function clearTimer() {
|
||||
clearTimeout(tooltipTimeout.current);
|
||||
@@ -41,7 +37,7 @@ const NonInjectedHotbarSelector = observer(({ hotbar, hotbarStore, openCommandOv
|
||||
function onTooltipShow() {
|
||||
setTooltipVisible(true);
|
||||
clearTimer();
|
||||
tooltipTimeout.current = setTimeout(() => setTooltipVisible(false), 1500);
|
||||
tooltipTimeout.current = window.setTimeout(() => setTooltipVisible(false), 1500);
|
||||
}
|
||||
|
||||
function onPrevClick() {
|
||||
@@ -61,7 +57,10 @@ const NonInjectedHotbarSelector = observer(({ hotbar, hotbarStore, openCommandOv
|
||||
|
||||
return (
|
||||
<div className={styles.HotbarSelector}>
|
||||
<Icon material="play_arrow" className={cssNames(styles.Icon, styles.previous)} onClick={onPrevClick}/>
|
||||
<Icon
|
||||
material="play_arrow"
|
||||
className={cssNames(styles.Icon, styles.previous)}
|
||||
onClick={onPrevClick}/>
|
||||
<div className={styles.HotbarIndex}>
|
||||
<Badge
|
||||
id="hotbarIndex"
|
||||
@@ -80,7 +79,11 @@ const NonInjectedHotbarSelector = observer(({ hotbar, hotbarStore, openCommandOv
|
||||
{hotbar.name}
|
||||
</Tooltip>
|
||||
</div>
|
||||
<Icon material="play_arrow" className={styles.Icon} onClick={onNextClick} />
|
||||
<Icon
|
||||
material="play_arrow"
|
||||
className={styles.Icon}
|
||||
onClick={onNextClick}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -6,72 +6,82 @@
|
||||
import React from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { Select } from "../select";
|
||||
import hotbarStoreInjectable from "../../../common/hotbar-store.injectable";
|
||||
import hotbarStoreInjectable from "../../../common/hotbars/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 { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import commandOverlayInjectable from "../command-palette/command-overlay.injectable";
|
||||
import type { HotbarStore } from "../../../common/hotbar-store";
|
||||
import type { HotbarStore } from "../../../common/hotbars/store";
|
||||
|
||||
const addActionId = "__add__";
|
||||
const removeActionId = "__remove__";
|
||||
const renameActionId = "__rename__";
|
||||
const hotbarAddAction = Symbol("hotbar-add");
|
||||
const hotbarRemoveAction = Symbol("hotbar-remove");
|
||||
const hotbarRenameAction = Symbol("hotbar-rename");
|
||||
|
||||
interface Dependencies {
|
||||
hotbarStore: HotbarStore;
|
||||
commandOverlay: CommandOverlay;
|
||||
}
|
||||
|
||||
function getHotbarSwitchOptions(hotbarStore: HotbarStore) {
|
||||
const options = hotbarStore.hotbars.map(hotbar => ({
|
||||
value: hotbar.id,
|
||||
label: hotbarStore.getDisplayLabel(hotbar),
|
||||
}));
|
||||
|
||||
options.push({ value: addActionId, label: "Add hotbar ..." });
|
||||
|
||||
if (hotbarStore.hotbars.length > 1) {
|
||||
options.push({ value: removeActionId, label: "Remove hotbar ..." });
|
||||
}
|
||||
|
||||
options.push({ value: renameActionId, label: "Rename hotbar ..." });
|
||||
|
||||
return options;
|
||||
function ignoreIf<T>(check: boolean, menuItems: T[]): T[] {
|
||||
return check ? [] : menuItems;
|
||||
}
|
||||
|
||||
const NonInjectedHotbarSwitchCommand = observer(({ hotbarStore, commandOverlay }: Dependencies) => {
|
||||
const options = getHotbarSwitchOptions(hotbarStore);
|
||||
const NonInjectedHotbarSwitchCommand = observer(({
|
||||
hotbarStore,
|
||||
commandOverlay,
|
||||
}: Dependencies) => (
|
||||
<Select
|
||||
id="switch-to-hotbar-input"
|
||||
menuPortalTarget={null}
|
||||
onChange={(option) => {
|
||||
if (!option) {
|
||||
return;
|
||||
}
|
||||
|
||||
const onChange = (idOrAction: string): void => {
|
||||
switch (idOrAction) {
|
||||
case addActionId:
|
||||
return commandOverlay.open(<HotbarAddCommand />);
|
||||
case removeActionId:
|
||||
return commandOverlay.open(<HotbarRemoveCommand />);
|
||||
case renameActionId:
|
||||
return commandOverlay.open(<HotbarRenameCommand />);
|
||||
default:
|
||||
hotbarStore.setActiveHotbar(idOrAction);
|
||||
if (typeof option.value === "symbol") {
|
||||
switch (option.value) {
|
||||
case hotbarAddAction:
|
||||
return commandOverlay.open(<HotbarAddCommand />);
|
||||
case hotbarRemoveAction:
|
||||
return commandOverlay.open(<HotbarRemoveCommand />);
|
||||
case hotbarRenameAction:
|
||||
return commandOverlay.open(<HotbarRenameCommand />);
|
||||
}
|
||||
} else {
|
||||
hotbarStore.setActiveHotbar(option.value);
|
||||
commandOverlay.close();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Select
|
||||
id="switch-to-hotbar-input"
|
||||
menuPortalTarget={null}
|
||||
onChange={(v) => onChange(v.value)}
|
||||
components={{ DropdownIndicator: null, IndicatorSeparator: null }}
|
||||
menuIsOpen={true}
|
||||
options={options}
|
||||
autoFocus={true}
|
||||
escapeClearsValue={false}
|
||||
placeholder="Switch to hotbar"
|
||||
/>
|
||||
);
|
||||
});
|
||||
}
|
||||
}}
|
||||
components={{ DropdownIndicator: null, IndicatorSeparator: null }}
|
||||
menuIsOpen={true}
|
||||
options={[
|
||||
...hotbarStore.hotbars.map(hotbar => ({
|
||||
value: hotbar,
|
||||
label: hotbarStore.getDisplayLabel(hotbar),
|
||||
})),
|
||||
{
|
||||
value: hotbarAddAction,
|
||||
label: "Add hotbar ...",
|
||||
},
|
||||
...ignoreIf(hotbarStore.hotbars.length > 1, [
|
||||
{
|
||||
value: hotbarRemoveAction,
|
||||
label: "Remove hotbar ...",
|
||||
},
|
||||
]),
|
||||
{
|
||||
value: hotbarRenameAction,
|
||||
label: "Rename hotbar ...",
|
||||
},
|
||||
]}
|
||||
autoFocus={true}
|
||||
escapeClearsValue={false}
|
||||
isClearable={false}
|
||||
placeholder="Switch to hotbar"
|
||||
/>
|
||||
));
|
||||
|
||||
export const HotbarSwitchCommand = withInjectables<Dependencies>(NonInjectedHotbarSwitchCommand, {
|
||||
getProps: (di, props) => ({
|
||||
|
||||
Reference in new issue
Block a user