import { InjectionToken, Injector, Type } from '@angular/core';
import { Observable } from 'rxjs';
import { ExtensionFactory, GenericHookType, GenericHookOptions } from '../common/extension-hooks';
import { DynamicComponentAlertAggregator } from './dynamic-component-alert-aggregator';
import { DynamicDetailsResolver } from './dynamic-details-resolver';
/**
 * Time the hook waits until it emits an undefined value.
 * Used for not defined widgets -> by default after 5s we
 * show an error that the widget could not be loaded.
 */
export declare const RESOLVING_COMPONENT_WAIT_TIME: InjectionToken<number>;
/**
 * An extension HOOK can use either a pure value:
 * ```typescript
 *  { provide: HOOK_X, useValue: { ...hookValue }, multi: true }
 * ```
 *
 * Or an array to directly register multiple:
 * ```typescript
 *  { provide: HOOK_X, useValue: [{ ...hookValues }], multi: true }
 * ```
 *
 * Or an ExtensionFactory which allows to define a get() function. This function
 * gets called on each navigation with the current route and can return values
 * async (observable or promise).
 * ```typescript
 *  { provide: HOOK_X, useFactory: { get: (route) => doSomethingAsync(route) }, multi: true }
 * ```
 */
export type DynamicComponentExtension = DynamicComponentDefinition | DynamicComponentDefinition[] | ExtensionFactory<DynamicComponentDefinition>;
/**
 * A hook to add dynamic components to the UI (e.g. widgets).
 * @deprecated Consider using the `hookComponent` function instead.
 */
export declare const HOOK_COMPONENTS: InjectionToken<DynamicComponentExtension[]>;
/**
 * A hook to add dynamic components to the UI (e.g. widgets).
 *
 * You can either provide a single `DynamicComponentDefinition` as parameter:
 * ```typescript
 *  hookComponent(...)
 * ```
 *
 * Or an array to directly register multiple:
 * ```typescript
 *  hookComponent([...])
 * ```
 *
 * Or you provide an Service that implements `ExtensionFactory<DynamicComponentDefinition>`
 * ```typescript
 *  export class MyDynamicComponentDefinitionFactory implements ExtensionFactory<DynamicComponentDefinition> {...}
 *  ...
 *  hookComponent(MyDynamicComponentDefinitionFactory)
 * ```
 * A typed alternative to `HOOK_COMPONENTS`.
 * @param components The `DynamicComponentDefinition`'s or `ExtensionFactory` to be provided.
 * @returns An `Provider` to be provided in your module.
 */
export declare function hookComponent(components: GenericHookType<DynamicComponentDefinition>, options?: Partial<GenericHookOptions>): import("@angular/core").ValueProvider | import("@angular/core").ClassProvider | import("@angular/core").ExistingProvider;
/**
 * Hook to add dynamic widget components to the UI.
 *
 * You can either provide a single `DynamicWidgetDefinition` as parameter:
 * ```typescript
 *  hookWidget(...)
 * ```
 *
 * Or an array to directly register multiple:
 * ```typescript
 *  hookWidget([...])
 * ```
 *
 *  * Or you provide a Service that implements `ExtensionFactory<DynamicWidgetDefinition>`
 * ```typescript
 *  export class MyDynamicWidgetDefinitionFactory implements ExtensionFactory<DynamicWidgetDefinition> {...}
 *  ...
 *  hookWidget(MyDynamicWidgetDefinitionFactory)
 * ```
 * A widget specific alternative to `hookComponent`..
 * @param components The `DynamicWidgetDefinition`'s or `ExtensionFactory` to be provided.
 * @param options Options to configure the hook.
 * @returns An `Provider` to be provided in your module.
 */
export declare function hookWidget(components: GenericHookType<DynamicWidgetDefinition>, options?: Partial<GenericHookOptions>): import("@angular/core").ValueProvider | import("@angular/core").ClassProvider | import("@angular/core").ExistingProvider;
/**
 * A dynamic component can be defined in a the HOOK_COMPONENTS to display any kind
 * of component dynamically just by referencing it's id. The most common use case is on dashboards,
 * where the `configComponent` is used to define what is displayed on the `component`
 * on the dashboard.
 *
 * To use the component you can use the c8y-dynamic-component.
 *
 * ```
 *   <c8y-dynamic-component
 *     componentId="angular.widget.demo"
 *     [config]="{ text: 'Hello world' }"
 *     [mode]="editComponent ? 'config' : 'component'"
 *   ></c8y-dynamic-component>
 *   ```
 */
export type DynamicComponentDefinition = DynamicComponentDefinitionBase & DynamicComponents;
export type DynamicWidgetDefinition = DynamicWidgetDefinitionBase & DynamicComponents;
export interface DynamicComponentDefinitionBase extends DefinitionBase {
    /**
     * Add any random data, specially to angular.js dashboards.
     * Should be serializable to allow to save it to the API.
     */
    data?: any;
}
export interface DynamicWidgetDefinitionBase extends DefinitionBase {
    /**
     * Add any random data, specially to angular.js dashboards.
     * Should be serializable to allow to save it to the API.
     */
    data?: WidgetDataType;
}
export interface DefinitionBase {
    /**
     * Unique serializable id
     */
    id: string;
    /**
     * The label shown for this dynamic component on add widgets
     */
    label: string;
    /**
     * The description shown on add widget
     */
    description: string;
    /**
     * Add any random data, specially to angular.js dashboards.
     * Should be searilzabled to allow to save it to the API.
     */
    data?: any;
    /**
     * An url to an preview image.
     */
    previewImage?: string;
    /**
     * The injector to use to inject this component. If used in a module federation
     * plugin, the injector of the plugin should be used. Defaults to the root injector.
     */
    injector?: Injector;
    /**
     * Attributes of the dynamic components configuration to be resolved.
     */
    resolve?: {
        [key: string]: Type<DynamicDetailsResolver>;
    };
    /**
     * Determines if dynamic component or widget itself should render alerts.
     */
    errorStrategy?: DynamicComponentErrorStrategy;
    /**
     * Ordering of the components
     */
    priority?: number;
}
type WidgetDisplaySettingsCore = {
    /**
     * If enabled the widget is bound to the global time context. You can listen to ngOnChanges() change detection
     * to react to changes on the context. When a more detailed configuration is needed, use the <c8y-widget-time-context>
     * component instead.
     */
    globalTimeContext?: boolean;
    /**
     * If enabled the widget is bound to the global realtime context. You can listen to ngOnChanges() change detection
     * to react to changes on the context.
     */
    globalRealtimeContext?: boolean;
    /**
     * If enabled the widget is bound to the global aggregation context. You can listen to ngOnChanges() change detection
     * to react to changes on the context.
     */
    globalAggregationContext?: boolean;
};
export interface WidgetDataType {
    /**
     * Settings that define the context to which the widget is bound.
     * E.g. global time context, global realtime context, global aggregation context.
     */
    displaySettings?: WidgetDisplaySettingsCore;
    /**
     * Settings that are used to configure the widget.
     * They are static and will not be saved.
     */
    settings?: WidgetSettings;
}
export interface WidgetSettings {
    /**
     * Avoids to show the widget in the "add widget" modal
     */
    noNewWidgets?: boolean;
    upgrade?: boolean;
    widgetDefaults?: {
        _width?: number;
        _height?: number;
        [key: string]: any;
    };
    ng1?: {
        options?: {
            /**
             * Set this to false, to hide the device/group selector
             * @deprecated: This is currently only implemented in angularjs and will be exported to a separate component.
             */
            noDeviceTarget?: boolean;
            /**
             * Set this to false to only select devices
             * @deprecated: This is currently only implemented in angularjs and will be exported to a separate component.
             */
            groupsSelectable?: boolean;
            [key: string]: any;
        };
        /**
         * The context from the device selector.
         */
        context?: {
            id?: string;
            name?: string;
            [key: string]: any;
        };
        [key: string]: any;
    };
    /**
     * Additional settings for the widget.
     */
    [key: string]: any;
}
export interface AngularJSWidgetSettings extends WidgetSettings {
    /**
     * The config component name.
     * @deprecated: Only used for angularjs plugins.
     */
    configComponent?: string;
    /**
     * The widget component name.
     * @deprecated: Only used for angularjs plugins.
     */
    widgetComponent?: string;
    /**
     * The config template URL for legacy plugins.
     * @deprecated: Only used for angularjs plugins.
     */
    configTemplateUrl?: string;
    /**
     * Transforms widget's config by executing transform function.
     * The transform function can take injectable arguments
     * @deprecated: Only used for angularjs plugins.
     */
    transformConfigWithContext?: () => void;
}
export type DynamicComponents = EagerDynamicComponents | LazyDynamicComponents;
export interface EagerDynamicComponents {
    /**
     * The component which is used when the component should be displayed (e.g. on a dashboard)
     */
    component: Type<any>;
    loadComponent?: never;
    /**
     * The configuration component used when a widget is added or edited.
     */
    configComponent?: Type<any>;
    loadConfigComponent?: never;
}
export interface LazyDynamicComponents {
    /**
     * A function returning a promise of the component which is used when the component should be displayed (e.g. on a dashboard)
     *
     * A sample function to be provided could look like this:
     * ```
     * async function loadViewComponent() {
     *  const { LazyWidgetViewComponent } = await import('./lazy-widget-view');
     *  return LazyWidgetViewComponent;
     * }
     * ```
     */
    loadComponent: () => Promise<Type<any>>;
    component?: never;
    /**
     * A function returning a promise of the configuration component used when a widget is added or edited.
     *
     * A sample function to be provided could look like this:
     * ```
     * async function loadConfigComponent() {
     *  const { LazyWidgetConfigComponent } = await import('./lazy-widget-config');
     *  return LazyWidgetConfigComponent;
     * }
     * ```
     */
    loadConfigComponent?: () => Promise<Type<any>>;
    configComponent?: never;
}
export declare function isLazyDynamicComponents(componentDefinition: DynamicComponents): componentDefinition is LazyDynamicComponents;
export declare function isEagerDynamicComponents(componentDefinition: DynamicComponents): componentDefinition is EagerDynamicComponents;
export declare enum DynamicComponentErrorStrategy {
    /**
     * Will not render/initialize the Widget in case an error was detected.
     */
    NOT_RENDER = "NOT_RENDER",
    /**
     * Will add an overlay over the Widget, displaying the error message.
     */
    OVERLAY_ERROR = "OVERLAY_ERROR",
    /**
     * The widget implements error handling on its own.
     */
    CUSTOM = "CUSTOM"
}
/**
 * Use this interface on any component to define the interchange between
 * config and display component.
 */
export interface DynamicComponent {
    /**
     * The configuration which is shared between configuration component and display component.
     * Should be searilzabled to allow to save it to the API.
     */
    config: any;
    /**
     * Alerts related to the dynamic component.
     * Can either be set by the dynamic component it self or via it's resolvers.
     */
    alerts?: DynamicComponentAlertAggregator;
    /**
     * A reference to the ng1Form on angularjs dashboards to disable/enable the save button.
     * @deprecated: Will not work on Angular-Dashboards (1.6.1.0). Use `ContextServiceDashboard.formDisabled` instead.
     */
    ng1FormRef?: any;
}
/**
 * An lifecycle hook which is called before an configuration is saved.
 */
export interface OnBeforeSave {
    /**
     * Called before a configuration object is saved. The function can be used to manipulate the
     * passed config object or to cancel the saving (return false or Observable<boolean>).
     */
    onBeforeSave(config?: any): boolean | Promise<boolean> | Observable<boolean>;
}
export {};
//# sourceMappingURL=dynamic-component.model.d.ts.map