/**
 * Copyright (c) OpenLens Maintainers. All rights reserved.
 * Licensed under MIT License. See LICENSE in root directory for more information.
 */
/// <reference types="react" />
import type TypedEmitter from "typed-emitter";
import type { Disposer, StrictReactNode } from "@openlens/utilities";
import type { CategoryColumnRegistration, TitleCellProps } from "../../renderer/components/catalog/custom-category-columns";
export type { CategoryColumnRegistration, TitleCellProps };
export type CatalogEntityDataFor<Entity> = Entity extends CatalogEntity<infer Metadata, infer Status, infer Spec> ? CatalogEntityData<Metadata, Status, Spec> : never;
export type CatalogEntityInstanceFrom<Constructor> = Constructor extends CatalogEntityConstructor<infer Entity> ? Entity : never;
export type CatalogEntityConstructor<Entity extends CatalogEntity> = (new (data: CatalogEntityDataFor<Entity>) => Entity);
export interface CatalogCategoryVersion {
    /**
     * The specific version that the associated constructor is for. This MUST be
     * a DNS label and SHOULD be of the form `vN`, `vNalphaY`, or `vNbetaY` where
     * `N` and `Y` are both integers greater than 0.
     *
     * Examples: The following are valid values for this field.
     * - `v1`
     * - `v1beta1`
     * - `v1alpha2`
     * - `v3beta2`
     */
    readonly name: string;
    /**
     * The constructor for the entities.
     */
    readonly entityClass: CatalogEntityConstructor<CatalogEntity>;
}
export interface CatalogCategorySpec {
    /**
     * The grouping for for the category. This MUST be a DNS label.
     */
    readonly group: string;
    /**
     * The specific versions of the constructors.
     *
     * NOTE: the field `.apiVersion` after construction MUST match `{.group}/{.versions.[] | .name}`.
     * For example, if `group = "entity.k8slens.dev"` and there is an entry in `.versions` with
     * `name = "v1alpha1"` then the resulting `.apiVersion` MUST be `entity.k8slens.dev/v1alpha1`
     */
    readonly versions: CatalogCategoryVersion[];
    /**
     * This is the concerning the category
     */
    readonly names: {
        /**
         * The kind of entity that this category is for. This value MUST be a DNS
         * label and MUST be equal to the `kind` fields that are produced by the
         * `.versions.[] | .entityClass` fields.
         */
        readonly kind: string;
    };
    /**
     * These are the columns used for displaying entities when in the catalog.
     *
     * If this is not provided then some default columns will be used, similar in
     * scope to the columns in the "Browse" view.
     *
     * Even if you provide columns, a "Name" column will be provided as well with
     * `priority: 0`.
     *
     * These columns will not be used in the "Browse" view.
     */
    readonly displayColumns?: CategoryColumnRegistration[];
}
/**
 * If the filter return a thruthy value, the menu item is displayed
 */
export type AddMenuFilter = (menu: CatalogEntityAddMenu) => any;
export interface CatalogCategoryEvents {
    /**
     * This event will be emitted when the category is loaded in the catalog
     * view.
     */
    load: () => void;
    /**
     * This event will be emitted when the catalog add menu is opened and is the
     * way to added entries to that menu.
     */
    catalogAddMenu: (context: CatalogEntityAddMenuContext) => void;
    /**
     * This event will be emitted when the context menu for an entity is declared
     * by this category is opened.
     */
    contextMenuOpen: (entity: CatalogEntity, context: CatalogEntityContextMenuContext) => void;
}
export interface CatalogCategoryMetadata {
    /**
     * The name of your category. The category can be searched for by this
     * value. This will also be used for the catalog menu.
     */
    readonly name: string;
    /**
     * Either an `<svg>` or one of the provided svg names from {@link Renderer.Component.NamedSvg}
     */
    readonly icon: string;
}
export declare function categoryVersion<T extends CatalogEntity<Metadata, Status, Spec>, Metadata extends CatalogEntityMetadata, Status extends CatalogEntityStatus, Spec extends CatalogEntitySpec>(name: string, entityClass: new (data: CatalogEntityData<Metadata, Status, Spec>) => T): CatalogCategoryVersion;
declare const CatalogCategory_base: new () => TypedEmitter<CatalogCategoryEvents>;
export declare abstract class CatalogCategory extends CatalogCategory_base {
    /**
     * The version of category that you are wanting to declare.
     *
     * Currently supported values:
     *
     * - `"catalog.k8slens.dev/v1alpha1"`
     */
    abstract readonly apiVersion: string;
    /**
     * The kind of item you wish to declare.
     *
     * Currently supported values:
     *
     * - `"CatalogCategory"`
     */
    abstract readonly kind: string;
    /**
     * The data about the category itself
     */
    abstract readonly metadata: CatalogCategoryMetadata;
    /**
     * The most important part of a category, as it is where entity versions are declared.
     */
    abstract readonly spec: CatalogCategorySpec;
    /**
     * @internal
     */
    protected readonly filters: import("mobx").ObservableSet<AddMenuFilter>;
    /**
     * Parse a category ID into parts.
     * @param id The id of a category is parse
     * @returns The group and kind parts of the ID
     */
    static parseId(id: string): {
        group?: string;
        kind?: string;
    };
    /**
     * Get the ID of this category
     */
    getId(): string;
    /**
     * Get the name of this category
     */
    getName(): string;
    /**
     * Get the badge of this category.
     * Defaults to no badge.
     * The badge is displayed next to the Category name in the Catalog Category menu
     */
    getBadge(): StrictReactNode;
    /**
     * Add a filter for menu items of catalogAddMenu
     * @param fn The function that should return a truthy value if that menu item should be displayed
     * @returns A function to remove that filter
     */
    addMenuFilter(fn: AddMenuFilter): Disposer;
    /**
     * Filter menuItems according to the Category's set filters
     * @param menuItems menu items to filter
     * @returns filtered menu items
     */
    filteredItems(menuItems: CatalogEntityAddMenu[]): CatalogEntityAddMenu[];
}
export type EntityMetadataObject = {
    [Key in string]?: EntityMetadataValue;
};
export type EntityMetadataValue = string | number | boolean | EntityMetadataObject | undefined;
export interface CatalogEntityMetadata extends EntityMetadataObject {
    uid: string;
    name: string;
    shortName?: string;
    description?: string;
    source?: string;
    labels: Partial<Record<string, string>>;
}
export interface CatalogEntityStatus {
    phase: string;
    reason?: string;
    /**
     * @default true
     */
    enabled?: boolean;
    message?: string;
    active?: boolean;
}
export interface CatalogEntityActionContext {
    navigate: (url: string) => void;
    setCommandPaletteContext: (context?: CatalogEntity) => void;
}
export interface CatalogEntityContextMenu {
    /**
     * Menu title
     */
    title: string;
    /**
     * Menu icon
     */
    icon?: string;
    /**
     * OnClick handler
     */
    onClick: () => void | Promise<void>;
    /**
     * Confirm click with a message
     */
    confirm?: {
        message: string;
    };
}
export interface CatalogEntityAddMenu extends CatalogEntityContextMenu {
    icon: string;
    defaultAction?: boolean;
}
export interface CatalogEntitySettingsMenu {
    group?: string;
    title: string;
    components: {
        View: React.ComponentType<any>;
    };
}
export interface CatalogEntityContextMenuNavigate {
    /**
     * @param pathname The location to navigate to in the main iframe
     */
    (pathname: string, forceMainFrame?: boolean): void;
    /**
     * @param pathname The location to navigate to in the current iframe. Useful for when called within the cluster frame
     */
    (pathname: string, forceMainFrame: false): void;
}
export interface CatalogEntityContextMenuContext {
    /**
     * Navigate to the specified pathname
     */
    navigate: CatalogEntityContextMenuNavigate;
    menuItems: CatalogEntityContextMenu[];
}
export interface CatalogEntitySettingsContext {
    menuItems: CatalogEntityContextMenu[];
}
export interface CatalogEntityAddMenuContext {
    navigate: (url: string) => void;
    menuItems: CatalogEntityAddMenu[];
}
export type CatalogEntitySpec = Record<string, any>;
export interface CatalogEntityData<Metadata extends CatalogEntityMetadata = CatalogEntityMetadata, Status extends CatalogEntityStatus = CatalogEntityStatus, Spec extends CatalogEntitySpec = CatalogEntitySpec> {
    metadata: Metadata;
    status: Status;
    spec: Spec;
}
export interface CatalogEntityKindData {
    readonly apiVersion: string;
    readonly kind: string;
}
export declare abstract class CatalogEntity<Metadata extends CatalogEntityMetadata = CatalogEntityMetadata, Status extends CatalogEntityStatus = CatalogEntityStatus, Spec extends CatalogEntitySpec = CatalogEntitySpec> implements CatalogEntityKindData {
    /**
     * The group and version of this class.
     */
    abstract readonly apiVersion: string;
    /**
     * A DNS label name of the entity.
     */
    abstract readonly kind: string;
    metadata: Metadata;
    status: Status;
    spec: Spec;
    constructor({ metadata, status, spec }: CatalogEntityData<Metadata, Status, Spec>);
    /**
     * Get the UID of this entity
     */
    getId(): string;
    /**
     * Get the name of this entity
     */
    getName(): string;
    /**
     * Get the specified source of this entity, defaulting to `"unknown"` if not
     * provided
     */
    getSource(): string;
    /**
     * Get if this entity is enabled.
     */
    isEnabled(): boolean;
    onRun?(context: CatalogEntityActionContext): void | Promise<void>;
    onContextMenuOpen?(context: CatalogEntityContextMenuContext): void | Promise<void>;
    onSettingsOpen?(context: CatalogEntitySettingsContext): void | Promise<void>;
}
