mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Remove BaseStore<T> and replace with composition of dependencies (#7002)
* Rename ExtensionStore -> BaseExtensionStore - The name was too close to ExtensionsStore Signed-off-by: Sebastian Malton <sebastian@malton.name> * Move ExtensionsStore to new format Signed-off-by: Sebastian Malton <sebastian@malton.name> * Move ClusterStore to new format Signed-off-by: Sebastian Malton <sebastian@malton.name> * Move UserStore to new format Signed-off-by: Sebastian Malton <sebastian@malton.name> * Cleanup types to remove multiple cast locations Signed-off-by: Sebastian Malton <sebastian@malton.name> * Move HotbarStore to new format Signed-off-by: Sebastian Malton <sebastian@malton.name> * Move WeblinkStore to new format Signed-off-by: Sebastian Malton <sebastian@malton.name> * Move FileSystemProvisionerStore to new format Signed-off-by: Sebastian Malton <sebastian@malton.name> * Update snapshots Signed-off-by: Sebastian Malton <sebastian@malton.name> * Clean up impl and rename to better describe intent Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix remaining type errors Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fully split apart the enabled extensions storage Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fully split apart the clusters storage Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fully split apart the hotbar storage Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fully split apart the weblinks storage Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fully split apart the user preferences storage Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix crashing Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix tests and snapshots Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix integration test failures Signed-off-by: Sebastian Malton <sebastian@malton.name> * Improve typing to prevent errors in the future. Signed-off-by: Sebastian Malton <sebastian@malton.name> * Cleanup @k8slens/messaging and friends - To fix type errors Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix lint issue Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix type errors Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix global override not being complete enough causing tests to fail Signed-off-by: Sebastian Malton <sebastian@malton.name> * Bump memory for unit tests on CI Signed-off-by: Sebastian Malton <sebastian@malton.name> * Attempt to fix memory issue on CI again Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fixup test because of new injectables Signed-off-by: Sebastian Malton <sebastian@malton.name> * Upgrade Jest Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix unit tests falling over Signed-off-by: Sebastian Malton <sebastian@malton.name> * Back out jest config change Signed-off-by: Sebastian Malton <sebastian@malton.name> * Remove console log Signed-off-by: Sebastian Malton <sebastian@malton.name> * Update snapshot Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix tests by matching equality instead of snapshots Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix tests by forcing specific snapshot style - Ubuntu CI seems to format arrays in snapshots differently than macOS locally Signed-off-by: Sebastian Malton <sebastian@malton.name> --------- Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
1 parent
ba4a283af9
commit
49f0a1af9c
365 files changed
+6733
-3972
No files matched your search
+11
-3
@@ -4,16 +4,24 @@
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { computed } from "mobx";
|
||||
import clusterStoreInjectable from "../../../../common/cluster-store/cluster-store.injectable";
|
||||
import getClusterByIdInjectable from "../../../../features/cluster/storage/common/get-by-id.injectable";
|
||||
import catalogEntityRegistryInjectable from "./registry.injectable";
|
||||
|
||||
const activeEntityInternalClusterInjectable = getInjectable({
|
||||
id: "active-entity-internal-cluster",
|
||||
instantiate: (di) => {
|
||||
const store = di.inject(clusterStoreInjectable);
|
||||
const getClusterById = di.inject(getClusterByIdInjectable);
|
||||
const entityRegistry = di.inject(catalogEntityRegistryInjectable);
|
||||
|
||||
return computed(() => store.getById(entityRegistry.activeEntity?.getId()));
|
||||
return computed(() => {
|
||||
const entityId = entityRegistry.activeEntity?.getId();
|
||||
|
||||
if (entityId) {
|
||||
return getClusterById(entityId);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { shouldBaseStoreDisableSyncInIpcListenerInjectionToken } from "../../common/base-store/disable-sync";
|
||||
import { shouldPersistentStorageDisableSyncInIpcListenerInjectionToken } from "../../common/persistent-storage/disable-sync";
|
||||
|
||||
const shouldBaseStoreDisableSyncInIpcListenerInjectable = getInjectable({
|
||||
id: "should-base-store-disable-sync-in-ipc-listener",
|
||||
instantiate: () => true,
|
||||
injectionToken: shouldBaseStoreDisableSyncInIpcListenerInjectionToken,
|
||||
injectionToken: shouldPersistentStorageDisableSyncInIpcListenerInjectionToken,
|
||||
});
|
||||
|
||||
export default shouldBaseStoreDisableSyncInIpcListenerInjectable;
|
||||
@@ -3,7 +3,7 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { baseStoreIpcChannelPrefixesInjectionToken } from "../../common/base-store/channel-prefix";
|
||||
import { persistentStorageIpcChannelPrefixesInjectionToken } from "../../common/persistent-storage/channel-prefix";
|
||||
|
||||
const baseStoreIpcChannelPrefixInjectable = getInjectable({
|
||||
id: "base-store-ipc-channel-prefix",
|
||||
@@ -11,7 +11,7 @@ const baseStoreIpcChannelPrefixInjectable = getInjectable({
|
||||
local: "store-sync-renderer",
|
||||
remote: "store-sync-main",
|
||||
}),
|
||||
injectionToken: baseStoreIpcChannelPrefixesInjectionToken,
|
||||
injectionToken: persistentStorageIpcChannelPrefixesInjectionToken,
|
||||
});
|
||||
|
||||
export default baseStoreIpcChannelPrefixInjectable;
|
||||
@@ -3,7 +3,7 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { persistStateToConfigInjectionToken } from "../../common/base-store/save-to-file";
|
||||
import { persistStateToConfigInjectionToken } from "../../common/persistent-storage/save-to-file";
|
||||
import { noop } from "@k8slens/utilities";
|
||||
|
||||
const persistStateToConfigInjectable = getInjectable({
|
||||
|
||||
+1
-1
@@ -4,9 +4,9 @@
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import catalogCategoryRegistryInjectable from "../../../common/catalog/category-registry.injectable";
|
||||
import getClusterByIdInjectable from "../../../common/cluster-store/get-by-id.injectable";
|
||||
import loadKubeconfigInjectable from "../../../common/cluster/load-kubeconfig.injectable";
|
||||
import loggerInjectable from "../../../common/logger.injectable";
|
||||
import getClusterByIdInjectable from "../../../features/cluster/storage/common/get-by-id.injectable";
|
||||
import openDeleteClusterDialogInjectable from "../../components/delete-cluster-dialog/open.injectable";
|
||||
import { beforeFrameStartsSecondInjectionToken } from "../tokens";
|
||||
|
||||
|
||||
@@ -4,16 +4,20 @@
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import hostedClusterIdInjectable from "./hosted-cluster-id.injectable";
|
||||
import clusterStoreInjectable from "../../common/cluster-store/cluster-store.injectable";
|
||||
import getClusterByIdInjectable from "../../features/cluster/storage/common/get-by-id.injectable";
|
||||
|
||||
const hostedClusterInjectable = getInjectable({
|
||||
id: "hosted-cluster",
|
||||
|
||||
instantiate: (di) => {
|
||||
const hostedClusterId = di.inject(hostedClusterIdInjectable);
|
||||
const store = di.inject(clusterStoreInjectable);
|
||||
const getClusterById = di.inject(getClusterByIdInjectable);
|
||||
|
||||
return store.getById(hostedClusterId);
|
||||
if (!hostedClusterId) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return getClusterById(hostedClusterId);
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable";
|
||||
import { computed } from "mobx";
|
||||
import hostedClusterInjectable from "./hosted-cluster.injectable";
|
||||
import { shouldShowResourceInjectionToken } from "../../common/cluster-store/allowed-resources-injection-token";
|
||||
import { shouldShowResourceInjectionToken } from "../../features/cluster/showing-kube-resources/common/allowed-resources-injection-token";
|
||||
import type { KubeApiResourceDescriptor } from "../../common/rbac";
|
||||
import { formatKubeApiResource } from "../../common/rbac";
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ import { getDiForUnitTesting } from "../../../getDiForUnitTesting";
|
||||
import type { AdditionalCategoryColumnRegistration, CategoryColumnRegistration } from "../custom-category-columns";
|
||||
import type { CategoryColumns, GetCategoryColumnsParams } from "../columns/get.injectable";
|
||||
import getCategoryColumnsInjectable from "../columns/get.injectable";
|
||||
import hotbarStoreInjectable from "../../../../common/hotbars/store.injectable";
|
||||
import extensionInjectable from "../../../../extensions/extension-loader/extension/extension.injectable";
|
||||
import currentlyInClusterFrameInjectable from "../../../routes/currently-in-cluster-frame.injectable";
|
||||
|
||||
@@ -46,7 +45,6 @@ describe("Custom Category Columns", () => {
|
||||
beforeEach(() => {
|
||||
di = getDiForUnitTesting();
|
||||
|
||||
di.override(hotbarStoreInjectable, () => ({}));
|
||||
di.override(currentlyInClusterFrameInjectable, () => false);
|
||||
|
||||
getCategoryColumns = di.inject(getCategoryColumnsInjectable);
|
||||
|
||||
@@ -28,8 +28,6 @@ import type { VisitEntityContextMenu } from "../../../common/catalog/visit-entit
|
||||
import visitEntityContextMenuInjectable from "../../../common/catalog/visit-entity-context-menu.injectable";
|
||||
import type { NavigateToCatalog } from "../../../common/front-end-routing/routes/catalog/navigate-to-catalog.injectable";
|
||||
import navigateToCatalogInjectable from "../../../common/front-end-routing/routes/catalog/navigate-to-catalog.injectable";
|
||||
import type { HotbarStore } from "../../../common/hotbars/store";
|
||||
import hotbarStoreInjectable from "../../../common/hotbars/store.injectable";
|
||||
import type { Logger } from "../../../common/logger";
|
||||
import loggerInjectable from "../../../common/logger.injectable";
|
||||
import type { NormalizeCatalogEntityContextMenu } from "../../catalog/normalize-menu-item.injectable";
|
||||
@@ -51,6 +49,8 @@ import type { OnCatalogEntityListClick } from "./entity-details/on-catalog-click
|
||||
import onCatalogEntityListClickInjectable from "./entity-details/on-catalog-click.injectable";
|
||||
import type { ShowEntityDetails } from "./entity-details/show.injectable";
|
||||
import showEntityDetailsInjectable from "./entity-details/show.injectable";
|
||||
import type { Hotbar } from "../../../features/hotbar/storage/common/hotbar";
|
||||
import activeHotbarInjectable from "../../../features/hotbar/storage/common/active.injectable";
|
||||
|
||||
interface Dependencies {
|
||||
catalogPreviousActiveTabStorage: StorageLayer<string | null>;
|
||||
@@ -65,13 +65,13 @@ interface Dependencies {
|
||||
kind: IComputedValue<string>;
|
||||
};
|
||||
navigateToCatalog: NavigateToCatalog;
|
||||
hotbarStore: HotbarStore;
|
||||
catalogCategoryRegistry: CatalogCategoryRegistry;
|
||||
visitEntityContextMenu: VisitEntityContextMenu;
|
||||
navigate: Navigate;
|
||||
normalizeMenuItem: NormalizeCatalogEntityContextMenu;
|
||||
showErrorNotification: ShowNotification;
|
||||
logger: Logger;
|
||||
activeHotbar: IComputedValue<Hotbar | undefined>;
|
||||
}
|
||||
|
||||
@observer
|
||||
@@ -156,11 +156,11 @@ class NonInjectedCatalog extends React.Component<Dependencies> {
|
||||
}
|
||||
|
||||
addToHotbar(entity: CatalogEntity): void {
|
||||
this.props.hotbarStore.addToHotbar(entity);
|
||||
this.props.activeHotbar.get()?.addEntity(entity);
|
||||
}
|
||||
|
||||
removeFromHotbar(entity: CatalogEntity): void {
|
||||
this.props.hotbarStore.removeFromHotbar(entity.getId());
|
||||
this.props.activeHotbar.get()?.removeEntity(entity.getId());
|
||||
}
|
||||
|
||||
onTabChange = action((tabId: string | null) => {
|
||||
@@ -323,7 +323,7 @@ export const Catalog = withInjectables<Dependencies>(NonInjectedCatalog, {
|
||||
routeParameters: di.inject(catalogRouteParametersInjectable),
|
||||
navigateToCatalog: di.inject(navigateToCatalogInjectable),
|
||||
emitEvent: di.inject(emitAppEventInjectable),
|
||||
hotbarStore: di.inject(hotbarStoreInjectable),
|
||||
activeHotbar: di.inject(activeHotbarInjectable),
|
||||
catalogCategoryRegistry: di.inject(catalogCategoryRegistryInjectable),
|
||||
visitEntityContextMenu: di.inject(visitEntityContextMenuInjectable),
|
||||
navigate: di.inject(navigateInjectable),
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import styles from "../catalog.module.scss";
|
||||
import type { RegisteredAdditionalCategoryColumn } from "../custom-category-columns";
|
||||
import renderNamedCategoryColumnCellInjectable from "./render-named-category-column-cell.injectable";
|
||||
|
||||
const namedCategoryColumnInjectable = getInjectable({
|
||||
id: "name-category-column",
|
||||
instantiate: (di): RegisteredAdditionalCategoryColumn => ({
|
||||
id: "name",
|
||||
priority: 0,
|
||||
renderCell: di.inject(renderNamedCategoryColumnCellInjectable),
|
||||
titleProps: {
|
||||
title: "Name",
|
||||
className: styles.entityName,
|
||||
id: "name",
|
||||
sortBy: "name",
|
||||
},
|
||||
searchFilter: (entity) => entity.getName(),
|
||||
sortCallback: (entity) => `name=${entity.getName()}`,
|
||||
}),
|
||||
});
|
||||
|
||||
export default namedCategoryColumnInjectable;
|
||||
@@ -1,65 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import styles from "../catalog.module.scss";
|
||||
import type { CatalogEntity } from "../../../../common/catalog";
|
||||
import { prevDefault } from "@k8slens/utilities";
|
||||
import { Avatar } from "../../avatar";
|
||||
import { Icon } from "../../icon";
|
||||
import React from "react";
|
||||
import type { RegisteredAdditionalCategoryColumn } from "../custom-category-columns";
|
||||
import hotbarStoreInjectable from "../../../../common/hotbars/store.injectable";
|
||||
import type { HotbarStore } from "../../../../common/hotbars/store";
|
||||
|
||||
const renderEntityName = (hotbarStore: HotbarStore) => (entity: CatalogEntity) => {
|
||||
const isItemInHotbar = hotbarStore.isAddedToActive(entity);
|
||||
const onClick = prevDefault(
|
||||
isItemInHotbar
|
||||
? () => hotbarStore.removeFromHotbar(entity.getId())
|
||||
: () => hotbarStore.addToHotbar(entity),
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Avatar
|
||||
title={entity.getName()}
|
||||
colorHash={`${entity.getName()}-${entity.getSource()}`}
|
||||
src={entity.spec.icon?.src}
|
||||
background={entity.spec.icon?.background}
|
||||
className={styles.catalogAvatar}
|
||||
size={24}
|
||||
>
|
||||
{entity.spec.icon?.material && <Icon material={entity.spec.icon?.material} small/>}
|
||||
</Avatar>
|
||||
<span>{entity.getName()}</span>
|
||||
<Icon
|
||||
small
|
||||
className={styles.pinIcon}
|
||||
svg={isItemInHotbar ? "push_off" : "push_pin"}
|
||||
tooltip={isItemInHotbar ? "Remove from Hotbar" : "Add to Hotbar"}
|
||||
onClick={onClick}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const namedCategoryColumnInjectable = getInjectable({
|
||||
id: "name-category-column",
|
||||
instantiate: (di): RegisteredAdditionalCategoryColumn => ({
|
||||
id: "name",
|
||||
priority: 0,
|
||||
renderCell: renderEntityName(di.inject(hotbarStoreInjectable)),
|
||||
titleProps: {
|
||||
title: "Name",
|
||||
className: styles.entityName,
|
||||
id: "name",
|
||||
sortBy: "name",
|
||||
},
|
||||
searchFilter: (entity) => entity.getName(),
|
||||
sortCallback: (entity) => `name=${entity.getName()}`,
|
||||
}),
|
||||
});
|
||||
|
||||
export default namedCategoryColumnInjectable;
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import styles from "../catalog.module.scss";
|
||||
import React from "react";
|
||||
import activeHotbarInjectable from "../../../../features/hotbar/storage/common/active.injectable";
|
||||
import { Avatar } from "../../avatar";
|
||||
import type { RegisteredAdditionalCategoryColumn } from "../custom-category-columns";
|
||||
import { Icon } from "../../icon";
|
||||
import { prevDefault } from "@k8slens/utilities";
|
||||
|
||||
const renderNamedCategoryColumnCellInjectable = getInjectable({
|
||||
id: "render-named-category-column-cell",
|
||||
instantiate: (di): RegisteredAdditionalCategoryColumn["renderCell"] => {
|
||||
const activeHotbar = di.inject(activeHotbarInjectable);
|
||||
|
||||
return (entity) => {
|
||||
const hotbar = activeHotbar.get();
|
||||
|
||||
if (!hotbar) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const isItemInHotbar = hotbar.hasEntity(entity.getId());
|
||||
const onClick = prevDefault((
|
||||
isItemInHotbar
|
||||
? () => hotbar.removeEntity(entity.getId())
|
||||
: () => hotbar.addEntity(entity)
|
||||
));
|
||||
|
||||
return (
|
||||
<>
|
||||
<Avatar
|
||||
title={entity.getName()}
|
||||
colorHash={`${entity.getName()}-${entity.getSource()}`}
|
||||
src={entity.spec.icon?.src}
|
||||
background={entity.spec.icon?.background}
|
||||
className={styles.catalogAvatar}
|
||||
size={24}
|
||||
>
|
||||
{entity.spec.icon?.material && <Icon material={entity.spec.icon?.material} small/>}
|
||||
</Avatar>
|
||||
<span>{entity.getName()}</span>
|
||||
<Icon
|
||||
small
|
||||
className={styles.pinIcon}
|
||||
svg={isItemInHotbar ? "push_off" : "push_pin"}
|
||||
tooltip={isItemInHotbar ? "Remove from Hotbar" : "Add to Hotbar"}
|
||||
onClick={onClick}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export default renderNamedCategoryColumnCellInjectable;
|
||||
@@ -9,11 +9,12 @@ import { MenuItem } from "../menu";
|
||||
|
||||
import type { CatalogEntity } from "../../api/catalog-entity";
|
||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import hotbarStoreInjectable from "../../../common/hotbars/store.injectable";
|
||||
import type { HotbarStore } from "../../../common/hotbars/store";
|
||||
import type { IComputedValue } from "mobx";
|
||||
import type { Hotbar } from "../../../features/hotbar/storage/common/hotbar";
|
||||
import activeHotbarInjectable from "../../../features/hotbar/storage/common/active.injectable";
|
||||
|
||||
interface Dependencies {
|
||||
hotbarStore: HotbarStore;
|
||||
activeHotbar: IComputedValue<Hotbar | undefined>;
|
||||
}
|
||||
|
||||
interface HotbarToggleMenuItemProps {
|
||||
@@ -25,19 +26,19 @@ interface HotbarToggleMenuItemProps {
|
||||
function NonInjectedHotbarToggleMenuItem({
|
||||
addContent,
|
||||
entity,
|
||||
hotbarStore,
|
||||
activeHotbar,
|
||||
removeContent,
|
||||
}: Dependencies & HotbarToggleMenuItemProps) {
|
||||
const [itemInHotbar, setItemInHotbar] = useState(hotbarStore.isAddedToActive(entity));
|
||||
const [itemInHotbar, setItemInHotbar] = useState(activeHotbar.get()?.hasEntity(entity.getId()) ?? false);
|
||||
|
||||
return (
|
||||
<MenuItem
|
||||
onClick={() => {
|
||||
if (itemInHotbar) {
|
||||
hotbarStore.removeFromHotbar(entity.getId());
|
||||
activeHotbar.get()?.removeEntity(entity.getId());
|
||||
setItemInHotbar(false);
|
||||
} else {
|
||||
hotbarStore.addToHotbar(entity);
|
||||
activeHotbar.get()?.addEntity(entity);
|
||||
setItemInHotbar(true);
|
||||
}
|
||||
}}
|
||||
@@ -47,14 +48,10 @@ function NonInjectedHotbarToggleMenuItem({
|
||||
);
|
||||
}
|
||||
|
||||
export const HotbarToggleMenuItem = withInjectables<Dependencies, HotbarToggleMenuItemProps>(
|
||||
NonInjectedHotbarToggleMenuItem,
|
||||
|
||||
{
|
||||
getProps: (di, props) => ({
|
||||
hotbarStore: di.inject(hotbarStoreInjectable),
|
||||
...props,
|
||||
}),
|
||||
},
|
||||
);
|
||||
export const HotbarToggleMenuItem = withInjectables<Dependencies, HotbarToggleMenuItemProps>(NonInjectedHotbarToggleMenuItem, {
|
||||
getProps: (di, props) => ({
|
||||
...props,
|
||||
activeHotbar: di.inject(activeHotbarInjectable),
|
||||
}),
|
||||
});
|
||||
|
||||
+2
-2
@@ -6,8 +6,8 @@ import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import React from "react";
|
||||
import type { KubernetesCluster } from "../../../../common/catalog-entities";
|
||||
import type { GetClusterById } from "../../../../common/cluster-store/get-by-id.injectable";
|
||||
import getClusterByIdInjectable from "../../../../common/cluster-store/get-by-id.injectable";
|
||||
import type { GetClusterById } from "../../../../features/cluster/storage/common/get-by-id.injectable";
|
||||
import getClusterByIdInjectable from "../../../../features/cluster/storage/common/get-by-id.injectable";
|
||||
import { ClusterIconSetting } from "../../cluster-settings/icon-settings";
|
||||
import { ClusterKubeconfig } from "../../cluster-settings/kubeconfig";
|
||||
import { ClusterNameSetting } from "../../cluster-settings/name-setting";
|
||||
|
||||
+2
-2
@@ -5,8 +5,8 @@
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import React from "react";
|
||||
import type { GetClusterById } from "../../../../common/cluster-store/get-by-id.injectable";
|
||||
import getClusterByIdInjectable from "../../../../common/cluster-store/get-by-id.injectable";
|
||||
import type { GetClusterById } from "../../../../features/cluster/storage/common/get-by-id.injectable";
|
||||
import getClusterByIdInjectable from "../../../../features/cluster/storage/common/get-by-id.injectable";
|
||||
import { ClusterMetricsSetting } from "../../cluster-settings/metrics-setting";
|
||||
import { ClusterPrometheusSetting } from "../../cluster-settings/prometheus-setting";
|
||||
import { ShowMetricsSetting } from "../../cluster-settings/show-metrics";
|
||||
|
||||
+2
-2
@@ -5,8 +5,8 @@
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import React from "react";
|
||||
import type { GetClusterById } from "../../../../common/cluster-store/get-by-id.injectable";
|
||||
import getClusterByIdInjectable from "../../../../common/cluster-store/get-by-id.injectable";
|
||||
import type { GetClusterById } from "../../../../features/cluster/storage/common/get-by-id.injectable";
|
||||
import getClusterByIdInjectable from "../../../../features/cluster/storage/common/get-by-id.injectable";
|
||||
import { ClusterAccessibleNamespaces } from "../../cluster-settings/accessible-namespaces";
|
||||
import type { EntitySettingViewProps } from "../extension-registrator.injectable";
|
||||
import { entitySettingInjectionToken } from "../token";
|
||||
|
||||
+2
-2
@@ -5,8 +5,8 @@
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import React from "react";
|
||||
import type { GetClusterById } from "../../../../common/cluster-store/get-by-id.injectable";
|
||||
import getClusterByIdInjectable from "../../../../common/cluster-store/get-by-id.injectable";
|
||||
import type { GetClusterById } from "../../../../features/cluster/storage/common/get-by-id.injectable";
|
||||
import getClusterByIdInjectable from "../../../../features/cluster/storage/common/get-by-id.injectable";
|
||||
import { ClusterNodeShellSetting } from "../../cluster-settings/node-shell-setting";
|
||||
import type { EntitySettingViewProps } from "../extension-registrator.injectable";
|
||||
import { entitySettingInjectionToken } from "../token";
|
||||
|
||||
+2
-2
@@ -5,8 +5,8 @@
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import React from "react";
|
||||
import type { GetClusterById } from "../../../../common/cluster-store/get-by-id.injectable";
|
||||
import getClusterByIdInjectable from "../../../../common/cluster-store/get-by-id.injectable";
|
||||
import type { GetClusterById } from "../../../../features/cluster/storage/common/get-by-id.injectable";
|
||||
import getClusterByIdInjectable from "../../../../features/cluster/storage/common/get-by-id.injectable";
|
||||
import { ClusterProxySetting } from "../../cluster-settings/proxy-setting";
|
||||
import type { EntitySettingViewProps } from "../extension-registrator.injectable";
|
||||
import { entitySettingInjectionToken } from "../token";
|
||||
|
||||
+2
-2
@@ -5,8 +5,8 @@
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import React from "react";
|
||||
import type { GetClusterById } from "../../../../common/cluster-store/get-by-id.injectable";
|
||||
import getClusterByIdInjectable from "../../../../common/cluster-store/get-by-id.injectable";
|
||||
import type { GetClusterById } from "../../../../features/cluster/storage/common/get-by-id.injectable";
|
||||
import getClusterByIdInjectable from "../../../../features/cluster/storage/common/get-by-id.injectable";
|
||||
import { ClusterLocalTerminalSetting } from "../../cluster-settings/local-terminal-settings";
|
||||
import type { EntitySettingViewProps } from "../extension-registrator.injectable";
|
||||
import { entitySettingInjectionToken } from "../token";
|
||||
|
||||
+3
-3
@@ -7,15 +7,15 @@ import { getInjectable } from "@ogre-tools/injectable";
|
||||
import React from "react";
|
||||
import execFileInjectable from "../../../../common/fs/exec-file.injectable";
|
||||
import loggerInjectable from "../../../../common/logger.injectable";
|
||||
import { defaultExtensionRegistryUrl } from "../../../../common/user-store/preferences-helpers";
|
||||
import userStoreInjectable from "../../../../common/user-store/user-store.injectable";
|
||||
import { defaultExtensionRegistryUrl } from "../../../../features/user-preferences/common/preferences-helpers";
|
||||
import userPreferencesStateInjectable from "../../../../features/user-preferences/common/state.injectable";
|
||||
import showErrorNotificationInjectable from "../../notifications/show-error-notification.injectable";
|
||||
|
||||
const getBaseRegistryUrlInjectable = getInjectable({
|
||||
id: "get-base-registry-url",
|
||||
|
||||
instantiate: (di) => {
|
||||
const { extensionRegistryUrl } = di.inject(userStoreInjectable);
|
||||
const { extensionRegistryUrl } = di.inject(userPreferencesStateInjectable);
|
||||
const showErrorNotification = di.inject(showErrorNotificationInjectable);
|
||||
const logger = di.inject(loggerInjectable);
|
||||
const execFile = di.inject(execFileInjectable);
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { computed } from "mobx";
|
||||
import { shouldShowResourceInjectionToken } from "../../../../common/cluster-store/allowed-resources-injection-token";
|
||||
import { shouldShowResourceInjectionToken } from "../../../../features/cluster/showing-kube-resources/common/allowed-resources-injection-token";
|
||||
import { byOrderNumber } from "../../../../common/utils/composable-responsibilities/orderable/orderable";
|
||||
import { workloadInjectionToken } from "./workload-injection-token";
|
||||
|
||||
|
||||
@@ -8,9 +8,9 @@ import styles from "./avatar.module.scss";
|
||||
import type { ImgHTMLAttributes, MouseEventHandler } from "react";
|
||||
import React from "react";
|
||||
import randomColor from "randomcolor";
|
||||
import GraphemeSplitter from "grapheme-splitter";
|
||||
import type { SingleOrMany } from "@k8slens/utilities";
|
||||
import { cssNames, isDefined, iter } from "@k8slens/utilities";
|
||||
import { cssNames } from "@k8slens/utilities";
|
||||
import { computeDefaultShortName } from "../../../common/catalog/helpers";
|
||||
|
||||
export interface AvatarProps {
|
||||
title: string;
|
||||
@@ -28,40 +28,6 @@ export interface AvatarProps {
|
||||
"data-testid"?: string;
|
||||
}
|
||||
|
||||
function getNameParts(name: string): string[] {
|
||||
const byWhitespace = name.split(/\s+/);
|
||||
|
||||
if (byWhitespace.length > 1) {
|
||||
return byWhitespace;
|
||||
}
|
||||
|
||||
const byDashes = name.split(/[-_]+/);
|
||||
|
||||
if (byDashes.length > 1) {
|
||||
return byDashes;
|
||||
}
|
||||
|
||||
return name.split(/@+/);
|
||||
}
|
||||
|
||||
function getLabelFromTitle(title: string) {
|
||||
if (!title) {
|
||||
return "??";
|
||||
}
|
||||
|
||||
const [rawFirst, rawSecond, rawThird] = getNameParts(title);
|
||||
const splitter = new GraphemeSplitter();
|
||||
const first = splitter.iterateGraphemes(rawFirst);
|
||||
const second = rawSecond ? splitter.iterateGraphemes(rawSecond): first;
|
||||
const third = rawThird ? splitter.iterateGraphemes(rawThird) : iter.newEmpty();
|
||||
|
||||
return [
|
||||
...iter.take(first, 1),
|
||||
...iter.take(second, 1),
|
||||
...iter.take(third, 1),
|
||||
].filter(isDefined).join("");
|
||||
}
|
||||
|
||||
export const Avatar = ({
|
||||
title,
|
||||
variant = "rounded",
|
||||
@@ -104,6 +70,6 @@ export const Avatar = ({
|
||||
alt={title}
|
||||
/>
|
||||
)
|
||||
: children || getLabelFromTitle(title)}
|
||||
: children || computeDefaultShortName(title)}
|
||||
</div>
|
||||
);
|
||||
@@ -7,15 +7,15 @@ import React from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { Input } from "../input";
|
||||
import { isUrl } from "../input/input_validators";
|
||||
import type { WeblinkStore } from "../../../common/weblinks-store/weblink-store";
|
||||
import { computed, makeObservable, observable } from "mobx";
|
||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import commandOverlayInjectable from "../command-palette/command-overlay.injectable";
|
||||
import weblinkStoreInjectable from "../../../common/weblinks-store/weblink-store.injectable";
|
||||
import type { AddWeblink } from "../../../features/weblinks/common/add.injectable";
|
||||
import addWeblinkInjectable from "../../../features/weblinks/common/add.injectable";
|
||||
|
||||
interface Dependencies {
|
||||
closeCommandOverlay: () => void;
|
||||
weblinkStore: WeblinkStore;
|
||||
addWeblink: AddWeblink;
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ class NonInjectedWeblinkAddCommand extends React.Component<Dependencies> {
|
||||
}
|
||||
|
||||
onSubmit(name: string) {
|
||||
this.props.weblinkStore.add({
|
||||
this.props.addWeblink({
|
||||
name: name || this.url,
|
||||
url: this.url,
|
||||
});
|
||||
@@ -97,6 +97,6 @@ export const WeblinkAddCommand = withInjectables<Dependencies>(NonInjectedWeblin
|
||||
getProps: (di, props) => ({
|
||||
...props,
|
||||
closeCommandOverlay: di.inject(commandOverlayInjectable).close,
|
||||
weblinkStore: di.inject(weblinkStoreInjectable),
|
||||
addWeblink: di.inject(addWeblinkInjectable),
|
||||
}),
|
||||
});
|
||||
+1
-1
@@ -3,8 +3,8 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import getClusterByIdInjectable from "../../../common/cluster-store/get-by-id.injectable";
|
||||
import loggerInjectable from "../../../common/logger.injectable";
|
||||
import getClusterByIdInjectable from "../../../features/cluster/storage/common/get-by-id.injectable";
|
||||
import { ClusterFrameHandler } from "./cluster-frame-handler";
|
||||
import emitClusterVisibilityInjectable from "./emit-cluster-visibility.injectable";
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@ import type { Disposer } from "@k8slens/utilities";
|
||||
import { onceDefined } from "@k8slens/utilities";
|
||||
import assert from "assert";
|
||||
import type { Logger } from "../../../common/logger";
|
||||
import type { GetClusterById } from "../../../common/cluster-store/get-by-id.injectable";
|
||||
import { getClusterFrameUrl } from "../../../common/utils";
|
||||
import type { GetClusterById } from "../../../features/cluster/storage/common/get-by-id.injectable";
|
||||
|
||||
export interface LensView {
|
||||
isLoaded: boolean;
|
||||
|
||||
@@ -18,10 +18,10 @@ import clusterViewRouteParametersInjectable from "./cluster-view-route-parameter
|
||||
import clusterFrameHandlerInjectable from "./cluster-frame-handler.injectable";
|
||||
import type { CatalogEntityRegistry } from "../../api/catalog/entity/registry";
|
||||
import catalogEntityRegistryInjectable from "../../api/catalog/entity/registry.injectable";
|
||||
import type { GetClusterById } from "../../../common/cluster-store/get-by-id.injectable";
|
||||
import getClusterByIdInjectable from "../../../common/cluster-store/get-by-id.injectable";
|
||||
import type { RequestClusterActivation } from "../../../features/cluster/activation/common/request-token";
|
||||
import requestClusterActivationInjectable from "../../../features/cluster/activation/renderer/request-activation.injectable";
|
||||
import type { GetClusterById } from "../../../features/cluster/storage/common/get-by-id.injectable";
|
||||
import getClusterByIdInjectable from "../../../features/cluster/storage/common/get-by-id.injectable";
|
||||
|
||||
interface Dependencies {
|
||||
clusterId: IComputedValue<string>;
|
||||
|
||||
@@ -15,9 +15,7 @@ import { Dialog } from "../dialog";
|
||||
import { Icon } from "../icon";
|
||||
import { Select } from "../select";
|
||||
import { Checkbox } from "../checkbox";
|
||||
import type { HotbarStore } from "../../../common/hotbars/store";
|
||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import hotbarStoreInjectable from "../../../common/hotbars/store.injectable";
|
||||
import type { DeleteClusterDialogState } from "./state.injectable";
|
||||
import deleteClusterDialogStateInjectable from "./state.injectable";
|
||||
import type { RequestSetClusterAsDeleting } from "../../../features/cluster/delete-dialog/renderer/request-set-as-deleting.injectable";
|
||||
@@ -32,16 +30,18 @@ import showErrorNotificationInjectable from "../notifications/show-error-notific
|
||||
import { isCurrentContext } from "./is-current-context";
|
||||
import type { IsInLocalKubeconfig } from "./is-in-local-kubeconfig.injectable";
|
||||
import isInLocalKubeconfigInjectable from "./is-in-local-kubeconfig.injectable";
|
||||
import type { RemoveEntityFromAllHotbars } from "../../../features/hotbar/storage/common/remove-entity-from-all.injectable";
|
||||
import removeEntityFromAllHotbarsInjectable from "../../../features/hotbar/storage/common/remove-entity-from-all.injectable";
|
||||
|
||||
interface Dependencies {
|
||||
state: IObservableValue<DeleteClusterDialogState | undefined>;
|
||||
hotbarStore: HotbarStore;
|
||||
requestSetClusterAsDeleting: RequestSetClusterAsDeleting;
|
||||
requestDeleteCluster: RequestDeleteCluster;
|
||||
requestClearClusterAsDeleting: RequestClearClusterAsDeleting;
|
||||
showErrorNotification: ShowNotification;
|
||||
saveKubeconfig: SaveKubeconfig;
|
||||
isInLocalKubeconfig: IsInLocalKubeconfig;
|
||||
removeEntityFromAllHotbars: RemoveEntityFromAllHotbars;
|
||||
}
|
||||
|
||||
@observer
|
||||
@@ -65,7 +65,7 @@ class NonInjectedDeleteClusterDialog extends React.Component<Dependencies> {
|
||||
|
||||
try {
|
||||
await this.props.saveKubeconfig(config, cluster.kubeConfigPath.get());
|
||||
this.props.hotbarStore.removeAllHotbarItems(cluster.id);
|
||||
this.props.removeEntityFromAllHotbars(cluster.id);
|
||||
await this.props.requestDeleteCluster(cluster.id);
|
||||
} catch(error) {
|
||||
this.props.showErrorNotification(`Cannot remove cluster, failed to process config file. ${error}`);
|
||||
@@ -267,7 +267,6 @@ class NonInjectedDeleteClusterDialog extends React.Component<Dependencies> {
|
||||
|
||||
export const DeleteClusterDialog = withInjectables<Dependencies>(NonInjectedDeleteClusterDialog, {
|
||||
getProps: (di) => ({
|
||||
hotbarStore: di.inject(hotbarStoreInjectable),
|
||||
state: di.inject(deleteClusterDialogStateInjectable),
|
||||
requestSetClusterAsDeleting: di.inject(requestSetClusterAsDeletingInjectable),
|
||||
requestClearClusterAsDeleting: di.inject(requestClearClusterAsDeletingInjectable),
|
||||
@@ -275,5 +274,6 @@ export const DeleteClusterDialog = withInjectables<Dependencies>(NonInjectedDele
|
||||
saveKubeconfig: di.inject(saveKubeconfigInjectable),
|
||||
showErrorNotification: di.inject(showErrorNotificationInjectable),
|
||||
isInLocalKubeconfig: di.inject(isInLocalKubeconfigInjectable),
|
||||
removeEntityFromAllHotbars: di.inject(removeEntityFromAllHotbarsInjectable),
|
||||
}),
|
||||
});
|
||||
@@ -15,7 +15,6 @@ import { disposeOnUnmount, observer } from "mobx-react";
|
||||
import moment from "moment-timezone";
|
||||
import type { Align, ListOnScrollProps } from "react-window";
|
||||
import { SearchStore } from "../../../search-store/search-store";
|
||||
import type { UserStore } from "../../../../common/user-store";
|
||||
import { array, cssNames } from "@k8slens/utilities";
|
||||
import type { VirtualListRef } from "../../virtual-list";
|
||||
import { VirtualList } from "../../virtual-list";
|
||||
@@ -23,8 +22,9 @@ import { ToBottom } from "./to-bottom";
|
||||
import type { LogTabViewModel } from "../logs/logs-view-model";
|
||||
import { Spinner } from "../../spinner";
|
||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import userStoreInjectable from "../../../../common/user-store/user-store.injectable";
|
||||
import autoBindReact from "auto-bind/react";
|
||||
import type { UserPreferencesState } from "../../../../features/user-preferences/common/state.injectable";
|
||||
import userPreferencesStateInjectable from "../../../../features/user-preferences/common/state.injectable";
|
||||
|
||||
export interface LogListProps {
|
||||
model: LogTabViewModel;
|
||||
@@ -37,7 +37,7 @@ export interface LogListRef {
|
||||
}
|
||||
|
||||
interface Dependencies {
|
||||
userStore: UserStore;
|
||||
state: UserPreferencesState;
|
||||
}
|
||||
|
||||
@observer
|
||||
@@ -129,7 +129,7 @@ class NonForwardedLogList extends React.Component<Dependencies & LogListProps &
|
||||
|
||||
return this.props.model.timestampSplitLogs
|
||||
.get()
|
||||
.map(([logTimestamp, log]) => (`${logTimestamp && moment.tz(logTimestamp, this.props.userStore.localeTimezone).format()}${log}`));
|
||||
.map(([logTimestamp, log]) => (`${logTimestamp && moment.tz(logTimestamp, this.props.state.localeTimezone).format()}${log}`));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -283,7 +283,7 @@ class NonForwardedLogList extends React.Component<Dependencies & LogListProps &
|
||||
const InjectedNonForwardedLogList = withInjectables<Dependencies, LogListProps & { innerRef: ForwardedRef<LogListRef> }>(NonForwardedLogList, {
|
||||
getProps: (di, props) => ({
|
||||
...props,
|
||||
userStore: di.inject(userStoreInjectable),
|
||||
state: di.inject(userPreferencesStateInjectable),
|
||||
}),
|
||||
});
|
||||
|
||||
|
||||
@@ -8,13 +8,12 @@ import { Terminal } from "./terminal";
|
||||
import type { TabId } from "../dock/store";
|
||||
import type { TerminalApi } from "../../../api/terminal-api";
|
||||
import terminalSpawningPoolInjectable from "./terminal-spawning-pool.injectable";
|
||||
import terminalConfigInjectable from "../../../../common/user-store/terminal-config.injectable";
|
||||
import terminalCopyOnSelectInjectable
|
||||
from "../../../../common/user-store/terminal-copy-on-select.injectable";
|
||||
import isMacInjectable from "../../../../common/vars/is-mac.injectable";
|
||||
import openLinkInBrowserInjectable from "../../../../common/utils/open-link-in-browser.injectable";
|
||||
import xtermColorThemeInjectable from "../../../themes/terminal-colors.injectable";
|
||||
import loggerInjectable from "../../../../common/logger.injectable";
|
||||
import terminalConfigInjectable from "../../../../features/user-preferences/common/terminal-config.injectable";
|
||||
import terminalCopyOnSelectInjectable from "../../../../features/user-preferences/common/terminal-copy-on-select.injectable";
|
||||
|
||||
export type CreateTerminal = (tabId: TabId, api: TerminalApi) => Terminal;
|
||||
|
||||
|
||||
@@ -14,11 +14,11 @@ import { disposer } from "@k8slens/utilities";
|
||||
import { once } from "lodash";
|
||||
import { clipboard } from "electron";
|
||||
import type { Logger } from "../../../../common/logger";
|
||||
import type { TerminalConfig } from "../../../../common/user-store/preferences-helpers";
|
||||
import assert from "assert";
|
||||
import { TerminalChannels } from "../../../../common/terminal/channels";
|
||||
import { LinkProvider } from "xterm-link-provider";
|
||||
import type { OpenLinkInBrowser } from "../../../../common/utils/open-link-in-browser.injectable";
|
||||
import type { TerminalConfig } from "../../../../features/user-preferences/common/preferences-helpers";
|
||||
|
||||
export interface TerminalDependencies {
|
||||
readonly spawningPool: HTMLElement;
|
||||
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`<HotbarRemoveCommand /> renders w/o errors 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="Select theme-dark css-b62m3t-container"
|
||||
>
|
||||
<span
|
||||
class="css-1f43avz-a11yText-A11yText"
|
||||
id="react-select-2-live-region"
|
||||
>
|
||||
<span
|
||||
id="aria-selection"
|
||||
>
|
||||
option , selected.
|
||||
</span>
|
||||
<span
|
||||
id="aria-context"
|
||||
>
|
||||
2 results available. Use Up and Down to choose options, press Enter to select the currently focused option, press Escape to exit the menu, press Tab to select the option and exit the menu.
|
||||
</span>
|
||||
</span>
|
||||
<span
|
||||
aria-atomic="false"
|
||||
aria-live="polite"
|
||||
aria-relevant="additions text"
|
||||
class="css-1f43avz-a11yText-A11yText"
|
||||
/>
|
||||
<div
|
||||
class="Select__control Select__control--is-focused Select__control--menu-is-open css-t3ipsp-control"
|
||||
>
|
||||
<div
|
||||
class="Select__value-container css-1fdsijx-ValueContainer"
|
||||
>
|
||||
<div
|
||||
class="Select__placeholder css-1jqq78o-placeholder"
|
||||
id="react-select-2-placeholder"
|
||||
>
|
||||
Remove hotbar
|
||||
</div>
|
||||
<div
|
||||
class="Select__input-container css-qbdosj-Input"
|
||||
data-value=""
|
||||
>
|
||||
<input
|
||||
aria-autocomplete="list"
|
||||
aria-controls="react-select-2-listbox"
|
||||
aria-describedby="react-select-2-placeholder"
|
||||
aria-expanded="true"
|
||||
aria-haspopup="true"
|
||||
aria-owns="react-select-2-listbox"
|
||||
autocapitalize="none"
|
||||
autocomplete="off"
|
||||
autocorrect="off"
|
||||
class="Select__input"
|
||||
id="react-select-2-input"
|
||||
role="combobox"
|
||||
spellcheck="false"
|
||||
style="opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
|
||||
tabindex="0"
|
||||
type="text"
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="Select__indicators css-1hb7zxy-IndicatorsContainer"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="theme-dark Select__menu css-1nmdiq5-menu"
|
||||
id="react-select-2-listbox"
|
||||
>
|
||||
<div
|
||||
class="Select__menu-list css-1n6sfyn-MenuList"
|
||||
>
|
||||
<div
|
||||
aria-disabled="false"
|
||||
class="Select__option css-10wo9uf-option"
|
||||
id="react-select-2-option-0"
|
||||
tabindex="-1"
|
||||
>
|
||||
1: default
|
||||
</div>
|
||||
<div
|
||||
aria-disabled="false"
|
||||
class="Select__option css-10wo9uf-option"
|
||||
id="react-select-2-option-1"
|
||||
tabindex="-1"
|
||||
>
|
||||
2: non-default
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
+30
-49
@@ -5,75 +5,56 @@
|
||||
|
||||
import "@testing-library/jest-dom/extend-expect";
|
||||
import { HotbarRemoveCommand } from "../hotbar-remove-command";
|
||||
import type { RenderResult } from "@testing-library/react";
|
||||
import { fireEvent } from "@testing-library/react";
|
||||
import React from "react";
|
||||
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/hotbars/store.injectable";
|
||||
import { ConfirmDialog } from "../../confirm-dialog";
|
||||
import directoryForUserDataInjectable from "../../../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable";
|
||||
import type { HotbarStore } from "../../../../common/hotbars/store";
|
||||
import storesAndApisCanBeCreatedInjectable from "../../../stores-apis-can-be-created.injectable";
|
||||
|
||||
const mockHotbars: Partial<Record<string, any>> = {
|
||||
"1": {
|
||||
id: "1",
|
||||
name: "Default",
|
||||
items: [],
|
||||
},
|
||||
};
|
||||
import hotbarsStateInjectable from "../../../../features/hotbar/storage/common/state.injectable";
|
||||
import type { CreateHotbar } from "../../../../features/hotbar/storage/common/create-hotbar.injectable";
|
||||
import createHotbarInjectable from "../../../../features/hotbar/storage/common/create-hotbar.injectable";
|
||||
import type { IComputedValue } from "mobx";
|
||||
import type { Hotbar } from "../../../../features/hotbar/storage/common/hotbar";
|
||||
import hotbarsInjectable from "../../../../features/hotbar/storage/common/hotbars.injectable";
|
||||
|
||||
describe("<HotbarRemoveCommand />", () => {
|
||||
let di: DiContainer;
|
||||
let render: DiRender;
|
||||
let result: RenderResult;
|
||||
let createHotbar: CreateHotbar;
|
||||
let hotbars: IComputedValue<Hotbar[]>;
|
||||
|
||||
beforeEach(() => {
|
||||
di = getDiForUnitTesting();
|
||||
const di = getDiForUnitTesting();
|
||||
const render = renderFor(di);
|
||||
|
||||
di.override(storesAndApisCanBeCreatedInjectable, () => true);
|
||||
di.override(directoryForUserDataInjectable, () => "/some-directory-for-user-data");
|
||||
|
||||
render = renderFor(di);
|
||||
});
|
||||
createHotbar = di.inject(createHotbarInjectable);
|
||||
hotbars = di.inject(hotbarsInjectable);
|
||||
|
||||
it("renders w/o errors", () => {
|
||||
di.override(hotbarStoreInjectable, () => ({
|
||||
hotbars: [mockHotbars["1"]],
|
||||
getById: (id: string) => mockHotbars[id],
|
||||
remove: () => {
|
||||
},
|
||||
hotbarIndex: () => 0,
|
||||
getDisplayLabel: () => "1: Default",
|
||||
}) as unknown as HotbarStore);
|
||||
const hotbarsState = di.inject(hotbarsStateInjectable);
|
||||
const defaultHotbar = createHotbar({ name: "default" });
|
||||
const nonDefaultHotbar = createHotbar({ name: "non-default" });
|
||||
|
||||
const { container } = render(<HotbarRemoveCommand />);
|
||||
hotbarsState.set(defaultHotbar.id, defaultHotbar);
|
||||
hotbarsState.set(nonDefaultHotbar.id, nonDefaultHotbar);
|
||||
|
||||
expect(container).toBeInstanceOf(HTMLElement);
|
||||
});
|
||||
|
||||
it("calls remove if you click on the entry", () => {
|
||||
const removeMock = jest.fn();
|
||||
|
||||
di.override(hotbarStoreInjectable, () => ({
|
||||
hotbars: [mockHotbars["1"]],
|
||||
getById: (id: string) => mockHotbars[id],
|
||||
remove: removeMock,
|
||||
hotbarIndex: () => 0,
|
||||
getDisplayLabel: () => "1: Default",
|
||||
}) as unknown as HotbarStore);
|
||||
|
||||
const { getByText } = render(
|
||||
result = render((
|
||||
<>
|
||||
<HotbarRemoveCommand />
|
||||
<ConfirmDialog />
|
||||
</>,
|
||||
);
|
||||
</>
|
||||
));
|
||||
});
|
||||
|
||||
fireEvent.click(getByText("1: Default"));
|
||||
fireEvent.click(getByText("Remove Hotbar"));
|
||||
it("renders w/o errors", () => {
|
||||
expect(result.container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
expect(removeMock).toHaveBeenCalled();
|
||||
it("calls remove if you click on the entry", () => {
|
||||
fireEvent.click(result.getByText("1: default"));
|
||||
fireEvent.click(result.getByText("Remove Hotbar"));
|
||||
expect(hotbars.get().length).toBe(1);
|
||||
});
|
||||
});
|
||||
@@ -7,15 +7,15 @@ import React from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import type { InputValidator } from "../input";
|
||||
import { Input } from "../input";
|
||||
import type { CreateHotbarData, CreateHotbarOptions } from "../../../common/hotbars/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 addHotbarInjectable from "../../../common/hotbars/add-hotbar.injectable";
|
||||
import type { AddHotbar } from "../../../features/hotbar/storage/common/add.injectable";
|
||||
import addHotbarInjectable from "../../../features/hotbar/storage/common/add.injectable";
|
||||
|
||||
interface Dependencies {
|
||||
closeCommandOverlay: () => void;
|
||||
addHotbar: (data: CreateHotbarData, opts: CreateHotbarOptions) => void;
|
||||
addHotbar: AddHotbar;
|
||||
uniqueHotbarName: InputValidator<boolean>;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import "./hotbar-menu.scss";
|
||||
|
||||
import React from "react";
|
||||
import React, { useState } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { HotbarEntityIcon } from "./hotbar-entity-icon";
|
||||
import type { IClassName } from "@k8slens/utilities";
|
||||
@@ -16,57 +16,46 @@ import { DragDropContext, Draggable, Droppable, type DropResult } from "react-be
|
||||
import { HotbarSelector } from "./hotbar-selector";
|
||||
import { HotbarCell } from "./hotbar-cell";
|
||||
import { HotbarIcon } from "./hotbar-icon";
|
||||
import type { HotbarItem } from "../../../common/hotbars/types";
|
||||
import { defaultHotbarCells } from "../../../common/hotbars/types";
|
||||
import { action, makeObservable, observable } from "mobx";
|
||||
import hotbarStoreInjectable from "../../../common/hotbars/store.injectable";
|
||||
import type { HotbarItem } from "../../../features/hotbar/storage/common/types";
|
||||
import { defaultHotbarCells } from "../../../features/hotbar/storage/common/types";
|
||||
import type { IComputedValue } from "mobx";
|
||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import type { HotbarStore } from "../../../common/hotbars/store";
|
||||
import catalogEntityRegistryInjectable from "../../api/catalog/entity/registry.injectable";
|
||||
import type { Hotbar } from "../../../features/hotbar/storage/common/hotbar";
|
||||
import activeHotbarInjectable from "../../../features/hotbar/storage/common/active.injectable";
|
||||
|
||||
export interface HotbarMenuProps {
|
||||
className?: IClassName;
|
||||
}
|
||||
|
||||
interface Dependencies {
|
||||
hotbarStore: HotbarStore;
|
||||
activeHotbar: IComputedValue<Hotbar | undefined>;
|
||||
entityRegistry: CatalogEntityRegistry;
|
||||
}
|
||||
|
||||
@observer
|
||||
class NonInjectedHotbarMenu extends React.Component<Dependencies & HotbarMenuProps> {
|
||||
@observable draggingOver = false;
|
||||
const NonInjectedHotbarMenu = observer((props: Dependencies & HotbarMenuProps) => {
|
||||
const {
|
||||
activeHotbar,
|
||||
entityRegistry,
|
||||
className,
|
||||
} = props;
|
||||
|
||||
constructor(props: Dependencies & HotbarMenuProps) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
const [draggingOver, setDraggingOver] = useState(false);
|
||||
const hotbar = activeHotbar.get();
|
||||
|
||||
get hotbar() {
|
||||
return this.props.hotbarStore.getActive();
|
||||
}
|
||||
|
||||
getEntity(item: HotbarItem | null) {
|
||||
const hotbar = this.props.hotbarStore.getActive();
|
||||
|
||||
if (!hotbar || !item) {
|
||||
return null;
|
||||
const getEntity = (item: HotbarItem | null) => {
|
||||
if (!item) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return this.props.entityRegistry.getById(item.entity.uid) ?? null;
|
||||
}
|
||||
return entityRegistry.getById(item.entity.uid);
|
||||
};
|
||||
const onDragStart = () => setDraggingOver(true);
|
||||
const onDragEnd = (result: DropResult) => {
|
||||
setDraggingOver(false);
|
||||
|
||||
@action
|
||||
onDragStart() {
|
||||
this.draggingOver = true;
|
||||
}
|
||||
|
||||
@action
|
||||
onDragEnd(result: DropResult) {
|
||||
const { source, destination } = result;
|
||||
|
||||
this.draggingOver = false;
|
||||
|
||||
if (!destination) { // Dropped outside of the list
|
||||
return;
|
||||
}
|
||||
@@ -74,135 +63,115 @@ class NonInjectedHotbarMenu extends React.Component<Dependencies & HotbarMenuPro
|
||||
const from = parseInt(source.droppableId);
|
||||
const to = parseInt(destination.droppableId);
|
||||
|
||||
this.props.hotbarStore.restackItems(from, to);
|
||||
}
|
||||
|
||||
removeItem = (uid: string) => {
|
||||
const hotbar = this.props.hotbarStore;
|
||||
|
||||
hotbar.removeFromHotbar(uid);
|
||||
hotbar?.restack(from, to);
|
||||
};
|
||||
|
||||
addItem = (entity: CatalogEntity, index = -1) => {
|
||||
const hotbar = this.props.hotbarStore;
|
||||
|
||||
hotbar.addToHotbar(entity, index);
|
||||
const removeItem = (entityId: string) => {
|
||||
hotbar?.removeEntity(entityId);
|
||||
};
|
||||
|
||||
getMoveAwayDirection(entityId: string | undefined | null, cellIndex: number) {
|
||||
if (!entityId) {
|
||||
const addItem = (entity: CatalogEntity) => {
|
||||
hotbar?.addEntity(entity);
|
||||
};
|
||||
const getMoveAwayDirection = (entityId: string | undefined | null, cellIndex: number) => {
|
||||
if (!entityId || !hotbar) {
|
||||
return "animateDown";
|
||||
}
|
||||
|
||||
const draggableItemIndex = this.hotbar.items.findIndex(item => item?.entity.uid == entityId);
|
||||
const draggableItemIndex = hotbar.items.findIndex(item => item?.entity.uid == entityId);
|
||||
|
||||
return draggableItemIndex > cellIndex ? "animateDown" : "animateUp";
|
||||
}
|
||||
};
|
||||
|
||||
renderGrid() {
|
||||
return this.hotbar.items.map((item, index) => {
|
||||
const entity = this.getEntity(item);
|
||||
|
||||
return (
|
||||
<Droppable droppableId={`${index}`} key={index}>
|
||||
{(provided, snapshot) => (
|
||||
<HotbarCell
|
||||
index={index}
|
||||
key={entity ? entity.getId() : `cell${index}`}
|
||||
innerRef={provided.innerRef}
|
||||
className={cssNames(
|
||||
{
|
||||
isDraggingOver: snapshot.isDraggingOver,
|
||||
isDraggingOwner: snapshot.draggingOverWith == entity?.getId(),
|
||||
},
|
||||
this.getMoveAwayDirection(snapshot.draggingOverWith, index),
|
||||
)}
|
||||
{...provided.droppableProps}
|
||||
>
|
||||
{item && (
|
||||
<Draggable
|
||||
draggableId={item.entity.uid}
|
||||
key={item.entity.uid}
|
||||
index={0}
|
||||
>
|
||||
{(provided, snapshot) => {
|
||||
const style = {
|
||||
zIndex: defaultHotbarCells - index,
|
||||
position: "absolute",
|
||||
...provided.draggableProps.style,
|
||||
} as React.CSSProperties;
|
||||
|
||||
return (
|
||||
<div
|
||||
key={item.entity.uid}
|
||||
ref={provided.innerRef}
|
||||
{...provided.draggableProps}
|
||||
{...provided.dragHandleProps}
|
||||
style={style}
|
||||
>
|
||||
{entity ? (
|
||||
<HotbarEntityIcon
|
||||
key={index}
|
||||
index={index}
|
||||
entity={entity}
|
||||
onClick={() => this.props.entityRegistry.onRun(entity)}
|
||||
className={cssNames({ isDragging: snapshot.isDragging })}
|
||||
remove={this.removeItem}
|
||||
add={this.addItem}
|
||||
size={40}
|
||||
/>
|
||||
) : (
|
||||
<HotbarIcon
|
||||
uid={`hotbar-icon-${item.entity.uid}`}
|
||||
title={item.entity.name}
|
||||
source={item.entity.source ?? "local"}
|
||||
tooltip={`${item.entity.name} (${item.entity.source})`}
|
||||
menuItems={[
|
||||
{
|
||||
title: "Remove from Hotbar",
|
||||
onClick: () => this.removeItem(item.entity.uid),
|
||||
},
|
||||
]}
|
||||
disabled
|
||||
size={40}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
</Draggable>
|
||||
)}
|
||||
{provided.placeholder}
|
||||
</HotbarCell>
|
||||
)}
|
||||
</Droppable>
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const { className, hotbarStore } = this.props;
|
||||
const hotbar = hotbarStore.getActive();
|
||||
const renderGrid = () => hotbar?.items.map((item, index) => {
|
||||
const entity = getEntity(item);
|
||||
|
||||
return (
|
||||
<div className={cssNames("HotbarMenu flex column", { draggingOver: this.draggingOver }, className)}>
|
||||
<div className="HotbarItems flex column gaps">
|
||||
<DragDropContext
|
||||
onDragStart={() => this.onDragStart()}
|
||||
onDragEnd={(result) => this.onDragEnd(result)}>
|
||||
{this.renderGrid()}
|
||||
</DragDropContext>
|
||||
</div>
|
||||
<HotbarSelector hotbar={hotbar} />
|
||||
</div>
|
||||
<Droppable droppableId={`${index}`} key={index}>
|
||||
{(provided, snapshot) => (
|
||||
<HotbarCell
|
||||
index={index}
|
||||
key={entity ? entity.getId() : `cell${index}`}
|
||||
innerRef={provided.innerRef}
|
||||
className={cssNames(
|
||||
{
|
||||
isDraggingOver: snapshot.isDraggingOver,
|
||||
isDraggingOwner: snapshot.draggingOverWith == entity?.getId(),
|
||||
},
|
||||
getMoveAwayDirection(snapshot.draggingOverWith, index),
|
||||
)}
|
||||
{...provided.droppableProps}
|
||||
>
|
||||
{item && (
|
||||
<Draggable
|
||||
draggableId={item.entity.uid}
|
||||
key={item.entity.uid}
|
||||
index={0}
|
||||
>
|
||||
{(provided, snapshot) => (
|
||||
<div
|
||||
key={item.entity.uid}
|
||||
ref={provided.innerRef}
|
||||
{...provided.draggableProps}
|
||||
{...provided.dragHandleProps}
|
||||
style={{
|
||||
zIndex: defaultHotbarCells - index,
|
||||
position: "absolute" as const,
|
||||
...provided.draggableProps.style,
|
||||
}}
|
||||
>
|
||||
{entity ? (
|
||||
<HotbarEntityIcon
|
||||
key={index}
|
||||
index={index}
|
||||
entity={entity}
|
||||
onClick={() => entityRegistry.onRun(entity)}
|
||||
className={cssNames({ isDragging: snapshot.isDragging })}
|
||||
remove={removeItem}
|
||||
add={addItem}
|
||||
size={40} />
|
||||
) : (
|
||||
<HotbarIcon
|
||||
uid={`hotbar-icon-${item.entity.uid}`}
|
||||
title={item.entity.name}
|
||||
source={item.entity.source ?? "local"}
|
||||
tooltip={`${item.entity.name} (${item.entity.source})`}
|
||||
menuItems={[
|
||||
{
|
||||
title: "Remove from Hotbar",
|
||||
onClick: () => removeItem(item.entity.uid),
|
||||
},
|
||||
]}
|
||||
disabled
|
||||
size={40} />
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</Draggable>
|
||||
)}
|
||||
{provided.placeholder}
|
||||
</HotbarCell>
|
||||
)}
|
||||
</Droppable>
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<div className={cssNames("HotbarMenu flex column", { draggingOver }, className)}>
|
||||
<div className="HotbarItems flex column gaps">
|
||||
<DragDropContext
|
||||
onDragStart={() => onDragStart()}
|
||||
onDragEnd={(result) => onDragEnd(result)}>
|
||||
{renderGrid()}
|
||||
</DragDropContext>
|
||||
</div>
|
||||
<HotbarSelector />
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
export const HotbarMenu = withInjectables<Dependencies, HotbarMenuProps>(NonInjectedHotbarMenu, {
|
||||
getProps: (di, props) => ({
|
||||
...props,
|
||||
hotbarStore: di.inject(hotbarStoreInjectable),
|
||||
entityRegistry: di.inject(catalogEntityRegistryInjectable),
|
||||
activeHotbar: di.inject(activeHotbarInjectable),
|
||||
}),
|
||||
});
|
||||
@@ -6,23 +6,32 @@
|
||||
import React from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { Select } from "../select";
|
||||
import hotbarStoreInjectable from "../../../common/hotbars/store.injectable";
|
||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import commandOverlayInjectable from "../command-palette/command-overlay.injectable";
|
||||
import type { HotbarStore } from "../../../common/hotbars/store";
|
||||
import type { OpenConfirmDialog } from "../confirm-dialog/open.injectable";
|
||||
import openConfirmDialogInjectable from "../confirm-dialog/open.injectable";
|
||||
import type { IComputedValue } from "mobx";
|
||||
import type { Hotbar } from "../../../features/hotbar/storage/common/hotbar";
|
||||
import type { ComputeHotbarDisplayLabel } from "../../../features/hotbar/storage/common/compute-display-label.injectable";
|
||||
import computeHotbarDisplayLabelInjectable from "../../../features/hotbar/storage/common/compute-display-label.injectable";
|
||||
import hotbarsInjectable from "../../../features/hotbar/storage/common/hotbars.injectable";
|
||||
import type { RemoveHotbar } from "../../../features/hotbar/storage/common/remove.injectable";
|
||||
import removeHotbarInjectable from "../../../features/hotbar/storage/common/remove.injectable";
|
||||
|
||||
interface Dependencies {
|
||||
closeCommandOverlay: () => void;
|
||||
openConfirmDialog: OpenConfirmDialog;
|
||||
hotbarStore: HotbarStore;
|
||||
hotbars: IComputedValue<Hotbar[]>;
|
||||
computeHotbarDisplayLabel: ComputeHotbarDisplayLabel;
|
||||
removeHotbar: RemoveHotbar;
|
||||
}
|
||||
|
||||
const NonInjectedHotbarRemoveCommand = observer(({
|
||||
closeCommandOverlay,
|
||||
hotbarStore,
|
||||
openConfirmDialog,
|
||||
hotbars,
|
||||
computeHotbarDisplayLabel,
|
||||
removeHotbar,
|
||||
}: Dependencies) => (
|
||||
<Select
|
||||
menuPortalTarget={null}
|
||||
@@ -38,28 +47,28 @@ const NonInjectedHotbarRemoveCommand = observer(({
|
||||
primary: false,
|
||||
accent: true,
|
||||
},
|
||||
ok: () => hotbarStore.remove(option.value),
|
||||
ok: () => removeHotbar(option.value),
|
||||
message: (
|
||||
<div className="confirm flex column gaps">
|
||||
<p>
|
||||
Are you sure you want remove hotbar
|
||||
{" "}
|
||||
<b>
|
||||
{option.value.name}
|
||||
{option.value.name.get()}
|
||||
</b>
|
||||
?
|
||||
</p>
|
||||
</div>
|
||||
),
|
||||
});
|
||||
} }
|
||||
}}
|
||||
components={{ DropdownIndicator: null, IndicatorSeparator: null }}
|
||||
menuIsOpen={true}
|
||||
options={(
|
||||
hotbarStore.hotbars
|
||||
hotbars.get()
|
||||
.map(hotbar => ({
|
||||
value: hotbar,
|
||||
label: hotbarStore.getDisplayLabel(hotbar),
|
||||
label: computeHotbarDisplayLabel(hotbar),
|
||||
}))
|
||||
)}
|
||||
autoFocus={true}
|
||||
@@ -72,7 +81,9 @@ export const HotbarRemoveCommand = withInjectables<Dependencies>(NonInjectedHotb
|
||||
getProps: (di, props) => ({
|
||||
...props,
|
||||
closeCommandOverlay: di.inject(commandOverlayInjectable).close,
|
||||
hotbarStore: di.inject(hotbarStoreInjectable),
|
||||
openConfirmDialog: di.inject(openConfirmDialogInjectable),
|
||||
computeHotbarDisplayLabel: di.inject(computeHotbarDisplayLabelInjectable),
|
||||
hotbars: di.inject(hotbarsInjectable),
|
||||
removeHotbar: di.inject(removeHotbarInjectable),
|
||||
}),
|
||||
});
|
||||
@@ -6,36 +6,46 @@
|
||||
import React, { useState } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { Select } from "../select";
|
||||
import hotbarStoreInjectable from "../../../common/hotbars/store.injectable";
|
||||
import type { InputValidator } from "../input";
|
||||
import { Input } from "../input";
|
||||
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";
|
||||
import type { IComputedValue } from "mobx";
|
||||
import { action } from "mobx";
|
||||
import type { Hotbar } from "../../../features/hotbar/storage/common/hotbar";
|
||||
import type { GetHotbarById } from "../../../features/hotbar/storage/common/get-by-id.injectable";
|
||||
import getHotbarByIdInjectable from "../../../features/hotbar/storage/common/get-by-id.injectable";
|
||||
import hotbarsInjectable from "../../../features/hotbar/storage/common/hotbars.injectable";
|
||||
import type { ComputeHotbarDisplayLabel } from "../../../features/hotbar/storage/common/compute-display-label.injectable";
|
||||
import computeHotbarDisplayLabelInjectable from "../../../features/hotbar/storage/common/compute-display-label.injectable";
|
||||
|
||||
interface Dependencies {
|
||||
closeCommandOverlay: () => void;
|
||||
hotbarStore: HotbarStore;
|
||||
getHotbarById: GetHotbarById;
|
||||
computeHotbarDisplayLabel: ComputeHotbarDisplayLabel;
|
||||
uniqueHotbarName: InputValidator<false>;
|
||||
hotbars: IComputedValue<Hotbar[]>;
|
||||
}
|
||||
|
||||
const NonInjectedHotbarRenameCommand = observer(({
|
||||
closeCommandOverlay,
|
||||
hotbarStore,
|
||||
getHotbarById,
|
||||
computeHotbarDisplayLabel,
|
||||
uniqueHotbarName,
|
||||
hotbars,
|
||||
}: Dependencies) => {
|
||||
const [hotbarId, setHotbarId] = useState("");
|
||||
const [hotbarName, setHotbarName] = useState("");
|
||||
|
||||
const onSubmit = (name: string) => {
|
||||
const onSubmit = action((name: string) => {
|
||||
if (!name.trim()) {
|
||||
return;
|
||||
}
|
||||
|
||||
hotbarStore.setHotbarName(hotbarId, name);
|
||||
getHotbarById(hotbarId)?.name.set(name);
|
||||
closeCommandOverlay();
|
||||
};
|
||||
});
|
||||
|
||||
if (hotbarId) {
|
||||
return (
|
||||
@@ -65,16 +75,16 @@ const NonInjectedHotbarRenameCommand = observer(({
|
||||
onChange={(option) => {
|
||||
if (option) {
|
||||
setHotbarId(option.value.id);
|
||||
setHotbarName(option.value.name);
|
||||
setHotbarName(option.value.name.get());
|
||||
}
|
||||
}}
|
||||
components={{ DropdownIndicator: null, IndicatorSeparator: null }}
|
||||
menuIsOpen={true}
|
||||
options={(
|
||||
hotbarStore.hotbars
|
||||
hotbars.get()
|
||||
.map(hotbar => ({
|
||||
value: hotbar,
|
||||
label: hotbarStore.getDisplayLabel(hotbar),
|
||||
label: computeHotbarDisplayLabel(hotbar),
|
||||
}))
|
||||
)}
|
||||
autoFocus={true}
|
||||
@@ -86,9 +96,11 @@ const NonInjectedHotbarRenameCommand = observer(({
|
||||
|
||||
export const HotbarRenameCommand = withInjectables<Dependencies>(NonInjectedHotbarRenameCommand, {
|
||||
getProps: (di, props) => ({
|
||||
closeCommandOverlay: di.inject(commandOverlayInjectable).close,
|
||||
hotbarStore: di.inject(hotbarStoreInjectable),
|
||||
uniqueHotbarName: di.inject(uniqueHotbarNameInjectable),
|
||||
...props,
|
||||
closeCommandOverlay: di.inject(commandOverlayInjectable).close,
|
||||
uniqueHotbarName: di.inject(uniqueHotbarNameInjectable),
|
||||
getHotbarById: di.inject(getHotbarByIdInjectable),
|
||||
hotbars: di.inject(hotbarsInjectable),
|
||||
computeHotbarDisplayLabel: di.inject(computeHotbarDisplayLabelInjectable),
|
||||
}),
|
||||
});
|
||||
@@ -7,28 +7,40 @@ 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/hotbars/store.injectable";
|
||||
import { HotbarSwitchCommand } from "./hotbar-switch-command";
|
||||
import { Tooltip, TooltipPosition } from "../tooltip";
|
||||
import { observer } from "mobx-react";
|
||||
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 "@k8slens/utilities";
|
||||
import type { HotbarStore } from "../../../common/hotbars/store";
|
||||
import type { IComputedValue } from "mobx";
|
||||
import activeHotbarInjectable from "../../../features/hotbar/storage/common/active.injectable";
|
||||
import type { SwitchToPreviousHotbar } from "../../../features/hotbar/storage/common/switch-to-previous.injectable";
|
||||
import type { SwitchToNextHotbar } from "../../../features/hotbar/storage/common/switch-to-next.injectable";
|
||||
import switchToNextHotbarInjectable from "../../../features/hotbar/storage/common/switch-to-next.injectable";
|
||||
import switchToPreviousHotbarInjectable from "../../../features/hotbar/storage/common/switch-to-previous.injectable";
|
||||
import type { Hotbar } from "../../../features/hotbar/storage/common/hotbar";
|
||||
import type { ComputeDisplayIndex } from "../../../features/hotbar/storage/common/compute-display-index.injectable";
|
||||
import computeDisplayIndexInjectable from "../../../features/hotbar/storage/common/compute-display-index.injectable";
|
||||
|
||||
interface Dependencies {
|
||||
hotbarStore: HotbarStore;
|
||||
activeHotbar: IComputedValue<Hotbar | undefined>;
|
||||
openCommandOverlay: (component: React.ReactElement) => void;
|
||||
switchToPreviousHotbar: SwitchToPreviousHotbar;
|
||||
switchToNextHotbar: SwitchToNextHotbar;
|
||||
computeDisplayIndex: ComputeDisplayIndex;
|
||||
}
|
||||
|
||||
export interface HotbarSelectorProps extends Partial<Dependencies> {
|
||||
hotbar: Hotbar;
|
||||
}
|
||||
|
||||
const NonInjectedHotbarSelector = observer(({ hotbar, hotbarStore, openCommandOverlay }: HotbarSelectorProps & Dependencies) => {
|
||||
const NonInjectedHotbarSelector = observer(({
|
||||
activeHotbar,
|
||||
openCommandOverlay,
|
||||
switchToNextHotbar,
|
||||
switchToPreviousHotbar,
|
||||
computeDisplayIndex,
|
||||
}: Dependencies) => {
|
||||
const [tooltipVisible, setTooltipVisible] = useState(false);
|
||||
const tooltipTimeout = useRef<number>();
|
||||
const hotbar = activeHotbar.get();
|
||||
|
||||
function clearTimer() {
|
||||
clearTimeout(tooltipTimeout.current);
|
||||
@@ -42,12 +54,12 @@ const NonInjectedHotbarSelector = observer(({ hotbar, hotbarStore, openCommandOv
|
||||
|
||||
function onPrevClick() {
|
||||
onTooltipShow();
|
||||
hotbarStore.switchToPrevious();
|
||||
switchToPreviousHotbar();
|
||||
}
|
||||
|
||||
function onNextClick() {
|
||||
onTooltipShow();
|
||||
hotbarStore.switchToNext();
|
||||
switchToNextHotbar();
|
||||
}
|
||||
|
||||
function onMouseEvent(event: React.MouseEvent) {
|
||||
@@ -59,13 +71,13 @@ const NonInjectedHotbarSelector = observer(({ hotbar, hotbarStore, openCommandOv
|
||||
<div className={styles.HotbarSelector}>
|
||||
<Icon
|
||||
material="arrow_left"
|
||||
className={cssNames(styles.Icon, styles.previous)}
|
||||
className={cssNames(styles.Icon)}
|
||||
onClick={onPrevClick}/>
|
||||
<div className={styles.HotbarIndex}>
|
||||
<Badge
|
||||
id="hotbarIndex"
|
||||
small
|
||||
label={hotbarStore.getDisplayIndex(hotbarStore.getActive())}
|
||||
label={hotbar ? computeDisplayIndex(hotbar.id) : "??"}
|
||||
onClick={() => openCommandOverlay(<HotbarSwitchCommand />)}
|
||||
className={styles.Badge}
|
||||
onMouseEnter={onMouseEvent}
|
||||
@@ -76,7 +88,7 @@ const NonInjectedHotbarSelector = observer(({ hotbar, hotbarStore, openCommandOv
|
||||
targetId="hotbarIndex"
|
||||
preferredPositions={[TooltipPosition.TOP, TooltipPosition.TOP_LEFT]}
|
||||
>
|
||||
{hotbar.name}
|
||||
{hotbar?.name}
|
||||
</Tooltip>
|
||||
</div>
|
||||
<Icon
|
||||
@@ -88,10 +100,13 @@ const NonInjectedHotbarSelector = observer(({ hotbar, hotbarStore, openCommandOv
|
||||
);
|
||||
});
|
||||
|
||||
export const HotbarSelector = withInjectables<Dependencies, HotbarSelectorProps>(NonInjectedHotbarSelector, {
|
||||
export const HotbarSelector = withInjectables<Dependencies>(NonInjectedHotbarSelector, {
|
||||
getProps: (di, props) => ({
|
||||
hotbarStore: di.inject(hotbarStoreInjectable),
|
||||
openCommandOverlay: di.inject(commandOverlayInjectable).open,
|
||||
...props,
|
||||
openCommandOverlay: di.inject(commandOverlayInjectable).open,
|
||||
activeHotbar: di.inject(activeHotbarInjectable),
|
||||
switchToNextHotbar: di.inject(switchToNextHotbarInjectable),
|
||||
switchToPreviousHotbar: di.inject(switchToPreviousHotbarInjectable),
|
||||
computeDisplayIndex: di.inject(computeDisplayIndexInjectable),
|
||||
}),
|
||||
});
|
||||
@@ -6,21 +6,28 @@
|
||||
import React from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { Select } from "../select";
|
||||
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/hotbars/store";
|
||||
import type { SetAsActiveHotbar } from "../../../features/hotbar/storage/common/set-as-active.injectable";
|
||||
import type { IComputedValue } from "mobx";
|
||||
import type { Hotbar } from "../../../features/hotbar/storage/common/hotbar";
|
||||
import type { ComputeHotbarDisplayLabel } from "../../../features/hotbar/storage/common/compute-display-label.injectable";
|
||||
import computeHotbarDisplayLabelInjectable from "../../../features/hotbar/storage/common/compute-display-label.injectable";
|
||||
import hotbarsInjectable from "../../../features/hotbar/storage/common/hotbars.injectable";
|
||||
import setAsActiveHotbarInjectable from "../../../features/hotbar/storage/common/set-as-active.injectable";
|
||||
|
||||
const hotbarAddAction = Symbol("hotbar-add");
|
||||
const hotbarRemoveAction = Symbol("hotbar-remove");
|
||||
const hotbarRenameAction = Symbol("hotbar-rename");
|
||||
|
||||
interface Dependencies {
|
||||
hotbarStore: HotbarStore;
|
||||
setAsActiveHotbar: SetAsActiveHotbar;
|
||||
computeHotbarDisplayLabel: ComputeHotbarDisplayLabel;
|
||||
hotbars: IComputedValue<Hotbar[]>;
|
||||
commandOverlay: CommandOverlay;
|
||||
}
|
||||
|
||||
@@ -29,7 +36,9 @@ function ignoreIf<T>(check: boolean, menuItems: T[]): T[] {
|
||||
}
|
||||
|
||||
const NonInjectedHotbarSwitchCommand = observer(({
|
||||
hotbarStore,
|
||||
setAsActiveHotbar,
|
||||
computeHotbarDisplayLabel,
|
||||
hotbars,
|
||||
commandOverlay,
|
||||
}: Dependencies) => (
|
||||
<Select
|
||||
@@ -50,22 +59,22 @@ const NonInjectedHotbarSwitchCommand = observer(({
|
||||
return commandOverlay.open(<HotbarRenameCommand />);
|
||||
}
|
||||
} else {
|
||||
hotbarStore.setActiveHotbar(option.value);
|
||||
setAsActiveHotbar(option.value);
|
||||
commandOverlay.close();
|
||||
}
|
||||
}}
|
||||
components={{ DropdownIndicator: null, IndicatorSeparator: null }}
|
||||
menuIsOpen={true}
|
||||
options={[
|
||||
...hotbarStore.hotbars.map(hotbar => ({
|
||||
...hotbars.get().map(hotbar => ({
|
||||
value: hotbar,
|
||||
label: hotbarStore.getDisplayLabel(hotbar),
|
||||
label: computeHotbarDisplayLabel(hotbar),
|
||||
})),
|
||||
{
|
||||
value: hotbarAddAction,
|
||||
label: "Add hotbar ...",
|
||||
},
|
||||
...ignoreIf(hotbarStore.hotbars.length > 1, [
|
||||
...ignoreIf(hotbars.get().length > 1, [
|
||||
{
|
||||
value: hotbarRemoveAction,
|
||||
label: "Remove hotbar ...",
|
||||
@@ -85,8 +94,10 @@ const NonInjectedHotbarSwitchCommand = observer(({
|
||||
|
||||
export const HotbarSwitchCommand = withInjectables<Dependencies>(NonInjectedHotbarSwitchCommand, {
|
||||
getProps: (di, props) => ({
|
||||
hotbarStore: di.inject(hotbarStoreInjectable),
|
||||
commandOverlay: di.inject(commandOverlayInjectable),
|
||||
...props,
|
||||
commandOverlay: di.inject(commandOverlayInjectable),
|
||||
computeHotbarDisplayLabel: di.inject(computeHotbarDisplayLabelInjectable),
|
||||
hotbars: di.inject(hotbarsInjectable),
|
||||
setAsActiveHotbar: di.inject(setAsActiveHotbarInjectable),
|
||||
}),
|
||||
});
|
||||
+3
-3
@@ -4,19 +4,19 @@
|
||||
*/
|
||||
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import hotbarStoreInjectable from "../../../../common/hotbars/store.injectable";
|
||||
import findHotbarByNameInjectable from "../../../../features/hotbar/storage/common/find-by-name.injectable";
|
||||
import { inputValidator } from "../input_validators";
|
||||
|
||||
const uniqueHotbarNameInjectable = getInjectable({
|
||||
id: "unique-hotbar-name",
|
||||
|
||||
instantiate: di => {
|
||||
const store = di.inject(hotbarStoreInjectable);
|
||||
const findHotbarByName = di.inject(findHotbarByNameInjectable);
|
||||
|
||||
return inputValidator({
|
||||
condition: ({ required }) => required,
|
||||
message: () => "Hotbar with this name already exists",
|
||||
validate: value => !store.findByName(value),
|
||||
validate: value => !findHotbarByName(value),
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
@@ -25,15 +25,17 @@ import type { LensTheme } from "../../themes/lens-theme";
|
||||
import { MenuActions } from "../menu/menu-actions";
|
||||
import { MenuItem } from "../menu";
|
||||
import { Checkbox } from "../checkbox";
|
||||
import type { UserStore } from "../../../common/user-store";
|
||||
import type { ItemListStore } from "./list-layout";
|
||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import userStoreInjectable from "../../../common/user-store/user-store.injectable";
|
||||
import pageFiltersStoreInjectable from "./page-filters/store.injectable";
|
||||
import type { OpenConfirmDialog } from "../confirm-dialog/open.injectable";
|
||||
import openConfirmDialogInjectable from "../confirm-dialog/open.injectable";
|
||||
import activeThemeInjectable from "../../themes/active.injectable";
|
||||
import autoBindReact from "auto-bind/react";
|
||||
import type { ToggleTableColumnVisibility } from "../../../features/user-preferences/common/toggle-table-column-visibility.injectable";
|
||||
import toggleTableColumnVisibilityInjectable from "../../../features/user-preferences/common/toggle-table-column-visibility.injectable";
|
||||
import type { IsTableColumnHidden } from "../../../features/user-preferences/common/is-table-column-hidden.injectable";
|
||||
import isTableColumnHiddenInjectable from "../../../features/user-preferences/common/is-table-column-hidden.injectable";
|
||||
|
||||
export interface ItemListLayoutContentProps<Item extends ItemObject, PreLoadStores extends boolean> {
|
||||
getFilters: () => Filter[];
|
||||
@@ -74,9 +76,10 @@ export interface ItemListLayoutContentProps<Item extends ItemObject, PreLoadStor
|
||||
|
||||
interface Dependencies {
|
||||
activeTheme: IComputedValue<LensTheme>;
|
||||
userStore: UserStore;
|
||||
pageFiltersStore: PageFiltersStore;
|
||||
openConfirmDialog: OpenConfirmDialog;
|
||||
toggleTableColumnVisibility: ToggleTableColumnVisibility;
|
||||
isTableColumnHidden: IsTableColumnHidden;
|
||||
}
|
||||
|
||||
@observer
|
||||
@@ -342,7 +345,7 @@ class NonInjectedItemListLayoutContent<
|
||||
showColumn({ id: columnId, showWithColumn }: TableCellProps): boolean {
|
||||
const { tableId, isConfigurable } = this.props;
|
||||
|
||||
return !isConfigurable || !tableId || !this.props.userStore.isTableColumnHidden(tableId, columnId, showWithColumn);
|
||||
return !isConfigurable || !tableId || !this.props.isTableColumnHidden(tableId, columnId, showWithColumn);
|
||||
}
|
||||
|
||||
renderColumnVisibilityMenu(tableId: string) {
|
||||
@@ -365,7 +368,7 @@ class NonInjectedItemListLayoutContent<
|
||||
<Checkbox
|
||||
label={cellProps.title ?? `<${cellProps.className}>`}
|
||||
value={this.showColumn(cellProps)}
|
||||
onChange={() => this.props.userStore.toggleTableColumnVisibility(tableId, cellProps.id)}
|
||||
onChange={() => this.props.toggleTableColumnVisibility(tableId, cellProps.id)}
|
||||
/>
|
||||
</MenuItem>
|
||||
))
|
||||
@@ -379,8 +382,9 @@ export const ItemListLayoutContent = withInjectables<Dependencies, ItemListLayou
|
||||
getProps: (di, props) => ({
|
||||
...props,
|
||||
activeTheme: di.inject(activeThemeInjectable),
|
||||
userStore: di.inject(userStoreInjectable),
|
||||
pageFiltersStore: di.inject(pageFiltersStoreInjectable),
|
||||
openConfirmDialog: di.inject(openConfirmDialogInjectable),
|
||||
toggleTableColumnVisibility: di.inject(toggleTableColumnVisibilityInjectable),
|
||||
isTableColumnHidden: di.inject(isTableColumnHiddenInjectable),
|
||||
}),
|
||||
}) as <Item extends ItemObject, PreLoadStores extends boolean>(props: ItemListLayoutContentProps<Item, PreLoadStores>) => React.ReactElement;
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`<SidebarCluster/> renders w/o errors 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="SidebarCluster"
|
||||
data-testid="sidebar-cluster-dropdown"
|
||||
id="cluster-test-uid"
|
||||
role="menubar"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="Avatar rounded avatar"
|
||||
style="width: 40px; height: 40px; background: rgb(96, 130, 10);"
|
||||
>
|
||||
tc
|
||||
</div>
|
||||
<div
|
||||
class="clusterName"
|
||||
id="tooltip-cluster-test-uid"
|
||||
>
|
||||
test-cluster
|
||||
</div>
|
||||
<i
|
||||
class="Icon dropdown material focusable"
|
||||
>
|
||||
<span
|
||||
class="icon"
|
||||
data-icon-name="arrow_drop_down"
|
||||
>
|
||||
arrow_drop_down
|
||||
</span>
|
||||
</i>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@@ -5,56 +5,47 @@
|
||||
|
||||
import React from "react";
|
||||
import "@testing-library/jest-dom/extend-expect";
|
||||
import type { RenderResult } from "@testing-library/react";
|
||||
import { fireEvent } from "@testing-library/react";
|
||||
import { SidebarCluster } from "../sidebar-cluster";
|
||||
import { KubernetesCluster } from "../../../../common/catalog-entities";
|
||||
import { getDiForUnitTesting } from "../../../getDiForUnitTesting";
|
||||
import type { DiRender } from "../../test-utils/renderFor";
|
||||
import { renderFor } from "../../test-utils/renderFor";
|
||||
import hotbarStoreInjectable from "../../../../common/hotbars/store.injectable";
|
||||
import type { HotbarStore } from "../../../../common/hotbars/store";
|
||||
|
||||
const clusterEntity = new KubernetesCluster({
|
||||
metadata: {
|
||||
uid: "test-uid",
|
||||
name: "test-cluster",
|
||||
source: "local",
|
||||
labels: {},
|
||||
},
|
||||
spec: {
|
||||
kubeconfigPath: "",
|
||||
kubeconfigContext: "",
|
||||
},
|
||||
status: {
|
||||
phase: "connected",
|
||||
},
|
||||
});
|
||||
|
||||
describe("<SidebarCluster/>", () => {
|
||||
let render: DiRender;
|
||||
let result: RenderResult;
|
||||
|
||||
beforeEach(() => {
|
||||
const di = getDiForUnitTesting();
|
||||
const render = renderFor(di);
|
||||
|
||||
di.override(hotbarStoreInjectable, () => ({
|
||||
isAddedToActive: () => {},
|
||||
}) as unknown as HotbarStore);
|
||||
const clusterEntity = new KubernetesCluster({
|
||||
metadata: {
|
||||
uid: "test-uid",
|
||||
name: "test-cluster",
|
||||
source: "local",
|
||||
labels: {},
|
||||
},
|
||||
spec: {
|
||||
kubeconfigPath: "",
|
||||
kubeconfigContext: "",
|
||||
},
|
||||
status: {
|
||||
phase: "connected",
|
||||
},
|
||||
});
|
||||
|
||||
render = renderFor(di);
|
||||
result = render(<SidebarCluster clusterEntity={clusterEntity}/>);
|
||||
});
|
||||
|
||||
it("renders w/o errors", () => {
|
||||
const { container } = render(<SidebarCluster clusterEntity={clusterEntity}/>);
|
||||
|
||||
expect(container).toBeInstanceOf(HTMLElement);
|
||||
expect(result.container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("renders cluster avatar and name", () => {
|
||||
const { getByText, getAllByText } = render(<SidebarCluster clusterEntity={clusterEntity}/>);
|
||||
expect(result.getByText("tc")).toBeInTheDocument();
|
||||
|
||||
expect(getByText("tc")).toBeInTheDocument();
|
||||
|
||||
const v = getAllByText("test-cluster");
|
||||
const v = result.getAllByText("test-cluster");
|
||||
|
||||
expect(v.length).toBeGreaterThan(0);
|
||||
|
||||
@@ -64,11 +55,8 @@ describe("<SidebarCluster/>", () => {
|
||||
});
|
||||
|
||||
it("renders cluster menu", () => {
|
||||
const { getByTestId, getByText } = render(<SidebarCluster clusterEntity={clusterEntity}/>);
|
||||
const link = getByTestId("sidebar-cluster-dropdown");
|
||||
|
||||
fireEvent.click(link);
|
||||
expect(getByText("Add to Hotbar")).toBeInTheDocument();
|
||||
fireEvent.click(result.getByTestId("sidebar-cluster-dropdown"));
|
||||
expect(result.getByText("Add to Hotbar")).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -14,8 +14,6 @@ import { Icon } from "../icon";
|
||||
import { Menu, MenuItem } from "../menu";
|
||||
import { Tooltip } from "../tooltip";
|
||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import hotbarStoreInjectable from "../../../common/hotbars/store.injectable";
|
||||
import type { HotbarStore } from "../../../common/hotbars/store";
|
||||
import { observer } from "mobx-react";
|
||||
import type { VisitEntityContextMenu } from "../../../common/catalog/visit-entity-context-menu.injectable";
|
||||
import visitEntityContextMenuInjectable from "../../../common/catalog/visit-entity-context-menu.injectable";
|
||||
@@ -23,6 +21,8 @@ import type { Navigate } from "../../navigation/navigate.injectable";
|
||||
import type { NormalizeCatalogEntityContextMenu } from "../../catalog/normalize-menu-item.injectable";
|
||||
import navigateInjectable from "../../navigation/navigate.injectable";
|
||||
import normalizeCatalogEntityContextMenuInjectable from "../../catalog/normalize-menu-item.injectable";
|
||||
import type { ActiveHotbarModel } from "../../../features/hotbar/storage/common/toggling.injectable";
|
||||
import activeHotbarInjectable from "../../../features/hotbar/storage/common/toggling.injectable";
|
||||
|
||||
export interface SidebarClusterProps {
|
||||
clusterEntity: CatalogEntity | null | undefined;
|
||||
@@ -31,16 +31,16 @@ export interface SidebarClusterProps {
|
||||
interface Dependencies {
|
||||
navigate: Navigate;
|
||||
normalizeMenuItem: NormalizeCatalogEntityContextMenu;
|
||||
hotbarStore: HotbarStore;
|
||||
visitEntityContextMenu: VisitEntityContextMenu;
|
||||
entityInActiveHotbar: ActiveHotbarModel;
|
||||
}
|
||||
|
||||
const NonInjectedSidebarCluster = observer(({
|
||||
clusterEntity,
|
||||
hotbarStore,
|
||||
visitEntityContextMenu: onContextMenuOpen,
|
||||
navigate,
|
||||
normalizeMenuItem,
|
||||
entityInActiveHotbar,
|
||||
}: Dependencies & SidebarClusterProps) => {
|
||||
const [menuItems] = useState(observable.array<CatalogEntityContextMenu>());
|
||||
const [opened, setOpened] = useState(false );
|
||||
@@ -61,13 +61,10 @@ const NonInjectedSidebarCluster = observer(({
|
||||
}
|
||||
|
||||
const onMenuOpen = () => {
|
||||
const isAddedToActive = hotbarStore.isAddedToActive(clusterEntity);
|
||||
const title = isAddedToActive
|
||||
const title = entityInActiveHotbar.hasEntity(clusterEntity.getId())
|
||||
? "Remove from Hotbar"
|
||||
: "Add to Hotbar";
|
||||
const onClick = isAddedToActive
|
||||
? () => hotbarStore.removeFromHotbar(clusterEntity.getId())
|
||||
: () => hotbarStore.addToHotbar(clusterEntity);
|
||||
const onClick = () => entityInActiveHotbar.toggleEntity(clusterEntity);
|
||||
|
||||
menuItems.replace([{ title, onClick }]);
|
||||
onContextMenuOpen(clusterEntity, {
|
||||
@@ -148,9 +145,9 @@ const NonInjectedSidebarCluster = observer(({
|
||||
export const SidebarCluster = withInjectables<Dependencies, SidebarClusterProps>(NonInjectedSidebarCluster, {
|
||||
getProps: (di, props) => ({
|
||||
...props,
|
||||
hotbarStore: di.inject(hotbarStoreInjectable),
|
||||
visitEntityContextMenu: di.inject(visitEntityContextMenuInjectable),
|
||||
navigate: di.inject(navigateInjectable),
|
||||
normalizeMenuItem: di.inject(normalizeCatalogEntityContextMenuInjectable),
|
||||
entityInActiveHotbar: di.inject(activeHotbarInjectable),
|
||||
}),
|
||||
});
|
||||
@@ -6,27 +6,27 @@
|
||||
import React from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import moment from "moment-timezone";
|
||||
import type { UserStore } from "../../../common/user-store";
|
||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import userStoreInjectable from "../../../common/user-store/user-store.injectable";
|
||||
import type { UserPreferencesState } from "../../../features/user-preferences/common/state.injectable";
|
||||
import userPreferencesStateInjectable from "../../../features/user-preferences/common/state.injectable";
|
||||
|
||||
export interface LocaleDateProps {
|
||||
date: string;
|
||||
}
|
||||
|
||||
interface Dependencies {
|
||||
userStore: UserStore;
|
||||
state: UserPreferencesState;
|
||||
}
|
||||
|
||||
const NonInjectedLocaleDate = observer(({ date, userStore }: LocaleDateProps & Dependencies) => (
|
||||
const NonInjectedLocaleDate = observer(({ date, state }: LocaleDateProps & Dependencies) => (
|
||||
<>
|
||||
{`${moment.tz(date, userStore.localeTimezone).format()}`}
|
||||
{`${moment.tz(date, state.localeTimezone).format()}`}
|
||||
</>
|
||||
));
|
||||
|
||||
export const LocaleDate = withInjectables<Dependencies, LocaleDateProps>(NonInjectedLocaleDate, {
|
||||
getProps: (di, props) => ({
|
||||
...props,
|
||||
userStore: di.inject(userStoreInjectable),
|
||||
state: di.inject(userPreferencesStateInjectable),
|
||||
}),
|
||||
});
|
||||
@@ -13,15 +13,15 @@ import type { MonacoTheme } from "./monaco-themes";
|
||||
import { type MonacoValidator, monacoValidators } from "./monaco-validators";
|
||||
import { debounce, merge } from "lodash";
|
||||
import { cssNames, disposer } from "@k8slens/utilities";
|
||||
import type { UserStore } from "../../../common/user-store";
|
||||
import type { LensTheme } from "../../themes/lens-theme";
|
||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import userStoreInjectable from "../../../common/user-store/user-store.injectable";
|
||||
import activeThemeInjectable from "../../themes/active.injectable";
|
||||
import getEditorHeightFromLinesCountInjectable from "./get-editor-height-from-lines-number.injectable";
|
||||
import type { Logger } from "../../../common/logger";
|
||||
import loggerInjectable from "../../../common/logger.injectable";
|
||||
import autoBindReact from "auto-bind/react";
|
||||
import type { UserPreferencesState } from "../../../features/user-preferences/common/state.injectable";
|
||||
import userPreferencesStateInjectable from "../../../features/user-preferences/common/state.injectable";
|
||||
|
||||
export type MonacoEditorId = string;
|
||||
|
||||
@@ -45,7 +45,7 @@ export interface MonacoEditorProps {
|
||||
}
|
||||
|
||||
interface Dependencies {
|
||||
userStore: UserStore;
|
||||
state: UserPreferencesState;
|
||||
activeTheme: IComputedValue<LensTheme>;
|
||||
getEditorHeightFromLinesCount: (linesCount: number) => number;
|
||||
logger: Logger;
|
||||
@@ -116,7 +116,7 @@ class NonInjectedMonacoEditor extends React.Component<MonacoEditorProps & Depend
|
||||
|
||||
@computed get options(): editor.IStandaloneEditorConstructionOptions {
|
||||
return merge({},
|
||||
this.props.userStore.editorConfiguration,
|
||||
this.props.state.editorConfiguration,
|
||||
this.props.options,
|
||||
);
|
||||
}
|
||||
@@ -325,15 +325,16 @@ class NonInjectedMonacoEditor extends React.Component<MonacoEditorProps & Depend
|
||||
}
|
||||
}
|
||||
|
||||
export const MonacoEditor = withInjectables<Dependencies, MonacoEditorProps, MonacoEditorRef>(
|
||||
React.forwardRef<MonacoEditorRef, MonacoEditorProps & Dependencies>((props, ref) => <NonInjectedMonacoEditor innerRef={ref} {...props} />),
|
||||
{
|
||||
getProps: (di, props) => ({
|
||||
...props,
|
||||
userStore: di.inject(userStoreInjectable),
|
||||
activeTheme: di.inject(activeThemeInjectable),
|
||||
getEditorHeightFromLinesCount: di.inject(getEditorHeightFromLinesCountInjectable),
|
||||
logger: di.inject(loggerInjectable),
|
||||
}),
|
||||
},
|
||||
);
|
||||
const ForwardedRefMonacoEditor = React.forwardRef<MonacoEditorRef, MonacoEditorProps & Dependencies>((
|
||||
(props, ref) => <NonInjectedMonacoEditor innerRef={ref} {...props} />
|
||||
));
|
||||
|
||||
export const MonacoEditor = withInjectables<Dependencies, MonacoEditorProps, MonacoEditorRef>(ForwardedRefMonacoEditor, {
|
||||
getProps: (di, props) => ({
|
||||
...props,
|
||||
state: di.inject(userPreferencesStateInjectable),
|
||||
activeTheme: di.inject(activeThemeInjectable),
|
||||
getEditorHeightFromLinesCount: di.inject(getEditorHeightFromLinesCountInjectable),
|
||||
logger: di.inject(loggerInjectable),
|
||||
}),
|
||||
});
|
||||
@@ -3,7 +3,6 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import type { Writable } from "type-fest";
|
||||
import fileSystemProvisionerStoreInjectable from "../../../extensions/extension-loader/file-system-provisioner-store/file-system-provisioner-store.injectable";
|
||||
import { lensExtensionDependencies } from "../../../extensions/lens-extension";
|
||||
import { LensMainExtension } from "../../../extensions/lens-main-extension";
|
||||
import navigateForExtensionInjectable from "../../../main/start-main-application/lens-window/navigate-for-extension.injectable";
|
||||
@@ -16,6 +15,7 @@ import catalogEntityRegistryForMainInjectable from "../../../main/catalog/entity
|
||||
import catalogEntityRegistryForRendererInjectable from "../../api/catalog/entity/registry.injectable";
|
||||
import type { DiContainer } from "@ogre-tools/injectable";
|
||||
import loggerInjectable from "../../../common/logger.injectable";
|
||||
import ensureHashedDirectoryForExtensionInjectable from "../../../extensions/extension-loader/file-system-provisioner-store/ensure-hashed-directory-for-extension.injectable";
|
||||
|
||||
export class TestExtensionMain extends LensMainExtension {}
|
||||
export class TestExtensionRenderer extends LensRendererExtension {}
|
||||
@@ -47,7 +47,7 @@ export const getMainExtensionFakeWith = (di: DiContainer) => ({ id, name, mainOp
|
||||
Object.assign(instance, mainOptions);
|
||||
|
||||
(instance as Writable<LensMainExtension>)[lensExtensionDependencies] = {
|
||||
fileSystemProvisionerStore: di.inject(fileSystemProvisionerStoreInjectable),
|
||||
ensureHashedDirectoryForExtension: di.inject(ensureHashedDirectoryForExtensionInjectable),
|
||||
entityRegistry: di.inject(catalogEntityRegistryForMainInjectable),
|
||||
navigate: di.inject(navigateForExtensionInjectable),
|
||||
logger: di.inject(loggerInjectable),
|
||||
@@ -78,7 +78,7 @@ export const getRendererExtensionFakeWith = (di: DiContainer) => ({ id, name, re
|
||||
(instance as Writable<LensRendererExtension>)[lensExtensionDependencies] = {
|
||||
categoryRegistry: di.inject(catalogCategoryRegistryInjectable),
|
||||
entityRegistry: di.inject(catalogEntityRegistryForRendererInjectable),
|
||||
fileSystemProvisionerStore: di.inject(fileSystemProvisionerStoreInjectable),
|
||||
ensureHashedDirectoryForExtension: di.inject(ensureHashedDirectoryForExtensionInjectable),
|
||||
getExtensionPageParameters: di.inject(getExtensionPageParametersInjectable),
|
||||
navigateToRoute: di.inject(navigateToRouteInjectable),
|
||||
routes: di.inject(routesInjectable),
|
||||
|
||||
@@ -7,7 +7,7 @@ import type { Writable } from "type-fest";
|
||||
import catalogCategoryRegistryInjectable from "../../common/catalog/category-registry.injectable";
|
||||
import loggerInjectable from "../../common/logger.injectable";
|
||||
import { createExtensionInstanceInjectionToken } from "../../extensions/extension-loader/create-extension-instance.token";
|
||||
import fileSystemProvisionerStoreInjectable from "../../extensions/extension-loader/file-system-provisioner-store/file-system-provisioner-store.injectable";
|
||||
import ensureHashedDirectoryForExtensionInjectable from "../../extensions/extension-loader/file-system-provisioner-store/ensure-hashed-directory-for-extension.injectable";
|
||||
import { lensExtensionDependencies } from "../../extensions/lens-extension";
|
||||
import type { LensRendererExtensionDependencies } from "../../extensions/lens-extension-set-dependencies";
|
||||
import type { LensRendererExtension } from "../../extensions/lens-renderer-extension";
|
||||
@@ -22,7 +22,7 @@ const createExtensionInstanceInjectable = getInjectable({
|
||||
const deps: LensRendererExtensionDependencies = {
|
||||
categoryRegistry: di.inject(catalogCategoryRegistryInjectable),
|
||||
entityRegistry: di.inject(catalogEntityRegistryInjectable),
|
||||
fileSystemProvisionerStore: di.inject(fileSystemProvisionerStoreInjectable),
|
||||
ensureHashedDirectoryForExtension: di.inject(ensureHashedDirectoryForExtensionInjectable),
|
||||
getExtensionPageParameters: di.inject(getExtensionPageParametersInjectable),
|
||||
navigateToRoute: di.inject(navigateToRouteInjectable),
|
||||
routes: di.inject(routesInjectable),
|
||||
|
||||
@@ -3,24 +3,24 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import userStoreInjectable from "../../common/user-store/user-store.injectable";
|
||||
import React from "react";
|
||||
import navigateToKubernetesPreferencesInjectable from "../../features/preferences/common/navigate-to-kubernetes-preferences.injectable";
|
||||
import { runInAction } from "mobx";
|
||||
import showSuccessNotificationInjectable from "../components/notifications/show-success-notification.injectable";
|
||||
import userPreferencesStateInjectable from "../../features/user-preferences/common/state.injectable";
|
||||
|
||||
const addSyncEntriesInjectable = getInjectable({
|
||||
id: "add-sync-entries",
|
||||
|
||||
instantiate: (di) => {
|
||||
const userStore = di.inject(userStoreInjectable);
|
||||
const state = di.inject(userPreferencesStateInjectable);
|
||||
const navigateToKubernetesPreferences = di.inject(navigateToKubernetesPreferencesInjectable);
|
||||
const showSuccessNotification = di.inject(showSuccessNotificationInjectable);
|
||||
|
||||
return async (paths: string[]) => {
|
||||
runInAction(() => {
|
||||
for (const path of paths) {
|
||||
userStore.syncKubeconfigEntries.set(path, {});
|
||||
state.syncKubeconfigEntries.set(path, {});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import type { IComputedValue } from "mobx";
|
||||
import { observer } from "mobx-react";
|
||||
import React from "react";
|
||||
import { shouldShowResourceInjectionToken } from "../../common/cluster-store/allowed-resources-injection-token";
|
||||
import { shouldShowResourceInjectionToken } from "../../features/cluster/showing-kube-resources/common/allowed-resources-injection-token";
|
||||
import { Events } from "../components/+events/events";
|
||||
|
||||
export interface WorkloadEventsProps {}
|
||||
|
||||
@@ -10,8 +10,8 @@ import type { IpcRendererEvent } from "electron";
|
||||
import React from "react";
|
||||
import notificationsStoreInjectable from "../components/notifications/notifications-store.injectable";
|
||||
import { getMillisecondsFromUnixEpoch } from "../../common/utils/date/get-current-date-time";
|
||||
import getClusterByIdInjectable from "../../common/cluster-store/get-by-id.injectable";
|
||||
import showSuccessNotificationInjectable from "../components/notifications/show-success-notification.injectable";
|
||||
import getClusterByIdInjectable from "../../features/cluster/storage/common/get-by-id.injectable";
|
||||
|
||||
const intervalBetweenNotifications = 1000 * 60; // 60s
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { defaultHotbarCells } from "../../common/hotbars/types";
|
||||
import { defaultHotbarCells } from "../../features/hotbar/storage/common/types";
|
||||
import { clusterListNamespaceForbiddenChannel } from "../../common/ipc/cluster";
|
||||
import { hotbarTooManyItemsChannel } from "../../common/ipc/hotbar";
|
||||
import showErrorNotificationInjectable from "../components/notifications/show-error-notification.injectable";
|
||||
|
||||
+1
-3
@@ -12,11 +12,9 @@ import navigateToExtensionsInjectable from "../../../common/front-end-routing/ro
|
||||
import navigateToEntitySettingsInjectable from "../../../common/front-end-routing/routes/entity-settings/navigate-to-entity-settings.injectable";
|
||||
import navigateToClusterViewInjectable from "../../../common/front-end-routing/routes/cluster-view/navigate-to-cluster-view.injectable";
|
||||
import catalogEntityRegistryInjectable from "../../api/catalog/entity/registry.injectable";
|
||||
|
||||
// TODO: Importing from features is not OK. Make protocol-router to comply with Open Closed Principle to allow moving implementation under a feature
|
||||
import navigateToPreferencesInjectable from "../../../features/preferences/common/navigate-to-preferences.injectable";
|
||||
import getClusterByIdInjectable from "../../../common/cluster-store/get-by-id.injectable";
|
||||
import showShortInfoNotificationInjectable from "../../components/notifications/show-short-info.injectable";
|
||||
import getClusterByIdInjectable from "../../../features/cluster/storage/common/get-by-id.injectable";
|
||||
|
||||
const bindProtocolAddRouteHandlersInjectable = getInjectable({
|
||||
id: "bind-protocol-add-route-handlers",
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ import type { NavigateToEntitySettings } from "../../../common/front-end-routing
|
||||
import type { NavigateToClusterView } from "../../../common/front-end-routing/routes/cluster-view/navigate-to-cluster-view.injectable";
|
||||
import assert from "assert";
|
||||
import type { AttemptInstallByInfo } from "../../components/+extensions/attempt-install-by-info.injectable";
|
||||
import type { GetClusterById } from "../../../common/cluster-store/get-by-id.injectable";
|
||||
import type { GetClusterById } from "../../../features/cluster/storage/common/get-by-id.injectable";
|
||||
|
||||
interface Dependencies {
|
||||
attemptInstallByInfo: AttemptInstallByInfo;
|
||||
|
||||
+2
-2
@@ -5,17 +5,17 @@
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import extensionLoaderInjectable from "../../../extensions/extension-loader/extension-loader.injectable";
|
||||
import { LensProtocolRouterRenderer } from "./lens-protocol-router-renderer";
|
||||
import extensionsStoreInjectable from "../../../extensions/extensions-store/extensions-store.injectable";
|
||||
import loggerInjectable from "../../../common/logger.injectable";
|
||||
import showErrorNotificationInjectable from "../../components/notifications/show-error-notification.injectable";
|
||||
import showShortInfoNotificationInjectable from "../../components/notifications/show-short-info.injectable";
|
||||
import isExtensionEnabledInjectable from "../../../features/extensions/enabled/common/is-enabled.injectable";
|
||||
|
||||
const lensProtocolRouterRendererInjectable = getInjectable({
|
||||
id: "lens-protocol-router-renderer",
|
||||
|
||||
instantiate: (di) => new LensProtocolRouterRenderer({
|
||||
extensionLoader: di.inject(extensionLoaderInjectable),
|
||||
extensionsStore: di.inject(extensionsStoreInjectable),
|
||||
isExtensionEnabled: di.inject(isExtensionEnabledInjectable),
|
||||
logger: di.inject(loggerInjectable),
|
||||
showErrorNotification: di.inject(showErrorNotificationInjectable),
|
||||
showShortInfoNotification: di.inject(showShortInfoNotificationInjectable),
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import userStoreInjectable from "../../common/user-store/user-store.injectable";
|
||||
import { beforeFrameStartsSecondInjectionToken } from "../before-frame-starts/tokens";
|
||||
import initDefaultUpdateChannelInjectable from "../vars/default-update-channel/init.injectable";
|
||||
|
||||
const initUserStoreInjectable = getInjectable({
|
||||
id: "init-user-store",
|
||||
instantiate: (di) => ({
|
||||
run: () => {
|
||||
const userStore = di.inject(userStoreInjectable);
|
||||
|
||||
return userStore.load();
|
||||
},
|
||||
runAfter: initDefaultUpdateChannelInjectable,
|
||||
}),
|
||||
injectionToken: beforeFrameStartsSecondInjectionToken,
|
||||
});
|
||||
|
||||
export default initUserStoreInjectable;
|
||||
@@ -5,7 +5,7 @@
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import assert from "assert";
|
||||
import { computed } from "mobx";
|
||||
import lensColorThemePreferenceInjectable from "../../common/user-store/lens-color-theme.injectable";
|
||||
import lensColorThemePreferenceInjectable from "../../features/user-preferences/common/lens-color-theme.injectable";
|
||||
import { lensThemeDeclarationInjectionToken } from "./declaration";
|
||||
import defaultLensThemeInjectable from "./default-theme.injectable";
|
||||
import systemThemeConfigurationInjectable from "./system-theme.injectable";
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import loggerInjectable from "../../common/logger.injectable";
|
||||
import userStoreInjectable from "../../common/user-store/user-store.injectable";
|
||||
import { object } from "@k8slens/utilities";
|
||||
import type { LensTheme } from "./lens-theme";
|
||||
import resetThemeInjectable from "../../features/user-preferences/common/reset-theme.injectable";
|
||||
|
||||
export type ApplyLensTheme = (theme: LensTheme) => void;
|
||||
|
||||
@@ -14,7 +14,7 @@ const applyLensThemeInjectable = getInjectable({
|
||||
id: "apply-lens-theme",
|
||||
instantiate: (di): ApplyLensTheme => {
|
||||
const logger = di.inject(loggerInjectable);
|
||||
const userStore = di.inject(userStoreInjectable);
|
||||
const resetTheme = di.inject(resetThemeInjectable);
|
||||
|
||||
return (theme) => {
|
||||
try {
|
||||
@@ -28,7 +28,7 @@ const applyLensThemeInjectable = getInjectable({
|
||||
document.body.classList.toggle("theme-light", theme.type === "light");
|
||||
} catch (error) {
|
||||
logger.error("[THEME]: Failed to apply active theme", error);
|
||||
userStore.resetTheme();
|
||||
resetTheme();
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
@@ -6,7 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { reaction } from "mobx";
|
||||
import initializeSystemThemeTypeInjectable from "../../features/theme/system-type/renderer/initialize.injectable";
|
||||
import { beforeFrameStartsSecondInjectionToken } from "../before-frame-starts/tokens";
|
||||
import initUserStoreInjectable from "../stores/init-user-store.injectable";
|
||||
import initUserStoreInjectable from "../../features/user-preferences/renderer/load-storage.injectable";
|
||||
import activeThemeInjectable from "./active.injectable";
|
||||
import applyLensThemeInjectable from "./apply-lens-theme.injectable";
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { computed } from "mobx";
|
||||
import terminalThemePreferenceInjectable from "../../common/user-store/terminal-theme.injectable";
|
||||
import terminalThemePreferenceInjectable from "../../features/user-preferences/common/terminal-theme.injectable";
|
||||
import activeThemeInjectable from "./active.injectable";
|
||||
import lensThemesInjectable from "./themes.injectable";
|
||||
|
||||
|
||||
Reference in new issue
Block a user