1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00
lens/src/features/preferences/renderer/preference-navigation/preferences-navigation.tsx
Janne Savolainen 1a5073caad
Remove duplication from exhaustiveness checks for discriminating unions
Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
2022-10-21 08:23:25 +03:00

104 lines
3.3 KiB
TypeScript

/**
* 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 "../../../../common/utils/composite/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";
import { compositeHasDescendant } from "../../../../common/utils/composite/composite-has-descendant/composite-has-descendant";
import type { PreferenceTabsRoot } from "../preference-items/preference-tab-root";
import { Icon } from "../../../../renderer/components/icon";
import { checkThatAllDiscriminablesAreExhausted } from "../../../../common/utils/composable-responsibilities/discriminable/discriminable";
interface Dependencies {
composite: IComputedValue<Composite<PreferenceTypes | PreferenceTabsRoot>>;
}
const NonInjectedPreferencesNavigation = observer(({ composite }: Dependencies) => (
<Tabs className="flex column" scrollable={false}>
{toNavigationHierarchy(composite.get())}
</Tabs>
));
export const PreferencesNavigation = withInjectables<Dependencies>(
NonInjectedPreferencesNavigation,
{
getProps: (di) => ({
composite: di.inject(preferencesCompositeInjectable),
}),
},
);
const toNavigationHierarchy = (composite: Composite<PreferenceTypes | PreferenceTabsRoot>) => {
// Note: This makes tab groups and tabs without content not render anything in navigation.
if (!hasContent(composite)) {
return emptyRender;
}
const value = composite.value;
switch (value.kind) {
// Note: These preference item types are not rendered in navigation,
// yet they are interesting for deciding if eg. a tab group or a tab has content
// somewhere in structure, and therefore not be hidden.
case "page": {
return emptyRender;
}
case "block": {
return emptyRender;
}
case "tab-group": {
return (
<div data-preference-tab-group-test={value.id}>
<div className="header flex items-center">
{value.iconName && (
<Icon
material={value.iconName}
smallest
className="mr-3"
/>
)}
{value.label}
</div>
<Map items={composite.children}>{toNavigationHierarchy}</Map>
</div>
);
}
case "tab": {
return <PreferencesNavigationTab tab={value} />;
}
case "preference-tabs-root": {
return (
<Map items={composite.children} getSeparator={value.childSeparator}>
{toNavigationHierarchy}
</Map>
);
}
default: {
throw checkThatAllDiscriminablesAreExhausted(value);
}
}
};
const hasContent = compositeHasDescendant<PreferenceTypes | PreferenceTabsRoot>(
(composite) => composite.value.kind === "block",
);
const emptyRender = <></>;