,\n element: React.CElement,\n container: Element,\n callback?: (component: T) => any): T;\n export function unstable_renderSubtreeIntoContainer
(\n parentComponent: React.Component,\n element: React.ReactElement,\n container: Element,\n callback?: (component?: React.Component
| Element) => any): React.Component
| Element | void;\n\n export interface Renderer {\n // Deprecated(render): The return value is deprecated.\n // In future releases the render function's return type will be void.\n\n (\n element: React.DOMElement, T>,\n container: Element | null,\n callback?: () => void\n ): T;\n\n (\n element: Array, any>>,\n container: Element | null,\n callback?: () => void\n ): Element;\n\n (\n element: React.SFCElement | Array>,\n container: Element | null,\n callback?: () => void\n ): void;\n\n >(\n element: React.CElement
,\n container: Element | null,\n callback?: () => void\n ): T;\n\n (\n element: Array>>,\n container: Element | null,\n callback?: () => void\n ): React.Component;\n\n (\n element: React.ReactElement
,\n container: Element | null,\n callback?: () => void\n ): React.Component
| Element | void;\n\n (\n element: Array>,\n container: Element | null,\n callback?: () => void\n ): React.Component | Element | void;\n\n (\n parentComponent: React.Component | Array>,\n element: React.SFCElement,\n container: Element,\n callback?: () => void\n ): void;\n }\n}","namespace Q {\r\n export function extend(obj: any, props: any) {\r\n for (let i in props)\r\n obj[i] = props[i];\r\n\r\n return obj;\r\n }\r\n\r\n var uniqueId = 0;\r\n\r\n export function uidGenerator(): () => (() => string) {\r\n var prefix = \"uid_\" + (++uniqueId) + \"_\";\r\n return function () {\r\n var counter = 0;\r\n return function () {\r\n return prefix + (++counter);\r\n }\r\n }\r\n }\r\n\r\n var hasOwn = {}.hasOwnProperty;\r\n\r\n export function cssClass(...args: any[]): string {\r\n var classes = [];\r\n \r\n for (var i = 0; i < arguments.length; i++) {\r\n var arg = arguments[i];\r\n if (!arg) continue;\r\n\r\n var argType = typeof arg;\r\n\r\n if (argType === 'string' || argType === 'number') {\r\n classes.push(arg);\r\n } else if (Array.isArray(arg) && arg.length) {\r\n var inner = cssClass.apply(null, arg);\r\n if (inner) {\r\n classes.push(inner);\r\n }\r\n } else if (argType === 'object') {\r\n for (var key in arg) {\r\n if (hasOwn.call(arg, key) && arg[key]) {\r\n classes.push(key);\r\n }\r\n }\r\n }\r\n }\r\n\r\n return classes.join(' ');\r\n }\r\n}","namespace Q {\r\n function widgetComponentFactory(widgetType: any) {\r\n\r\n return (function (_super) {\r\n __extends(Wrapper, _super);\r\n\r\n function Wrapper() {\r\n return _super !== null && _super.apply(this, arguments) || this;\r\n }\r\n\r\n Wrapper.prototype.render = function () {\r\n return React.createElement(\"div\", {\r\n ref: ((el: any) => this.wrapper = el),\r\n className: 'widget-wrapper'\r\n });\r\n };\r\n\r\n Wrapper.prototype.componentWillReceiveProps = function (nextProps: Serenity.WidgetComponentProps) {\r\n var props: Serenity.WidgetComponentProps = this.props;\r\n\r\n var widget = this.widget;\r\n if (widget == null || widget.element == null)\r\n return;\r\n\r\n var $node = widget.element;\r\n var node = $node[0];\r\n\r\n if (nextProps.id !== props.id) {\r\n node.id = nextProps.id;\r\n }\r\n\r\n if (nextProps.name !== props.name && $node.is(':input')) {\r\n (node as any).name = nextProps.name;\r\n }\r\n\r\n if (nextProps.placeholder !== props.placeholder && $node.is(':input')) {\r\n (node as any).placeholder = nextProps.placeholder;\r\n }\r\n\r\n if (nextProps.className !== props.className) {\r\n $node.removeClass(props.className || '').addClass(nextProps.className);\r\n }\r\n\r\n if (nextProps.oneWay !== props.oneWay) {\r\n node.dataset.oneWay = nextProps.oneWay ? \"1\" : undefined;\r\n }\r\n\r\n if (nextProps.maxLength != props.maxLength)\r\n node.setAttribute(\"maxLength\", nextProps.maxLength || 0);\r\n\r\n if (nextProps.required !== props.required)\r\n Serenity.EditorUtils.setRequired(this.widget, nextProps.required);\r\n\r\n if (props.readOnly !== props.readOnly)\r\n Serenity.EditorUtils.setReadOnly(this.widget, nextProps.readOnly);\r\n\r\n if (nextProps.setOptions != props.setOptions) {\r\n Serenity.ReflectionOptionsSetter.set(this.widget, nextProps.setOptions);\r\n }\r\n\r\n if (nextProps.value !== props.value) {\r\n Serenity.EditorUtils.setValue(this.widget, nextProps.value);\r\n }\r\n\r\n if (nextProps.onChange !== props.onChange) {\r\n this.widget.element.off('.wcf');\r\n if (nextProps.onChange)\r\n this.widget.element.on('change.wcf', nextProps.onChange);\r\n }\r\n\r\n if (nextProps.onChangeSelect2 !== props.onChangeSelect2) {\r\n this.widget.element.off('.wcf2');\r\n if (nextProps.onChangeSelect2) {\r\n this.widget.element.on('change.wcf2', (e: any, x: any) => {\r\n if (!!(Serenity.WX.hasOriginalEvent(e) || !x)) {\r\n this.props.onChangeSelect2 && this.props.onChangeSelect2(e);\r\n }\r\n });\r\n }\r\n }\r\n }\r\n\r\n Wrapper.prototype.componentDidMount = function () {\r\n\r\n if (this.widget != null)\r\n return;\r\n\r\n var $node = Serenity.Widget.elementFor(widgetType);\r\n var node = $node[0];\r\n this.wrapper.appendChild(node);\r\n\r\n var props: Serenity.WidgetComponentProps = this.props;\r\n\r\n if (props.id != null)\r\n node.id = props.id;\r\n\r\n if ($node.is(':input')) {\r\n $node.addClass(\"editor\");\r\n if (props.name != null)\r\n (node as any).name = props.name;\r\n\r\n if (props.placeholder != null)\r\n (node as any).placeholder = props.placeholder;\r\n }\r\n\r\n if (props.className != null)\r\n $node.addClass(props.className);\r\n\r\n if (props.oneWay)\r\n node.dataset.oneWay = \"1\";\r\n\r\n this.widget = new (widgetType as any)($node, props);\r\n\r\n if (props.maxLength != null)\r\n node.setAttribute(\"maxLength\", props.maxLength.toString());\r\n\r\n if (props.required)\r\n Serenity.EditorUtils.setRequired(this.widget, true);\r\n\r\n if (props.readOnly)\r\n Serenity.EditorUtils.setReadOnly(this.widget, true);\r\n\r\n if (props.setOptions != null) {\r\n Serenity.ReflectionOptionsSetter.set(this.widget, props.setOptions);\r\n }\r\n\r\n if (props.value !== undefined)\r\n Serenity.EditorUtils.setValue(this.widget, props.value);\r\n else if (props.defaultValue !== undefined)\r\n Serenity.EditorUtils.setValue(this.widget, props.defaultValue);\r\n\r\n if (props.onChange != null)\r\n this.widget.element.on('change.wcf', props.onChange);\r\n\r\n if (props.onChangeSelect2 != null) {\r\n this.widget.element.on('change.wcf2', (e: any, x: any) => {\r\n if (!!(Serenity.WX.hasOriginalEvent(e) || !x)) {\r\n props.onChangeSelect2 && props.onChangeSelect2(e);\r\n }\r\n });\r\n }\r\n }\r\n\r\n Wrapper.prototype.componentWillUnmount = function () {\r\n this.widget && this.widget.destroy();\r\n this.widget = null;\r\n };\r\n\r\n Wrapper.prototype.shouldComponentUpdate = function () {\r\n return false;\r\n };\r\n\r\n Wrapper.prototype.isWidgetWrapper = true;\r\n\r\n (Wrapper as any).displayName = \"Wrapped<\" + (ss as any).getTypeFullName(widgetType) + \">\";\r\n\r\n return Wrapper;\r\n }(React.Component));\r\n }\r\n\r\n var reactCreateElement = React.createElement;\r\n (React as any).createElement = function () {\r\n var arg = arguments[0];\r\n if (typeof arg === \"function\" && arg.__isWidgetType === true) {\r\n if (arg.__componentFactory === undefined)\r\n arguments[0] = arg.__componentFactory = widgetComponentFactory(arg);\r\n else\r\n arguments[0] = arg.__componentFactory;\r\n\r\n if (arguments.length > 1 && arguments[1] && arguments[1].ref) {\r\n var ref = arguments[1].ref;\r\n arguments[1].ref = function (wrapper: any) {\r\n if (wrapper == null)\r\n ref(null);\r\n else\r\n ref(wrapper.widget);\r\n }\r\n }\r\n }\r\n\r\n\r\n return reactCreateElement.apply(this, arguments);\r\n };\r\n}","namespace Serenity.UI {\r\n\r\n export class EditorRefs {\r\n\r\n private setters: Q.Dictionary<(ref: any) => void> = Object.create(null);\r\n private refs: Q.Dictionary = Object.create(null);\r\n\r\n constructor(private inner?: (name: string, ref: any) => void) {\r\n this.set = this.set.bind(this);\r\n this.setter = this.setter.bind(this);\r\n }\r\n\r\n get(name: string) {\r\n return this.refs[name];\r\n }\r\n\r\n set(name: string, ref: any) {\r\n this.refs[name] = ref;\r\n if (this.inner != null)\r\n this.inner(name, ref);\r\n }\r\n\r\n setter(name: string): ((ref: any) => void) {\r\n var func = this.setters[name];\r\n if (func != null)\r\n return func;\r\n\r\n var setRef = this.set;\r\n func = (function (ref: any) {\r\n setRef(name, ref);\r\n });\r\n\r\n this.setters[name] = func;\r\n return func;\r\n }\r\n\r\n loadFrom(source: any, names?: string[]) {\r\n\r\n names = Q.coalesce(names, Object.keys(this.refs));\r\n\r\n for (var name of names) {\r\n var editor = this.refs[name];\r\n if (editor == null)\r\n continue;\r\n\r\n if (editor.isWidgetWrapper) {\r\n editor = editor.widget;\r\n if (editor)\r\n Serenity.EditorUtils.loadValue(editor, { name: name }, source);\r\n }\r\n else if (editor.nodeType) {\r\n source[name] = editor.value;\r\n }\r\n else if (editor.element) {\r\n Serenity.EditorUtils.loadValue(editor, { name: name }, source);\r\n }\r\n }\r\n }\r\n\r\n saveTo(target: any, names?: string[], ignoreOneWay?: boolean) {\r\n\r\n names = Q.coalesce(names, Object.keys(this.refs));\r\n\r\n for (var name of names) {\r\n var editor = this.refs[name];\r\n if (editor.isWidgetWrapper) {\r\n if (ignoreOneWay || !editor.props.oneWay) {\r\n editor = editor.widget;\r\n if (editor)\r\n Serenity.EditorUtils.saveValue(editor, { name: name }, target);\r\n }\r\n }\r\n else if (editor.nodeType) {\r\n if (ignoreOneWay ||\r\n !(editor as HTMLElement).dataset ||\r\n !(editor as HTMLElement).dataset.oneWay)\r\n target[name] = editor.value;\r\n }\r\n else if (editor.element) {\r\n if (ignoreOneWay ||\r\n !editor.options ||\r\n !editor.options.oneWay) {\r\n Serenity.EditorUtils.saveValue(editor, { name: name }, target);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n}","namespace Serenity.UI {\r\n export interface LabelProps {\r\n hint?: string;\r\n htmlFor?: string;\r\n width?: string | number;\r\n required?: boolean;\r\n }\r\n\r\n export class Label extends React.Component {\r\n render() {\r\n var props = this.props;\r\n var width = typeof props.width == \"string\" || props.width == null ? null :\r\n (typeof (props.width) == \"number\" ? props.width + \"px\" :\r\n props.width);\r\n\r\n var style = width == null ? null : (width == \"0\" ? { display: \"none\" } : { width: width });\r\n\r\n return (\r\n \r\n );\r\n }\r\n }\r\n}","namespace Serenity.UI {\r\n export class ValidationMark extends React.Component {\r\n\r\n render() {\r\n return ();\r\n }\r\n\r\n shouldComponentUpdate() {\r\n return false;\r\n }\r\n }\r\n}","namespace Serenity.UI {\r\n export type EditorRenderProps = {\r\n className?: string;\r\n name?: string;\r\n id?: string;\r\n required?: boolean;\r\n ref?: (editor: any) => void;\r\n }\r\n\r\n export interface FieldProps {\r\n name?: string;\r\n id?: string;\r\n className?: string;\r\n caption?: string | false;\r\n labelWidth?: number | string;\r\n label?: ((p: LabelProps) => JSX.Element);\r\n htmlFor?: string;\r\n editor?: ((p: EditorRenderProps) => JSX.Element);\r\n setRef?: (name: string, editor: any) => void;\r\n hint?: string;\r\n required?: boolean;\r\n vx?: boolean;\r\n }\r\n\r\n export class Field extends React.Component {\r\n\r\n private editorRef: any;\r\n\r\n componentWillReceiveProps(nextProps: FieldProps, nextContext?: any): void {\r\n if (nextProps != null && nextProps.setRef !== this.props.setRef) {\r\n this.editorRef = null;\r\n }\r\n }\r\n\r\n render() {\r\n var props = this.props;\r\n\r\n var lblElement: JSX.Element;\r\n if (props.label != null)\r\n lblElement = props.label(this.props);\r\n else if (props.caption !== false) {\r\n lblElement = (\r\n \r\n );\r\n }\r\n\r\n var className = \"field\";\r\n if (props.name) {\r\n className += \" \" + props.name;\r\n }\r\n\r\n if (props.className) {\r\n className += \" \" + props.className;\r\n }\r\n\r\n var name = props.name;\r\n if (this.props.setRef != null &&\r\n this.editorRef == null) {\r\n var setRef = this.props.setRef;\r\n this.editorRef = function (x: any) {\r\n setRef(name, x);\r\n };\r\n }\r\n\r\n var editorProps: EditorRenderProps = {\r\n className: \"editor\",\r\n name: name,\r\n id: this.props.id,\r\n required: this.props.required,\r\n ref: this.editorRef\r\n }\r\n\r\n return (\r\n \r\n {lblElement}\r\n {props.editor != null && props.editor(editorProps)}\r\n {props.children}\r\n {props.vx !== false &&
}\r\n
\r\n
\r\n );\r\n }\r\n }\r\n}","namespace Serenity.UI {\r\n export interface PropertyFieldProps extends Serenity.PropertyItem {\r\n idPrefix?: string\r\n localTextPrefix?: string;\r\n setRef?: (name: string, editor: any) => void;\r\n }\r\n\r\n export class PropertyField extends React.Component {\r\n\r\n protected text = Q.prefixedText(this.props.localTextPrefix);\r\n\r\n getCaption(): string {\r\n return this.text(this.props.title, this.props.name);\r\n }\r\n\r\n getHint(): string {\r\n var hint = this.text(this.props.hint, this.props.name + '_Hint');\r\n\r\n if (hint == null)\r\n return this.getCaption();\r\n\r\n return hint || null;\r\n }\r\n\r\n getPlaceHolder() {\r\n return this.text(this.props.placeholder, this.props.name + '_Placeholder');\r\n }\r\n\r\n getClassName() {\r\n var className = this.props.cssClass || \"\";\r\n\r\n if (!Q.isEmptyOrNull(this.props.formCssClass)) {\r\n className += (className ? \" \" : \"\") + this.props.formCssClass;\r\n }\r\n\r\n return className;\r\n }\r\n\r\n getHtmlFor(editorType: any) {\r\n var htmlFor;\r\n if ((editorType === RadioButtonEditor || editorType === BooleanEditor) &&\r\n (this.props.editorParams == null || !!!this.props.editorParams['labelFor'])) {\r\n htmlFor = null;\r\n }\r\n return htmlFor;\r\n }\r\n\r\n getEditorType() {\r\n if (this.props.editorType == null)\r\n return Serenity.StringEditor;\r\n\r\n if (typeof this.props.editorType == \"string\")\r\n return Serenity.EditorTypeRegistry.get(this.props.editorType);\r\n\r\n return this.props.editorType;\r\n }\r\n\r\n getEditorId() {\r\n return (this.props.idPrefix || \"\") + (this.props.name || \"\");\r\n }\r\n\r\n getMaxLength() {\r\n return this.props.maxLength > 0 ? this.props.maxLength : null;\r\n }\r\n\r\n render() {\r\n var EditorType = this.getEditorType();\r\n\r\n return (\r\n \r\n \r\n }\r\n >\r\n {this.props.children}\r\n \r\n );\r\n }\r\n }\r\n}","namespace Serenity.UI {\r\n\r\n export interface CategoryTitleProps {\r\n categoryId?: string;\r\n collapsed?: boolean;\r\n onClick?: React.EventHandler;\r\n }\r\n\r\n export class CategoryTitle extends React.Component {\r\n\r\n static collapsedIcon = ;\r\n static expandedIcon = ;\r\n\r\n render() {\r\n return (\r\n \r\n
\r\n {this.props.children}\r\n \r\n {this.props.collapsed != null && (this.props.collapsed ? CategoryTitle.collapsedIcon : CategoryTitle.expandedIcon)}\r\n
\r\n )\r\n }\r\n }\r\n}","namespace Serenity.UI {\r\n export interface CategoryLineBreakProps {\r\n breakClass: string;\r\n }\r\n\r\n export class CategoryLineBreak extends React.Component {\r\n\r\n getBreakClass() {\r\n var breakClass = \"line-break\";\r\n\r\n var splitted = this.props.breakClass.split(' ');\r\n if (splitted.indexOf('line-break-xs') >= 0) {\r\n }\r\n else if (splitted.indexOf('line-break-sm') >= 0) {\r\n breakClass += \" hidden-xs\";\r\n }\r\n else if (splitted.indexOf('line-break-md') >= 0) {\r\n breakClass += \" hidden-sm\";\r\n }\r\n else if (splitted.indexOf('line-break-lg') >= 0) {\r\n breakClass += \" hidden-md\";\r\n }\r\n\r\n return breakClass;\r\n }\r\n\r\n render() {\r\n return ();\r\n }\r\n }\r\n}","namespace Serenity.UI {\r\n\r\n export interface CategoryLinkProps {\r\n categoryId?: string;\r\n onClick?: React.EventHandler\r\n }\r\n\r\n export class CategoryLink extends React.Component {\r\n\r\n handleClick(e: React.MouseEvent) {\r\n e.preventDefault();\r\n\r\n this.props.onClick && this.props.onClick(e);\r\n\r\n var title = $('a[id=' + this.props.categoryId + ']');\r\n\r\n var category = title.closest('.category');\r\n if (category.hasClass('collapsed'))\r\n category.children('.category-title').click();\r\n\r\n if (!title && !title.fadeTo)\r\n return;\r\n\r\n var animate = function () {\r\n title.fadeTo(100, 0.5, function () {\r\n title.fadeTo(100, 1, function () {\r\n });\r\n });\r\n };\r\n\r\n if (category.closest(':scrollable(both)').length === 0)\r\n animate();\r\n else {\r\n var siv = (category as any).scrollintoview;\r\n siv && siv.scrollintoview({\r\n duration: 'fast',\r\n direction: 'y',\r\n complete: animate\r\n });\r\n }\r\n }\r\n\r\n getLink() {\r\n if (Q.isEmptyOrNull(this.props.categoryId))\r\n return null;\r\n\r\n return \"#\" + this.props.categoryId;\r\n }\r\n\r\n render() {\r\n return (\r\n this.handleClick(e)} href={this.getLink()}>\r\n {this.props.children}\r\n \r\n )\r\n }\r\n }\r\n}","namespace Serenity.UI {\r\n\r\n export interface CategoryLinksProps {\r\n idPrefix?: string;\r\n items?: Serenity.PropertyItem[];\r\n defaultCategory?: string;\r\n categoryOrder?: string;\r\n localTextPrefix?: string;\r\n }\r\n\r\n export class CategoryLinks extends React.Component {\r\n\r\n protected text = Q.prefixedText(this.props.localTextPrefix);\r\n\r\n renderSeparator(key: any) {\r\n return |;\r\n }\r\n\r\n render() {\r\n var groups = Categories.groupByCategory(this.props.items);\r\n\r\n return (\r\n \r\n {groups.inOrder.map((g, idx) => [\r\n (idx > 0 && this.renderSeparator(\"sep-\" + idx)),\r\n \r\n {this.text(g.key, \"Categories.\" + g.key)}\r\n \r\n ])}\r\n
\r\n )\r\n }\r\n }\r\n}","namespace Serenity.UI {\r\n\r\n export interface CategoryProps {\r\n categoryId?: string;\r\n category?: string;\r\n collapsed?: boolean;\r\n idPrefix?: string;\r\n localTextPrefix?: string;\r\n items?: PropertyItem[];\r\n renderField?: (props: PropertyItem) => React.ReactNode;\r\n setRef?: (name: string, editor: any) => void;\r\n }\r\n\r\n export class Category extends React.Component> {\r\n\r\n protected text = Q.prefixedText(this.props.localTextPrefix);\r\n\r\n constructor(props: CategoryProps, context?: any) {\r\n super(props, context);\r\n\r\n this.state = {\r\n collapsed: this.props.collapsed\r\n };\r\n }\r\n\r\n componentWillReceiveProps(nextProps: CategoryProps) {\r\n if (nextProps.collapsed !== this.props.collapsed) {\r\n this.setState({\r\n collapsed: nextProps.collapsed\r\n });\r\n }\r\n }\r\n\r\n getClassName() {\r\n if (this.state.collapsed == null)\r\n return \"category \";\r\n\r\n if (this.state.collapsed == true)\r\n return \"category collapsible collapsed\";\r\n\r\n return \"category collapsible\";\r\n }\r\n\r\n getCategoryId() {\r\n if (!this.props.categoryId)\r\n return null;\r\n\r\n return Q.coalesce(this.props.idPrefix, '') + this.props.categoryId;\r\n }\r\n\r\n handleTitleClick() {\r\n if (this.state.collapsed == null)\r\n return;\r\n\r\n this.setState({\r\n collapsed: !this.state.collapsed\r\n });\r\n }\r\n\r\n renderTitle() {\r\n if (this.props.category == null)\r\n return null;\r\n\r\n return (\r\n this.handleTitleClick()}>\r\n {this.text(this.props.category, \"Categories.\" + this.props.category)}\r\n \r\n );\r\n }\r\n\r\n renderField(item: PropertyItem) {\r\n var props = Q.extend({\r\n idPrefix: this.props.idPrefix,\r\n localTextPrefix: this.props.localTextPrefix,\r\n key: item.name,\r\n setRef: this.props.setRef\r\n }, item);\r\n\r\n if (this.props.renderField != null) {\r\n var content = this.props.renderField(props);\r\n if (content !== undefined)\r\n return content;\r\n }\r\n\r\n return React.createElement(PropertyField, props);\r\n }\r\n\r\n renderWithBreak(item: PropertyItem) {\r\n return [, this.renderField(item)];\r\n }\r\n\r\n render() {\r\n var props = this.props;\r\n return (\r\n \r\n {this.renderTitle()}\r\n {props.items && props.items.map(item => {\r\n if (item.formCssClass && item.formCssClass.indexOf('line-break-') >= 0)\r\n return this.renderWithBreak(item);\r\n\r\n return this.renderField(item);\r\n })}\r\n {props.children}\r\n
\r\n );\r\n }\r\n }\r\n}","namespace Serenity.UI {\r\n\r\n export class CategoriesProps {\r\n idPrefix?: string;\r\n items?: Serenity.PropertyItem[];\r\n defaultCategory?: string;\r\n categoryOrder?: string;\r\n localTextPrefix?: string;\r\n renderCategory?: (props: CategoryProps) => React.ReactNode;\r\n renderField?: (props: PropertyItem) => React.ReactNode;\r\n setRef?: (name: string, editor: any) => void;\r\n }\r\n\r\n export class Categories extends React.Component {\r\n\r\n static applyOrder(groups: Q.Groups, categoryOrder: string): void {\r\n if (!categoryOrder)\r\n return;\r\n\r\n var split = categoryOrder.split(';');\r\n var order = 0;\r\n var catOrder = {};\r\n\r\n for (var s of split) {\r\n var x = Q.trimToNull(s);\r\n if (x == null || catOrder[x] != null)\r\n continue;\r\n catOrder[x] = order++;\r\n }\r\n\r\n groups.inOrder.sort((g1, g2) => {\r\n var order1 = catOrder[g1.key];\r\n if (order1 == null)\r\n catOrder[g1.key] = catOrder = order++;\r\n\r\n var order2 = catOrder[g2.key];\r\n if (order2 == null)\r\n catOrder[g2.key] = catOrder = order++;\r\n\r\n return order1 - order2;\r\n });\r\n\r\n for (order = 0; order < groups.inOrder.length; order++)\r\n groups.inOrder[order].order = order;\r\n }\r\n\r\n static groupByCategory(items: PropertyItem[], defaultCategory?: string, categoryOrder?: string): Q.Groups {\r\n var defCat = Q.coalesce(defaultCategory, '');\r\n var groups = Q.groupBy(items || [], x => Q.coalesce(x.category, defCat));\r\n Categories.applyOrder(groups, categoryOrder);\r\n return groups;\r\n }\r\n\r\n renderCategory(group: Q.Group) {\r\n\r\n var catProps: CategoryProps & { key?: any } = {\r\n categoryId: \"Category\" + group.order,\r\n category: group.key,\r\n idPrefix: this.props.idPrefix,\r\n localTextPrefix: this.props.localTextPrefix,\r\n items: group.items,\r\n key: group.order,\r\n renderField: this.props.renderField,\r\n setRef: this.props.setRef\r\n };\r\n\r\n if (this.props.renderCategory != null) {\r\n var content = this.props.renderCategory(catProps);\r\n if (content !== undefined)\r\n return content;\r\n }\r\n\r\n return \r\n }\r\n\r\n render() {\r\n\r\n return (\r\n \r\n {Categories.groupByCategory(this.props.items || [],\r\n this.props.defaultCategory, this.props.categoryOrder).inOrder.map(g =>\r\n this.renderCategory(g))\r\n }\r\n
\r\n )\r\n }\r\n }\r\n}","namespace Serenity.UI {\r\n export type ValidateFormProps = {\r\n options?: JQueryValidation.ValidationOptions;\r\n } & React.HTMLAttributes;\r\n\r\n export class ValidateForm extends React.Component {\r\n\r\n private validator: JQueryValidation.Validator;\r\n private form: HTMLFormElement;\r\n\r\n render() {\r\n var { options, ...other } = this.props;\r\n return (\r\n \r\n );\r\n }\r\n\r\n handleSubmit(e: React.FormEvent) {\r\n if (!this.validator.valid())\r\n return false;\r\n }\r\n\r\n componentDidMount() {\r\n this.validator = $(this.form).validate(Q.validateOptions(this.props.options));\r\n }\r\n\r\n validateForm(): boolean {\r\n return this.validator == null || !!this.validator.form();\r\n }\r\n\r\n serialize(): any {\r\n var result: any = {};\r\n $(this.form).find(':input, .editor').each((i, e) => {\r\n var name = $(e).attr('name');\r\n if (!name)\r\n return;\r\n\r\n var widget = $(e).tryGetWidget(Widget);\r\n if (widget)\r\n result[name] = EditorUtils.getValue(widget);\r\n else\r\n result[name] = $(e).val();\r\n });\r\n return result;\r\n }\r\n }\r\n}","namespace Serenity.UI {\r\n\r\n export class Form extends ValidateForm {\r\n render() {\r\n return (\r\n \r\n
\r\n {super.render()}\r\n
\r\n
\r\n );\r\n }\r\n }\r\n\r\n}","namespace Serenity.UI {\r\n\r\n export interface PropertyTabProps {\r\n idPrefix?: string;\r\n items?: Serenity.PropertyItem[];\r\n localTextPrefix?: string;\r\n categoryOrder?: string;\r\n defaultCategory?: string;\r\n renderCategories?: (tab: string, props: CategoriesProps) => React.ReactNode;\r\n renderCategory?: (props: CategoryProps) => React.ReactNode;\r\n renderField?: (props: PropertyItem) => React.ReactNode;\r\n setRef?: (name: string, editor: any) => void;\r\n }\r\n\r\n export class PropertyTabs extends React.Component {\r\n\r\n protected text = Q.prefixedText(this.props.localTextPrefix);\r\n\r\n static groupByTab(items: PropertyItem[]): Q.Groups {\r\n return Q.groupBy(items || [], x => Q.coalesce(x.tab, ''));\r\n }\r\n\r\n renderTab(group: Q.Group) {\r\n return (\r\n \r\n \r\n {this.text(group.key, \"Tabs.\" + group.key)}\r\n \r\n \r\n );\r\n }\r\n\r\n renderPane(group: Q.Group) {\r\n return (\r\n \r\n {this.renderCategories(group)}\r\n
\r\n );\r\n }\r\n\r\n renderCategories(group: Q.Group) {\r\n\r\n var props: CategoriesProps = {\r\n items: group.items,\r\n idPrefix: this.props.idPrefix,\r\n localTextPrefix: this.props.localTextPrefix,\r\n categoryOrder: this.props.categoryOrder,\r\n defaultCategory: this.props.defaultCategory,\r\n renderCategory: this.props.renderCategory,\r\n renderField: this.props.renderField,\r\n setRef: this.props.setRef\r\n }\r\n\r\n if (this.props.renderCategories) {\r\n var content = this.props.renderCategories(group.key, props);\r\n if (content !== undefined)\r\n return content;\r\n }\r\n\r\n return \r\n }\r\n\r\n render() {\r\n var tabs = PropertyTabs.groupByTab(this.props.items || []);\r\n\r\n return (\r\n \r\n \r\n {tabs.inOrder.map((g) => this.renderTab(g))}\r\n
\r\n \r\n {tabs.inOrder.map((g) => this.renderPane(g))}\r\n
\r\n \r\n );\r\n }\r\n }\r\n}","namespace Serenity {\r\n export interface PropertyGridOptions {\r\n idPrefix?: string;\r\n items?: PropertyItem[];\r\n useCategories?: boolean;\r\n categoryOrder?: string;\r\n defaultCategory?: string;\r\n localTextPrefix?: string;\r\n mode?: PropertyGridMode;\r\n renderCategories?: (tab: string, props: UI.CategoriesProps) => React.ReactNode;\r\n renderCategory?: (props: UI.CategoryProps) => React.ReactNode;\r\n renderField?: (props: PropertyItem) => React.ReactNode;\r\n setRef?: (name: string, editor: any) => void;\r\n }\r\n}\r\n\r\nnamespace Serenity.UI {\r\n\r\n export class IntraPropertyGrid extends React.Component {\r\n\r\n loadFrom(source: any, editors: UI.EditorRefs): void {\r\n var items = this.props.items || [];\r\n\r\n for (var item of items) {\r\n\r\n if (this.props.mode != PropertyGridMode.update &&\r\n item.defaultValue != null &&\r\n typeof (source[item.name]) === 'undefined') {\r\n source[item.name] = item.defaultValue;\r\n }\r\n }\r\n\r\n editors.loadFrom(source, items.map(x => x.name));\r\n }\r\n\r\n canModifyItem(item: PropertyItem) {\r\n if (this.props.mode != PropertyGridMode.update) {\r\n if (item.insertable === false) {\r\n return false;\r\n }\r\n\r\n if (item.insertPermission == null) {\r\n return true;\r\n }\r\n\r\n return Q.Authorization.hasPermission(item.insertPermission);\r\n }\r\n\r\n if (item.updatable === false) {\r\n return false;\r\n }\r\n\r\n if (item.updatePermission == null) {\r\n return true;\r\n }\r\n\r\n return Q.Authorization.hasPermission(item.updatePermission);\r\n }\r\n\r\n saveTo(target: any, editors: EditorRefs): void {\r\n editors.saveTo(target);\r\n }\r\n\r\n getItems() {\r\n return (this.props.items || []).map(item => {\r\n var canModify = this.canModifyItem(item);\r\n var oneWay = !!item.oneWay || !canModify;\r\n var readOnly = item.readOnly === true || !canModify;\r\n var required = !readOnly && !!item.required && item.editorType !== 'Boolean';\r\n var visible = !((item.readPermission != null &&\r\n !Q.Authorization.hasPermission(item.readPermission)) ||\r\n item.visible === false ||\r\n (this.props.mode != Serenity.PropertyGridMode.update && item.hideOnInsert === true) ||\r\n (this.props.mode == Serenity.PropertyGridMode.update && item.hideOnUpdate === true));\r\n\r\n return Q.extend(Q.extend({}, item), {\r\n readOnly: readOnly,\r\n oneWay: oneWay,\r\n required: required,\r\n visible: visible\r\n });\r\n });\r\n }\r\n\r\n render(): React.ReactNode {\r\n\r\n var props: PropertyGridOptions = Q.extend({}, this.props);\r\n props.items = this.getItems();\r\n\r\n var useTabs = Q.any(props.items, function (x) {\r\n return !Q.isEmptyOrNull(x.tab);\r\n });\r\n\r\n if (useTabs)\r\n return React.createElement(UI.PropertyTabs, props);\r\n\r\n var useCategories = props.useCategories !== false && Q.any(props.items, function (x) {\r\n return !Q.isEmptyOrNull(x.category);\r\n });\r\n\r\n if (useCategories) {\r\n \r\n {React.createElement(UI.CategoryLinks, props)}\r\n {React.createElement(UI.Categories, props)}\r\n \r\n }\r\n\r\n return (\r\n \r\n {React.createElement(UI.Category, props)}\r\n
\r\n )\r\n }\r\n }\r\n\r\n export class PropertyGrid extends IntraPropertyGrid {\r\n\r\n render() {\r\n return (\r\n \r\n {super.render()}\r\n
\r\n );\r\n }\r\n }\r\n}","namespace Serenity.UI {\r\n\r\n export class ButtonPanel extends React.Component {\r\n render() {\r\n return (\r\n \r\n {this.props.children}\r\n
\r\n )\r\n }\r\n }\r\n\r\n}","namespace Serenity {\r\n export interface ToolButton {\r\n title?: string;\r\n hint?: string;\r\n cssClass?: string;\r\n icon?: string;\r\n onClick?: any;\r\n htmlEncode?: any;\r\n hotkey?: string;\r\n hotkeyAllowDefault?: boolean;\r\n hotkeyContext?: any;\r\n separator?: (false | true | 'left' | 'right' | 'both');\r\n }\r\n\r\n export interface ToolbarOptions {\r\n buttons?: ToolButton[];\r\n hotkeyContext?: any;\r\n }\r\n\r\n export namespace UI {\r\n\r\n export interface ToolButtonProps extends Serenity.ToolButton {\r\n disabled?: boolean;\r\n hidden?: boolean;\r\n }\r\n\r\n @Decorators.registerClass(\"Serenity.UI.ToolButton\")\r\n export class ToolButton extends React.Component {\r\n\r\n static buttonSelector = \"div.tool-button\";\r\n\r\n static adjustIconClass(icon: string): string {\r\n if (!icon)\r\n return icon;\r\n\r\n if (Q.startsWith(icon, 'fa-'))\r\n return 'fa ' + icon;\r\n\r\n if (Q.startsWith(icon, 'glyphicon-'))\r\n return 'glyphicon ' + icon;\r\n\r\n return icon;\r\n }\r\n\r\n static className(btn: ToolButtonProps) {\r\n return Q.cssClass({\r\n \"tool-button\": true,\r\n \"icon-tool-button\": !!btn.icon,\r\n \"no-text\": !btn.title,\r\n disabled: btn.disabled,\r\n [btn.cssClass]: !!btn.cssClass,\r\n });\r\n }\r\n\r\n handleClick(e: React.MouseEvent) {\r\n if (!this.props.onClick || $(e.currentTarget).hasClass('disabled'))\r\n return;\r\n\r\n this.props.onClick(e);\r\n }\r\n\r\n render() {\r\n return (\r\n this.handleClick(e)}>\r\n
\r\n {this.renderButtonText()}\r\n
\r\n
\r\n );\r\n }\r\n\r\n renderButtonText() {\r\n var btn = this.props;\r\n var klass = ToolButton.adjustIconClass(btn.icon);\r\n if (!klass && !btn.title)\r\n return ;\r\n\r\n var title = Q.coalesce(btn.title, '');\r\n\r\n if (btn.htmlEncode === false) {\r\n var h = (klass ? ' ' : '') + title;\r\n return ();\r\n }\r\n\r\n if (!klass)\r\n return {title}\r\n\r\n return {title}\r\n }\r\n }\r\n\r\n export class IntraToolbar extends React.Component {\r\n\r\n public el: Element;\r\n protected mouseTrap: any;\r\n\r\n setupMouseTrap() {\r\n if (!window['Mousetrap'])\r\n return;\r\n\r\n var buttons;\r\n for (var b of (this.props.buttons || [])) {\r\n if (Q.isEmptyOrNull(b.hotkey))\r\n continue;\r\n\r\n this.mouseTrap = this.mouseTrap || window['Mousetrap'](\r\n this.props.hotkeyContext || window.document.documentElement);\r\n\r\n ((x) => {\r\n var btn = (buttons = buttons || $(this.el).find(UI.ToolButton.buttonSelector))\r\n .filter(\".\" + x.cssClass);\r\n\r\n this.mouseTrap.bind(x.hotkey, function (e: BaseJQueryEventObject, action: any) {\r\n if (btn.is(':visible')) {\r\n btn.click();\r\n }\r\n return x.hotkeyAllowDefault;\r\n });\r\n })(b);\r\n }\r\n }\r\n\r\n componentDidMount() {\r\n this.setupMouseTrap();\r\n }\r\n\r\n componentWillUnmount() {\r\n $(this.el).find(UI.ToolButton.buttonSelector).unbind('click');\r\n if (this.mouseTrap) {\r\n if (!!this.mouseTrap.destroy) {\r\n this.mouseTrap.destroy();\r\n }\r\n else {\r\n this.mouseTrap.reset();\r\n }\r\n\r\n this.mouseTrap = null;\r\n }\r\n }\r\n\r\n render() {\r\n return (\r\n this.el = el}>\r\n
\r\n {this.renderButtons(this.props.buttons || [])}\r\n
\r\n
\r\n );\r\n }\r\n\r\n renderButtons(buttons: Serenity.ToolButton[]) {\r\n var result: JSX.Element[] = [];\r\n for (var btn of buttons) {\r\n if (btn.separator)\r\n result.push();\r\n\r\n result.push();\r\n }\r\n\r\n var key = 0;\r\n return (\r\n {result.map(x => { x.key = ++key; return x; })}\r\n {this.props.children}\r\n
);\r\n }\r\n }\r\n\r\n @Decorators.registerClass(\"Serenity.UI.Toolbar\")\r\n export class Toolbar extends IntraToolbar {\r\n render() {\r\n return (\r\n \r\n {super.render()}\r\n
\r\n );\r\n }\r\n }\r\n }\r\n}","namespace Serenity.UI {\r\n export interface SaveButtonProps extends ToolButtonProps {\r\n isUpdate?: boolean;\r\n }\r\n\r\n export class SaveButton extends React.Component {\r\n\r\n render() {\r\n var title = Q.text(\"Controls.EntityDialog.\" + (this.props.isUpdate ? \"UpdateButton\" : \"SaveButton\"));\r\n\r\n return (\r\n \r\n \r\n );\r\n }\r\n\r\n }\r\n\r\n export class ApplyChangesButton extends React.Component {\r\n\r\n render() {\r\n var hint = Q.text(\"Controls.EntityDialog.ApplyChangesButton\");\r\n\r\n return (\r\n \r\n \r\n );\r\n }\r\n\r\n }\r\n\r\n export class DeleteButton extends React.Component {\r\n\r\n render() {\r\n var title = Q.text(\"Controls.EntityDialog.DeleteButton\");\r\n\r\n return (\r\n \r\n \r\n );\r\n }\r\n }\r\n}","namespace Serenity.UI { \r\n export enum FormMode {\r\n Initial = 0,\r\n New = 1,\r\n Edit = 2,\r\n View = 3,\r\n Deleted = 4\r\n }\r\n}","namespace Serenity.UI { \r\n export interface FormDataModel {\r\n entity: TEntity;\r\n entityId?: any;\r\n formMode: FormMode;\r\n formTitle?: string;\r\n onSave?: (values: TEntity) => PromiseLike;\r\n onDelete?: () => PromiseLike;\r\n onUndelete?: () => PromiseLike;\r\n onReload?: () => PromiseLike;\r\n }\r\n}","namespace Serenity.UI { \r\n\r\n export interface FormDataSourceProps {\r\n service?: string;\r\n retrieveService?: string;\r\n createService?: string;\r\n updateService?: string;\r\n entityId?: any;\r\n entity?: TEntity;\r\n idProperty?: string;\r\n nameProperty?: string;\r\n isActiveProperty?: string;\r\n isDeletedProperty?: string;\r\n localTextPrefix?: string;\r\n readOnly?: boolean;\r\n view?: (model: FormDataModel) => React.ReactNode;\r\n }\r\n\r\n export interface FormDataSourceState {\r\n entity: TEntity;\r\n formMode: FormMode;\r\n formTitle: string;\r\n localizations?: any;\r\n }\r\n\r\n export class FormDataSource extends React.Component, FormDataSourceState> {\r\n\r\n private emptyEntity: TEntity = Object.create(null);\r\n private pendingEntity: TEntity;\r\n private canSetState: boolean;\r\n\r\n constructor(props: FormDataSourceProps, context?: any) {\r\n super(props, context);\r\n\r\n var entity = this.props.entity;\r\n\r\n var mode = this.modeFor(entity);\r\n this.state = {\r\n formMode: mode,\r\n formTitle: this.titleFor(entity, mode),\r\n entity: entity\r\n };\r\n\r\n if (this.props.entityId != null)\r\n this.loadById(this.props.entityId);\r\n\r\n this.delete = this.delete.bind(this);\r\n this.save = this.save.bind(this); \r\n }\r\n\r\n componentWillReceiveProps(nextProps: FormDataSourceProps) {\r\n var nextEntityId = Q.coalesce(nextProps.entityId, null);\r\n var entityId = Q.coalesce(this.props.entityId, null);\r\n if (nextEntityId !== entityId) {\r\n if (nextEntityId === null) {\r\n this.loadEntity(nextProps.entity || Object.create(null));\r\n }\r\n else {\r\n this.loadById(nextProps.entityId);\r\n }\r\n }\r\n else if (nextProps.entity !== this.props.entity) {\r\n this.loadEntity(Q.coalesce(nextProps.entity, Object.create(null)));\r\n }\r\n }\r\n\r\n componentDidMount() {\r\n this.canSetState = true;\r\n if (this.pendingEntity !== undefined) {\r\n this.loadEntity(this.pendingEntity || Object.create(null));\r\n }\r\n }\r\n\r\n componentWillUnmount() {\r\n this.canSetState = false;\r\n }\r\n\r\n loadEntity(entity: TEntity) {\r\n if (this.canSetState) {\r\n var mode = this.modeFor(entity);\r\n this.setState({\r\n formMode: mode,\r\n formTitle: this.titleFor(entity, mode),\r\n entity: entity\r\n });\r\n this.pendingEntity = undefined;\r\n }\r\n else {\r\n this.pendingEntity = entity || null;\r\n }\r\n }\r\n\r\n loadResponse(response: RetrieveResponse) {\r\n this.loadEntity(response.Entity);\r\n }\r\n\r\n getLoadByIdRequest(entityId: any): RetrieveRequest {\r\n return {\r\n EntityId: entityId\r\n }\r\n }\r\n\r\n getServiceFor(method: string): string {\r\n\r\n var service = this.props[method.charAt(0).toLowerCase() + method.substr(1) + \"Service\"];\r\n if (service != null)\r\n return service;\r\n\r\n return (this.props.service || \"ServiceNotSet!\") + \"/\" + method;\r\n }\r\n\r\n getLoadByIdOptions(entityId: any): ServiceOptions> {\r\n return {\r\n service: this.getServiceFor(\"Retrieve\"),\r\n request: this.getLoadByIdRequest(entityId)\r\n }\r\n }\r\n\r\n loadById(entityId: any): PromiseLike> {\r\n var options = this.getLoadByIdOptions(entityId);\r\n return Q.serviceCall(options).then(response => {\r\n this.loadResponse(response);\r\n return response;\r\n });\r\n }\r\n\r\n isDeleted(entity: TEntity): boolean {\r\n if (this.props.isDeletedProperty && entity[this.props.isDeletedProperty])\r\n return true;\r\n\r\n if (this.props.isActiveProperty && entity[this.props.isActiveProperty] === -1)\r\n return true;\r\n }\r\n\r\n modeFor(entity: TEntity) {\r\n if (entity == null)\r\n return FormMode.Initial;\r\n\r\n if (this.props.readOnly)\r\n return FormMode.View;\r\n\r\n if (this.props.idProperty && entity[this.props.idProperty] != null)\r\n return FormMode.Edit;\r\n\r\n if (this.isDeleted(entity))\r\n return FormMode.Deleted;\r\n\r\n return FormMode.New;\r\n }\r\n\r\n protected getEntityName(): string {\r\n if (this.props.localTextPrefix) {\r\n var es = Q.tryGetText(\"Db.\" + this.props.localTextPrefix + '.EntitySingular');\r\n if (es)\r\n return es;\r\n }\r\n\r\n return \"Item\";\r\n }\r\n\r\n protected getNameValue(entity: TEntity): any {\r\n if (!entity || !this.props.nameProperty)\r\n return \"\";\r\n\r\n return Q.coalesce(entity[this.props.nameProperty], '').toString();\r\n }\r\n\r\n titleFor(entity: TEntity, mode: FormMode) {\r\n\r\n if (mode == FormMode.New)\r\n return Q.format(Q.text('Controls.EntityDialog.NewRecordTitle'), this.getEntityName());\r\n\r\n var title = Q.coalesce(this.getNameValue(entity), '');\r\n return Q.format(Q.text('Controls.EntityDialog.EditRecordTitle'),\r\n this.getEntityName(), (Q.isEmptyOrNull(title) ? '' : (' (' + title + ')')));\r\n }\r\n\r\n isEditMode() {\r\n return this.state.formMode == FormMode.Edit;\r\n }\r\n\r\n getSaveEntity(values: TEntity): TEntity {\r\n return values;\r\n }\r\n\r\n getSaveOptions(values: TEntity): ServiceOptions {\r\n\r\n var opt: Q.ServiceOptions = {};\r\n opt.service = this.getServiceFor(this.isEditMode() ? \"Update\" : \"Create\");\r\n opt.request = this.getSaveRequest(values);\r\n\r\n return opt;\r\n }\r\n\r\n getIdProperty() {\r\n return this.props.idProperty || \"NoIdProperty!\";\r\n }\r\n\r\n protected getLanguages(): any[] {\r\n if (Serenity.EntityDialog.defaultLanguageList != null)\r\n return Serenity.EntityDialog.defaultLanguageList() || [];\r\n\r\n return [];\r\n }\r\n\r\n protected getPendingLocalizations(): any {\r\n if (this.state.localizations == null) {\r\n return null;\r\n }\r\n\r\n var result: Q.Dictionary = {};\r\n var idField = this.getIdProperty();\r\n var langs = this.getLanguages();\r\n\r\n for (var pair of langs) {\r\n var language = pair[0];\r\n var entity: any = {};\r\n\r\n if (idField != null) {\r\n entity[idField] = this.entity[this.getIdProperty()];\r\n }\r\n\r\n var prefix = language + '$';\r\n\r\n for (var k of Object.keys(this.state.localizations)) {\r\n if (Q.startsWith(k, prefix))\r\n entity[k.substr(prefix.length)] = this.state.localizations[k];\r\n }\r\n\r\n result[language] = entity;\r\n }\r\n\r\n return result;\r\n }\r\n\r\n getSaveRequest(values: TEntity) {\r\n var entity = this.getSaveEntity(values);\r\n var req: SaveRequest = {};\r\n req.Entity = entity;\r\n\r\n if (this.isEditMode()) {\r\n var idField = this.getIdProperty();\r\n if (idField != null) {\r\n req.EntityId = this.entity[this.props.idProperty];\r\n }\r\n }\r\n\r\n if (this.state.localizations != null) {\r\n req.Localizations = this.getPendingLocalizations();\r\n }\r\n\r\n return req;\r\n }\r\n\r\n save(values: TEntity): PromiseLike {\r\n var options = this.getSaveOptions(values);\r\n return Q.serviceCall(options);\r\n }\r\n\r\n delete(): PromiseLike {\r\n return null;\r\n }\r\n\r\n undelete(): PromiseLike {\r\n return null;\r\n }\r\n\r\n getDataModel(): FormDataModel {\r\n return {\r\n entity: this.state.entity || this.emptyEntity,\r\n formMode: this.state.formMode,\r\n formTitle: this.state.formTitle,\r\n onSave: (this.state.formMode == FormMode.Edit || this.state.formMode == FormMode.New) ? this.save : null,\r\n onDelete: this.state.formMode == FormMode.Edit ? this.delete : null,\r\n onUndelete: this.state.formMode == FormMode.Deleted ? this.undelete : null,\r\n };\r\n }\r\n\r\n get dataModel() {\r\n return this.getDataModel();\r\n }\r\n\r\n get entity() {\r\n return this.pendingEntity !== undefined ? this.pendingEntity : this.state.entity;\r\n }\r\n\r\n render() {\r\n return this.props.view(this.getDataModel());\r\n }\r\n }\r\n}","namespace Serenity.UI { \r\n export interface FormViewProps extends FormDataModel {\r\n onClose?: () => void;\r\n }\r\n\r\n export class FormView = FormViewProps, TState = any>\r\n extends React.Component {\r\n\r\n protected editors = new EditorRefs();\r\n\r\n canSave(): boolean {\r\n return this.props.onSave != null;\r\n }\r\n\r\n showSave(): boolean {\r\n return this.props.formMode == FormMode.Edit || this.props.formMode == FormMode.New;\r\n }\r\n\r\n canClose(): boolean {\r\n return this.props.onClose != null;\r\n }\r\n\r\n showApplyChanges(): boolean {\r\n return this.showSave() && this.canClose();\r\n }\r\n\r\n isUpdate(): boolean {\r\n return this.props.formMode == FormMode.Edit;\r\n }\r\n\r\n canDelete(): boolean {\r\n return this.props.onDelete != null;\r\n }\r\n\r\n showDelete(): boolean {\r\n return this.props.formMode == FormMode.Edit;\r\n }\r\n\r\n canUndelete(): boolean {\r\n return this.props.onUndelete != null;\r\n }\r\n\r\n showUndelete(): boolean {\r\n return this.props.formMode == FormMode.Deleted;\r\n }\r\n\r\n loadEntity(entity: TEntity) {\r\n this.editors.loadFrom(entity);\r\n }\r\n\r\n componentDidMount() {\r\n this.loadEntity(this.props.entity || Object.create(null));\r\n }\r\n\r\n componentWillReceiveProps(nextProps: TProps) {\r\n if (nextProps.entity !== null &&\r\n this.props.entity !== nextProps.entity) {\r\n this.loadEntity(nextProps.entity || Object.create(null));\r\n }\r\n }\r\n\r\n renderSaveButton() {\r\n return this.save(true)} />;\r\n }\r\n\r\n renderApplyChangesButton() {\r\n return this.save(false)} />;\r\n }\r\n\r\n renderDeleteButton() {\r\n return ;\r\n }\r\n\r\n renderToolbar(children?: React.ReactNode) {\r\n return (\r\n \r\n {this.showSave() && this.renderSaveButton()}\r\n {this.showApplyChanges() && this.renderApplyChangesButton()}\r\n {this.showDelete() && this.renderDeleteButton()}\r\n {children}\r\n \r\n )\r\n }\r\n\r\n save(close?: boolean): PromiseLike {\r\n if (this.props.onSave == null)\r\n return Promise.reject(\"No onSave handler!\");\r\n\r\n var values: TEntity = Object.create(null);\r\n this.editors.saveTo(values);\r\n\r\n var promise = this.props.onSave(values);\r\n\r\n if (close) {\r\n if (this.props.onClose != null)\r\n promise = promise.then(e => this.props.onClose != null && this.props.onClose());\r\n }\r\n else if (this.props.onReload != null) {\r\n promise = promise.then(e => this.props.onReload != null && this.props.onReload());\r\n }\r\n\r\n return promise;\r\n }\r\n }\r\n}","namespace Serenity.UI {\r\n\r\n export class Dialog extends Serenity.TemplatedDialog {\r\n protected view: any;\r\n protected entityId: any;\r\n protected entity: any;\r\n\r\n constructor(options?: TOptions) {\r\n super(options);\r\n\r\n this.mountView();\r\n }\r\n\r\n public loadByIdAndOpenDialog(entityId: any, asPanel?: boolean) {\r\n this.entityId = entityId;\r\n this.dialogOpen(asPanel);\r\n this.mountView();\r\n }\r\n\r\n public loadEntityAndOpenDialog(entity: any, asPanel?: boolean): void {\r\n this.entityId = null;\r\n this.entity = entity;\r\n this.dialogOpen(asPanel);\r\n this.mountView();\r\n }\r\n\r\n public loadNewAndOpenDialog(asPanel?: boolean) {\r\n this.entityId = null;\r\n this.entity = {};\r\n this.dialogOpen(asPanel);\r\n this.mountView();\r\n }\r\n\r\n private mountView() {\r\n if (!this.element || !this.element.length)\r\n return;\r\n\r\n var props = Q.extend({}, this.options);\r\n this.view = ReactDOM.render(this.render() as any, this.element[0]);\r\n }\r\n\r\n getTemplate() {\r\n return '';\r\n }\r\n }\r\n}"]}