mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Introduce competition for preferences navigation
Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
This commit is contained in:
parent
6d56771404
commit
515ec34c87
@ -93,7 +93,7 @@ exports[`add custom helm repository in preferences when navigating to preference
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="Tab flex gaps align-center"
|
class="Tab flex gaps align-center"
|
||||||
data-testid="tab-link-for-application"
|
data-testid="tab-link-for-app"
|
||||||
role="tab"
|
role="tab"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
@ -690,7 +690,7 @@ exports[`add custom helm repository in preferences when navigating to preference
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="Tab flex gaps align-center"
|
class="Tab flex gaps align-center"
|
||||||
data-testid="tab-link-for-application"
|
data-testid="tab-link-for-app"
|
||||||
role="tab"
|
role="tab"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
@ -1298,7 +1298,7 @@ exports[`add custom helm repository in preferences when navigating to preference
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="Tab flex gaps align-center"
|
class="Tab flex gaps align-center"
|
||||||
data-testid="tab-link-for-application"
|
data-testid="tab-link-for-app"
|
||||||
role="tab"
|
role="tab"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
@ -2017,7 +2017,7 @@ exports[`add custom helm repository in preferences when navigating to preference
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="Tab flex gaps align-center"
|
class="Tab flex gaps align-center"
|
||||||
data-testid="tab-link-for-application"
|
data-testid="tab-link-for-app"
|
||||||
role="tab"
|
role="tab"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
@ -2633,7 +2633,7 @@ exports[`add custom helm repository in preferences when navigating to preference
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="Tab flex gaps align-center"
|
class="Tab flex gaps align-center"
|
||||||
data-testid="tab-link-for-application"
|
data-testid="tab-link-for-app"
|
||||||
role="tab"
|
role="tab"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
@ -3352,7 +3352,7 @@ exports[`add custom helm repository in preferences when navigating to preference
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="Tab flex gaps align-center"
|
class="Tab flex gaps align-center"
|
||||||
data-testid="tab-link-for-application"
|
data-testid="tab-link-for-app"
|
||||||
role="tab"
|
role="tab"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
@ -4253,7 +4253,7 @@ exports[`add custom helm repository in preferences when navigating to preference
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="Tab flex gaps align-center"
|
class="Tab flex gaps align-center"
|
||||||
data-testid="tab-link-for-application"
|
data-testid="tab-link-for-app"
|
||||||
role="tab"
|
role="tab"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
@ -4972,7 +4972,7 @@ exports[`add custom helm repository in preferences when navigating to preference
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="Tab flex gaps align-center"
|
class="Tab flex gaps align-center"
|
||||||
data-testid="tab-link-for-application"
|
data-testid="tab-link-for-app"
|
||||||
role="tab"
|
role="tab"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
@ -5873,7 +5873,7 @@ exports[`add custom helm repository in preferences when navigating to preference
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="Tab flex gaps align-center"
|
class="Tab flex gaps align-center"
|
||||||
data-testid="tab-link-for-application"
|
data-testid="tab-link-for-app"
|
||||||
role="tab"
|
role="tab"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
@ -6593,7 +6593,7 @@ exports[`add custom helm repository in preferences when navigating to preference
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="Tab flex gaps align-center"
|
class="Tab flex gaps align-center"
|
||||||
data-testid="tab-link-for-application"
|
data-testid="tab-link-for-app"
|
||||||
role="tab"
|
role="tab"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
@ -7209,7 +7209,7 @@ exports[`add custom helm repository in preferences when navigating to preference
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="Tab flex gaps align-center"
|
class="Tab flex gaps align-center"
|
||||||
data-testid="tab-link-for-application"
|
data-testid="tab-link-for-app"
|
||||||
role="tab"
|
role="tab"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
@ -7814,7 +7814,7 @@ exports[`add custom helm repository in preferences when navigating to preference
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="Tab flex gaps align-center"
|
class="Tab flex gaps align-center"
|
||||||
data-testid="tab-link-for-application"
|
data-testid="tab-link-for-app"
|
||||||
role="tab"
|
role="tab"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
|
|||||||
@ -219,7 +219,7 @@ const testPreferenceTabInjectable = getInjectable({
|
|||||||
kind: "tab" as const,
|
kind: "tab" as const,
|
||||||
id: "test-tab",
|
id: "test-tab",
|
||||||
pathId: "test-tab",
|
pathId: "test-tab",
|
||||||
parentId: "preference-tabs" as const,
|
parentId: "general-tab-group" as const,
|
||||||
testId: "some-test-id-for-test-tab",
|
testId: "some-test-id-for-test-tab",
|
||||||
label: "Test",
|
label: "Test",
|
||||||
orderNumber: 90,
|
orderNumber: 90,
|
||||||
|
|||||||
@ -11,10 +11,10 @@ const applicationPreferenceTabInjectable = getInjectable({
|
|||||||
instantiate: () => ({
|
instantiate: () => ({
|
||||||
kind: "tab" as const,
|
kind: "tab" as const,
|
||||||
id: "application-tab",
|
id: "application-tab",
|
||||||
parentId: "preference-tabs" as const,
|
parentId: "general-tab-group" as const,
|
||||||
pathId: "app",
|
pathId: "app",
|
||||||
testId: "application-preferences-page",
|
testId: "application-preferences-page",
|
||||||
label: "Application",
|
label: "App",
|
||||||
orderNumber: 10,
|
orderNumber: 10,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|||||||
@ -3,65 +3,39 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import { computedInjectManyInjectable } from "@ogre-tools/injectable-extension-for-mobx";
|
|
||||||
import { computed } from "mobx";
|
import { computed } from "mobx";
|
||||||
import type { PreferenceTab, PreferenceTypes } from "./preference-item-injection-token";
|
import type { PreferenceTab, PreferenceTypes } from "./preference-item-injection-token";
|
||||||
import { preferenceItemInjectionToken } from "./preference-item-injection-token";
|
|
||||||
import type { Composite } from "../../../application-menu/main/menu-items/get-composite/get-composite";
|
import type { Composite } from "../../../application-menu/main/menu-items/get-composite/get-composite";
|
||||||
import getComposite from "../../../application-menu/main/menu-items/get-composite/get-composite";
|
|
||||||
import routePathParametersInjectable from "../../../../renderer/routes/route-path-parameters.injectable";
|
import routePathParametersInjectable from "../../../../renderer/routes/route-path-parameters.injectable";
|
||||||
import preferencesRouteInjectable from "../../common/preferences-route.injectable";
|
import preferencesRouteInjectable from "../../common/preferences-route.injectable";
|
||||||
import { filter, find } from "lodash/fp";
|
import { filter, map } from "lodash/fp";
|
||||||
import { pipeline } from "@ogre-tools/fp";
|
import { pipeline } from "@ogre-tools/fp";
|
||||||
|
import { normalizeComposite } from "../../../application-menu/main/menu-items/get-composite/normalize-composite/normalize-composite";
|
||||||
interface PreferenceTabsRoot {
|
import { findExactlyOne } from "../../../../common/utils/find-exactly-one/find-exactly-one";
|
||||||
kind: "preference-tabs-root";
|
import type { PreferenceTabsRoot } from "./preferences-composite.injectable";
|
||||||
id: string;
|
import preferencesCompositeInjectable from "./preferences-composite.injectable";
|
||||||
parentId: undefined;
|
|
||||||
isShown: true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const preferenceTabRoot: PreferenceTabsRoot = {
|
|
||||||
kind: "preference-tabs-root" as const,
|
|
||||||
id: "preference-tabs",
|
|
||||||
parentId: undefined,
|
|
||||||
isShown: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
const currentPreferenceTabCompositeInjectable = getInjectable({
|
const currentPreferenceTabCompositeInjectable = getInjectable({
|
||||||
id: "current-preference-page-composite",
|
id: "current-preference-page-composite",
|
||||||
|
|
||||||
instantiate: (di) => {
|
instantiate: (di) => {
|
||||||
const computedInjectMany = di.inject(computedInjectManyInjectable);
|
|
||||||
const preferenceItems = computedInjectMany(preferenceItemInjectionToken);
|
|
||||||
const preferencesRoute = di.inject(preferencesRouteInjectable);
|
const preferencesRoute = di.inject(preferencesRouteInjectable);
|
||||||
const routePathParameters = di.inject(routePathParametersInjectable, preferencesRoute);
|
const routePathParameters = di.inject(routePathParametersInjectable, preferencesRoute);
|
||||||
|
const preferencesComposite = di.inject(preferencesCompositeInjectable);
|
||||||
|
|
||||||
return computed(() => {
|
return computed(() => {
|
||||||
const { preferenceTabId } = routePathParameters.get();
|
const { preferenceTabId } = routePathParameters.get();
|
||||||
|
|
||||||
const tabComposite = pipeline(
|
return pipeline(
|
||||||
[preferenceTabRoot, ...preferenceItems.get()],
|
normalizeComposite(preferencesComposite.get()),
|
||||||
filter(isShown),
|
map(([, composite]) => composite),
|
||||||
(items) => getComposite({ source: items }),
|
|
||||||
(rootComposite) => rootComposite.children,
|
|
||||||
filter(isPreferenceTab),
|
filter(isPreferenceTab),
|
||||||
find(hasMatchingPathId(preferenceTabId)),
|
findExactlyOne(hasMatchingPathId(preferenceTabId)),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!tabComposite) {
|
|
||||||
throw new Error(
|
|
||||||
`Tried to open preferences but no tab exists for ID "${preferenceTabId}"`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return tabComposite;
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const isShown = (item: PreferenceTypes) => item.isShown ?? true;
|
|
||||||
|
|
||||||
const isPreferenceTab = (composite: Composite<PreferenceTypes | PreferenceTabsRoot>): composite is Composite<PreferenceTab> =>
|
const isPreferenceTab = (composite: Composite<PreferenceTypes | PreferenceTabsRoot>): composite is Composite<PreferenceTab> =>
|
||||||
composite.value.kind === "tab";
|
composite.value.kind === "tab";
|
||||||
|
|
||||||
|
|||||||
@ -11,11 +11,11 @@ const editorPreferenceTabInjectable = getInjectable({
|
|||||||
instantiate: () => ({
|
instantiate: () => ({
|
||||||
kind: "tab" as const,
|
kind: "tab" as const,
|
||||||
id: "editor-tab",
|
id: "editor-tab",
|
||||||
parentId: "preference-tabs" as const,
|
parentId: "general-tab-group" as const,
|
||||||
pathId: "editor",
|
pathId: "editor",
|
||||||
testId: "editor-preferences-page",
|
testId: "editor-preferences-page",
|
||||||
label: "Editor",
|
label: "Editor",
|
||||||
orderNumber: 30,
|
orderNumber: 40,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
injectionToken: preferenceItemInjectionToken,
|
injectionToken: preferenceItemInjectionToken,
|
||||||
|
|||||||
@ -0,0 +1,22 @@
|
|||||||
|
/**
|
||||||
|
* 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 { preferenceItemInjectionToken } from "./preference-item-injection-token";
|
||||||
|
|
||||||
|
const generalPreferenceTabGroupInjectable = getInjectable({
|
||||||
|
id: "general-preference-tab-group",
|
||||||
|
|
||||||
|
instantiate: () => ({
|
||||||
|
kind: "tab-group" as const,
|
||||||
|
id: "general-tab-group",
|
||||||
|
parentId: "preference-tabs" as const,
|
||||||
|
label: "Preferences",
|
||||||
|
orderNumber: 10,
|
||||||
|
}),
|
||||||
|
|
||||||
|
injectionToken: preferenceItemInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default generalPreferenceTabGroupInjectable;
|
||||||
@ -11,11 +11,11 @@ const kubernetesPreferenceTabInjectable = getInjectable({
|
|||||||
instantiate: () => ({
|
instantiate: () => ({
|
||||||
kind: "tab" as const,
|
kind: "tab" as const,
|
||||||
id: "kubernetes-tab",
|
id: "kubernetes-tab",
|
||||||
parentId: "preference-tabs" as const,
|
parentId: "general-tab-group" as const,
|
||||||
pathId: "kubernetes",
|
pathId: "kubernetes",
|
||||||
testId: "kubernetes-preferences-page",
|
testId: "kubernetes-preferences-page",
|
||||||
label: "Kubernetes",
|
label: "Kubernetes",
|
||||||
orderNumber: 10,
|
orderNumber: 30,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
injectionToken: preferenceItemInjectionToken,
|
injectionToken: preferenceItemInjectionToken,
|
||||||
|
|||||||
@ -10,7 +10,7 @@ export type PreferenceItemComponent = React.ComponentType<{ children: React.Reac
|
|||||||
export interface PreferenceTab {
|
export interface PreferenceTab {
|
||||||
kind: "tab";
|
kind: "tab";
|
||||||
id: string;
|
id: string;
|
||||||
parentId: "preference-tabs";
|
parentId: string;
|
||||||
pathId: string;
|
pathId: string;
|
||||||
testId: string;
|
testId: string;
|
||||||
label: string;
|
label: string;
|
||||||
@ -18,6 +18,15 @@ export interface PreferenceTab {
|
|||||||
isShown?: boolean;
|
isShown?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface PreferenceTabGroup {
|
||||||
|
kind: "tab-group";
|
||||||
|
id: string;
|
||||||
|
parentId: "preference-tabs";
|
||||||
|
label: string;
|
||||||
|
orderNumber: number;
|
||||||
|
isShown?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
export interface PreferencePage {
|
export interface PreferencePage {
|
||||||
kind: "page";
|
kind: "page";
|
||||||
id: string;
|
id: string;
|
||||||
@ -45,7 +54,7 @@ export interface PreferenceItem {
|
|||||||
childrenSeparator?: () => React.ReactElement;
|
childrenSeparator?: () => React.ReactElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PreferenceTypes = PreferenceTab | PreferenceItem | PreferencePage | PreferenceGroup;
|
export type PreferenceTypes = PreferenceTabGroup | PreferenceTab | PreferenceItem | PreferencePage | PreferenceGroup;
|
||||||
|
|
||||||
export const preferenceItemInjectionToken = getInjectionToken<PreferenceTypes>({
|
export const preferenceItemInjectionToken = getInjectionToken<PreferenceTypes>({
|
||||||
id: "preference-item-injection-token",
|
id: "preference-item-injection-token",
|
||||||
|
|||||||
@ -0,0 +1,47 @@
|
|||||||
|
/**
|
||||||
|
* 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 { computedInjectManyInjectable } from "@ogre-tools/injectable-extension-for-mobx";
|
||||||
|
import { computed } from "mobx";
|
||||||
|
import type { PreferenceTypes } from "./preference-item-injection-token";
|
||||||
|
import { preferenceItemInjectionToken } from "./preference-item-injection-token";
|
||||||
|
import getComposite from "../../../application-menu/main/menu-items/get-composite/get-composite";
|
||||||
|
import { filter } from "lodash/fp";
|
||||||
|
import { pipeline } from "@ogre-tools/fp";
|
||||||
|
|
||||||
|
export interface PreferenceTabsRoot {
|
||||||
|
kind: "preference-tabs-root";
|
||||||
|
id: string;
|
||||||
|
parentId: undefined;
|
||||||
|
isShown: true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const preferenceTabsRoot: PreferenceTabsRoot = {
|
||||||
|
kind: "preference-tabs-root" as const,
|
||||||
|
id: "preference-tabs",
|
||||||
|
parentId: undefined,
|
||||||
|
isShown: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
const preferencesCompositeInjectable = getInjectable({
|
||||||
|
id: "preferences-composite",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const computedInjectMany = di.inject(computedInjectManyInjectable);
|
||||||
|
const preferenceItems = computedInjectMany(preferenceItemInjectionToken);
|
||||||
|
|
||||||
|
return computed(() =>
|
||||||
|
pipeline(
|
||||||
|
[preferenceTabsRoot, ...preferenceItems.get()],
|
||||||
|
filter(isShown),
|
||||||
|
(items) => getComposite({ source: items }),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const isShown = (item: PreferenceTypes) => item.isShown ?? true;
|
||||||
|
|
||||||
|
export default preferencesCompositeInjectable;
|
||||||
@ -11,7 +11,7 @@ const proxyPreferenceTabInjectable = getInjectable({
|
|||||||
instantiate: () => ({
|
instantiate: () => ({
|
||||||
kind: "tab" as const,
|
kind: "tab" as const,
|
||||||
id: "proxy-tab",
|
id: "proxy-tab",
|
||||||
parentId: "preference-tabs" as const,
|
parentId: "general-tab-group" as const,
|
||||||
pathId: "proxy",
|
pathId: "proxy",
|
||||||
testId: "proxy-preferences-page",
|
testId: "proxy-preferences-page",
|
||||||
label: "Proxy",
|
label: "Proxy",
|
||||||
|
|||||||
@ -6,18 +6,24 @@ import { getInjectable } from "@ogre-tools/injectable";
|
|||||||
import { preferenceItemInjectionToken } from "../preference-item-injection-token";
|
import { preferenceItemInjectionToken } from "../preference-item-injection-token";
|
||||||
import { TelemetryPage } from "./telemetry-page";
|
import { TelemetryPage } from "./telemetry-page";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
import sentryDataSourceNameInjectable from "../../../../../common/vars/sentry-dsn-url.injectable";
|
||||||
|
|
||||||
const telemetryPreferencePageInjectable = getInjectable({
|
const telemetryPreferencePageInjectable = getInjectable({
|
||||||
id: "telemetry-preference-page",
|
id: "telemetry-preference-page",
|
||||||
|
|
||||||
instantiate: () => ({
|
instantiate: (di) => {
|
||||||
|
const sentryDnsUrl = di.inject(sentryDataSourceNameInjectable);
|
||||||
|
|
||||||
|
return {
|
||||||
kind: "page" as const,
|
kind: "page" as const,
|
||||||
id: "telemetry-page",
|
id: "telemetry-page",
|
||||||
parentId: "telemetry-tab",
|
parentId: "telemetry-tab",
|
||||||
orderNumber: 0,
|
orderNumber: 0,
|
||||||
Component: TelemetryPage,
|
Component: TelemetryPage,
|
||||||
childrenSeparator: () => <hr className="small" />,
|
childrenSeparator: () => <hr className="small" />,
|
||||||
}),
|
isShown: !!sentryDnsUrl,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
injectionToken: preferenceItemInjectionToken,
|
injectionToken: preferenceItemInjectionToken,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -4,19 +4,25 @@
|
|||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import { preferenceItemInjectionToken } from "../preference-item-injection-token";
|
import { preferenceItemInjectionToken } from "../preference-item-injection-token";
|
||||||
|
import sentryDataSourceNameInjectable from "../../../../../common/vars/sentry-dsn-url.injectable";
|
||||||
|
|
||||||
const telemetryPreferenceTabInjectable = getInjectable({
|
const telemetryPreferenceTabInjectable = getInjectable({
|
||||||
id: "telemetry-preference-tab",
|
id: "telemetry-preference-tab",
|
||||||
|
|
||||||
instantiate: () => ({
|
instantiate: (di) => {
|
||||||
|
const sentryDnsUrl = di.inject(sentryDataSourceNameInjectable);
|
||||||
|
|
||||||
|
return {
|
||||||
kind: "tab" as const,
|
kind: "tab" as const,
|
||||||
id: "telemetry-tab",
|
id: "telemetry-tab",
|
||||||
parentId: "preference-tabs" as const,
|
parentId: "general-tab-group" as const,
|
||||||
pathId: "telemetry",
|
pathId: "telemetry",
|
||||||
testId: "terminal-preferences-page",
|
testId: "terminal-preferences-page",
|
||||||
label: "Telemetry",
|
label: "Telemetry",
|
||||||
orderNumber: 20,
|
orderNumber: 60,
|
||||||
}),
|
isShown: !!sentryDnsUrl,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
injectionToken: preferenceItemInjectionToken,
|
injectionToken: preferenceItemInjectionToken,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -12,10 +12,10 @@ const terminalPreferenceTabInjectable = getInjectable({
|
|||||||
kind: "tab" as const,
|
kind: "tab" as const,
|
||||||
id: "terminal-tab",
|
id: "terminal-tab",
|
||||||
pathId: "terminal",
|
pathId: "terminal",
|
||||||
parentId: "preference-tabs" as const,
|
parentId: "general-tab-group" as const,
|
||||||
testId: "terminal-preferences-page",
|
testId: "terminal-preferences-page",
|
||||||
label: "Terminal",
|
label: "Terminal",
|
||||||
orderNumber: 20,
|
orderNumber: 50,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
injectionToken: preferenceItemInjectionToken,
|
injectionToken: preferenceItemInjectionToken,
|
||||||
|
|||||||
@ -0,0 +1,42 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { Tab } from "../../../../renderer/components/tabs";
|
||||||
|
import navigateToPreferenceTabInjectable from "../../../../renderer/components/+preferences/preferences-navigation/navigate-to-preference-tab/navigate-to-preference-tab.injectable";
|
||||||
|
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||||
|
import { observer } from "mobx-react";
|
||||||
|
import type { PreferenceTab } from "../preference-items/preference-item-injection-token";
|
||||||
|
import type { IComputedValue } from "mobx";
|
||||||
|
import preferenceTabIsActiveInjectable from "../../../../renderer/components/+preferences/preferences-navigation/navigate-to-preference-tab/preference-tab-is-active.injectable";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
interface Dependencies {
|
||||||
|
navigateToTab: (tabId: string) => void;
|
||||||
|
tabIsActive: IComputedValue<boolean>;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PreferenceNavigationTabProps {
|
||||||
|
tab: PreferenceTab;
|
||||||
|
}
|
||||||
|
|
||||||
|
const NonInjectedPreferencesNavigationTab = observer(({ navigateToTab, tabIsActive, tab } : Dependencies & PreferenceNavigationTabProps) => (
|
||||||
|
<Tab
|
||||||
|
onClick={() => navigateToTab(tab.pathId)}
|
||||||
|
data-testid={`tab-link-for-${tab.pathId}`}
|
||||||
|
active={tabIsActive.get()}
|
||||||
|
label={tab.label}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
|
||||||
|
export const PreferencesNavigationTab = withInjectables<Dependencies, PreferenceNavigationTabProps>(
|
||||||
|
NonInjectedPreferencesNavigationTab,
|
||||||
|
|
||||||
|
{
|
||||||
|
getProps: (di, props) => ({
|
||||||
|
navigateToTab: di.inject(navigateToPreferenceTabInjectable),
|
||||||
|
tabIsActive: di.inject(preferenceTabIsActiveInjectable, props.tab.pathId),
|
||||||
|
...props,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
);
|
||||||
@ -0,0 +1,78 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { Tabs } from "../../../../renderer/components/tabs";
|
||||||
|
import React from "react";
|
||||||
|
import type { Composite } from "../../../application-menu/main/menu-items/get-composite/get-composite";
|
||||||
|
import type { PreferenceTypes } from "../preference-items/preference-item-injection-token";
|
||||||
|
import { Map } from "../../../../renderer/components/map/map";
|
||||||
|
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||||
|
import type { IComputedValue } from "mobx";
|
||||||
|
import preferencesCompositeInjectable from "../preference-items/preferences-composite.injectable";
|
||||||
|
import { observer } from "mobx-react";
|
||||||
|
import { PreferencesNavigationTab } from "./preferences-navigation-tab";
|
||||||
|
|
||||||
|
interface Dependencies {
|
||||||
|
composite: IComputedValue<Composite<PreferenceTypes>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const NonInjectedPreferencesNavigation = observer(({ composite }: Dependencies) => (
|
||||||
|
<Tabs className="flex column" scrollable={false}>
|
||||||
|
<Map items={composite.get().children}>{toNavigationHierarchy}</Map>
|
||||||
|
</Tabs>
|
||||||
|
));
|
||||||
|
|
||||||
|
export const PreferencesNavigation = withInjectables<Dependencies>(
|
||||||
|
NonInjectedPreferencesNavigation,
|
||||||
|
|
||||||
|
{
|
||||||
|
getProps: (di) => ({
|
||||||
|
composite: di.inject(preferencesCompositeInjectable),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
const toNavigationHierarchy = (composite: Composite<PreferenceTypes>) => {
|
||||||
|
const value = composite.value;
|
||||||
|
|
||||||
|
switch (value.kind) {
|
||||||
|
case "page":
|
||||||
|
case "item":
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-fallthrough
|
||||||
|
case "group": {
|
||||||
|
throw new Error("Should never come here");
|
||||||
|
}
|
||||||
|
|
||||||
|
case "tab-group": {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="header">{value.label}</div>
|
||||||
|
|
||||||
|
<Map items={composite.children}>{toNavigationHierarchy}</Map>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
case "tab": {
|
||||||
|
return (
|
||||||
|
<PreferencesNavigationTab tab={value} />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
default: {
|
||||||
|
// Note: this will fail at transpilation time, if all kinds
|
||||||
|
// are not handled in switch/case.
|
||||||
|
const _exhaustiveCheck: never = value;
|
||||||
|
|
||||||
|
// Note: this code is unreachable, it is here to make ts not complain about
|
||||||
|
// _exhaustiveCheck not being used.
|
||||||
|
// See: https://www.typescriptlang.org/docs/handbook/2/narrowing.html#exhaustiveness-checking
|
||||||
|
throw new Error(
|
||||||
|
`Tried to create preference navigation, but foreign item was encountered: ${_exhaustiveCheck} ${composite.value}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -6,7 +6,6 @@ import "../../../renderer/components/+preferences/preferences.scss";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import { SettingLayout } from "../../../renderer/components/layout/setting-layout";
|
import { SettingLayout } from "../../../renderer/components/layout/setting-layout";
|
||||||
import { PreferencesNavigation } from "../../../renderer/components/+preferences/preferences-navigation/preferences-navigation";
|
|
||||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||||
import closePreferencesInjectable from "../../../renderer/components/+preferences/close-preferences.injectable";
|
import closePreferencesInjectable from "../../../renderer/components/+preferences/close-preferences.injectable";
|
||||||
import currentPreferenceTabCompositeInjectable from "./preference-items/current-preference-tab-composite.injectable";
|
import currentPreferenceTabCompositeInjectable from "./preference-items/current-preference-tab-composite.injectable";
|
||||||
@ -15,6 +14,7 @@ import type { PreferenceTypes, PreferenceTab } from "./preference-items/preferen
|
|||||||
import type { IComputedValue } from "mobx";
|
import type { IComputedValue } from "mobx";
|
||||||
import { Map } from "../../../renderer/components/map/map";
|
import { Map } from "../../../renderer/components/map/map";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
|
import { PreferencesNavigation } from "./preference-navigation/preferences-navigation";
|
||||||
|
|
||||||
interface Dependencies {
|
interface Dependencies {
|
||||||
closePreferences: () => void;
|
closePreferences: () => void;
|
||||||
@ -69,6 +69,9 @@ const toPreferenceItemHierarchy = (composite: Composite<PreferenceTypes>) => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case "tab-group":
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-fallthrough
|
||||||
case "tab": {
|
case "tab": {
|
||||||
return (
|
return (
|
||||||
<Map items={composite.children}>
|
<Map items={composite.children}>
|
||||||
@ -78,7 +81,7 @@ const toPreferenceItemHierarchy = (composite: Composite<PreferenceTypes>) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
// Note: this will fail at transpilation time, if all ApplicationMenuItemTypes
|
// Note: this will fail at transpilation time, if all kinds
|
||||||
// are not handled in switch/case.
|
// are not handled in switch/case.
|
||||||
const _exhaustiveCheck: never = composite.value;
|
const _exhaustiveCheck: never = composite.value;
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user