Compare commits
10 Commits
Author | SHA1 | Date | |
---|---|---|---|
0af54a0d52 | |||
d8dcf636ea | |||
6bb8afd914 | |||
3eb96fc75e | |||
d6597270dd | |||
fbad143bed | |||
e3459d136e | |||
fe0e2667a0 | |||
0e93e7c52f | |||
832cca1c66 |
69
client/package-lock.json
generated
69
client/package-lock.json
generated
@ -1162,22 +1162,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@babel/runtime-corejs2": {
|
|
||||||
"version": "7.7.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.7.4.tgz",
|
|
||||||
"integrity": "sha512-hKNcmHQbBSJFnZ82ewYtWDZ3fXkP/l1XcfRtm7c8gHPM/DMecJtFFBEp7KMLZTuHwwb7RfemHdsEnd7L916Z6A==",
|
|
||||||
"requires": {
|
|
||||||
"core-js": "^2.6.5",
|
|
||||||
"regenerator-runtime": "^0.13.2"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"regenerator-runtime": {
|
|
||||||
"version": "0.13.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz",
|
|
||||||
"integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw=="
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"@babel/template": {
|
"@babel/template": {
|
||||||
"version": "7.7.0",
|
"version": "7.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.0.tgz",
|
||||||
@ -1259,11 +1243,11 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@lourenci/react-kanban": {
|
"@lourenci/react-kanban": {
|
||||||
"version": "0.15.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@lourenci/react-kanban/-/react-kanban-0.15.0.tgz",
|
"resolved": "https://registry.npmjs.org/@lourenci/react-kanban/-/react-kanban-2.0.0.tgz",
|
||||||
"integrity": "sha512-/2XjB26iXcvpwDwlT3sz8/ptQ7QyTpMGlrPf1f02+V1Z4jdbVMo6Luz1sGlHe/TP68N8yz69/YT9qwqHZ6YYmQ==",
|
"integrity": "sha512-ieNi7d/01wgT9t8kN7Z/RBubyZq9VvKXyU/5sj+UlrY8h4GPRNrN11jLV/ykg55lhyXGKgXDk3ObYurOfrmu3w==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"react-beautiful-dnd": "^11.0.0"
|
"react-beautiful-dnd": "^13.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@redux-saga/core": {
|
"@redux-saga/core": {
|
||||||
@ -2530,7 +2514,8 @@
|
|||||||
"core-js": {
|
"core-js": {
|
||||||
"version": "2.6.10",
|
"version": "2.6.10",
|
||||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.10.tgz",
|
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.10.tgz",
|
||||||
"integrity": "sha512-I39t74+4t+zau64EN1fE5v2W31Adtc/REhzWN+gWRRXg6WH5qAsZm62DHpQ1+Yhe4047T55jvzz7MUqF/dBBlA=="
|
"integrity": "sha512-I39t74+4t+zau64EN1fE5v2W31Adtc/REhzWN+gWRRXg6WH5qAsZm62DHpQ1+Yhe4047T55jvzz7MUqF/dBBlA==",
|
||||||
|
"dev": true
|
||||||
},
|
},
|
||||||
"core-js-compat": {
|
"core-js-compat": {
|
||||||
"version": "3.4.1",
|
"version": "3.4.1",
|
||||||
@ -2635,9 +2620,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"css-box-model": {
|
"css-box-model": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/css-box-model/-/css-box-model-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/css-box-model/-/css-box-model-1.2.1.tgz",
|
||||||
"integrity": "sha512-lri0br+jSNV0kkkiGEp9y9y3Njq2PmpqbeGWRFQJuZteZzY9iC9GZhQ8Y4WpPwM/2YocjHePxy14igJY7YKzkA==",
|
"integrity": "sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"tiny-invariant": "^1.0.6"
|
"tiny-invariant": "^1.0.6"
|
||||||
}
|
}
|
||||||
@ -6201,18 +6186,32 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"react-beautiful-dnd": {
|
"react-beautiful-dnd": {
|
||||||
"version": "11.0.5",
|
"version": "13.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/react-beautiful-dnd/-/react-beautiful-dnd-11.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/react-beautiful-dnd/-/react-beautiful-dnd-13.0.0.tgz",
|
||||||
"integrity": "sha512-7llby9U+jIfkINcyxPHVWU0HFYzqxMemUYgGHsFsbx4fZo1n/pW6sYKYzhxGxR3Ap5HxqswcQkKUZX4uEUWhlw==",
|
"integrity": "sha512-87It8sN0ineoC3nBW0SbQuTFXM6bUqM62uJGY4BtTf0yzPl8/3+bHMWkgIe0Z6m8e+gJgjWxefGRVfpE3VcdEg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/runtime-corejs2": "^7.4.5",
|
"@babel/runtime": "^7.8.4",
|
||||||
"css-box-model": "^1.1.2",
|
"css-box-model": "^1.2.0",
|
||||||
"memoize-one": "^5.0.4",
|
"memoize-one": "^5.1.1",
|
||||||
"raf-schd": "^4.0.0",
|
"raf-schd": "^4.0.2",
|
||||||
"react-redux": "^7.0.3",
|
"react-redux": "^7.1.1",
|
||||||
"redux": "^4.0.1",
|
"redux": "^4.0.4",
|
||||||
"tiny-invariant": "^1.0.4",
|
"use-memo-one": "^1.1.1"
|
||||||
"use-memo-one": "^1.1.0"
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": {
|
||||||
|
"version": "7.10.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.2.tgz",
|
||||||
|
"integrity": "sha512-6sF3uQw2ivImfVIl62RZ7MXhO2tap69WeWK57vAaimT6AZbE4FbqjdEJIN1UqoD6wI6B+1n9UiagafH1sxjOtg==",
|
||||||
|
"requires": {
|
||||||
|
"regenerator-runtime": "^0.13.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"regenerator-runtime": {
|
||||||
|
"version": "0.13.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz",
|
||||||
|
"integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA=="
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"react-dom": {
|
"react-dom": {
|
||||||
|
@ -48,7 +48,7 @@
|
|||||||
"ts-loader": "^7.0.2"
|
"ts-loader": "^7.0.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@lourenci/react-kanban": "^0.15.0",
|
"@lourenci/react-kanban": "^2.0.0",
|
||||||
"bulma": "^0.7.2",
|
"bulma": "^0.7.2",
|
||||||
"bulma-switch": "^2.0.0",
|
"bulma-switch": "^2.0.0",
|
||||||
"react": "^16.12.0",
|
"react": "^16.12.0",
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React, { Fragment } from 'react';
|
import React, { Fragment } from 'react';
|
||||||
import { Page } from '../Page';
|
import { Page } from '../Page';
|
||||||
import { connect, DispatchProp } from 'react-redux';
|
import { connect, DispatchProp } from 'react-redux';
|
||||||
import Board from '@lourenci/react-kanban';
|
import Board, { addColumn } from '@lourenci/react-kanban';
|
||||||
import { fetchBoards } from '../../store/actions/boards';
|
import { fetchBoards } from '../../store/actions/boards';
|
||||||
import { createIssue } from '../../store/actions/issues';
|
import { createIssue } from '../../store/actions/issues';
|
||||||
import { buildKanboard, moveCard } from '../../store/actions/kanboards';
|
import { buildKanboard, moveCard } from '../../store/actions/kanboards';
|
||||||
@ -13,6 +13,7 @@ export interface BoardPageProps extends DispatchProp {
|
|||||||
board: any
|
board: any
|
||||||
kanboard: any
|
kanboard: any
|
||||||
}
|
}
|
||||||
|
|
||||||
export class BoardPage extends React.Component<BoardPageProps> {
|
export class BoardPage extends React.Component<BoardPageProps> {
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
@ -24,6 +25,7 @@ export class BoardPage extends React.Component<BoardPageProps> {
|
|||||||
project: ""
|
project: ""
|
||||||
},
|
},
|
||||||
compactMode: true,
|
compactMode: true,
|
||||||
|
hasError: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
onNewCardTitleChange: (evt: any) => void;
|
onNewCardTitleChange: (evt: any) => void;
|
||||||
@ -41,19 +43,22 @@ export class BoardPage extends React.Component<BoardPageProps> {
|
|||||||
this.onNewCardSaveClick = this.onNewCardSaveClick.bind(this);
|
this.onNewCardSaveClick = this.onNewCardSaveClick.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidCatch(error, errorInfo) {
|
||||||
|
// You can also log the error to an error reporting service
|
||||||
|
console.error(error, errorInfo);
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { board } = this.props;
|
const { board } = this.props;
|
||||||
return (
|
return (
|
||||||
<Page title={`${board ? (board.title + ' - ') : ''}GenGitKan`}>
|
<Page title={`${board ? (board.title + ' - ') : ''}GenGitKan`}>
|
||||||
<div className="container is-fluid">
|
|
||||||
{this.renderBoard()}
|
{this.renderBoard()}
|
||||||
</div>
|
|
||||||
</Page>
|
</Page>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderBoard() {
|
renderBoard() {
|
||||||
const { kanboard } = this.props;
|
const { kanboard, board } = this.props;
|
||||||
|
|
||||||
if (!kanboard) {
|
if (!kanboard) {
|
||||||
return <Loader></Loader>
|
return <Loader></Loader>
|
||||||
@ -61,29 +66,49 @@ export class BoardPage extends React.Component<BoardPageProps> {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<div className="is-clearfix has-margin-top-normal">
|
<nav className="navbar is-light">
|
||||||
<div className="is-pulled-right">
|
<div className="container is-fluid">
|
||||||
|
<div className="navbar-start">
|
||||||
|
<div className="navbar-item">
|
||||||
|
{board.title}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="navbar-end">
|
||||||
|
<div className="navbar-item">
|
||||||
|
|
||||||
<div className="field">
|
<div className="field">
|
||||||
<input id="compactMode"
|
<input id="compactMode"
|
||||||
checked={this.state.compactMode}
|
checked={this.state.compactMode}
|
||||||
onChange={this.onCompactModeChange.bind(this)}
|
onChange={this.onCompactModeChange.bind(this)}
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
className="switch is-rtl"
|
className="switch is-outlined is-success"
|
||||||
name="compactMode"
|
name="compactMode"
|
||||||
/>
|
/>
|
||||||
<label htmlFor="compactMode">Mode compact</label>
|
<label htmlFor="compactMode">Mode compact</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<a href={`#/boards/${board.id}/edit`} className="navbar-item">
|
||||||
|
<span className="icon">
|
||||||
|
<i className="fa fa-edit fa-fw"></i>
|
||||||
|
</span>
|
||||||
|
<span>Modifier le tableau</span>
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
<div className="container is-fluid">
|
||||||
<div className="kanboard-container is-fullheight">
|
<div className="kanboard-container is-fullheight">
|
||||||
<Board disableLaneDrag={true}
|
<Board
|
||||||
renderCard={this.renderCard.bind(this)}
|
renderCard={this.renderCard.bind(this)}
|
||||||
renderLaneHeader={this.renderLaneHeader}
|
renderColumnHeader={this.renderLaneHeader.bind(this)}
|
||||||
onCardDragEnd={this.onCardDragEnd.bind(this)}>
|
onCardDragEnd={this.onCardDragEnd.bind(this)}
|
||||||
|
disableColumnDrag={true}
|
||||||
|
>
|
||||||
{kanboard}
|
{kanboard}
|
||||||
</Board>
|
</Board>
|
||||||
{ this.renderNewCardModal() }
|
{ this.renderNewCardModal() }
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
|
|
||||||
);
|
);
|
||||||
@ -167,28 +192,49 @@ export class BoardPage extends React.Component<BoardPageProps> {
|
|||||||
<div className="kanboard-lane">
|
<div className="kanboard-lane">
|
||||||
<div className="level">
|
<div className="level">
|
||||||
<div className="level-left">
|
<div className="level-left">
|
||||||
<h3 className="level-item is-size-3">{lane.title}</h3>
|
<div className="level-item">
|
||||||
|
<span className="tag is-primary is-light is-normal">{lane.cards.length}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="level-right">
|
<button className="button is-light level-item is-small expand"
|
||||||
<button className="button is-light level-item is-medium"
|
onClick={this.onMinimizeColumn}>
|
||||||
|
<span className="icon">
|
||||||
|
<i className="fas fa-chevron-right" aria-hidden="true"></i>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
<h3 className="level-item is-size-5">
|
||||||
|
{lane.title}
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
<div className="level-right is-show-expand">
|
||||||
|
<button className="button is-light level-item is-small"
|
||||||
onClick={this.onNewCardClick.bind(this, lane.id)}>
|
onClick={this.onNewCardClick.bind(this, lane.id)}>
|
||||||
<span className="icon">
|
<span className="icon">
|
||||||
<i className="fas fa-plus" aria-hidden="true"></i>
|
<i className="fas fa-plus" aria-hidden="true"></i>
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
|
<button className="button is-light level-item is-small"
|
||||||
|
onClick={this.onMinimizeColumn}>
|
||||||
|
<span className="icon">
|
||||||
|
<i className="fas fa-chevron-left" aria-hidden="true"></i>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
onCardDragEnd(source: any, dest: any) {
|
onMinimizeColumn(e: any) {
|
||||||
|
e.currentTarget.closest('.react-kanban-column').classList.toggle('minimized');
|
||||||
|
}
|
||||||
|
|
||||||
|
onCardDragEnd(card: any, source: any, dest: any) {
|
||||||
const { board } = this.props;
|
const { board } = this.props;
|
||||||
this.props.dispatch(moveCard(
|
this.props.dispatch(moveCard(
|
||||||
board.id,
|
board.id,
|
||||||
source.fromLaneId,
|
source.fromColumnId,
|
||||||
source.fromPosition,
|
source.fromPosition,
|
||||||
dest.toLaneId,
|
dest.toColumnId,
|
||||||
dest.toPosition
|
dest.toPosition
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -16,41 +16,50 @@ export class IssueCard extends React.PureComponent<IssueCardProps> {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="kanboard-card">
|
<div className="kanboard-card">
|
||||||
<div className={`box ${compact ? 'has-padding-small': ''}`}>
|
<div className="box has-padding-small is-radiusless">
|
||||||
<div className="media">
|
<div className="media">
|
||||||
|
<div className="media-content">
|
||||||
|
<div className="content">
|
||||||
|
{ !compact &&
|
||||||
|
<nav className="level">
|
||||||
|
<div className="level-left">
|
||||||
|
<div className="level-item">
|
||||||
|
<a target="_blank" href={issueURL}><strong>{`#${card.issue.number}`}</strong></a>
|
||||||
|
</div>
|
||||||
|
{ !compact &&
|
||||||
|
<div className="level-item">
|
||||||
|
<a target="_blank" href={projectURL}>{card.project}</a>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<div className="level-right">
|
||||||
{
|
{
|
||||||
card.issue.assignee && !compact ?
|
card.issue.assignee && !compact ?
|
||||||
<div className="media-left">
|
<div className="level-item">
|
||||||
<figure className="image is-64x64">
|
|
||||||
<img src={card.issue.assignee.avatar_url} alt="Image" />
|
|
||||||
</figure>
|
|
||||||
<small>{`@${card.issue.assignee.login}`}</small>
|
<small>{`@${card.issue.assignee.login}`}</small>
|
||||||
</div>
|
</div>
|
||||||
: null
|
: null
|
||||||
}
|
}
|
||||||
<div className="media-content">
|
|
||||||
<div className="content">
|
|
||||||
<p>
|
|
||||||
<a target="_blank" href={issueURL}><strong>{`#${card.issue.number}`}</strong></a>
|
|
||||||
{ !compact && card.issue.milestone ? <small>{`- ${card.issue.milestone.title}`}</small> : null }
|
|
||||||
{ !compact ? <br /> : ' - ' }
|
|
||||||
<span className="is-size-6">{card.issue.title}</span>
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</nav>
|
||||||
</div>
|
|
||||||
{
|
|
||||||
!compact ?
|
|
||||||
<div className="level is-mobile" style={{marginTop:'1rem'}}>
|
|
||||||
<div className="level-left">
|
|
||||||
<small className="level-item"><a href={projectURL}>{card.project}</a></small>
|
|
||||||
</div>
|
|
||||||
<div className="level-right">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div> :
|
|
||||||
null
|
|
||||||
}
|
}
|
||||||
|
{ compact &&
|
||||||
|
<a target="_blank" className="mr-1" href={issueURL}><strong>{`#${card.issue.number}`}</strong></a>
|
||||||
|
}
|
||||||
|
<span>{card.issue.title ? card.issue.title : ''}</span>
|
||||||
|
</div>
|
||||||
|
{ !compact &&
|
||||||
|
<nav className="level">
|
||||||
|
<div className="level-left"></div>
|
||||||
|
<div className="level-right">
|
||||||
|
<div className="level-item is-size-7">
|
||||||
|
{card.issue.milestone ? card.issue.milestone.title : ''}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
@import 'bulma/bulma.sass';
|
@import 'bulma/bulma.sass';
|
||||||
|
@import '../../node_modules/@lourenci/react-kanban/dist/styles.css';
|
||||||
@import 'bulma-switch/dist/css/bulma-switch.sass';
|
@import 'bulma-switch/dist/css/bulma-switch.sass';
|
||||||
@import '_base.scss';
|
@import '_base.scss';
|
||||||
@import '_loader.scss';
|
@import '_loader.scss';
|
||||||
|
@ -19,3 +19,7 @@ html, body {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mr-1 {
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
@ -44,6 +44,12 @@
|
|||||||
|
|
||||||
.kanboard-lane {
|
.kanboard-lane {
|
||||||
margin-bottom: $size-small;
|
margin-bottom: $size-small;
|
||||||
|
background: $white;
|
||||||
|
top: 0;
|
||||||
|
|
||||||
|
.expand {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,3 +58,141 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
width: 50% !important;
|
width: 50% !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.react-kanban-board {
|
||||||
|
max-height: calc(100vh - calc(52px * 2));
|
||||||
|
overflow: hidden;
|
||||||
|
overflow-x: scroll;
|
||||||
|
|
||||||
|
scrollbar-color: $grey-lighter, #f1f1f1;
|
||||||
|
scrollbar-width: 5px;
|
||||||
|
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
width: 5px;
|
||||||
|
height: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Track */
|
||||||
|
&::-webkit-scrollbar-track {
|
||||||
|
background: #f1f1f1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handle */
|
||||||
|
&::-webkit-scrollbar-thumb {
|
||||||
|
background: $grey-lighter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handle on hover */
|
||||||
|
&::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: $green;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.react-kanban-column {
|
||||||
|
transition: width ease .2s;
|
||||||
|
max-width: 305px;
|
||||||
|
min-width: 305px;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
max-height: 100%;
|
||||||
|
overflow-x: hidden;
|
||||||
|
overflow-y: scroll;
|
||||||
|
|
||||||
|
scrollbar-color: $grey-lighter, #f1f1f1;
|
||||||
|
scrollbar-width: 5px;
|
||||||
|
|
||||||
|
.kanboard-card {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.minimized {
|
||||||
|
max-width: 70px;
|
||||||
|
min-width: 70px;
|
||||||
|
|
||||||
|
writing-mode: vertical-rl;
|
||||||
|
text-orientation: sideways-right;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.level-item {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.level-left {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.level-right.is-show-expand {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kanboard-lane {
|
||||||
|
/*margin-right: -1em;*/
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
margin-top: .5em;
|
||||||
|
/*margin-right: -.5em;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag {
|
||||||
|
writing-mode: horizontal-tb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.expand {
|
||||||
|
display: block !important;
|
||||||
|
margin-top: .5em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.kanboard-card {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
width: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Track */
|
||||||
|
&::-webkit-scrollbar-track {
|
||||||
|
background: #f1f1f1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handle */
|
||||||
|
&::-webkit-scrollbar-thumb {
|
||||||
|
background: $grey-lighter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handle on hover */
|
||||||
|
&::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: $green;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.react-kanban-card__title {
|
||||||
|
position: sticky;
|
||||||
|
position: -webkit-sticky;
|
||||||
|
}
|
||||||
|
|
||||||
|
.react-kanban-column {
|
||||||
|
background: white !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.kanboard-card {
|
||||||
|
overflow-wrap: break-word;
|
||||||
|
|
||||||
|
a {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.level {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.level-item {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
}
|
@ -37,22 +37,22 @@ function handleMoveCard(state: any, action: any) {
|
|||||||
|
|
||||||
const kanboard = state.byID[boardID];
|
const kanboard = state.byID[boardID];
|
||||||
|
|
||||||
const lanes = [ ...kanboard.lanes ];
|
const columns = [ ...kanboard.columns ];
|
||||||
const fromLane = lanes[fromLaneID];
|
const fromLane = columns[fromLaneID];
|
||||||
const toLane = lanes[toLaneID];
|
const toLane = columns[toLaneID];
|
||||||
const card = fromLane.cards[fromPosition];
|
const card = fromLane.cards[fromPosition];
|
||||||
|
|
||||||
const fromCards = [ ...fromLane.cards ];
|
const fromCards = [ ...fromLane.cards ];
|
||||||
if (fromLaneID !== toLaneID) {
|
if (fromLaneID !== toLaneID) {
|
||||||
fromCards.splice(fromPosition, 1);
|
fromCards.splice(fromPosition, 1);
|
||||||
lanes[fromLaneID] = {
|
columns[fromLaneID] = {
|
||||||
...fromLane,
|
...fromLane,
|
||||||
cards: fromCards,
|
cards: fromCards,
|
||||||
};
|
};
|
||||||
|
|
||||||
const toCards = [ ...toLane.cards ];
|
const toCards = [ ...toLane.cards ];
|
||||||
toCards.splice(toPosition, 0, card);
|
toCards.splice(toPosition, 0, card);
|
||||||
lanes[toLaneID] = {
|
columns[toLaneID] = {
|
||||||
...toLane,
|
...toLane,
|
||||||
cards: toCards,
|
cards: toCards,
|
||||||
};
|
};
|
||||||
@ -67,7 +67,7 @@ function handleMoveCard(state: any, action: any) {
|
|||||||
...state.byID,
|
...state.byID,
|
||||||
[boardID]: {
|
[boardID]: {
|
||||||
...state.byID[boardID],
|
...state.byID[boardID],
|
||||||
lanes,
|
columns,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -22,7 +22,7 @@ export function* moveCardSaga(action: any) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const toLane = kanboard.lanes[toLaneID];
|
const toLane = kanboard.columns[toLaneID];
|
||||||
const card = toLane.cards[toPosition];
|
const card = toLane.cards[toPosition];
|
||||||
|
|
||||||
if (!card) return;
|
if (!card) return;
|
||||||
@ -145,7 +145,7 @@ function createKanboard(board: Board, issues: any) {
|
|||||||
|
|
||||||
const kanboard = {
|
const kanboard = {
|
||||||
id: board.id,
|
id: board.id,
|
||||||
lanes: createKanboardLanes(board, issues),
|
columns: createKanboardLanes(board, issues),
|
||||||
};
|
};
|
||||||
|
|
||||||
return kanboard;
|
return kanboard;
|
||||||
|
@ -3,10 +3,18 @@ import { FETCH_PROJECTS_SUCCESS, FETCH_PROJECTS_FAILURE } from '../actions/proje
|
|||||||
import { gitea } from '../../util/gitea';
|
import { gitea } from '../../util/gitea';
|
||||||
|
|
||||||
export function* fetchProjectsSaga() {
|
export function* fetchProjectsSaga() {
|
||||||
|
let projects = [];
|
||||||
let projects;
|
|
||||||
try {
|
try {
|
||||||
projects = yield call(gitea.fetchUserProjects.bind(gitea))
|
let page = 1;
|
||||||
|
while(true) {
|
||||||
|
let pageProjects = yield call(gitea.fetchUserProjects.bind(gitea), page);
|
||||||
|
if (pageProjects.length === 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
projects.push(...pageProjects);
|
||||||
|
page++;
|
||||||
|
}
|
||||||
|
|
||||||
} catch(error) {
|
} catch(error) {
|
||||||
yield put({ type: FETCH_PROJECTS_FAILURE, error });
|
yield put({ type: FETCH_PROJECTS_FAILURE, error });
|
||||||
return;
|
return;
|
||||||
|
@ -16,8 +16,8 @@ export class GiteaClient {
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchUserProjects() {
|
fetchUserProjects(page = 1) {
|
||||||
return fetch(`/gitea/api/v1/user/repos`)
|
return fetch(`/gitea/api/v1/user/repos?page=${page}`)
|
||||||
.then(this.assertAuthorization)
|
.then(this.assertAuthorization)
|
||||||
.then(this.assertOk)
|
.then(this.assertOk)
|
||||||
.then(res => res.json())
|
.then(res => res.json())
|
||||||
|
Loading…
Reference in New Issue
Block a user