import * as React from 'react' ; import { connect } from 'react-redux' ; import { Dispatch } from 'redux' ; import { ASSET_LIST_STYLE , IAssetItem , IAssetSearchParams , LIST_ACTION } from '../../interfaces' ; import { IApplicationState } from '../../store' ; import { superdeskApi } from '../../apis' ; import { getAssetListStyle , getAssetListTotal , getAssetSearchParams , getAssetSearchResults , getAssetSetFilter , } from '../../store/assets/selectors' ; import { loadNextAssetsPage , updateAssetSearchParamsAndListItems , updateSelectedAssetIds , } from '../../store/assets/actions' ; import { isFilterPanelOpen } from '../../store/workspace/selectors' ; import { toggleFilterPanelState } from '../../store/workspace/actions' ; import { Button , ButtonGroup } from 'superdesk-ui-framework/react' ; import { Modal , ModalBody , ModalHeader } from '../../ui' ; import { PageLayout } from '../../containers/PageLayout' ; import { WorkspaceSubnav } from '../workspaceSubnav' ; import { AssetFilterPanel } from './assetFilterPanel' ; import { AssetListPanel } from './assetListPanel' ; import { showModalConnectedToStore } from '../../utils/ui' ; interface IProps { closeModal ( ) : void ; totalAssets : number ; assets : Array < IAssetItem > ; loadNextPage ( ) : Promise < void > ; toggleFilterPanel ( ) : void ; filterPanelOpen : boolean ; listStyle : ASSET_LIST_STYLE ; searchParams : IAssetSearchParams ; updateAssetSearchParamsAndListItems ( params , listAction ) : void ; onAssetsSelected ( assets ) : void ; updateSelectedAssetIds ( asset ) : void ; } interface IState { nextPageLoading : boolean ; selectedItems : Dictionary < string , IAssetItem > ; } const mapStateToProps = ( state ) => ( { totalAssets : getAssetListTotal ( state ) , assets : getAssetSearchResults ( state ) , filterPanelOpen : isFilterPanelOpen ( state ) , listStyle : getAssetListStyle ( state ) , searchParams : getAssetSearchParams ( state ) , currentSet : getAssetSetFilter ( state ) , } ) ; const mapDispatchToProps = ( dispatch ) => ( { loadNextPage : ( ) => dispatch < any > ( loadNextAssetsPage ( ) ) , updateAssetSearchParamsAndListItems : ( params , listAction ) => { dispatch < any > ( updateAssetSearchParamsAndListItems ( params , listAction ) ) ; } , toggleFilterPanel : ( ) => { dispatch < any > ( toggleFilterPanelState ( ) ) ; } , updateSelectedAssetIds : ( asset ) => dispatch ( updateSelectedAssetIds ( asset . _id ) ) , } ) ; export function showSelectAssetModal ( ) { return new Promise ( ( resolve ) => { showModalConnectedToStore < Partial < IProps > > ( SelectAssetModal , { onAssetsSelected : ( assets ) => { resolve ( assets ) ; } , } ) ; } ) ; } export class SelectAssetModalComponent extends React . Component < IProps , IState > { constructor ( props ) { super ( props ) ; this . state = { nextPageLoading : false , selectedItems : { } , } ; this . onScroll = this . onScroll . bind ( this ) ; this . toggleItemSelected = this . toggleItemSelected . bind ( this ) ; this . attachAssets = this . attachAssets . bind ( this ) ; this . closeModal = this . closeModal . bind ( this ) ; } onScroll ( event ) { const node = event . currentTarget ; if ( node != null && this . state . nextPageLoading === false && this . props . totalAssets > this . props . assets . length && node . scrollTop + node . offsetHeight + 200 >= node . scrollHeight ) { this . setState ( { nextPageLoading : true } ) ; this . props . loadNextPage ( ) . finally ( ( ) => { this . setState ( { nextPageLoading : false } ) ; } ) ; } } toggleItemSelected ( asset ) { this . setState ( ( prevState ) => { const selectedItems = { ... prevState . selectedItems } ; if ( selectedItems [ asset . _id ] == null ) { selectedItems [ asset . _id ] = asset ; } else { delete selectedItems [ asset . _id ] ; } return { selectedItems : selectedItems } ; } ) ; } attachAssets ( ) { this . props . onAssetsSelected ( this . state . selectedItems ) ; this . props . closeModal ( ) ; } closeModal ( ) { this . props . onAssetsSelected ( { } ) ; this . props . closeModal ( ) ; } render ( ) { const { gettext } = superdeskApi . localization ; const selectedAssetIds = Object . keys ( this . state . selectedItems ) ; return ( < Modal id = "SelectAssetModal" size = "fullscreen" closeModal = { this . props . closeModal } theme = "dark-ui" > < ModalHeader text = { gettext ( 'Select Asset(s)' ) } flex = { true } > < ButtonGroup align = "right" > < Button text = { gettext ( 'Cancel' ) } onClick = { this . closeModal } style = "hollow" / > < Button text = { gettext ( 'Attach Asset(s)' ) } type = "primary" onClick = { this . attachAssets } / > < /ButtonGroup> < /ModalHeader> < ModalBody noPadding = { true } > < PageLayout header = { ( < WorkspaceSubnav />)} leftPanelOpen={this.props.filterPanelOpen} leftPanel={(this.props.filterPanelOpen === false ? (<div / > ) : ( < AssetFilterPanel searchParams = { this . props . searchParams } closeFilterPanel = { this . props . toggleFilterPanel } updateAssetSearchParamsAndListItems = { this . props . updateAssetSearchParamsAndListItems } / > ) ) } mainClassName = "sd-padding--2" mainProps = { { onScroll : this . onScroll } } main = { ( < AssetListPanel assets = { this . props . assets } listStyle = { this . props . listStyle } selectedItems = { selectedAssetIds } onItemClicked = { this . toggleItemSelected } selectedAssetIds = { selectedAssetIds } updateSelectedAssetIds = { this . toggleItemSelected } / > ) } /> < /ModalBody> < /Modal>); } } export const SelectAssetModal = connect ( mapStateToProps , mapDispatchToProps ) ( SelectAssetModalComponent ) ;