/**
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */ import * as React from 'react' ; import * as CLM from '@conversationlearner/models' ; import * as OF from 'office-ui-fabric-react' ; import * as Util from '../../Utils/util' ; import { bindActionCreators } from 'redux' ; import { connect } from 'react-redux' ; import { State } from '../../types' ; import { injectIntl , InjectedIntlProps } from 'react-intl' ; import { FM } from '../../react-intl-messages' ; import './MemorySetter.css' ; import { autobind } from 'core-decorators' ; class MemorySetter extends React . Component < Props > { constructor ( props ) { super ( props ) ; } @ autobind onClickAdd ( entity ) { const map = Util . deepCopy ( this . props . map ) ; this . addEntity ( map , entity ) ; this . props . onUpdate ( map ) ; } @ autobind onClickRemove ( index , entity ) { const map = Util . deepCopy ( this . props . map ) ; map [ entity . entityName ] . values . splice ( index , 1 ) ; if ( map [ entity . entityName ] . values . length === 0 ) { delete map [ entity . entityName ] ; } this . props . onUpdate ( map ) ; } @ autobind onClickNext ( index , entity ) { const editableEntities = this . getEditableEntities ( ) ; const map = Util . deepCopy ( this . props . map ) ; const removedValue = map [ entity . entityName ] . values . splice ( index , 1 ) ; if ( map [ entity . entityName ] . values . length === 0 ) { delete map [ entity . entityName ] ; } const removeIndex = editableEntities . findIndex ( e => e . entityId === entity . entityId ) ; let insertIndex = removeIndex + 1 ; if ( insertIndex === editableEntities . length ) { insertIndex = 0 ; } const insertEntity = editableEntities [ insertIndex ] ; this . insertValue ( map , insertEntity , removedValue [ 0 ] ) ; } @ autobind onClickPrev ( index , entity ) { const editableEntities = this . getEditableEntities ( ) ; const map = Util . deepCopy ( this . props . map ) ; const removedValue = map [ entity . entityName ] . values . splice ( index , 1 ) ; if ( map [ entity . entityName ] . values . length === 0 ) { delete map [ entity . entityName ] ; } const removeIndex = editableEntities . findIndex ( e => e . entityId === entity . entityId ) ; let insertIndex = removeIndex - 1 ; if ( insertIndex < 0 ) { insertIndex = editableEntities . length - 1 ; } const insertEntity = editableEntities [ insertIndex ] ; this . insertValue ( map , insertEntity , removedValue [ 0 ] ) ; } insertValue ( map , entity , value ) { if ( ! map [ entity . entityName ] ) { this . addEntity ( map , entity ) ; map [ entity . entityName ] . values = [ value ] ; } else { map [ entity . entityName ] . values . push ( value ) ; } this . props . onUpdate ( map ) ; } addEntity ( map , entity ) { const memoryValue = { userText : '' , displayText : null , builtinType : null , resolution : { } } ; if ( ! map [ entity . entityName ] ) { map [ entity . entityName ] = { entityId : entity . entityId , values : [ memoryValue ] } ; } else { map [ entity . entityName ] . values . push ( memoryValue ) ; } } onEnumChange ( item , entity ) { if ( ! item ) { return ; } const map = Util . deepCopy ( this . props . map ) ; map [ entity . entityName ] . values [ 0 ] . displayText = item . text ; map [ entity . entityName ] . values [ 0 ] . userText = item . text ; map [ entity . entityName ] . values [ 0 ] . enumValueId = item . key as string ; this . props . onUpdate ( map ) ; } onChange ( index , text , entity ) { if ( typeof text !== 'string' ) { return ; } const map = Util . deepCopy ( this . props . map ) ; map [ entity . entityName ] . values [ index ] . userText = text ; this . props . onUpdate ( map ) ; } getEditableEntities ( ) { return this . props . entities . filter ( entity => ! entity . positiveId && ! entity . doNotMemorize ) ; } render ( ) { const { intl } = this . props ; const editableEntities = this . getEditableEntities ( ) ; return ( < div > { editableEntities . map ( entity => { return ( < div className = "cl-memory-setter-block" key = { entity . entityId } > < OF . Label className = "cl-label cl-font--emphasis" data - testid = "teach-session-entity-name" > { entity . entityName } < /OF.Label> < OF . IconButton className = "cl-icon-plain" data - testid = "teach-session-add-initial-value" disabled = { ! entity . isMultivalue && this . props . map [ entity . entityName ] !== undefined } onClick = { ( ) => this . onClickAdd ( entity ) } ariaDescription = "Add Initial Value" iconProps = { { iconName : 'AddTo' } } /> { this . props . map [ entity . entityName ] && this . props . map [ entity . entityName ] . values . map ( ( memoryValue , index ) => { const key = `${ entity . entityId }+${ index }` ; return ( < div className = "cl-modal-buttons_primary" key = { key } > { entity . entityType === CLM . EntityType . ENUM ? < OF . Dropdown className = "cl-input--inline" selectedKey = { memoryValue . enumValueId ?? undefined } onChange = { ( event , item ) => this . onEnumChange ( item , entity ) } options = { entity . enumValues ! . map < OF . IDropdownOption > ( ev => { return { key : ev . enumValueId ! , text : ev . enumValue ! } ; } ) } / > : < OF . TextField data - testid = "teach-session-initial-value" className = "cl-input--inline" key = { key } onChange = { ( event , text ) => this . onChange ( index , text , entity ) } placeholder = { intl . formatMessage ( { id : FM . TEACHSESSIONINIT_INPUT_PLACEHOLDER , defaultMessage : "Value..." } ) } value = { memoryValue . userText ?? '' } / > } { ( editableEntities . length > 1 ) && < OF . IconButton className = "cl-icon-plain" onClick = { ( ) => this . onClickNext ( index , entity ) } ariaDescription = "Move to next Entity" text = "" iconProps = { { iconName : 'Down' } } />} { ( editableEntities . length > 1 ) && < OF . IconButton className = "cl-icon-plain" onClick = { ( ) => this . onClickPrev ( index , entity ) } ariaDescription = "Move to previous Entity" text = "" iconProps = { { iconName : 'Up' } } />} < OF . IconButton className = "cl-icon-warning" onClick = { ( ) => this . onClickRemove ( index , entity ) } ariaDescription = "Remove Value" iconProps = { { iconName : 'Delete' } } /> < /div>); } ) } < /div>); } ) } < /div>); } } const mapDispatchToProps = ( dispatch ) => { return bindActionCreators ( { } , dispatch ) ; } ; const mapStateToProps = ( state ) => { return { entities : state . entities } ; } ; export interface ReceivedProps { map : { [ key ] : CLM . FilledEntity ; } ; onUpdate : ( filledEntityMap : { [ key ] : CLM . FilledEntity ; } ) => void ; } type stateProps = ReturnType < typeof mapStateToProps > ; type dispatchProps = ReturnType < typeof mapDispatchToProps > ; type Props = stateProps & dispatchProps & ReceivedProps & InjectedIntlProps ; export default connect < stateProps , dispatchProps , ReceivedProps > ( mapStateToProps , mapDispatchToProps ) ( injectIntl ( MemorySetter ) ) ;