@aappddeevv/dynamics-client-ui
Version:
## What is it? A library to help you create great dynamics applications.
149 lines (148 loc) • 6.33 kB
TypeScript
/// <reference types="xrm" />
/// <reference types="react" />
/**
* Helpers for dealing with entity form state.
*/
import * as React from "react";
import * as PropTypes from "prop-types";
import { Dynamics, DynamicsProps, DynamicsContext } from "./Dynamics";
import { Notifier } from "./NotificationManager";
/** A dynamics form attribute. Entity lookup by default. */
export interface Attribute<T = Xrm.LookupValue> {
/** Standardized name e.g. "account" or "contact". Not sure this is needed. */
name: string;
/** Dynamics logical name. */
logicalName: string;
/** If the attribute currently has a value. */
hasValue: boolean;
/** Dynamics attribute, it must be a lookup. */
attribute: Xrm.Attributes.LookupAttribute;
/** Used to unregister the callback handler. */
unregisterToken?: any;
/** Current value. Typically an array so you need index-0. */
value: T | null;
}
/**
* Dynamics form attribute state. keys are dynamics attribute names
* (logical names) and values are this module's Attributes.
*/
export declare type AttributeState = Record<string, Attribute>;
/** Empty state. */
export declare const EmptyAttributeState: {};
/**
* Add on change handlers to attributes. Return a new state. Existing
* attributes in AttributeState are included in the return value untouched
* so this is safe to call incrementally.
*/
export declare function connect(attributes: Array<string>, state: AttributeState, getAttribute: (n: string) => Xrm.Attributes.Attribute, onChangeHandler: (name: string, value: any) => void): AttributeState;
/** Clears all values but setting it to null. */
export declare function clear(state: AttributeState): void;
/** Something that can dispose. Very traditional OOP. */
export interface Disposable {
dispose: () => void;
}
/** EntityForm's props, *not* for the children of EntityForm (see EntityFormChildProps). */
export interface EntityFormProps extends Partial<DynamicsProps> {
entityId?: string | null;
entityName?: string | null;
userId?: string | null;
/** Track form save and re-grab ids, etc. */
trackSave?: boolean;
/** Pass in strict value for the FormContext, if available. */
formContext?: Xrm.FormContext;
}
/**
* Extend these for your child's props using EntityFormChildProps or
* Partial<EntityFormChildProps>. Form attributes are also injected once
* they are connected to the form.
*/
export interface EntityFormChildProps {
/** Whether you can change values on the form e.g. true => can use Attribute.setValue. */
canChange: boolean | null;
/** entityId for the entity represented by the form. May be null if the entity is new w/o save. */
entityId: string | null;
entityName: string | null;
userId: string | null;
/** See Xrmenum.FormType */
formType: number | null;
/** Connect to Dynamics attributes so we get them as props. */
connect: (attributes: Array<string>) => Promise<void>;
/** Clear attributes by setting their values to null. */
clear: (attributes: Array<string>, fire: boolean) => Promise<void>;
/** Set an attribute value. */
setValue: (attribute: string, value: any) => Promise<void>;
/** Form context. */
formContextP: Promise<Xrm.FormContext>;
/** Convenience, a Notifier (a user message handler). */
notifier: Notifier;
}
export interface EntityFormState {
stateCode: number | null;
canChange: boolean | null;
entityId: string | null;
ename: string | null;
entityName: string | null;
formType: number | null;
}
export interface EntityFormContext extends DynamicsContext {
/** A form context promise. */
formContextP: Promise<Xrm.FormContext>;
}
/** Not used yet. */
export declare const entityFormShape: PropTypes.Requireable<any>;
/**
* Inject Xrm state into a child and provide Xrm state through
* a component's context. Can detect when the form has been saved
* because the entityId will appear as a value in the child props.
* Save handlers are run properly after the save. An update after
* save is automatically called. Using this component as your parent
* is alot like using `connect` in `react-redux`.
*
* The Xrm.FormContext is obtained via FormContextHolder or window.parent.
*/
export declare class EntityForm<P extends EntityFormProps = EntityFormProps, S extends EntityFormState = EntityFormState> extends Dynamics<P, S> {
constructor(props: P, context: any);
private formContextResolved;
private deferredFormContext;
private __className;
private __disposables;
private __afterSaves;
/** Attributes live outside the react world, so make it instance var. */
protected _attributeState: AttributeState;
getChildContext(): EntityFormContext;
static childContextTypes: {
notifier: PropTypes.Requireable<any>;
xrm: PropTypes.Requireable<any>;
errorHandler: PropTypes.Requireable<any>;
formContextP: PropTypes.Requireable<any>;
};
/** Can push a thunk. */
readonly _afterSaves: Array<() => void>;
/** Can push a Disposable. */
readonly _disposables: Array<Disposable>;
/** Get the class name. From Office Fabric. */
readonly className: string;
/**
* Setup the FormContext if it is not already set. When resolved, force an update.
*/
componentDidMount(): void;
componentWillUnmount(): void;
componentWillMount(): void;
/**
* Setup connections force an update so that values are propagated.
* @returns true if connections were created, false otherwise.
*/
protected connect: (attributes: string[]) => Promise<boolean>;
protected onChangeHandler: (name: string, value: any) => void;
/** For each value in a connected state. */
protected clear: (names: string[], fire?: boolean) => Promise<void>;
/** Give a FormContext, extract some values to pass to children as props on the next render. */
protected extractValues: (fctx: Xrm.FormContext) => void;
/**
* Setting value in dynamics attribute does *not* fire change event automatically,
* which is good for us. If fire is true, `fireOnChange()` is called.
*/
protected setValue: (name: string, value: any, fire?: boolean) => Promise<void>;
render(): React.ReactElement<any>;
}
export default EntityForm;