wrong brunch
This commit is contained in:
parent
1b18bc75e7
commit
68e53f2bc5
|
@ -13,6 +13,7 @@
|
|||
},
|
||||
"externals": {},
|
||||
"localizedResources": {
|
||||
"KanbanBoardStrings": "lib/kanban/loc/{locale}.js",
|
||||
"KanbanBoardWebPartStrings": "lib/webparts/kanbanBoard/loc/{locale}.js"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
|
||||
"solution": {
|
||||
"name": "react-kanban-board-client-side-solution",
|
||||
"id": "cccbd72b-7b89-4128-9348-0a4850ded8fd",
|
||||
"version": "1.0.0.0",
|
||||
"includeClientSideAssets": true,
|
||||
"skipFeatureDeployment": true,
|
||||
"isDomainIsolated": false
|
||||
},
|
||||
"paths": {
|
||||
"zippedPackage": "solution/react-kanban-board.sppkg"
|
||||
}
|
||||
}
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
|
||||
"solution": {
|
||||
"name": "react-kanban-board-client-side-solution",
|
||||
"id": "cccbd72b-7b89-4128-9348-0a4850ded8fd",
|
||||
"version": "1.0.1.0",
|
||||
"includeClientSideAssets": true,
|
||||
"skipFeatureDeployment": true,
|
||||
"isDomainIsolated": false
|
||||
},
|
||||
"paths": {
|
||||
"zippedPackage": "solution/react-kanban-board.sppkg"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
import { IKanbanBucket } from "./IKanbanBucket";
|
||||
|
||||
export interface IKanbanBoardTaskActions {
|
||||
|
||||
toggleCompleted?: (taskId: number | string) => void;
|
||||
allowMove?: (taskId: number | string, prevBucket: IKanbanBucket, targetBucket: IKanbanBucket) => boolean;
|
||||
moved?: (taskId: number | string, targetBucket: IKanbanBucket) => void;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
export interface IKanbanBoardTaskSettings {
|
||||
showLabels: boolean;
|
||||
showPriority: boolean;
|
||||
showAssignedTo: boolean;
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
export interface IKanbanBucket {
|
||||
bucket:string;
|
||||
bucketheadline:string;
|
||||
percentageComplete: number;
|
||||
color?:string;
|
||||
allowAddTask?:boolean;
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
export interface IKanbanTask {
|
||||
taskId: number | string;
|
||||
title: string;
|
||||
isCompleted?: boolean;
|
||||
bucket:string;
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
.bucket {
|
||||
display: table-cell;
|
||||
|
||||
|
||||
border-right: 1px solid gray;
|
||||
.headline {
|
||||
padding: 2px 10px;
|
||||
line-height: 2em;
|
||||
font-weight: 700;
|
||||
display: block;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
border-bottom: 1px solid gray;
|
||||
.colorindicator {
|
||||
width: 10px;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0px;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
import * as React from 'react';
|
||||
import styles from './KanbanBucket.module.scss';
|
||||
import { IKanbanBucket } from './IKanbanBucket';
|
||||
import { IKanbanTask } from './IKanbanTask';
|
||||
import { IKanbanBoardTaskSettings } from './IKanbanBoardTaskSettings';
|
||||
import { IKanbanBoardTaskActions } from './IKanbanBoardTaskActions';
|
||||
import { ProgressIndicator } from 'office-ui-fabric-react/lib/ProgressIndicator';
|
||||
import { ActionButton } from 'office-ui-fabric-react';
|
||||
import KanbanTask from './KanbanTask';
|
||||
import * as strings from 'KanbanBoardStrings';
|
||||
|
||||
export interface IKanbanBucketProps extends IKanbanBucket {
|
||||
buckettasks: IKanbanTask[];
|
||||
tasksettings: IKanbanBoardTaskSettings;
|
||||
taskactions: IKanbanBoardTaskActions;
|
||||
|
||||
openDetails?: (taskId: number | string) => void;
|
||||
}
|
||||
|
||||
export interface IKanbanBucketState { }
|
||||
|
||||
export default class KanbanBucket extends React.Component<IKanbanBucketProps, IKanbanBucketState> {
|
||||
|
||||
constructor(props: IKanbanBucketProps) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
|
||||
};
|
||||
}
|
||||
/*
|
||||
nice to use a object merge
|
||||
ECMAScript 2018 Standard Method
|
||||
{...t, ...tasksettings, ...taskactions}
|
||||
hope this will be translated
|
||||
*/
|
||||
public render(): React.ReactElement<IKanbanBucketProps> {
|
||||
const { bucketheadline, color, buckettasks, tasksettings, taskactions, percentageComplete, allowAddTask } = this.props;
|
||||
return (
|
||||
<div className={styles.bucket}
|
||||
onDragOver={(event) => this.onDragOver(event)}
|
||||
onDrop={this.onDrop.bind(this)}
|
||||
>
|
||||
<div className={styles.headline}>
|
||||
<span>{bucketheadline}</span>
|
||||
{color && <div style={{ backgroundColor: color }} className={styles.colorindicator}></div>}
|
||||
<ProgressIndicator percentComplete={percentageComplete / 100} />
|
||||
</div>
|
||||
{allowAddTask && (<ActionButton
|
||||
iconProps={{ iconName: 'Add' }}
|
||||
allowDisabledFocus={true}
|
||||
|
||||
>
|
||||
{strings.AddTask}
|
||||
</ActionButton>)}
|
||||
{
|
||||
buckettasks.map((t) => {
|
||||
const merge = { ...t, ...tasksettings, ...taskactions };
|
||||
return (
|
||||
<KanbanTask
|
||||
{...merge}
|
||||
openDetails={this.props.openDetails}
|
||||
/>
|
||||
);
|
||||
})
|
||||
}
|
||||
</div >
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
private onDragOver(event): void {
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
private onDrop(event): void {
|
||||
// this.props.name
|
||||
// let taskName = event.dataTransfer.getData("taskName");
|
||||
/*
|
||||
let tasks = this.state.tasks.filter((task) => {
|
||||
if (task.taskName == taskName) {
|
||||
task.type = cat;
|
||||
}
|
||||
return task;
|
||||
});
|
||||
|
||||
|
||||
this.setState({
|
||||
...this.state,
|
||||
tasks
|
||||
});
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
.kanbanBoard {
|
||||
display: table;
|
||||
width: 100%;
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
import * as React from 'react';
|
||||
import styles from './KanbanComponent.module.scss';
|
||||
import { IKanbanTask } from './IKanbanTask';
|
||||
import { IKanbanBoardTaskSettings } from './IKanbanBoardTaskSettings';
|
||||
import { IKanbanBoardTaskActions } from './IKanbanBoardTaskActions';
|
||||
import { IKanbanBucket } from './IKanbanBucket';
|
||||
import KanbanBucket from './KanbanBucket';
|
||||
|
||||
import { CommandBar } from 'office-ui-fabric-react/lib/CommandBar';
|
||||
|
||||
export interface IKanbanComponentProps {
|
||||
buckets: IKanbanBucket[];
|
||||
tasks: IKanbanTask[];
|
||||
tasksettings: IKanbanBoardTaskSettings;
|
||||
taskactions: IKanbanBoardTaskActions;
|
||||
showCommandbar?: boolean;
|
||||
/*
|
||||
showCommandbarNew: boolean;
|
||||
allowDialog: boolean; TODO im mock
|
||||
*/
|
||||
}
|
||||
|
||||
export interface IKanbanComponentState { }
|
||||
|
||||
export default class KanbanComponent extends React.Component<IKanbanComponentProps, IKanbanComponentState> {
|
||||
|
||||
constructor(props: IKanbanComponentProps) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
public render(): React.ReactElement<IKanbanComponentProps> {
|
||||
const { buckets, tasks, tasksettings, taskactions, showCommandbar } = this.props;
|
||||
return (
|
||||
<div>
|
||||
{showCommandbar && <CommandBar
|
||||
items={this.getItems()}
|
||||
|
||||
farItems={this.getFarItems()}
|
||||
ariaLabel={'Use left and right arrow keys to navigate between commands'}
|
||||
/>}
|
||||
<div className={styles.kanbanBoard}>
|
||||
{buckets.map((b) =>
|
||||
(<KanbanBucket
|
||||
{...b}
|
||||
buckettasks={tasks.filter((x) => x.bucket == b.bucket)}
|
||||
tasksettings={tasksettings}
|
||||
taskactions={taskactions}
|
||||
openDetails={(x) => alert(x)}
|
||||
/>)
|
||||
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
private getItems = () => {
|
||||
return [
|
||||
{
|
||||
key: 'newItem',
|
||||
name: 'New',
|
||||
cacheKey: 'myCacheKey', // changing this key will invalidate this items cache
|
||||
iconProps: {
|
||||
iconName: 'Add'
|
||||
}
|
||||
}]
|
||||
}
|
||||
|
||||
private getFarItems = () => {
|
||||
return [
|
||||
{
|
||||
key: 'info',
|
||||
name: 'Info',
|
||||
ariaLabel: 'Info',
|
||||
iconProps: {
|
||||
iconName: 'Info'
|
||||
},
|
||||
iconOnly: true,
|
||||
onClick: () => console.log('Info')
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
.taskcard {
|
||||
display: block;
|
||||
.titlerow {
|
||||
.title{
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
.membersAndLabels {
|
||||
.labels,
|
||||
.priority,
|
||||
.assignedto {
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
import * as React from 'react';
|
||||
import styles from './KanbanTask.module.scss';
|
||||
import * as strings from 'KanbanBoardStrings';
|
||||
import { IconButton } from 'office-ui-fabric-react/lib/Button';
|
||||
import {IKanbanTask} from './IKanbanTask';
|
||||
import {IKanbanBoardTaskSettings} from './IKanbanBoardTaskSettings';
|
||||
import {IKanbanBoardTaskActions} from './IKanbanBoardTaskActions';
|
||||
|
||||
export interface IKanbanTaskProps extends IKanbanTask,IKanbanBoardTaskSettings,IKanbanBoardTaskActions {
|
||||
|
||||
|
||||
openDetails?: (taskId: number | string) => void;
|
||||
|
||||
}
|
||||
|
||||
export interface IKanbanTaskState { }
|
||||
|
||||
export default class KanbanTask extends React.Component<IKanbanTaskProps, IKanbanTaskState> {
|
||||
constructor(props: IKanbanTaskProps) {
|
||||
super(props);
|
||||
this.state = {};
|
||||
}
|
||||
public render(): React.ReactElement<IKanbanTaskProps> {
|
||||
|
||||
const { title, showLabels, showPriority, showAssignedTo, isCompleted } = this.props;
|
||||
const showCompleted = !!this.props.toggleCompleted;
|
||||
const iconCompleted = { iconName: isCompleted ? 'RadioBtnOn' : 'RadioBtnOff' };
|
||||
return (
|
||||
<div className={styles.taskcard}
|
||||
onDragStart = {(event) => this.onDragStart(event)}
|
||||
>
|
||||
<div className={styles.titlerow}>
|
||||
{showCompleted && (
|
||||
<IconButton
|
||||
iconProps={iconCompleted}
|
||||
title={isCompleted ? strings.IsCompleted : strings.IsNotCompleted}
|
||||
ariaLabel={isCompleted ? strings.IsCompleted : strings.IsNotCompleted}
|
||||
onClick={this._toggleCompleted.bind(this)}
|
||||
/>)
|
||||
}
|
||||
<div className={styles.title}>{title}</div>
|
||||
</div>
|
||||
<div className={styles.membersAndLabels}>
|
||||
{showAssignedTo && (<div className={styles.assignedto}></div>)}
|
||||
{showLabels && (<div className={styles.labels}></div>)}
|
||||
{showPriority && (<div className={styles.priority}></div>)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
private _toggleCompleted(): void {
|
||||
if (this.props.toggleCompleted) {
|
||||
this.props.toggleCompleted(this.props.taskId);
|
||||
}
|
||||
}
|
||||
|
||||
private onDragStart(event): void {
|
||||
console.log('dragstart on div: ', this.props.taskId);
|
||||
event.dataTransfer.setData("taskId", this.props.taskId);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
import * as React from 'react';
|
||||
import KanbanComponent from './KanbanComponent';
|
||||
import { IKanbanBucket } from './IKanbanBucket';
|
||||
import { IKanbanTask } from './IKanbanTask';
|
||||
|
||||
export interface IMockKanbanProps { }
|
||||
|
||||
export interface IMockKanbanState {
|
||||
buckets: IKanbanBucket[];
|
||||
tasks: IKanbanTask[];
|
||||
}
|
||||
|
||||
export class MockKanban extends React.Component<IMockKanbanProps, IMockKanbanState> {
|
||||
|
||||
constructor(props: IMockKanbanProps) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
buckets:[
|
||||
{bucket:'Not Started', bucketheadline:'Not Started Head',percentageComplete:0, color:'yellow' ,allowAddTask:true},
|
||||
{bucket:'Test1', bucketheadline:'Test1 Head',percentageComplete:10, color:'orange',allowAddTask:true },
|
||||
{bucket:'Test2', bucketheadline:'Test2 Head',percentageComplete:50, color:'green' },
|
||||
{bucket:'Test3', bucketheadline:'Test3 Head',percentageComplete:50, color:'#FF0000' },
|
||||
{bucket:'Test4', bucketheadline:'Test4 Head',percentageComplete:0 ,allowAddTask:true }
|
||||
],
|
||||
tasks: [
|
||||
{taskId: 1, title:'test1',bucket:'Not Started'},
|
||||
{taskId: 2, title:'test2',bucket:'Not Started'},
|
||||
{taskId: 3, title:'test3',bucket:'Not Started'},
|
||||
{taskId: '4', title:'test 4',bucket:'Test4'},
|
||||
{taskId: '5', title:'test 5',bucket:'Test3'},
|
||||
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
public render(): React.ReactElement<IMockKanbanProps> {
|
||||
const { buckets, tasks } = this.state;
|
||||
return (
|
||||
<div>
|
||||
<KanbanComponent
|
||||
buckets={buckets}
|
||||
tasks={tasks}
|
||||
tasksettings={{
|
||||
showLabels: true,
|
||||
showPriority: true,
|
||||
showAssignedTo: true
|
||||
}
|
||||
}
|
||||
taskactions={{
|
||||
toggleCompleted: this._toggleCompleted.bind(this),
|
||||
allowMove: this._allowMove.bind(this),
|
||||
moved: this._moved.bind(this),
|
||||
}}
|
||||
showCommandbar={true}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
private _toggleCompleted(taskId: number | string): void {
|
||||
//TODO
|
||||
}
|
||||
private _allowMove(taskId: number | string, prevBucket: IKanbanBucket, targetBucket: IKanbanBucket): boolean {
|
||||
//TODO
|
||||
return true;
|
||||
}
|
||||
|
||||
private _moved(taskId: number | string, targetBucket: IKanbanBucket): void {
|
||||
//TODO
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
Property Panel:
|
||||
Liste Laden
|
||||
auswahl vom Status mittels Drag n drop PNP COntrol
|
||||
Edit percentrage and color for each State
|
|
@ -0,0 +1,8 @@
|
|||
define([], function() {
|
||||
return {
|
||||
"CompleteButton": "complete",
|
||||
"IsCompleted": "IsCompleted",
|
||||
"IsNotCompleted": "IsNotCompleted",
|
||||
"AddTask": "AddTask"
|
||||
}
|
||||
});
|
|
@ -0,0 +1,11 @@
|
|||
declare interface IKanbanBoardStrings {
|
||||
CompleteButton: string;
|
||||
IsCompleted: string;
|
||||
IsNotCompleted: string;
|
||||
AddTask: string;
|
||||
}
|
||||
|
||||
declare module 'KanbanBoardStrings' {
|
||||
const strings: IKanbanBoardStrings;
|
||||
export = strings;
|
||||
}
|
|
@ -14,6 +14,8 @@ import { IKanbanBoardProps } from './components/IKanbanBoardProps';
|
|||
import "@pnp/polyfill-ie11";
|
||||
import {sp} from '@pnp/sp';
|
||||
|
||||
import {MockKanban,IMockKanbanProps} from '../../kanban/MockKanban';
|
||||
|
||||
export interface IKanbanBoardWebPartProps {
|
||||
listTitle: string;
|
||||
lists: Array<any>;
|
||||
|
@ -36,7 +38,7 @@ export default class KanbanBoardWebPart extends BaseClientSideWebPart<IKanbanBoa
|
|||
public render(): void {
|
||||
|
||||
|
||||
|
||||
/*
|
||||
const element: React.ReactElement<IKanbanBoardProps > = React.createElement(
|
||||
KanbanBoard,
|
||||
{
|
||||
|
@ -44,6 +46,13 @@ export default class KanbanBoardWebPart extends BaseClientSideWebPart<IKanbanBoa
|
|||
webUrl: this.context.pageContext.web.absoluteUrl
|
||||
}
|
||||
);
|
||||
*/
|
||||
const element: React.ReactElement<IMockKanbanProps > = React.createElement(
|
||||
MockKanban,
|
||||
{
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
ReactDom.render(element, this.domElement);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue