/** * Copyright (c) OpenLens Authors. All rights reserved. * Licensed under MIT License. See LICENSE in root directory for more information. */ import styles from "./installed-extensions.module.scss"; import React, { useMemo } from "react"; import type { ExtensionDiscovery, InstalledExtension, } from "../../../extensions/extension-discovery/extension-discovery"; import { Icon } from "../icon"; import { List } from "../list/list"; import { MenuActions, MenuItem } from "../menu"; import { Spinner } from "../spinner"; import { cssNames } from "../../utils"; import { observer } from "mobx-react"; import type { Row } from "react-table"; import type { LensExtensionId } from "../../../extensions/lens-extension"; import extensionDiscoveryInjectable from "../../../extensions/extension-discovery/extension-discovery.injectable"; import { withInjectables } from "@ogre-tools/injectable-react"; import extensionInstallationStateStoreInjectable from "../../../extensions/extension-installation-state-store/extension-installation-state-store.injectable"; import type { ExtensionInstallationStateStore } from "../../../extensions/extension-installation-state-store/extension-installation-state-store"; interface Props { extensions: InstalledExtension[]; enable: (id: LensExtensionId) => void; disable: (id: LensExtensionId) => void; uninstall: (extension: InstalledExtension) => void; } interface Dependencies { extensionDiscovery: ExtensionDiscovery; extensionInstallationStateStore: ExtensionInstallationStateStore; } function getStatus(extension: InstalledExtension) { if (!extension.isCompatible) { return "Incompatible"; } return extension.isEnabled ? "Enabled" : "Disabled"; } const NonInjectedInstalledExtensions : React.FC = (({ extensionDiscovery, extensionInstallationStateStore, extensions, uninstall, enable, disable }) => { const filters = [ (extension: InstalledExtension) => extension.manifest.name, (extension: InstalledExtension) => getStatus(extension), (extension: InstalledExtension) => extension.manifest.version, ]; const columns = useMemo( () => [ { Header: "Name", accessor: "extension", width: 200, sortType: (rowA: Row, rowB: Row) => { // Custom sorting for extension name const nameA = extensions[rowA.index].manifest.name; const nameB = extensions[rowB.index].manifest.name; if (nameA > nameB) return -1; if (nameB > nameA) return 1; return 0; }, }, { Header: "Version", accessor: "version", }, { Header: "Status", accessor: "status", }, { Header: "", accessor: "actions", disableSortBy: true, width: 20, className: "actions", }, ], [], ); const data = useMemo( () => { return extensions.map(extension => { const { id, isEnabled, isCompatible, manifest } = extension; const { name, description, version } = manifest; const isUninstalling = extensionInstallationStateStore.isExtensionUninstalling(id); return { extension: (
{name}
{description}
), version, status: (
{getStatus(extension)}
), actions: ( { isCompatible && ( <> {isEnabled ? ( disable(id)} > Disable ) : ( enable(id)} > Enable )} )} uninstall(extension)} > Uninstall ), }; }); }, [extensions, extensionInstallationStateStore.anyUninstalling], ); if (!extensionDiscovery.isLoaded) { return
; } if (extensions.length == 0) { return (

There are no extensions installed.

Please use the form above to install or drag tarbar-file here.

); } return (
Installed extensions} columns={columns} data={data} items={extensions} filters={filters} />
); }); export const InstalledExtensions = withInjectables( observer(NonInjectedInstalledExtensions), { getProps: (di, props) => ({ extensionDiscovery: di.inject(extensionDiscoveryInjectable), extensionInstallationStateStore: di.inject(extensionInstallationStateStoreInjectable), ...props, }), }, );