import * as React from 'react'; import { DragDropContext, Droppable } from 'react-beautiful-dnd'; import I18n from 'i18n-js'; import Box from '../../common/Box'; import RoadmapEmbedding from './RoadmapEmbedding'; import SiteSettingsInfoBox from '../../common/SiteSettingsInfoBox'; import RoadmapPostStatus from './RoadmapPostStatus'; import IPostStatus from '../../../interfaces/IPostStatus'; import { PostStatusesState } from "../../../reducers/postStatusesReducer"; import { MutedText } from '../../common/CustomTexts'; interface Props { embeddedRoadmapUrl: string, authenticityToken: string, postStatuses: PostStatusesState, settingsAreUpdating: boolean, settingsError: string, requestPostStatuses(): void; updatePostStatus( id: number, showInRoadmap: boolean, onComplete: Function, authenticityToken: string, ): void; } interface State { isDragging: number; } class RoadmapSiteSettingsP extends React.Component { constructor(props: Props) { super(props); this.state = { isDragging: null, }; this.handleDragStart = this.handleDragStart.bind(this); this.handleDragEnd = this.handleDragEnd.bind(this); } componentDidMount() { this.props.requestPostStatuses(); } handleDragStart(result) { this.setState({ isDragging: parseInt(result.draggableId) }); } handleDragEnd(result) { if (result.destination == null || result.source.droppableId === result.destination.droppableId) { this.setState({ isDragging: null }); return; } this.props.updatePostStatus( result.draggableId, result.destination.droppableId === 'statusesInRoadmap', () => this.setState({ isDragging: null }), this.props.authenticityToken, ); } // Workaround needed because after dropping a post status, the state is not yet updated // with the new showInRoadmap value (we need to wait POSTSTATUS_UPDATE_SUCCESS dispatch) // and the UI would flicker, moving the poststatus back in its original spot placeDraggingStatusDuringUpdate(statusesInRoadmap: IPostStatus[], statusesNotInRoadmap: IPostStatus[]) { const { postStatuses } = this.props; const movedPostStatus = postStatuses.items.find(postStatus => postStatus.id === this.state.isDragging); if (movedPostStatus.showInRoadmap) { statusesInRoadmap = statusesInRoadmap.filter(postStatus => postStatus.id !== this.state.isDragging); statusesNotInRoadmap.push(movedPostStatus); statusesNotInRoadmap.sort((ps1, ps2) => ps1.order - ps2.order); } else { statusesNotInRoadmap = statusesNotInRoadmap.filter(postStatus => postStatus.id !== this.state.isDragging); statusesInRoadmap.push(movedPostStatus); statusesInRoadmap.sort((ps1, ps2) => ps1.order - ps2.order); } return [statusesInRoadmap, statusesNotInRoadmap]; } render() { const { embeddedRoadmapUrl, postStatuses, settingsAreUpdating, settingsError } = this.props; const { isDragging } = this.state; let statusesInRoadmap = postStatuses.items.filter(postStatus => postStatus.showInRoadmap); let statusesNotInRoadmap = postStatuses.items.filter(postStatus => !postStatus.showInRoadmap); if (settingsAreUpdating && this.state.isDragging) { [statusesInRoadmap, statusesNotInRoadmap] = this.placeDraggingStatusDuringUpdate(statusesInRoadmap, statusesNotInRoadmap); } return (

{I18n.t('site_settings.roadmap.title')}

{(provided, snapshot) => (
{statusesInRoadmap.map((postStatus, i) => ( ))} {provided.placeholder}
)}
{ statusesInRoadmap.length > 0 ? null : {I18n.t('site_settings.roadmap.empty')} } {I18n.t('site_settings.roadmap.help')}

{I18n.t('site_settings.roadmap.title2')}

{(provided, snapshot) => (
{statusesNotInRoadmap.map((postStatus, i) => ( ))} {provided.placeholder}
)}
); } } export default RoadmapSiteSettingsP;