import * as BaseActions from "actions/BaseEditActions";
import { EditableCallbacks, EditableProps} from "core/EditableProps";
import { connect } from "react-redux";
import {Store} from "stores";

type MappedProps<TProps extends EditableProps<any>> = TProps & EditableProps<TProps["value"]>;

type EditableComponentProps = EditableProps<any> & EditableCallbacks<any>;

type RequiredProps = {itemId: number};

function mapStateToProps <TProps extends EditableComponentProps>(state: Store, {itemId}: RequiredProps): MappedProps<TProps> {
    return state.document[itemId] as TProps;
};

const mapBaseActionsToProps = {
    onEdited: (id: number, newValue: any) => (<BaseActions.OnEdited> {
        itemId : id,
        type : "onEdited",
        value : newValue,
    }),
    setIsEditing : (id: number, isEditing: boolean) => (<BaseActions.SetIsEditing> {
        editing : isEditing,
        itemId : id,
        type : "setIsEditing",
    }),
};

export default function connectEditable<TProps extends EditableComponentProps>(Component: React.SFC<TProps> | React.ComponentClass<TProps>) {
    return connect(mapStateToProps, mapBaseActionsToProps)(Component);
}

import * as BaseActions from "actions/BaseEditActions";
import { EditableCallbacks, EditableProps} from "core/EditableProps";
import { connect } from "react-redux";
import {Store} from "stores";

type MappedProps<TProps extends EditableProps<any>> = TProps & EditableProps<TProps["value"]>;

type EditableComponentProps = EditableProps<any> & EditableCallbacks<any>;

type RequiredProps = {itemId: number};

function mapStateToProps <TProps extends EditableComponentProps>(state: Store, {itemId}: RequiredProps): MappedProps<TProps> {
    return {... state.document[itemId]} as TProps;
};

const mapBaseActionsToProps = {
    onEdited: (id: number, newValue: any) => (<BaseActions.OnEdited> {
        itemId : id,
        type : "onEdited",
        value : newValue,
    }),
    setIsEditing : (id: number, isEditing: boolean) => (<BaseActions.SetIsEditing> {
        editing : isEditing,
        itemId : id,
        type : "setIsEditing",
    }),
};

export default function connectEditable<TProps extends EditableComponentProps>(Component: React.SFC<TProps> | React.ComponentClass<TProps>) {
    return connect(mapStateToProps, mapBaseActionsToProps)(Component);
}

Use spread to create a new props object since we have some connected elements nested in nonconnected elements (so sometimes stuff will break if we don't clone the props)
Use spread to create a new props object since we have some connected elements nested in nonconnected elements (so sometimes stuff will break if we don't clone the props)
