// External Modules import * as React from 'react'; import {connect} from 'react-redux'; import {Dispatch} from 'redux'; // Types import {ASSET_LIST_STYLE, IAssetItem, IAssetSearchParams, LIST_ACTION} from '../../interfaces'; import {IApplicationState} from '../../store'; import {superdeskApi} from '../../apis'; // Redux Actions & Selectors 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'; // UI 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'; // Utils import {showModalConnectedToStore} from '../../utils/ui'; interface IProps { closeModal(): void; totalAssets: number; assets: Array; loadNextPage(): Promise; toggleFilterPanel(): void; filterPanelOpen: boolean; listStyle: ASSET_LIST_STYLE; searchParams: IAssetSearchParams; updateAssetSearchParamsAndListItems( params: Partial, listAction: LIST_ACTION, ): void; onAssetsSelected(assets: Dictionary): void; updateSelectedAssetIds(asset: IAssetItem): void; } interface IState { nextPageLoading: boolean; selectedItems: Dictionary; } const mapStateToProps = (state: IApplicationState) => ({ totalAssets: getAssetListTotal(state), assets: getAssetSearchResults(state), filterPanelOpen: isFilterPanelOpen(state), listStyle: getAssetListStyle(state), searchParams: getAssetSearchParams(state), currentSet: getAssetSetFilter(state), }); const mapDispatchToProps = (dispatch: Dispatch) => ({ loadNextPage: () => dispatch(loadNextAssetsPage()), updateAssetSearchParamsAndListItems: (params: Partial, listAction: LIST_ACTION) => { dispatch( updateAssetSearchParamsAndListItems( params, listAction, ), ); }, toggleFilterPanel: () => { dispatch(toggleFilterPanelState()); }, updateSelectedAssetIds: (asset: IAssetItem) => dispatch(updateSelectedAssetIds(asset._id)), }); export function showSelectAssetModal(): Promise> { return new Promise((resolve) => { showModalConnectedToStore>(SelectAssetModal, { onAssetsSelected: (assets) => { resolve(assets); }, }); }); } export class SelectAssetModalComponent extends React.Component { constructor(props: IProps) { 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: React.UIEvent) { 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: IAssetItem) { this.setState((prevState: IState) => { 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 (