| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- /*
- 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 <http://www.gnu.org/licenses/>.
- */
- 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<any>``
- 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<any>`
- display: flex;
- border-bottom: 1px solid ${ThemePalette.grayscale[5]};
- padding: 4px 8px;
- `
- const HeaderData = styled.div<any>`
- width: ${props => props.width};
- font-size: 10px;
- color: ${ThemePalette.grayscale[5]};
- font-weight: ${ThemeProps.fontWeights.medium};
- text-transform: uppercase;
- `
- const Body = styled.div<any>``
- type Props = {
- items: Task[],
- loading?: boolean,
- }
- type State = {
- openedItems: Task[],
- }
- @observer
- class Tasks extends React.Component<Props, State> {
- 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<HTMLDivElement>) {
- this.dragStartPosition = { x: e.screenX, y: e.screenY }
- }
- handleItemMouseUp(e: React.MouseEvent<HTMLDivElement>, 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 (
- <LoadingWrapper>
- <StatusImage loading />
- </LoadingWrapper>
- )
- }
- renderHeader() {
- return (
- <Header>
- <HeaderData width={ColumnWidths[0]}>Task</HeaderData>
- <HeaderData width={ColumnWidths[1]}>Instance</HeaderData>
- <HeaderData width={ColumnWidths[2]}>Latest Message</HeaderData>
- <HeaderData width={ColumnWidths[3]}>Timestamp</HeaderData>
- </Header>
- )
- }
- renderBody() {
- return (
- <Body>
- {this.props.items.map(item => (
- <TaskItem
- onMouseDown={e => 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}`}
- />
- ))}
- </Body>
- )
- }
- renderContent() {
- return (
- <ContentWrapper>
- {this.renderHeader()}
- {this.renderBody()}
- </ContentWrapper>
- )
- }
- render() {
- return (
- <Wrapper>
- {!this.isLoading ? this.renderContent() : null}
- {this.isLoading ? this.renderLoading() : null}
- </Wrapper>
- )
- }
- }
- export default Tasks
|