mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Turn on strict mode in tsconfig.json, some helpful lints, and required cleanup where strictness necessitates it (#5195)
* Turn on strict mode in tsconfig.json - Add route, clusterRoute, and payloadValidatedClusterRoute helper functions to improve types with backend routes - Turn on the following new lints: - react/jsx-first-prop-new-line - react/jsx-wrap-multilines - react/jsx-one-expression-per-line - react/jsx-max-props-per-line - react/jsx-indent - react/jsx-indent-props Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix build Signed-off-by: Sebastian Malton <sebastian@malton.name> * Replace KubeObject scope strings with enum Signed-off-by: Sebastian Malton <sebastian@malton.name> * Revert package.json version changes Signed-off-by: Sebastian Malton <sebastian@malton.name> * revert move hostedCluster(Id) Signed-off-by: Sebastian Malton <sebastian@malton.name> * change some type param names to be not single letters Signed-off-by: Sebastian Malton <sebastian@malton.name> * remove copy-extension-themes Signed-off-by: Sebastian Malton <sebastian@malton.name> * add new make clean action Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix build to not use webpack for generating types Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix kube-object-menu.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix select.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix catalog.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * revert move fileNameMigration to index Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix ref logic error Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix log-resource-selector.test.tsx tests Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix dock-store.test.ts test by overriding createStorage to not touch file system Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix cluster.test.ts tests Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix kube=api.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fixed hotbar-store.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix kubeconfig-manager.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix cluster-role-bindings/__tests__/dialog.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix role-bindings/__tests__/dialog.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix pods.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix delete-cluster-dialog.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix daemonset.store.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix replicaset.store.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix statefulsets/dialog/dialog.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix replicasets/scale-dialog/dialog.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix deployments.store.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix deployments/scale/dialog.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix cronjob.store.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix stateful-set.api.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix deployment.api.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix api-manager.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix statefulset.store.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix job.store.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix pods.store.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix scroll-spy.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix hotbar-remove-command.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix catalog-entity-registry.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix welcome.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix verify-that-all-routes-have-route-component.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix pod-tolerations.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * better fix for previous 3 fixes, plus also select.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix kube-object-menu.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix app-paths.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix dock-tabs.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix isReactNode typing Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix sub-title.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix drawer.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix list-layout.tsx and header.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix error-boundary.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix upgrade-chart/store.ts and dock-tab.store.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix install-chart/store.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix edit-resource/store.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix create-resource/store.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix namespace-select.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix namespace-select-filter.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix crd-list.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix wrong types for extensions Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix circular dependency Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix circular dependency on catalogCategoryRegistry Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix api-kube Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix type errors, most <Select /> errors Signed-off-by: Sebastian Malton <sebastian@malton.name> * fixing more type errors Signed-off-by: Sebastian Malton <sebastian@malton.name> * some more fixing type errors Signed-off-by: Sebastian Malton <sebastian@malton.name> * convert all KubeApis to injectable with legacy global backups Signed-off-by: Sebastian Malton <sebastian@malton.name> * factor out into a common file all the exports Signed-off-by: Sebastian Malton <sebastian@malton.name> * convert all KubeObjectStores to injectable with legacy global backups Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix lint Signed-off-by: Sebastian Malton <sebastian@malton.name> * remove unused legacy KubeApi globals Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix bad previous commit Signed-off-by: Sebastian Malton <sebastian@malton.name> * more crash fixing Signed-off-by: Sebastian Malton <sebastian@malton.name> * try and fix behavioural tests Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix sidebar-and-tab-navigation-for-core.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix sidebar-and-tab-navigation-for-extensions.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix navigation-using-application-menu.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix catalog.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * Make ThemeStore non-singleton and fix navigation-to-terminal-preferences.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * extensions.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix catalog-entity-registry.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix navigation-using-application-menu.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix log-resource-selector.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix dock-tabs.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix delete-cluster-dialog.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix navigation-to-kubernetes-preferences.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix navigation-to-editor-preferences.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix navigation-to-proxy-preferences.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix navigation-using-application-menu.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix navigation-to-application-preferences.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix dock-store.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix select.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix role-bindings/__tests__/dialog.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix hotbar-remove-command.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix cluster-role-bindings/__tests__/dialog.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix navigation-to-extension-specific-preferences.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix navigation-to-telemetry-preferences.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix closing-preferences.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix navigation-to-editor-preferences.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix navigation-to-proxy-preferences.test.ts - Fix other type errors too Signed-off-by: Sebastian Malton <sebastian@malton.name> * final tweaks Signed-off-by: Sebastian Malton <sebastian@malton.name> * Add more tsconfig files, fix bug in <Catalog> - Make all of history, navigation injectable Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix type errors Signed-off-by: Sebastian Malton <sebastian@malton.name> * Convert all of kube-details-params/ and navigate/ to injectable - This fixes a runtime error that was encountered during testing Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix runtime errors on renderer - remove all static uses of `createPageParam` (and then removed the legacy global) - Made LensRendererExtension and LensMainExtension just used dependencies and not the getLegacyDi - Fixed circular dep in extension-loader Signed-off-by: Sebastian Malton <sebastian@malton.name> * Move registerStore calls to after injectMany Signed-off-by: Sebastian Malton <sebastian@malton.name> * replace all the rest of the legacy uses of apiManager Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix stack overflow and cycles in DI Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix NamespaceSelectFilter not opening Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix WizardStep and AddNamespaceDialog Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix KubeApi's not being registered Signed-off-by: Sebastian Malton <sebastian@malton.name> * cleanup WindowManager Signed-off-by: Sebastian Malton <sebastian@malton.name> * Proper fix for Wizard, fix NamespaceStore.subscribe Signed-off-by: Sebastian Malton <sebastian@malton.name> * Rewrite withTooltip to be more type correct - Fixes mobx related "too many recursive actions" error - Change all the uses of withTooltips to be functional components Signed-off-by: Sebastian Malton <sebastian@malton.name> * Add e2e test to cover kube api registration Signed-off-by: Sebastian Malton <sebastian@malton.name> * cleanup internal-commands Signed-off-by: Sebastian Malton <sebastian@malton.name> * remove cast in <Animate> Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix command-palette e2e test Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix type error after rebase Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix test name Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix lint Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix code to help CodeQL scanner Signed-off-by: Sebastian Malton <sebastian@malton.name> * update intree extension lock files Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix build-extensions picking wrong @types/react Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix tests from rebase Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix type error Signed-off-by: Sebastian Malton <sebastian@malton.name> * Make KubeconfigSyncManager more injectable Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix crash in test mode for Dialog Signed-off-by: Sebastian Malton <sebastian@malton.name> * make Select snapshots deterministic Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix new type error Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix kube-object.store.test.ts typing Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix merge build issues Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix snapshots after merge Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix lint after merge Signed-off-by: Sebastian Malton <sebastian@malton.name> * reexport BaseKubeJsonApiObjectMetadata Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix typo in terminalSpawningPool Signed-off-by: Sebastian Malton <sebastian@malton.name> * remove duplicate license header Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix typo to waitUntilDefined Signed-off-by: Sebastian Malton <sebastian@malton.name> * remove iter use from getLegacyGlobalDiForExtensionApi Signed-off-by: Sebastian Malton <sebastian@malton.name> * remove complex createStorage override Signed-off-by: Sebastian Malton <sebastian@malton.name> * override logger with mocks only when needed for tests Signed-off-by: Sebastian Malton <sebastian@malton.name> * remove specialized overrideStore flags for getDiForUnitTesting Signed-off-by: Sebastian Malton <sebastian@malton.name> * remove unnecessary | undefined types from the exactOptionalFieldTypes experiment Signed-off-by: Sebastian Malton <sebastian@malton.name> * use more descriptive name for local test mocks Signed-off-by: Sebastian Malton <sebastian@malton.name> * remove unnecessary addition to 'make clean' target Signed-off-by: Sebastian Malton <sebastian@malton.name> * remove oddity of KubeObjectStore.getById(undefined) being allowed Signed-off-by: Sebastian Malton <sebastian@malton.name> * rename KubeObject.getDescriptor in favour of name without fundemental JS meaning Signed-off-by: Sebastian Malton <sebastian@malton.name> * Simplify legacyRegisterApi when working in behaviour unit tests - Don't emit within main environment as there should be no auto registering there Signed-off-by: Sebastian Malton <sebastian@malton.name> * change confusing variable name in ReactiveDuration Signed-off-by: Sebastian Malton <sebastian@malton.name> * make visitor pattern more explicit for Entity contextMenuOpen Signed-off-by: Sebastian Malton <sebastian@malton.name> * toggleDetails -> toggleKubeDetailsPane is more specific Signed-off-by: Sebastian Malton <sebastian@malton.name> * remove outdated comment Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix bug where LensExtension dependencies are not set Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix tests from the revert of react 18 Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix more tests from merge Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix typings with new is-compatible-extension tests Signed-off-by: Sebastian Malton <sebastian@malton.name> * more type fixing Signed-off-by: Sebastian Malton <sebastian@malton.name> * Revert in-tree extension versions Signed-off-by: Sebastian Malton <sebastian@malton.name> * Improve name of guarding injectable for stores and apis - New name better implies that it is just a guard state and does not do anything Signed-off-by: Sebastian Malton <sebastian@malton.name> * Add helper for <Select>.isMulti for storing in a Set<Value> Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix is-compatible-extension.test.ts types Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
1 parent
381d77c633
commit
dfcb7c3330
1062 files changed
+26512
-28689
No files matched your search
@@ -11,8 +11,8 @@ 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/hotbar-store.injectable";
|
||||
import type { HotbarStore } from "../../../../common/hotbar-store";
|
||||
import hotbarStoreInjectable from "../../../../common/hotbars/store.injectable";
|
||||
import type { HotbarStore } from "../../../../common/hotbars/store";
|
||||
|
||||
const clusterEntity = new KubernetesCluster({
|
||||
metadata: {
|
||||
|
||||
@@ -15,7 +15,11 @@ export interface CloseButtonProps extends HTMLAttributes<HTMLDivElement> {
|
||||
export function CloseButton(props: CloseButtonProps) {
|
||||
return (
|
||||
<div {...props}>
|
||||
<div className={styles.closeButton} role="button" aria-label="Close">
|
||||
<div
|
||||
className={styles.closeButton}
|
||||
role="button"
|
||||
aria-label="Close"
|
||||
>
|
||||
<Icon material="close" className={styles.icon}/>
|
||||
</div>
|
||||
<div className={styles.esc} aria-hidden="true">
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import type { DiContainer } from "@ogre-tools/injectable";
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import type { LensRendererExtension } from "../../../extensions/lens-renderer-extension";
|
||||
import React from "react";
|
||||
import { extensionRegistratorInjectionToken } from "../../../extensions/extension-loader/extension-registrator-injection-token";
|
||||
import type { SidebarItemRegistration } from "./sidebar-items.injectable";
|
||||
@@ -13,71 +11,70 @@ import { computed } from "mobx";
|
||||
import routesInjectable from "../../routes/routes.injectable";
|
||||
import { matches, noop } from "lodash/fp";
|
||||
import routeIsActiveInjectable from "../../routes/route-is-active.injectable";
|
||||
import { getExtensionRoutePath } from "../../routes/get-extension-route-path";
|
||||
import { navigateToRouteInjectionToken } from "../../../common/front-end-routing/navigate-to-route-injection-token";
|
||||
import { getExtensionRoutePath } from "../../routes/for-extension";
|
||||
import type { LensRendererExtension } from "../../../extensions/lens-renderer-extension";
|
||||
|
||||
const extensionSidebarItemRegistratorInjectable = getInjectable({
|
||||
id: "extension-sidebar-item-registrator",
|
||||
|
||||
instantiate:
|
||||
(di: DiContainer) =>
|
||||
(
|
||||
extension: LensRendererExtension,
|
||||
extensionInstallationCount: number,
|
||||
) => {
|
||||
const sidebarItemsForExtensionInjectable = getInjectable({
|
||||
id: `sidebar-items-for-extension-${extension.sanitizedExtensionId}-instance-${extensionInstallationCount}`,
|
||||
injectionToken: sidebarItemsInjectionToken,
|
||||
instantiate: (di) => (ext, extensionInstallationCount) => {
|
||||
const extension = ext as LensRendererExtension;
|
||||
|
||||
instantiate: (di) => {
|
||||
const navigateToRoute = di.inject(navigateToRouteInjectionToken);
|
||||
const routes = di.inject(routesInjectable);
|
||||
const sidebarItemsForExtensionInjectable = getInjectable({
|
||||
id: `sidebar-items-for-extension-${extension.sanitizedExtensionId}-instance-${extensionInstallationCount}`,
|
||||
injectionToken: sidebarItemsInjectionToken,
|
||||
|
||||
return computed((): SidebarItemRegistration[] => {
|
||||
const extensionRoutes = routes.get().filter(matches({ extension }));
|
||||
instantiate: (di) => {
|
||||
const navigateToRoute = di.inject(navigateToRouteInjectionToken);
|
||||
const routes = di.inject(routesInjectable);
|
||||
|
||||
return extension.clusterPageMenus.map((registration) => {
|
||||
const targetRoutePath = getExtensionRoutePath(
|
||||
extension,
|
||||
registration.target?.pageId,
|
||||
);
|
||||
return computed(() => {
|
||||
const extensionRoutes = routes.get().filter(matches({ extension }));
|
||||
|
||||
const targetRoute = extensionRoutes.find(
|
||||
matches({ path: targetRoutePath }),
|
||||
);
|
||||
return extension.clusterPageMenus.map((registration) => {
|
||||
const targetRoutePath = getExtensionRoutePath(
|
||||
extension,
|
||||
registration.target?.pageId,
|
||||
);
|
||||
|
||||
return {
|
||||
id: `${extension.sanitizedExtensionId}-${registration.id}`,
|
||||
extension,
|
||||
orderNumber: 9999,
|
||||
const targetRoute = extensionRoutes.find(
|
||||
matches({ path: targetRoutePath }),
|
||||
);
|
||||
|
||||
parentId: registration.parentId
|
||||
? `${extension.sanitizedExtensionId}-${registration.parentId}`
|
||||
: null,
|
||||
const res: SidebarItemRegistration = {
|
||||
id: `${extension.sanitizedExtensionId}-${registration.id}`,
|
||||
extension,
|
||||
orderNumber: 9999,
|
||||
|
||||
title: registration.title,
|
||||
getIcon: registration.components.Icon
|
||||
? () => <registration.components.Icon />
|
||||
: null,
|
||||
parentId: registration.parentId
|
||||
? `${extension.sanitizedExtensionId}-${registration.parentId}`
|
||||
: null,
|
||||
|
||||
...(targetRoute
|
||||
? {
|
||||
onClick: () => navigateToRoute(targetRoute),
|
||||
title: registration.title,
|
||||
getIcon: registration.components.Icon
|
||||
? () => <registration.components.Icon />
|
||||
: undefined,
|
||||
...(targetRoute
|
||||
? {
|
||||
onClick: () => navigateToRoute(targetRoute),
|
||||
|
||||
isActive: di.inject(
|
||||
routeIsActiveInjectable,
|
||||
targetRoute,
|
||||
),
|
||||
}
|
||||
: { onClick: noop }),
|
||||
};
|
||||
});
|
||||
});
|
||||
},
|
||||
isActive: di.inject(
|
||||
routeIsActiveInjectable,
|
||||
targetRoute,
|
||||
),
|
||||
}
|
||||
: { onClick: noop }),
|
||||
};
|
||||
|
||||
return res;
|
||||
});
|
||||
});
|
||||
|
||||
di.register(sidebarItemsForExtensionInjectable);
|
||||
},
|
||||
});
|
||||
|
||||
di.register(sidebarItemsForExtensionInjectable);
|
||||
},
|
||||
|
||||
injectionToken: extensionRegistratorInjectionToken,
|
||||
});
|
||||
|
||||
@@ -7,21 +7,19 @@ import styles from "./main-layout.module.scss";
|
||||
|
||||
import React from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import type { StorageHelper } from "../../utils";
|
||||
import type { StorageLayer } from "../../utils";
|
||||
import { cssNames } from "../../utils";
|
||||
import { ErrorBoundary } from "../error-boundary";
|
||||
import { ResizeDirection, ResizeGrowthDirection, ResizeSide, ResizingAnchor } from "../resizing-anchor";
|
||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import type {
|
||||
SidebarStorageState } from "./sidebar-storage/sidebar-storage.injectable";
|
||||
import sidebarStorageInjectable, {
|
||||
defaultSidebarWidth,
|
||||
} from "./sidebar-storage/sidebar-storage.injectable";
|
||||
import type { SidebarStorageState } from "./sidebar-storage/sidebar-storage.injectable";
|
||||
import sidebarStorageInjectable, { defaultSidebarWidth } from "./sidebar-storage/sidebar-storage.injectable";
|
||||
|
||||
export interface MainLayoutProps {
|
||||
sidebar: React.ReactNode;
|
||||
className?: string;
|
||||
footer?: React.ReactNode;
|
||||
children?: React.ReactNode | React.ReactNode[];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -31,7 +29,7 @@ export interface MainLayoutProps {
|
||||
*/
|
||||
|
||||
interface Dependencies {
|
||||
sidebarStorage: StorageHelper<SidebarStorageState>;
|
||||
sidebarStorage: StorageLayer<SidebarStorageState>;
|
||||
}
|
||||
|
||||
@observer
|
||||
@@ -71,15 +69,10 @@ class NonInjectedMainLayout extends React.Component<MainLayoutProps & Dependenci
|
||||
}
|
||||
}
|
||||
|
||||
export const MainLayout = withInjectables<Dependencies, MainLayoutProps>(
|
||||
NonInjectedMainLayout,
|
||||
|
||||
{
|
||||
getProps: (di, props) => ({
|
||||
sidebarStorage: di.inject(sidebarStorageInjectable),
|
||||
|
||||
...props,
|
||||
}),
|
||||
},
|
||||
);
|
||||
export const MainLayout = withInjectables<Dependencies, MainLayoutProps>(NonInjectedMainLayout, {
|
||||
getProps: (di, props) => ({
|
||||
...props,
|
||||
sidebarStorage: di.inject(sidebarStorageInjectable),
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -69,7 +69,7 @@ export class SettingLayout extends React.Component<SettingLayoutProps> {
|
||||
|
||||
if (evt.code === "Escape") {
|
||||
evt.stopPropagation();
|
||||
this.props.back(evt);
|
||||
this.props.back?.(evt);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -24,7 +24,8 @@ const NonInjectedSiblingsInTabLayout = observer(
|
||||
|
||||
if (dereferencedTabs.length) {
|
||||
return (
|
||||
<TabLayout tabs={dereferencedTabs}
|
||||
<TabLayout
|
||||
tabs={dereferencedTabs}
|
||||
>
|
||||
{children}
|
||||
</TabLayout>
|
||||
|
||||
@@ -14,31 +14,36 @@ import { Icon } from "../icon";
|
||||
import { Menu, MenuItem } from "../menu";
|
||||
import { Tooltip } from "../tooltip";
|
||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import hotbarStoreInjectable from "../../../common/hotbar-store.injectable";
|
||||
import type { HotbarStore } from "../../../common/hotbar-store";
|
||||
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";
|
||||
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";
|
||||
|
||||
export interface SidebarClusterProps {
|
||||
clusterEntity: CatalogEntity;
|
||||
clusterEntity: CatalogEntity | null | undefined;
|
||||
}
|
||||
|
||||
interface Dependencies {
|
||||
navigate: Navigate;
|
||||
normalizeMenuItem: NormalizeCatalogEntityContextMenu;
|
||||
hotbarStore: HotbarStore;
|
||||
visitEntityContextMenu: VisitEntityContextMenu;
|
||||
}
|
||||
|
||||
function NonInjectedSidebarCluster({
|
||||
const NonInjectedSidebarCluster = observer(({
|
||||
clusterEntity,
|
||||
hotbarStore,
|
||||
visitEntityContextMenu: onContextMenuOpen,
|
||||
navigate,
|
||||
normalizeMenuItem,
|
||||
}: SidebarClusterProps & Dependencies) {
|
||||
const [opened, setOpened] = useState(false);
|
||||
}: Dependencies & SidebarClusterProps) => {
|
||||
const [menuItems] = useState(observable.array<CatalogEntityContextMenu>());
|
||||
const [opened, setOpened] = useState(false );
|
||||
|
||||
if (!clusterEntity) {
|
||||
// render a Loading version of the SidebarCluster
|
||||
@@ -65,7 +70,7 @@ function NonInjectedSidebarCluster({
|
||||
: () => hotbarStore.addToHotbar(clusterEntity);
|
||||
|
||||
menuItems.replace([{ title, onClick }]);
|
||||
clusterEntity.onContextMenuOpen({
|
||||
onContextMenuOpen(clusterEntity, {
|
||||
menuItems,
|
||||
navigate: (url, forceMainFrame = true) => {
|
||||
if (forceMainFrame) {
|
||||
@@ -114,7 +119,7 @@ function NonInjectedSidebarCluster({
|
||||
<Tooltip targetId={tooltipId}>
|
||||
{clusterEntity.getName()}
|
||||
</Tooltip>
|
||||
<Icon material="arrow_drop_down" className={styles.dropdown}/>
|
||||
<Icon material="arrow_drop_down" className={styles.dropdown} />
|
||||
<Menu
|
||||
usePortal
|
||||
htmlFor={id}
|
||||
@@ -137,12 +142,13 @@ function NonInjectedSidebarCluster({
|
||||
</Menu>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
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),
|
||||
}),
|
||||
|
||||
@@ -7,20 +7,18 @@ import "./sidebar-item.scss";
|
||||
|
||||
import React from "react";
|
||||
import { computed, makeObservable } from "mobx";
|
||||
import type { StorageHelper } from "../../utils";
|
||||
import type { StorageLayer } from "../../utils";
|
||||
import { cssNames } from "../../utils";
|
||||
import { observer } from "mobx-react";
|
||||
import { NavLink } from "react-router-dom";
|
||||
import { Icon } from "../icon";
|
||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import type {
|
||||
SidebarStorageState,
|
||||
} from "./sidebar-storage/sidebar-storage.injectable";
|
||||
import type { SidebarStorageState } from "./sidebar-storage/sidebar-storage.injectable";
|
||||
import sidebarStorageInjectable from "./sidebar-storage/sidebar-storage.injectable";
|
||||
import type { HierarchicalSidebarItem } from "./sidebar-items.injectable";
|
||||
|
||||
interface Dependencies {
|
||||
sidebarStorage: StorageHelper<SidebarStorageState>;
|
||||
sidebarStorage: StorageLayer<SidebarStorageState>;
|
||||
}
|
||||
|
||||
export interface SidebarItemProps {
|
||||
@@ -125,13 +123,9 @@ class NonInjectedSidebarItem extends React.Component<
|
||||
}
|
||||
}
|
||||
|
||||
export const SidebarItem = withInjectables<Dependencies, SidebarItemProps>(
|
||||
NonInjectedSidebarItem,
|
||||
|
||||
{
|
||||
getProps: (di, props) => ({
|
||||
sidebarStorage: di.inject(sidebarStorageInjectable),
|
||||
...props,
|
||||
}),
|
||||
},
|
||||
);
|
||||
export const SidebarItem = withInjectables<Dependencies, SidebarItemProps>(NonInjectedSidebarItem, {
|
||||
getProps: (di, props) => ({
|
||||
...props,
|
||||
sidebarStorage: di.inject(sidebarStorageInjectable),
|
||||
}),
|
||||
});
|
||||
@@ -68,12 +68,8 @@ const sidebarItemsInjectable = getInjectable({
|
||||
),
|
||||
);
|
||||
|
||||
const getSidebarItemsHierarchy = (
|
||||
registrations: SidebarItemRegistration[],
|
||||
) => {
|
||||
const _getSidebarItemsHierarchy = (
|
||||
parentId: string,
|
||||
): HierarchicalSidebarItem[] =>
|
||||
const getSidebarItemsHierarchy = (registrations: SidebarItemRegistration[]) => {
|
||||
const _getSidebarItemsHierarchy = (parentId: string | null): HierarchicalSidebarItem[] =>
|
||||
pipeline(
|
||||
registrations,
|
||||
|
||||
|
||||
@@ -9,57 +9,46 @@ import React from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { cssNames } from "../../utils";
|
||||
import { SidebarItem } from "./sidebar-item";
|
||||
import { catalogEntityRegistry } from "../../api/catalog-entity-registry";
|
||||
import type { CatalogEntityRegistry } from "../../api/catalog/entity/registry";
|
||||
import { SidebarCluster } from "./sidebar-cluster";
|
||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import type {
|
||||
HierarchicalSidebarItem,
|
||||
} from "./sidebar-items.injectable";
|
||||
import type { HierarchicalSidebarItem } from "./sidebar-items.injectable";
|
||||
import sidebarItemsInjectable from "./sidebar-items.injectable";
|
||||
import type { IComputedValue } from "mobx";
|
||||
import catalogEntityRegistryInjectable from "../../api/catalog/entity/registry.injectable";
|
||||
|
||||
interface Dependencies {
|
||||
sidebarItems: IComputedValue<HierarchicalSidebarItem[]>;
|
||||
entityRegistry: CatalogEntityRegistry;
|
||||
}
|
||||
|
||||
@observer
|
||||
class NonInjectedSidebar extends React.Component<Dependencies> {
|
||||
static displayName = "Sidebar";
|
||||
export const NonInjectedSidebar = observer(({
|
||||
sidebarItems,
|
||||
entityRegistry,
|
||||
}: Dependencies) => (
|
||||
<div className={cssNames("flex flex-col")} data-testid="cluster-sidebar">
|
||||
<SidebarCluster clusterEntity={entityRegistry.activeEntity} />
|
||||
|
||||
get clusterEntity() {
|
||||
return catalogEntityRegistry.activeEntity;
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className={cssNames("flex flex-col")} data-testid="cluster-sidebar">
|
||||
<SidebarCluster clusterEntity={this.clusterEntity} />
|
||||
|
||||
<div className={`${styles.sidebarNav} sidebar-active-status`}>
|
||||
{this.props.sidebarItems.get().map((
|
||||
hierarchicalSidebarItem: HierarchicalSidebarItem,
|
||||
) => (
|
||||
<div className={`${styles.sidebarNav} sidebar-active-status`}>
|
||||
{
|
||||
sidebarItems.get()
|
||||
.map(hierarchicalSidebarItem => (
|
||||
<SidebarItem
|
||||
item={hierarchicalSidebarItem}
|
||||
key={hierarchicalSidebarItem.registration.id}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const Sidebar = withInjectables<Dependencies>(
|
||||
NonInjectedSidebar,
|
||||
|
||||
{
|
||||
getProps: (di, props) => ({
|
||||
sidebarItems: di.inject(sidebarItemsInjectable),
|
||||
...props,
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
));
|
||||
|
||||
export const Sidebar = withInjectables<Dependencies>(NonInjectedSidebar, {
|
||||
getProps: (di, props) => ({
|
||||
...props,
|
||||
sidebarItems: di.inject(sidebarItemsInjectable),
|
||||
entityRegistry: di.inject(catalogEntityRegistryInjectable),
|
||||
}),
|
||||
});
|
||||
|
||||
Sidebar.displayName = "Sidebar";
|
||||
@@ -5,12 +5,14 @@
|
||||
|
||||
import "./sub-header.scss";
|
||||
import React from "react";
|
||||
import type { SingleOrMany } from "../../utils";
|
||||
import { cssNames } from "../../utils";
|
||||
|
||||
export interface SubHeaderProps {
|
||||
className?: string;
|
||||
withLine?: boolean; // add bottom line
|
||||
compact?: boolean; // no extra padding around content
|
||||
children: SingleOrMany<React.ReactNode>;
|
||||
}
|
||||
|
||||
export class SubHeader extends React.Component<SubHeaderProps> {
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
import "./sub-title.scss";
|
||||
import React from "react";
|
||||
import type { SingleOrMany } from "../../utils";
|
||||
import { cssNames } from "../../utils";
|
||||
|
||||
export interface SubTitleProps {
|
||||
@@ -12,6 +13,7 @@ export interface SubTitleProps {
|
||||
title: React.ReactNode;
|
||||
compact?: boolean; // no bottom padding
|
||||
id?: string;
|
||||
children?: SingleOrMany<React.ReactNode>;
|
||||
}
|
||||
|
||||
export class SubTitle extends React.Component<SubTitleProps> {
|
||||
@@ -23,7 +25,9 @@ export class SubTitle extends React.Component<SubTitleProps> {
|
||||
|
||||
return (
|
||||
<div className={classNames} id={id}>
|
||||
{title} {children}
|
||||
{title}
|
||||
{" "}
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -40,21 +40,29 @@ export const TabLayout = observer(({ className, contentClass, tabs = [], childre
|
||||
<div className={cssNames("TabLayout", className)}>
|
||||
{hasTabs && (
|
||||
<Tabs center onChange={(url) => navigate(url)}>
|
||||
{tabs.map(({ title, routePath, url = routePath, exact }) => {
|
||||
const isActive = !!matchPath(currentLocation, { path: routePath, exact });
|
||||
|
||||
return <Tab key={url} label={title} value={url} active={isActive}/>;
|
||||
})}
|
||||
{tabs.map(({ title, routePath, url = routePath, exact }) => (
|
||||
<Tab
|
||||
key={url}
|
||||
label={title}
|
||||
value={url}
|
||||
active={!!matchPath(currentLocation, { path: routePath, exact })}
|
||||
/>
|
||||
))}
|
||||
</Tabs>
|
||||
)}
|
||||
<main className={cssNames(contentClass)}>
|
||||
<ErrorBoundary>
|
||||
{hasTabs && (
|
||||
<Switch>
|
||||
{tabs.map(({ routePath, exact, component }) => {
|
||||
return <Route key={routePath} exact={exact} path={routePath} component={component}/>;
|
||||
})}
|
||||
<Redirect to={startTabUrl}/>
|
||||
{tabs.map(({ routePath, exact, component }) => (
|
||||
<Route
|
||||
key={routePath}
|
||||
exact={exact}
|
||||
path={routePath}
|
||||
component={component}
|
||||
/>
|
||||
))}
|
||||
{startTabUrl && <Redirect to={startTabUrl}/>}
|
||||
</Switch>
|
||||
)}
|
||||
{children}
|
||||
|
||||
@@ -43,8 +43,14 @@ ipcRendererOn("history:can-go-forward", (event, state: boolean) => {
|
||||
nextEnabled.set(state);
|
||||
});
|
||||
|
||||
const NonInjectedTopBar = observer(({ items, navigateToCatalog, catalogRouteIsActive, isWindows, isLinux }: Dependencies) => {
|
||||
const elem = useRef<HTMLDivElement>();
|
||||
const NonInjectedTopBar = observer(({
|
||||
items,
|
||||
navigateToCatalog,
|
||||
catalogRouteIsActive,
|
||||
isWindows,
|
||||
isLinux,
|
||||
}: Dependencies) => {
|
||||
const elem = useRef<HTMLDivElement | null>(null);
|
||||
|
||||
const openAppContextMenu = () => {
|
||||
emitOpenAppMenuAsContextMenu();
|
||||
@@ -83,15 +89,24 @@ const NonInjectedTopBar = observer(({ items, navigateToCatalog, catalogRouteIsAc
|
||||
useEffect(() => watchHistoryState(), []);
|
||||
|
||||
return (
|
||||
<div className={styles.topBar} onDoubleClick={windowSizeToggle} ref={elem}>
|
||||
<div
|
||||
className={styles.topBar}
|
||||
onDoubleClick={windowSizeToggle}
|
||||
ref={elem}
|
||||
>
|
||||
<div className={styles.items}>
|
||||
{(isWindows || isLinux) && (
|
||||
<div className={styles.winMenu}>
|
||||
<div onClick={openAppContextMenu} data-testid="window-menu">
|
||||
<svg width="12" height="12" viewBox="0 0 12 12" shapeRendering="crispEdges">
|
||||
<path fill="currentColor" d="M0,8.5h12v1H0V8.5z"/>
|
||||
<path fill="currentColor" d="M0,5.5h12v1H0V5.5z"/>
|
||||
<path fill="currentColor" d="M0,2.5h12v1H0V2.5z"/>
|
||||
<svg
|
||||
width="12"
|
||||
height="12"
|
||||
viewBox="0 0 12 12"
|
||||
shapeRendering="crispEdges"
|
||||
>
|
||||
<path fill="currentColor" d="M0,8.5h12v1H0V8.5z" />
|
||||
<path fill="currentColor" d="M0,5.5h12v1H0V5.5z" />
|
||||
<path fill="currentColor" d="M0,2.5h12v1H0V2.5z" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
@@ -119,17 +134,42 @@ const NonInjectedTopBar = observer(({ items, navigateToCatalog, catalogRouteIsAc
|
||||
{renderRegisteredItems(items.get())}
|
||||
{(isWindows || isLinux) && (
|
||||
<div className={cssNames(styles.windowButtons, { [styles.linuxButtons]: isLinux })}>
|
||||
<div className={styles.minimize} data-testid="window-minimize" onClick={minimizeWindow}>
|
||||
<div
|
||||
className={styles.minimize}
|
||||
data-testid="window-minimize"
|
||||
onClick={minimizeWindow}
|
||||
>
|
||||
<svg shapeRendering="crispEdges" viewBox="0 0 12 12">
|
||||
<rect fill="currentColor" width="10" height="1" x="1" y="9" />
|
||||
<rect
|
||||
fill="currentColor"
|
||||
width="10"
|
||||
height="1"
|
||||
x="1"
|
||||
y="9"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div className={styles.maximize} data-testid="window-maximize" onClick={toggleMaximize}>
|
||||
<div
|
||||
className={styles.maximize}
|
||||
data-testid="window-maximize"
|
||||
onClick={toggleMaximize}
|
||||
>
|
||||
<svg shapeRendering="crispEdges" viewBox="0 0 12 12">
|
||||
<rect width="9" height="9" x="1.5" y="1.5" fill="none" stroke="currentColor" />
|
||||
<rect
|
||||
width="9"
|
||||
height="9"
|
||||
x="1.5"
|
||||
y="1.5"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div className={styles.close} data-testid="window-close" onClick={closeWindow}>
|
||||
<div
|
||||
className={styles.close}
|
||||
data-testid="window-close"
|
||||
onClick={closeWindow}
|
||||
>
|
||||
<svg shapeRendering="crispEdges" viewBox="0 0 12 12">
|
||||
<polygon fill="currentColor" points="11 1.576 6.583 6 11 10.424 10.424 11 6 6.583 1.576 11 1 10.424 5.417 6 1 1.576 1.576 1 6 5.417 10.424 1" />
|
||||
</svg>
|
||||
|
||||
Reference in new issue
Block a user