@genialis/resolwe
Version:
Resolwe frontend libraries
196 lines (195 loc) • 7.25 kB
TypeScript
import * as angular from 'angular';
import { SharedStoreManager } from '../shared_store/index';
import { ComponentBase, ComponentConfiguration } from './base';
import { StateManager } from './manager';
export declare class StateItemMetadata {
propertyName: string;
shared: boolean;
constructor(propertyName: string, shared: boolean);
getSharedStoreNameProperty(): string;
}
export interface StateMetadata {
[index: string]: StateItemMetadata;
}
/**
* A component which contains state that may be saved and reloaded later. Such
* stateful components are automatically organized into a hierarchy, so that
* parents also store state for all their children. Calling `saveState` on the
* top-level component will therefore save the state of the complete application.
*
* Component state is defined by using property decorators as follows:
* ```
* export class ProcessGroups extends ViewComponent {
* @state() public selectedGroup: number;
*
* // ...
* }
* ```
*
* It may be then referenced and watched from the controller or templates and
* will automatically be saved when calling [[StatefulComponentBase.saveState]]
* and reloaded when calling [[StatefulComponentBase.loadState]].
*
* A related decorator may be used to declare state, which is shared between
* multiple components:
* ```
* export class WidgetRose2 extends WidgetBase {
* @sharedState() public selectedValue: SharedStore<types.Data>;
*
* // ...
* }
* ```
*
* See [[SharedStoreManager]] and [[SharedStore]] for more documentation on
* defining shared state using shared stores.
*
* For example, if a stateful component defines a shared state property called
* `selectedValue` (as shown above) and you want to link it with the shared store
* named `rose2-selected-data-item`, you can do the following in your template:
* ```html
* <gen-widget-rose2 store-selected-value="rose2-selected-data-item"></gen-widget-rose2>
* ```
*
* Note that the template attribute name is prefixed with `store` even when the
* property is called just `selectedValue`. This is done because what you pass
* in the template is just a name of the store, which must be resolved using the
* shared store manager.
*
* Inside the components you can then dispatch and subscribe to the underlying
* store:
* ```
* // Publish something by dispatching an action to the shared store.
* this.selectedValue.dispatch({type: Actions.SET, value: 42});
*
* // Subscribe to updates of the shared store.
* this.subscribeSharedState('selectedValue', (data) => {
* console.log("Shared state 'selectedValue' is now", data);
* });
* ```
*/
export declare abstract class StatefulComponentBase extends ComponentBase {
__stateMetadata: StateMetadata;
stateId: string;
globalStateId: string;
private _parent;
private _children;
private _stateManager;
private _sharedStoreManager;
private _sharedStoreSubscribeRequests;
private _sharedStoreSubscriptions;
constructor($scope: angular.IScope, stateManager: StateManager);
onComponentInit(): void;
/**
* Sets up the shared store. This method may be overriden by subclasses when something
* different should be done here.
*
* @param {store} Shared state
*/
protected _setupSharedStore(store: string): void;
/**
* Returns the state manager.
*/
readonly stateManager: StateManager;
/**
* Returns the shared store manager.
*/
protected readonly sharedStoreManager: SharedStoreManager;
onComponentDestroyed(): void;
/**
* This method will be called after the component's state has been loaded.
*/
onComponentStateAfterLoad(): void;
/**
* This method will be called before the component's state has been saved.
*/
onComponentStatePreSave(): void;
/**
* Discovers the parent stateful component.
*/
private _findParentComponent;
/**
* Registers a new child of this stateful component.
*
* @param {StatefulComponentBase} child Child component instance
*/
private _registerChild;
/**
* Unregisters an existing child of this stateful component.
*
* @param {StatefulComponentBase} child Child component instance
*/
private _unregisterChild;
/**
* Returns the parent stateful component.
*/
parentComponent(): StatefulComponentBase;
/**
* Returns a list of child stateful components.
*/
childComponents(): StatefulComponentBase[];
/**
* Finds a child component by its state identifier.
*
* @param {string} stateId Child's state identifier
* @return {StatefulComponentBase} Child component instance
*/
getChildComponent<T extends StatefulComponentBase>(stateId: string): T;
/**
* Subscribes to shared state. This is the same as a normal subscribe, but in
* addition it also properly handles underlying data store changes when
* component state is reloaded.
*
* The value observed from the shared store MUST NOT be mutated in any way as
* doing so may cause undefined behavior. If you need to mutate the observed
* value, use [[subscribeSharedStateMutable]] instead.
*
* @param {string} name Name of shared state
* @param callback Callback to be invoked on subscription
*/
subscribeSharedState(name: string, callback: (value: any) => void): void;
/**
* A version of [[subscribeSharedState]], which ensures that the observed shared
* store value is copied and can thus be safely mutated afterwards.
*
* @param {string} name Name of shared state
* @param callback Callback to be invoked on subscription
*/
subscribeSharedStateMutable<T>(name: string, callback: (value: T) => void): void;
/**
* Returns metadata for specific component state.
*
* @param {string} name Name of shared state (not property name)
* @return {StateItemMetadata} State metadata
*/
private _getStateMetadata;
/**
* Saves this component's current state and returns it.
*/
saveState(saveChildren?: boolean): any;
/**
* Loads this component's current state.
*
* @param {any} globalState Global state
*/
loadState(globalState: any, loadChildren?: boolean): void;
/**
* Check if property has not been loaded from state, or isn't defined. Usually used
* before setting a deferred default value.
*/
isPropertyNotLoadedFromStateOrIsUndefined<P extends keyof this>(property: P): boolean;
static configureComponent(config: ComponentConfiguration): ComponentConfiguration;
}
/**
* Marks a property as being part of the component's state.
*
* @param {string} name Optional state name
* @param {boolean} shared Does this state reference a shared store
*/
export declare function state(name?: string, shared?: boolean): (target: StatefulComponentBase, propertyKey: string) => void;
/**
* Marks a property as being part of the component's state, which references
* a shared store.
*
* @param {string} name Optional state name
*/
export declare function sharedState(name?: string): (target: StatefulComponentBase, propertyKey: string) => void;