/** * Created by rburson on 3/18/16. */ import * as React from 'react' import { CvActionFiredResult, CvState, CvProps, CvBaseMixin, CvContext, CvNavigationResult, CvDetailsPane, CvDetailsPaneCallback, CvRecord, CvStateChangeResult, CvEvent, CvValueProvider, CvActionHandlerParams, CvValueListener, CvImagePackageDelete, CvImagePackagePick, CvImagePackageUndo, CvImageProducer } from 'catreact' import { CvCellValueDef, CvDataAnno, CvImageDefaultAddButtonClass, CvImageDefaultRemoveButtonClass, CvImageDefaultUndoButtonClass } from './catreact-html' import { FormContext, EntityRec, DetailsContext, CellValueDef, CellDef, ForcedLineCellValueDef, LabelCellValueDef, AttributeCellValueDef } from 'catavolt-sdk' import {openSignaturePopup} from "./CvSignaturePopup"; import {CvImageDefaultSignatureButtonClass} from "./CvImage"; export interface CvDetailsPanelState extends CvState { } /** * Details Panel Properties */ export interface CvDetailsPanelProps extends CvProps { formContext?:FormContext; paneRef?:number; detailsContext?:DetailsContext; navigationListeners?:Array<(event:CvEvent)=>void>; stateChangeListeners?:Array<(event:CvEvent)=>void>; actionListeners?:Array<(event:CvEvent)=>void>; actionProvider?:CvValueProvider; } let FORCED_LINE_DEF:ForcedLineCellValueDef = new ForcedLineCellValueDef(); /** * Renders a Details Panel, styled by CSS */ export let CvDetailsPanel = React.createClass({ mixins: [CvBaseMixin], render: function () { return { const detailsContext:DetailsContext = cvContext.scopeCtx.scopeObj; return ( { return (
{(()=>{ if(detailsContext.detailsDef.editable) { if(detailsContext.isReadMode) { return
} else if (detailsContext.isWriteMode){ const cancelButtonText = detailsContext.detailsDef.cancelButtonText; const commitButtonText = detailsContext.detailsDef.commitButtonText; return
} } else { return null } })()}
{this._layoutDetailsPane(detailsContext, record, detailsCallback)}
{(()=>{ const cancelButtonText = detailsContext.detailsDef.cancelButtonText; const commitButtonText = detailsContext.detailsDef.commitButtonText; return (detailsContext.detailsDef.editable && detailsContext.isWriteMode) ?
: null; })()}
); }}/> ); }}/> }, _layoutDetailsPane: function (detailsContext:DetailsContext, record:EntityRec, detailsCallback:CvDetailsPaneCallback) { const renderedDetailRows = []; if(detailsContext) { const outterColumns:number = detailsContext.detailsDef.rows.reduce((prv1, cellDefRow:CellDef[]) => { return Math.max(prv1, cellDefRow.length); }, 0); detailsContext.detailsDef.rows.forEach((cellDefRow:Array, index)=> { renderedDetailRows.push( {(()=>{ return cellDefRow.map((cellDef:CellDef, index:number)=>{ // Each cellDef represents a column let columnsInThisRow = cellDefRow.length; let colspan = ((index+1) == columnsInThisRow) ? outterColumns - columnsInThisRow + 1 : 1; let answer = null; if (cellDef.values.length <= 1) { let cellValueDef:CellValueDef = (cellDef.values.length == 1) ? cellDef.values[0] : FORCED_LINE_DEF; answer = } else { // If there are more than one cellDef.value they should be built in a sub-table to keep the parent column in tact. answer = {(()=>{ return cellDef.values.map((cellValueDef:CellValueDef, i2:number)=>{ // These are both labels and attributes return }); })()}
} return answer; }); })()}
); }); } return renderedDetailRows; }, _buildImageProducers(detailsContext:DetailsContext, cellValueDef:CellValueDef) { let imageProducers:Array = null; if (!this._isReadModeFor(detailsContext, cellValueDef)) { if (cellValueDef instanceof AttributeCellValueDef && detailsContext.isSignature(cellValueDef)) { imageProducers = [ { prodImageCB: (listener: CvValueListener)=> { openSignaturePopup(listener); }, buttonClassName: CvImageDefaultSignatureButtonClass, includeWhenImageisPresent: true, includeWhenImageIsMissing: true, includeWhenImageIsDeleted: true } ]; } else { imageProducers = [ { // Pick a new file with the file chooser. prodImageCB: (listener: CvValueListener) => { listener(new CvImagePackagePick()) }, buttonClassName: CvImageDefaultAddButtonClass, includeWhenImageisPresent: true, includeWhenImageIsMissing: true, includeWhenImageIsDeleted: true }, { // Delete existing image prodImageCB: (listener: CvValueListener) => { listener(new CvImagePackageDelete()) }, buttonClassName: CvImageDefaultRemoveButtonClass, includeWhenImageisPresent: true, includeWhenImageIsMissing: false, includeWhenImageIsDeleted: false }, { // Undo previous delete image prodImageCB: (listener: CvValueListener) => { listener(new CvImagePackageUndo()) }, buttonClassName: CvImageDefaultUndoButtonClass, includeWhenImageisPresent: false, includeWhenImageIsMissing: false, includeWhenImageIsDeleted: true } ]; } } return imageProducers; }, _isReadModeFor(detailsContext:DetailsContext, cellValueDef:CellValueDef) { return cellValueDef instanceof AttributeCellValueDef && detailsContext.isReadModeFor((cellValueDef as AttributeCellValueDef).propertyName); }, _openWriteMode: function(detailsCallback:CvDetailsPaneCallback) { detailsCallback.openWriteMode((success, error)=>{ }); }, _openReadMode: function(detailsCallback:CvDetailsPaneCallback) { detailsCallback.openReadMode((success, error)=>{ }); }, _refresh: function(detailsCallback:CvDetailsPaneCallback) { detailsCallback.refresh(); }, _save: function(detailsCallback:CvDetailsPaneCallback) { detailsCallback.saveChanges((success, error)=>{ }); } }); export let CvDetailsPanelCommitCancelControls = React.createClass<{cancelButtonText:string, commitButtonText:string, onCancel:()=>{}, onCommit:()=>{}}, {}>({ render: function() { const {cancelButtonText, commitButtonText, onCancel, onCommit} = this.props; return
} }); export let CvDetailsPanelControls = React.createClass<{onRefresh:()=>{}, onEdit:()=>{}}, {}>({ render: function() { return
} });