/** * Copyright (c) OpenLens Authors. All rights reserved. * Licensed under MIT License. See LICENSE in root directory for more information. */ import "./crd-list.scss"; import React from "react"; import { computed, makeObservable, observable } from "mobx"; import { observer } from "mobx-react"; import { Link } from "react-router-dom"; import { iter, stopPropagation } from "../../utils"; import { KubeObjectListLayout } from "../kube-object-list-layout"; import { customResourceDefinitionStore } from "./legacy-store"; import { Select } from "../select"; import { Icon } from "../icon"; import { KubeObjectAge } from "../kube-object/age"; import { TabLayout } from "../layout/tab-layout-2"; import type { PageParam } from "../../navigation"; import type { CustomResourceDefinitionStore } from "./definition.store"; import { withInjectables } from "@ogre-tools/injectable-react"; import crdGroupsUrlParamInjectable from "./crd-groups-url-param.injectable"; import customResourceDefinitionStoreInjectable from "./definition.store.injectable"; enum columnId { kind = "kind", group = "group", version = "version", scope = "scope", age = "age", } interface Dependencies { crdGroupsUrlParam: PageParam; customResourceDefinitionStore: CustomResourceDefinitionStore; } @observer class NonInjectedCustomResourceDefinitions extends React.Component { private readonly selectedGroups = observable.set(this.props.crdGroupsUrlParam.get()); constructor(props: Dependencies) { super(props); makeObservable(this); } @computed get items() { if (this.selectedGroups.size) { return this.props.customResourceDefinitionStore.items.filter(item => this.selectedGroups.has(item.getGroup())); } return this.props.customResourceDefinitionStore.items; // show all by default } @computed get groupSelectOptions() { return Object.keys(this.props.customResourceDefinitionStore.groups) .map(group => ({ value: group, label: group, isSelected: this.selectedGroups.has(group), })); } toggleSelection = (options: readonly ({ value: string })[]) => { const groups = options.map(({ value }) => value); this.selectedGroups.replace(groups); this.props.crdGroupsUrlParam.set(groups); }; private getPlaceholder() { if (this.selectedGroups.size === 0) { return "All groups"; } const prefix = this.selectedGroups.size === 1 ? "Group" : "Groups"; return `${prefix}: ${iter.join(this.selectedGroups, ", ")}`; } render() { return ( already has and is always mounted subscribeStores={false} items={this.items} sortingCallbacks={{ [columnId.kind]: crd => crd.getResourceKind(), [columnId.group]: crd => crd.getGroup(), [columnId.version]: crd => crd.getVersion(), [columnId.scope]: crd => crd.getScope(), [columnId.age]: crd => -crd.getCreationTimestamp(), }} searchFilters={[ crd => crd.getResourceKind(), crd => crd.getGroup(), crd => crd.getVersion(), crd => crd.getScope(), crd => -crd.getCreationTimestamp(), ]} renderHeaderTitle="Custom Resources" customizeHeader={({ filters, ...headerPlaceholders }) => ({ // todo: move to global filters filters: ( <> {filters}