/* Copyright (C) 2017 Cloudbase Solutions SRL This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ import React from 'react' import { observer } from 'mobx-react' import styled from 'styled-components' import TaskItem from '@src/components/modules/TransferModule/TaskItem/TaskItem' import type { Task } from '@src/@types/Task' import { ThemePalette, ThemeProps } from '@src/components/Theme' import StatusImage from '@src/components/ui/StatusComponents/StatusImage/StatusImage' const ColumnWidths = ['26%', '18%', '36%', '20%'] const Wrapper = styled.div`` const ContentWrapper = styled.div` background: ${ThemePalette.grayscale[1]}; ` const LoadingWrapper = styled.div` display: flex; align-items: center; justify-content: center; padding: 64px; ` const Header = styled.div` display: flex; border-bottom: 1px solid ${ThemePalette.grayscale[5]}; padding: 4px 8px; ` const HeaderData = styled.div` width: ${props => props.width}; font-size: 10px; color: ${ThemePalette.grayscale[5]}; font-weight: ${ThemeProps.fontWeights.medium}; text-transform: uppercase; ` const Body = styled.div`` type Props = { items: Task[], loading?: boolean, } type State = { openedItems: Task[], } @observer class Tasks extends React.Component { state: State = { openedItems: [], } dragStartPosition: { x: number, y: number } | null = null UNSAFE_componentWillMount() { this.UNSAFE_componentWillReceiveProps(this.props) } UNSAFE_componentWillReceiveProps(props: Props) { this.setState(prevState => { let openedItems = prevState.openedItems props.items.forEach(item => { if (item.status === 'RUNNING') { openedItems.push(item) return } // Close items that were previously in RUNNING state, but they no longer are const oldItem = this.props.items.find(i => i.id === item.id) if (oldItem && oldItem.status === 'RUNNING') { openedItems = openedItems.filter(i => i.id !== oldItem.id) } }) return { openedItems } }) } get isLoading() { return this.props.loading || this.props.items.length === 0 } handleItemMouseDown(e: React.MouseEvent) { this.dragStartPosition = { x: e.screenX, y: e.screenY } } handleItemMouseUp(e: React.MouseEvent, item: Task) { this.dragStartPosition = this.dragStartPosition || { x: e.screenX, y: e.screenY } if (this.dragStartPosition && Math.abs(this.dragStartPosition.x - e.screenX) < 3 && Math.abs(this.dragStartPosition.y - e.screenY) < 3) { this.toggleItem(item) } this.dragStartPosition = null } handleDependsOnClick(id: string) { const item = this.props.items.find(i => i.id === id) if (item) this.toggleItem(item) } toggleItem(item: Task) { this.setState(prevState => { let openedItems = prevState.openedItems if (openedItems.find(i => i.id === item.id)) { openedItems = openedItems.filter(i => i.id !== item.id) } else { openedItems = openedItems.filter(i => i.status === 'RUNNING') openedItems.push(item) } return { openedItems } }) } renderLoading() { return ( ) } renderHeader() { return (
Task Instance Latest Message Timestamp
) } renderBody() { return ( {this.props.items.map(item => ( this.handleItemMouseDown(e)} onMouseUp={e => this.handleItemMouseUp(e, item)} key={item.id} item={item} columnWidths={ColumnWidths} open={Boolean(this.state.openedItems.find(i => i.id === item.id))} onDependsOnClick={id => { this.handleDependsOnClick(id) }} data-test-id={`tasks-item-${item.id}`} /> ))} ) } renderContent() { return ( {this.renderHeader()} {this.renderBody()} ) } render() { return ( {!this.isLoading ? this.renderContent() : null} {this.isLoading ? this.renderLoading() : null} ) } } export default Tasks