Possibilité de créer une voie de type "Backlog"
Une voie peut désormais "récolter" toutes les issues qui ne sont pas déjà sélectionnées par d'autres voies i.e. matérialiser un "backlog". Voir #22
This commit is contained in:
@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import { Page } from '../Page';
|
||||
import { connect } from 'react-redux';
|
||||
import { connect, DispatchProp } from 'react-redux';
|
||||
import Board from '@lourenci/react-kanban';
|
||||
import { fetchBoards } from '../../store/actions/boards';
|
||||
import { createIssue } from '../../store/actions/issues';
|
||||
@ -9,7 +9,11 @@ import { Loader } from '../Loader';
|
||||
import { IssueCard } from './IssueCard';
|
||||
import { Modal } from '../Modal';
|
||||
|
||||
export class BoardPage extends React.Component {
|
||||
export interface BoardPageProps extends DispatchProp {
|
||||
board: any
|
||||
kanboard: any
|
||||
}
|
||||
export class BoardPage extends React.Component<BoardPageProps> {
|
||||
|
||||
state = {
|
||||
newCardModalActive: false,
|
||||
@ -21,7 +25,11 @@ export class BoardPage extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
onNewCardTitleChange: (evt: any) => void;
|
||||
onNewCardBodyChange: (evt: any) => void;
|
||||
onNewCardProjectChange: (evt: any) => void;
|
||||
|
||||
constructor(props: BoardPageProps) {
|
||||
super(props);
|
||||
this.renderLaneHeader = this.renderLaneHeader.bind(this);
|
||||
this.onNewCardClick = this.onNewCardClick.bind(this);
|
||||
@ -90,18 +98,18 @@ export class BoardPage extends React.Component {
|
||||
placeholder="Description du nouveau ticket..."
|
||||
value={this.state.newCard.body}
|
||||
onChange={this.onNewCardBodyChange}
|
||||
rows="10">
|
||||
rows={10}>
|
||||
</textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div className="field">
|
||||
<div className="control is-expanded">
|
||||
<div className="select is-fullwidth"
|
||||
value={this.state.newCard.project}
|
||||
onChange={this.onNewCardProjectChange}>
|
||||
<select>
|
||||
<div className="select is-fullwidth">
|
||||
<select
|
||||
value={this.state.newCard.project}
|
||||
onChange={this.onNewCardProjectChange}>
|
||||
{
|
||||
board.projects.map((p, i) => {
|
||||
board.projects.map((p: any, i: number) => {
|
||||
return <option key={`new-card-project-${i}`} value={p}>{p}</option>
|
||||
})
|
||||
}
|
||||
@ -130,11 +138,11 @@ export class BoardPage extends React.Component {
|
||||
)
|
||||
}
|
||||
|
||||
renderCard(card) {
|
||||
renderCard(card: any) {
|
||||
return <IssueCard card={card} />;
|
||||
}
|
||||
|
||||
renderLaneHeader(lane) {
|
||||
renderLaneHeader(lane: any) {
|
||||
return (
|
||||
<div className="kanboard-lane">
|
||||
<div className="level">
|
||||
@ -154,7 +162,7 @@ export class BoardPage extends React.Component {
|
||||
)
|
||||
}
|
||||
|
||||
onCardDragEnd(source, dest) {
|
||||
onCardDragEnd(source: any, dest: any) {
|
||||
const { board } = this.props;
|
||||
this.props.dispatch(moveCard(
|
||||
board.id,
|
||||
@ -175,7 +183,7 @@ export class BoardPage extends React.Component {
|
||||
this.requestBuildKanboard();
|
||||
}
|
||||
|
||||
onNewCardClick(laneID) {
|
||||
onNewCardClick(laneID: string) {
|
||||
const { board } = this.props;
|
||||
this.setState({
|
||||
newCardModalActive: true,
|
||||
@ -192,9 +200,9 @@ export class BoardPage extends React.Component {
|
||||
this.setState({ newCardModalActive: false });
|
||||
}
|
||||
|
||||
onNewCardAttrChange(attrName, evt) {
|
||||
const value = evt.target.value;
|
||||
this.setState(state => {
|
||||
onNewCardAttrChange(attrName: string, evt: React.ChangeEvent) {
|
||||
const value = (evt.target as HTMLInputElement).value;
|
||||
this.setState((state: any) => {
|
||||
return {
|
||||
...state,
|
||||
newCard: {
|
||||
@ -217,7 +225,7 @@ export class BoardPage extends React.Component {
|
||||
));
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
componentDidUpdate(prevProps: any) {
|
||||
if (prevProps.board !== this.props.board) this.requestBuildKanboard();
|
||||
}
|
||||
|
||||
@ -233,7 +241,7 @@ export class BoardPage extends React.Component {
|
||||
|
||||
}
|
||||
|
||||
export const ConnectedBoardPage = connect(function(state, props) {
|
||||
export const ConnectedBoardPage = connect(function(state: any, props: any) {
|
||||
const boardID = props.match.params.id;
|
||||
return {
|
||||
board: state.boards.byID[boardID],
|
||||
|
@ -30,6 +30,7 @@ export class EditBoardPage extends React.Component<EditorBoardPageProps> {
|
||||
onBoardDescriptionChange: (evt: any) => void;
|
||||
onBoardLaneTitleChange: (laneIndex: any, evt: any) => void;
|
||||
onBoardLaneIssueLabelChange: (laneIndex: any, evt: any) => void;
|
||||
onBoardLaneIssueCollectRemainingIssuesChange: (laneIndex: any, evt: any) => void;
|
||||
|
||||
static getDerivedStateFromProps(props: any, state: any) {
|
||||
const { board, isLoading } = props;
|
||||
@ -54,6 +55,7 @@ export class EditBoardPage extends React.Component<EditorBoardPageProps> {
|
||||
this.onBoardDescriptionChange = this.onBoardAttrChange.bind(this, 'description');
|
||||
this.onBoardLaneTitleChange = this.onBoardLaneAttrChange.bind(this, 'title');
|
||||
this.onBoardLaneIssueLabelChange = this.onBoardLaneAttrChange.bind(this, 'issueLabel');
|
||||
this.onBoardLaneIssueCollectRemainingIssuesChange = this.onBoardLaneAttrChange.bind(this, 'collectRemainingIssues');
|
||||
this.onDeleteBoardClick = this.onDeleteBoardClick.bind(this);
|
||||
}
|
||||
|
||||
@ -223,6 +225,21 @@ export class EditBoardPage extends React.Component<EditorBoardPageProps> {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="field is-horizontal">
|
||||
<div className="field-label is-normal"></div>
|
||||
<div className="field-body">
|
||||
<div className="field">
|
||||
<div className="control">
|
||||
<label className="checkbox">
|
||||
<input type="checkbox"
|
||||
checked={lane.hasOwnProperty('collectRemainingIssues') ? !!lane.collectRemainingIssues : false}
|
||||
onChange={this.onBoardLaneIssueCollectRemainingIssuesChange.bind(this, laneIndex)} />
|
||||
Inclure tous les tickets "restants" (i.e. non sélectionnés par les autres voies)
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="column is-2 is-flex">
|
||||
<div className="buttons">
|
||||
@ -378,13 +395,15 @@ export class EditBoardPage extends React.Component<EditorBoardPageProps> {
|
||||
}
|
||||
|
||||
onBoardLaneAttrChange(attrName: string, laneIndex: number, evt: React.ChangeEvent) {
|
||||
const value = (evt.target as HTMLInputElement).value;
|
||||
const input = evt.target as HTMLInputElement;
|
||||
const value = input.type === "checkbox" ? input.checked : input.value;
|
||||
this.setState((state: any) => {
|
||||
const lanes = [ ...state.board.lanes ];
|
||||
lanes[laneIndex] = {
|
||||
...state.board.lanes[laneIndex],
|
||||
[attrName]: value
|
||||
};
|
||||
console.log(lanes);
|
||||
return {
|
||||
...state,
|
||||
edited: true,
|
||||
|
@ -1,6 +1,10 @@
|
||||
import React from 'react';
|
||||
|
||||
export class IssueCard extends React.PureComponent {
|
||||
export interface IssueCardProps {
|
||||
card: any
|
||||
}
|
||||
|
||||
export class IssueCard extends React.PureComponent<IssueCardProps> {
|
||||
render() {
|
||||
const { card } = this.props;
|
||||
const issueURLInfo = extractInfoFromIssueURL(card.issue.url);
|
||||
@ -49,9 +53,12 @@ export class IssueCard extends React.PureComponent {
|
||||
}
|
||||
}
|
||||
|
||||
function extractInfoFromIssueURL(issueURL) {
|
||||
function extractInfoFromIssueURL(issueURL: string): any|void {
|
||||
const pattern = /^(https?:\/\/[^\/]+)\/api\/v1\/repos\/([^\/]+)\/([^\/]+)\/.*$/;
|
||||
const matches = pattern.exec(issueURL);
|
||||
|
||||
if (!matches) return;
|
||||
|
||||
return {
|
||||
baseURL: matches[1],
|
||||
owner: matches[2],
|
||||
|
@ -2,8 +2,8 @@ import React, { PropsWithChildren } from 'react';
|
||||
|
||||
export interface ModalProps {
|
||||
active: boolean
|
||||
showCloseButton: boolean
|
||||
onClose: (evt: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void
|
||||
showCloseButton?: boolean
|
||||
onClose?: (evt: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void
|
||||
}
|
||||
|
||||
export class Modal extends React.PureComponent<PropsWithChildren<ModalProps>> {
|
||||
|
Reference in New Issue
Block a user