Skip to content
This repository has been archived by the owner on Dec 13, 2020. It is now read-only.

Commit

Permalink
Merge pull request #916 from metasfresh/dev-833
Browse files Browse the repository at this point in the history
Dev 833
  • Loading branch information
damianprzygodzki authored Jun 20, 2017
2 parents a0dcc22 + f67181d commit 0dd03f6
Show file tree
Hide file tree
Showing 13 changed files with 704 additions and 11 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
"react-dnd-html5-backend": "~2.1.2",
"react-dom": "~15.5.0",
"react-dropzone": "~3.9.2",
"react-infinite-scroller": "^1.0.12",
"react-interpolate-component": "~0.11.0",
"react-onclickoutside": "~5.3.3",
"react-redux": "~4.4.5",
Expand Down
32 changes: 32 additions & 0 deletions src/actions/BoardActions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import axios from 'axios';

export function getView(boardId, viewId, firstRow) {
return axios.get(
config.API_URL +
'/board/' + boardId +
'/newCardsView' +
(viewId ? '/' + viewId : '') +
(viewId ? '?firstRow=' + firstRow + '&pageLength=50' : '')
);
}

export function addCard(boardId, laneId, cardId, index) {
return axios.post(
config.API_URL +
'/board/' + boardId +
'/card', {
'laneId': laneId,
'position': index,
'documentId': cardId
}
);
}

export function filterCards(boardId, viewId) {
return axios.post(
config.API_URL +
'/board/' + boardId +
'/newVardsView/' + viewId +
'/filter'
);
}
79 changes: 79 additions & 0 deletions src/assets/css/board.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
.board {
height: calc(100vh - 55px);
background-color: #fff;
padding: .4rem;
}

.board-header {
padding: .5rem;
}

.board-lanes {
display: flex;
flex-direction: row;
align-items: stretch;
overflow-x: scroll;
overflow-y: hidden;
height: calc(100% - 55px);
}

.board-lane {
border: 1px solid $brand-border-color;
}

.board-lane-placeholder {
opacity: .8;
}

.board-lane,
.board-lane-placeholder {
min-width: 25%;
border-radius: 3px;
margin-right: 3px;
background-color: $brand-bright-color;
}

.board-draggable-wrapper, .board-draggable-placeholder > * {
height: 100%;
}

.board-lane-header {
border-bottom: 1px solid $brand-border-color;
padding: .4rem;
}

.card {
margin: .4rem;
padding: .4rem;
background-color: #fff;
border: 1px solid $brand-border-color;
}

.lane-card-placeholder {
height:2px;
width: calc(100% - .8rem);
margin: .4rem;
background-color: $brand-success-color;
}

.board-sidenav {
position: fixed;
top: 55px;
right: 0;
width:25%;
height: calc(100% - 55px);
z-index: 999;
background-color: $brand-bright-color;
overflow-y: auto;
}

.board-sidenav-header {
background-color: $brand-color-primary;
color: #fff;
text-align: center;
padding: .4rem;
}

.card-placeholder {
height: 100%;
}
8 changes: 7 additions & 1 deletion src/assets/css/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
@import './variables.css';
@import './focus.css';


@import './board.css';
@import './charts.css';
@import './charts.css';
@import './daterangepicker.css';
@import './datetime.css';
Expand Down Expand Up @@ -1178,6 +1179,11 @@ td.pulse-off input {
height: 35px;
}

.avatar-sm {
width: 25px;
height: 25px;
}

.avatar-container {
width: 100%;
height: 100%;
Expand Down
26 changes: 26 additions & 0 deletions src/components/app/Avatar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React, { Component } from 'react';
import defaultAvatar from '../../assets/images/default-avatar.png';
import {getAvatar} from '../../actions/AppActions';

class Avatar extends Component {
constructor(props) {
super(props);
}

render() {
const {size, className, id, title} = this.props;
return (
<img
src={id ? getAvatar(id) : defaultAvatar}
title={title}
className={
'avatar img-fluid rounded-circle ' +
(size ? 'avatar-' + size + ' ' : '') +
(className ? className : '')
}
/>
);
}
}

export default Avatar;
133 changes: 133 additions & 0 deletions src/components/board/Card.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
import React, { Component } from 'react';
import Avatar from '../app/Avatar';
import { DragSource, DropTarget } from 'react-dnd';
import ItemTypes from '../../constants/ItemTypes';

const cardTarget = {
drop(props, monitor) {
props.onDrop && props.onDrop(monitor.getItem(), props.laneId);
},
hover(props, monitor) {
if(
!props.onHover
){
return;
}

if(
monitor.getItem().index === props.index &&
props.laneId === monitor.getItem().laneId
){
return;
}

props.onHover(monitor.getItem(), props.laneId, props.index);

monitor.getItem().index = props.index;
monitor.getItem().laneId = props.laneId;
}
};

function connect(connect) {
return {
connectDropTarget: connect.dropTarget()
};
}

const cardSource = {
beginDrag(props) {
return {
id: props.cardId,
index: props.index,
initLaneId: props.laneId,
laneId: props.laneId
};
},
endDrag(props) {
props.onReject && props.onReject();
}
};

function collect(connect, monitor) {
return {
connectDragSource: connect.dragSource(),
isDragging: monitor.isDragging()
};
}

const TargetIndicator = (props) => {
const {index, laneId, parentIndex, parentLaneId} = props;
if(laneId !== parentLaneId || index !== parentIndex) return false;
return (<div className="lane-card-placeholder" />);
}

class Card extends Component {
constructor(props) {
super(props);

this.state = {
mouseOn: false
}
}

renderCard = () => {
const {
caption, description, users, placeholder, connectDragSource,
connectDropTarget, onDelete, cardId, laneId
} = this.props;

const {mouseOn} = this.state;

if(placeholder){
return connectDropTarget(<div className="card-placeholder" />);
}else{
return connectDragSource(connectDropTarget(
<div className="card">
{mouseOn && onDelete && <i
className="pointer meta-icon-close-1 float-xs-right"
onClick={() => onDelete(laneId, cardId)}
/>}
<b>{caption}</b>
<p>{description}</p>
{users.map((user, i) =>
<Avatar
key={i}
id={user.avatarId}
className="float-xs-right"
size="sm"
title={user.fullname}
/>
)}
<span className="clearfix"/>
</div>
));
}
}

render() {
const {
targetIndicator, index, laneId
} = this.props;

return (
<div
onMouseEnter={() => this.setState({mouseOn: true})}
onMouseLeave={() => this.setState({mouseOn: false})}
>
{targetIndicator && <TargetIndicator
{...targetIndicator}
parentIndex={index}
parentLaneId={laneId}
/>}
{this.renderCard()}
</div>
);
}
}

Card = DragSource(ItemTypes.CARD, cardSource, collect)(
DropTarget(ItemTypes.CARD, cardTarget, connect)(
Card
));

export default Card;
48 changes: 48 additions & 0 deletions src/components/board/Lane.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React, { Component } from 'react';
import Card from './Card';

class Lane extends Component {
constructor(props) {
super(props);
}

render() {
const {
caption, cards, laneId, onHover, onDrop, targetIndicator, onReject,
onDelete, placeholder
} = this.props;

if(placeholder){
return (<div className="board-lane-placeholder" />)
}

return (
<div className="board-lane">
<div className="board-lane-header">{caption}</div>
<div
className={
'board-draggable-wrapper ' +
(!cards.length ? 'board-draggable-placeholder ' : '')
}
>
{!cards.length && <Card
index={0}
{...{laneId, onHover, onDrop, targetIndicator}}
placeholder={true} />
}
{cards.map((card, i) => <Card
key={i}
index={i}
{...{
laneId, onHover, onDrop, onReject, targetIndicator,
onDelete
}}
{...card} />
)}
</div>
</div>
);
}
}

export default Lane;
35 changes: 35 additions & 0 deletions src/components/board/Lanes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React, { Component } from 'react';
import Lane from './Lane';

class Lanes extends Component {
constructor(props) {
super(props);
}

render() {
const {
lanes, onDrop, onHover, onReject, onDelete, targetIndicator
} = this.props;

if(!lanes) return false;

return (
<div className="board-lanes">
{lanes.map((lane, i) => (
<Lane
key={i}
{...{
onDrop, onHover, onDelete, onReject, targetIndicator
}}
{...lane}
/>)
)}
<Lane
placeholder={true}
/>
</div>
);
}
}

export default Lanes;
Loading

0 comments on commit 0dd03f6

Please sign in to comment.